前言
大部分的商城都需要调用快递的接口来记录商城的物流信息,这里就给出一种快递接口(快递100)调用的方法。
正文
一、官方文档
1. 官方文档的地址为:
https://www.kuaidi100.com/openapi/api_subscribe.shtml
二、具体实现
1. 商城服务与快递接口服务具体交互示意图:
具体的实现逻辑为:
我们将订单号发给快递100,然后订阅该订单号的消息。当快递100中有订阅信息产生的时候,就会给指定的地址发一个消息去推送类似的消息。
贵公司将需要跟踪的运单提交给快递100指定的接口,快递100接到后就对这些单号进行监控,如果监控到运单有了更新,就主动将这些物流跟踪信息推送到贵公司指定的接口,
直到这些单的生命周期结束(一般以“已签收”为准),一个运单快递100一般会多次推送多条跟踪信息,贵方将之保存到数据库。当用户登录贵方网站、系统或手机APP时,
直接从贵司的数据库读取数据,并显示于贵方的网站、系统或手机APP。
2. 代码实现
(1)订阅某个订单信息
public static function subscribeExpress($courier_company, $courier_no){$data = ['company' => $courier_company,'number' => $courier_no,'key' => config('express_config.poll_key'),'parameters' => ['callbackurl' => env('API_HOST', 'http://panda.qujie8.com/') . 'api/alipay/express/notify','departureCountry' => 'CN']];$post_data = ['schema' => 'json','param' => json_encode($data),];Log::info('订阅快递100参数', [$post_data]);$o = '';foreach ($post_data as $k => $v) {$o .= "$k=" . urlencode($v) . '&';//默认UTF-8编码格式 }$post_data = substr($o, 0, -1);$url = env('EXPRESS_PUST_URL', 'http://poll.kuaidi100.com/poll');$ch = curl_init();curl_setopt($ch, CURLOPT_POST, 1);curl_setopt($ch, CURLOPT_HEADER, 0);curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);$rst = curl_exec($ch);curl_close($ch);Log::info('订阅快递100结果', [$rst]);$rst = json_decode($rst, 1);Log::info('订阅快递100结果', [$rst]);if ($rst['result'] == false) {if ($rst['returnCode'] == 501) {Log::info('订阅快递100重复', [$rst, 'company' => $courier_company, 'courier_no' => $courier_no]);return true;}throw new ServiceException('订阅快递100失败', $rst['returnCode']);}return true;}
(2)接收每个订单信息的回调
/*** 快递100回调*/public static function notifyExpressInfo($poll_express_info){$company = array_get($poll_express_info['lastResult'], 'com');$number = array_get($poll_express_info['lastResult'], 'nu');$borrow_express_type = FrontConst::BORROW_EXPRESS_TYPE_BORROW;$borrow_info = Borrow::where('business_courier_company_name', $company)->where('business_courier_no', $number)->first();if (empty($borrow_info)) {$borrow_express_type = FrontConst::BORROW_EXPRESS_TYPE_RETURN;$borrow_info = Borrow::where('courier_company_name', $company)->where('courier_no', $number)->first();}if (!empty($borrow_info)) {if ($borrow_info->status == FrontConst::STATUS_BORROW_DONE_RETURN) {\Log::info('---快递100传输已完成的订单号--', ['borrow_id' => $borrow_info->id, 'status' => $borrow_info->status, 'business_courier_no' => $borrow_info->business_courier_no, 'Request_courier_no' => $number]);throw new ServiceException('此单号已还书完成无需操作', -2000);}}if (empty($borrow_info)) {throw new ServiceException('没有该订单匹配的物流单号', -1000);}$express_last_info = array_get($poll_express_info, 'lastResult');if (empty($express_last_info)) {throw new ServiceException('没有最新快递物流信息', -1000);}$ischeck = array_get($express_last_info, 'ischeck');try {DB::beginTransaction();$express_data = array_reverse($express_last_info['data']);foreach ($express_data as $key => $value) {//查询该快递信息是否已经录入$borrow_express = BorrowExpress::where('borrow_id', $borrow_info->id)->where('ftime', $value['ftime'])->first();if (empty($borrow_express)) {$express_info = ['ischeck' => $ischeck,'state' => ExpressConst::$expressState[$express_last_info['state']],'ftime' => $value['ftime'],'content' => $value['context'],'control_status' => ExpressConst::$expressStatus[$poll_express_info['status']],'control_message' => $poll_express_info['message'],];//增加快递信息self::addExpress($borrow_info->id, $borrow_info->borrow_source, $borrow_info->status, $express_info, $borrow_express_type);}}//快递被签收if ($ischeck == 1 && $borrow_express_type == FrontConst::BORROW_EXPRESS_TYPE_BORROW) {$borrow_info->status = FrontConst::STATUS_BORROW_RECEIPT_DELIVERY;//修改订单dead_line,支付宝小程序不需要修改if ($borrow_info->borrow_source != FrontConst::SOURCE_ALIPAY_APPLETS) {$dead_line_info = BorrowRepository::getBorrowDeadOverdue($borrow_info);$borrow_info->dead_line = empty($dead_line_info['dead_line']) ? $borrow_info->dead_line : $dead_line_info['dead_line'];}$borrow_info->save();$return_time = strtotime($borrow_info->dead_line);if ($borrow_info->borrow_source == FrontConst::SOURCE_ALIPAY_APPLETS) {$return_time -= FrontConst::APPLETS_RENTS_EXPRESS_RETURN_TIME * 3600 * 24;}if ($borrow_info->borrow_source == FrontConst::SOURCE_ALIPAY) {//判断是否是信用借还$notify_alipay_status = true;$user_package = $borrow_info->user_package;$package_info = empty($user_package->book_package) ? $user_package->package : $user_package->book_package;$notify_alipay_status = (!empty($user_package->book_package)) ? true : ($package_info->subscribe_times > 1 ? false : true);//通知支付宝修改订单时间if ($notify_alipay_status) {BorrowRepository::orderRentModify($borrow_info, $dead_line_info['dead_line']);\Log::info('该订单' . $borrow_info->id . '使用的是' . $package_info->name . ',不需要修改到期时间', ['id' => $borrow_info->id]);}}self::addExpress($borrow_info->id, $borrow_info->borrow_source, $borrow_info->status);//发送短信SmsEntrance::sendCodeByScene($borrow_info->mobile, SmsEntrance::SCENES_USER_BORROW_RECEIPT, date('m', $return_time), date('d', $return_time));}DB::commit();} catch (ServiceException $e) {DB::rollBack();Log::error($e);throw new ServiceException($e->getMessage(), $e->getCode());} catch (Exception $e) {DB::rollBack();Log::error($e);throw new ServiceException($e->getMessage(), $e->getCode());}return true;}
后记
日子要一天一天的过,知识要一点一点的积累。