KdnService.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <?php
  2. namespace services\extend\logistics;
  3. use Yii;
  4. use Exception;
  5. use common\forms\LogisticsForm;
  6. use linslin\yii2\curl\Curl;
  7. use yii\helpers\Json;
  8. use yii\web\NotFoundHttpException;
  9. /**
  10. * Class KdnService
  11. * @package services\extend\logistics
  12. * @author jianyan74 <751393839@qq.com>
  13. */
  14. class KdnService
  15. {
  16. const URL = 'https://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx';
  17. const Sand_Box_URL = 'http://sandboxapi.kdniao.com:8080/kdniaosandbox/gateway/exterfaceInvoke.json';
  18. const KDNIAO_DATA_TYPE = 2;
  19. const SUCCESS_STATUS = 200;
  20. const STATUS_NO_TRACK = 0;
  21. const STATUS_PACKAGE = 1;
  22. const STATUS_ON_THE_WAY = 2;
  23. const STATUS_SIGNING = 3;
  24. const STATUS_QUESTION_PACKAGE = 4;
  25. const STATUS_IN_THE_CITY = 201;
  26. const STATUS_IN_THE_PACKAGE = 202;
  27. const STATUS_DIEPOSIT_ARK = 211;
  28. const STATUS_NORMAL_SIGNING = 301;
  29. const STATUS_ABNORMAL_SIGNING = 302;
  30. const STATUS_ISSUING_SIGNING = 304;
  31. const STATUS_ARK_SIGNING = 311;
  32. const STATUS_NO_DELIVERY_INFO = 401;
  33. const STATUS_TIMEOUT_NOT_SIGNING = 402;
  34. const STATUS_TIMEOUT_NOT_UPDATE = 403;
  35. const STATUS_RETURN_PACKAGE = 404;
  36. const STATUS_PACKAGE_ERROR = 405;
  37. const STATUS_RETURN_SINGNING = 406;
  38. const STATUS_RETURN_NOT_SINGNING = 407;
  39. const STATUS_ARK_NOT_SINGNING = 412;
  40. /**
  41. * @var string[]
  42. */
  43. public $statusMap = [
  44. self::STATUS_NO_TRACK => '无轨迹',
  45. self::STATUS_PACKAGE => '已揽收',
  46. self::STATUS_SIGNING => '已签收',
  47. self::STATUS_ON_THE_WAY => '在途中',
  48. self::STATUS_QUESTION_PACKAGE => '问题件',
  49. self::STATUS_IN_THE_CITY => '到达派件城市',
  50. self::STATUS_IN_THE_PACKAGE => '派件中',
  51. self::STATUS_DIEPOSIT_ARK => '已放入快递柜或驿站',
  52. self::STATUS_NORMAL_SIGNING => '正常签收',
  53. self::STATUS_ABNORMAL_SIGNING => '派件异常后最终签收',
  54. self::STATUS_ISSUING_SIGNING => '代收签收',
  55. self::STATUS_ARK_SIGNING => '快递柜或驿站签收',
  56. self::STATUS_NO_DELIVERY_INFO => '发货无信息',
  57. self::STATUS_TIMEOUT_NOT_SIGNING => '超时未签收',
  58. self::STATUS_TIMEOUT_NOT_UPDATE => '超时未更新',
  59. self::STATUS_RETURN_PACKAGE => '拒收(退件)',
  60. self::STATUS_PACKAGE_ERROR => '派件异常',
  61. self::STATUS_RETURN_SINGNING => '退货签收',
  62. self::STATUS_RETURN_NOT_SINGNING => '退货未签收',
  63. self::STATUS_ARK_NOT_SINGNING => '快递柜或驿站超时未取',
  64. ];
  65. /**
  66. * @param $no
  67. * @param $company
  68. * @param int $customerName ShipperCode 为 SF (顺丰) 时必填;对应寄件人/收件人手机号后四位
  69. * @return LogisticsForm
  70. * @throws NotFoundHttpException
  71. */
  72. public function query($no, $company = null, $customerName = null)
  73. {
  74. // 无物流公司,自动匹配物流
  75. if (empty($company)) {
  76. $companies = $this->autoCompanies([
  77. 'LogisticCode' => $no,
  78. ]);
  79. $company = $companies['Shippers'][0]['ShipperCode'];
  80. }
  81. $params = [
  82. 'LogisticCode' => $no,
  83. 'ShipperCode' => $company,
  84. 'CustomerName' => $customerName,
  85. ];
  86. $curl = new Curl();
  87. $request = $curl->setHeaders([
  88. 'Content-Type' => 'application/x-www-form-urlencoded;charset=utf-8',
  89. ])->setPostParams($this->getRequestParams($params, 1002))->post(self::URL);
  90. $data = Json::decode($request);
  91. if ($data['Success'] == false) {
  92. throw new NotFoundHttpException($data['Reason']);
  93. }
  94. $form = new LogisticsForm();
  95. $form->no = $no;
  96. $form->company = $company;
  97. $form->code = 200;
  98. $form->message = 'ok';
  99. $form->original = $data['Traces'];
  100. if (!empty($form->original)) {
  101. foreach ($form->original as $item) {
  102. $form->list[] = [
  103. 'datetime' => $item['AcceptTime'],
  104. 'remark' => $item['AcceptStation'],
  105. 'zone' => $item['Remark'],
  106. ];
  107. }
  108. }
  109. return $form;
  110. }
  111. /**
  112. * 获取物流公司列表
  113. *
  114. * @return mixed|null
  115. * @throws Exception
  116. */
  117. public function companies()
  118. {
  119. return [];
  120. }
  121. /**
  122. * 自动匹配单号
  123. *
  124. * @param $no
  125. * @return mixed|null
  126. * @throws NotFoundHttpException
  127. */
  128. public function autoCompanies($params)
  129. {
  130. $curl = new Curl();
  131. $request = $curl->setHeaders([
  132. 'Content-Type' => 'application/x-www-form-urlencoded;charset=utf-8',
  133. ])->setGetParams($this->getRequestParams($params, 2002))->get(self::URL);
  134. $data = Json::decode($request);
  135. if ($data['Success'] == false) {
  136. throw new NotFoundHttpException($data['Reason']);
  137. }
  138. // 错误码
  139. if (empty($data) || empty($data['Shippers'][0]['ShipperCode'])) {
  140. throw new NotFoundHttpException('未查询到该订单信息!');
  141. }
  142. return $data;
  143. }
  144. /**
  145. * @param $requestData
  146. * @param $requestType
  147. *
  148. * @return array
  149. */
  150. private function getRequestParams($requestData, $requestType)
  151. {
  152. return [
  153. 'EBusinessID' => trim(Yii::$app->services->config->backendConfig('logistics_kdniao_app_id')),
  154. 'DataType' => self::KDNIAO_DATA_TYPE,
  155. 'RequestType' => $requestType,
  156. 'RequestData' => urlencode(Json::encode($requestData)),
  157. 'DataSign' => $this->generateSign($requestData, trim(Yii::$app->services->config->backendConfig('logistics_kdniao_app_key'))),
  158. ];
  159. }
  160. /**
  161. * @param $param
  162. * @param $key
  163. *
  164. * @return string
  165. */
  166. protected function generateSign($param, $key)
  167. {
  168. return urlencode(base64_encode(md5(Json::encode($param).$key)));
  169. }
  170. }
粤ICP备19079148号