Model_cnev1.php 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. <?php
  2. class Model_Cnev1 extends Lin_Model {
  3. function __construct(){
  4. parent::__construct();
  5. $this->load->_model("Model_logic_ding","logic_ding");
  6. }
  7. public $appKey = 'LY3600_80601';
  8. public $appSecret = 'ee19055cef434ea8a17532df25dc033a';
  9. public $nonce = 'slnkda';
  10. public $version = '1.0';
  11. public $url = "https://pos.mailiancn.com";
  12. public function get_data($data)//海外
  13. {
  14. $cs = array('1'=>'2'.'nd','2'=>'3'.'rd','3'=>'4'.'th','4'=>'5'.'th','5'=>'6'.'th','6'=>'7'.'th','7'=>'8'.'th','8'=>'9'.'th','9'=>'10'.'th','10'=>'11'.'th','11'=>'12'.'th');
  15. $printnumber = ($data['printnumber']==0)?'':'-'.$cs[$data['printnumber']];
  16. //其中 FED_PB_CA=US-FED-GD-LAX-XY 邮编开头4-9 FED_PB_CA=US-FED-GD-JFK-XY 邮编开头0-3
  17. $code = array('FEDEX_G'=>array('US-2DAYS-JM',' US-2DAYS-JM','80-86'),'FedEx_GD'=>array('US-FED-GD-LAX-XY','US-FED-GD-JFK-XY','80-86'));
  18. $channel_code = '';
  19. if(!isset($code[$data['printcode']])){
  20. return array('x'=>'0','Description'=>'渠道未设置,请联系技术');
  21. }else{
  22. if($data['printcode'] == 'FEDEX_G'){
  23. $channel_code = $code[$data['printcode']][0];
  24. }elseif($data['printcode'] == 'FedEx_GD'){
  25. $first_zipcode = substr($data['zipcode'], 0, 1);
  26. if($first_zipcode >= 4){
  27. $channel_code = 'US-FED-GD-LAX-XY';
  28. }else{
  29. $channel_code = 'US-FED-GD-JFK-XY';
  30. }
  31. }
  32. }
  33. $ToState = array('alabama'=>'AL','alaska'=>'AK','arizona'=>'AZ','arkansas'=>'AR','california'=>'CA','colorado'=>'CO','connecticut'=>'CT','delaware'=>'DE','florida'=>'FL','georgia'=>'GA','hawaii'=>'HI','idaho'=>'ID','illinois'=>'IL','indiana'=>'IN','iowa'=>'IA','kansas'=>'KS','kentucky'=>'KY','louisiana'=>'LA','maine'=>'ME','maryland'=>'MD','massachusetts'=>'MA','michigan'=>'MI','minnesota'=>'MN','mississippi'=>'MS','missouri'=>'MO','montana'=>'MT','nebraska'=>'NE','nevada'=>'NV','new hampshire'=>'NH','new jersey'=>'NJ','new mexico'=>'NM','new york'=>'NY','north carolina'=>'NC','north dakota'=>'ND','ohio'=>'OH','oklahoma'=>'OK','oregon'=>'OR','pennsylvania'=>'PA','rhode island'=>'RI','south carolina'=>'SC','south dakota'=>'SD','tennessee'=>'TN','texas'=>'TX','utah'=>'UT','vermont'=>'VT','virginia'=>'VA','washington'=>'WA','west virginia'=>'WV','wisconsin'=>'WI','wyoming'=>'WY','district of columbia'=>'DC','virgin islands'=>'VI','guam'=>'GU','puerto rico'=>'PR');
  34. $data['province'] = preg_replace('/( | | |\s)/',' ',$data['province']);
  35. $data['province'] = trim($data['province'],' ');
  36. $dataprovince = strlen($data['province'])==2?$data['province']:$ToState[strtolower($data['province'])];
  37. $params = [
  38. 'platformType'=>'ZYXT',
  39. 'referenceno'=>$data['number'].$printnumber,//参考编号(订单号码)
  40. 'hubInCode'=>$channel_code,//指定路线
  41. 'weig'=>$data['zzl'],//重量[KG](
  42. 'reName'=>$data['name'],//收件人
  43. 'reCompany'=>$data['client'],//收件人公司
  44. 'reTel'=>preg_replace('/\D/s','',$data['phone']),//收件人电话
  45. 'reAddr'=>$data['address'].' '.$data['address2'],//500个字符
  46. 'reCountryCode'=>$data['lb'],//收件国家二字码
  47. 'reState'=> $dataprovince,//收件州/省
  48. 'reCity'=>$data['city'],//收件城市
  49. 'reDistrict'=>$data['street'],//收件区县
  50. 'reZip'=>trim($data['zipcode'],' '),//收件邮编
  51. 'reEmail'=>trim($data['email']),//收件邮箱
  52. 'sdName'=>'Kenny Kwok',//寄件人
  53. 'sdCompany'=>'Long Human Hair Factory Inc- Kenny Kwok',//
  54. 'sdTel'=>'929-389-8183',//寄件电话
  55. 'sdAddr'=>'819 6th Avenue Store front',//寄件地址 120个字符
  56. 'sdCountryCode'=>'US',//寄件国家简码
  57. 'sdState'=>'NY',//寄件州/省
  58. 'sdCity'=>'New York',//寄件城市
  59. 'sdDistrict'=>'',//寄件区县
  60. 'sdZip'=>'10001',//寄件邮编
  61. //'sdEmail'=>'',//寄件邮箱
  62. 'ccPayment'=>'PP',//付款方式
  63. 'cctaxPayment'=>'PP',//税金支付方式
  64. 'decValueCur'=>'USD',//申报币别
  65. 'oisInvoices'=>[
  66. [
  67. 'descrName'=>$data['zwpm'],//中文品名
  68. 'eDescrNamee'=>$data['sbpm'].'*'.$data['ts'],//英文品名
  69. 'qty'=>$data['ts'],//申报数量
  70. 'price'=>$data['dtsbjz'],//申报单价
  71. 'hsCode'=>isset($data['sbbm'])? $data['sbbm'] : "",
  72. ]
  73. ]
  74. ];
  75. $time = time();
  76. $time = $time.'000';
  77. $token = $this->getToken($time);
  78. if(empty($token)){
  79. return array('x'=>'0','Description'=>'获取token,请重试。如果还不行,请联系技术');
  80. }
  81. $this->logic_ding->sendToDing("云尚快递V1erp请求参数【".json_encode($params,JSON_UNESCAPED_UNICODE)."】");
  82. $ret_head = $this->getHeaders($token,$time);
  83. $url = $this->url."/ois/order";
  84. $ch = curl_init($url);
  85. $headers= [
  86. 'Content-Type: application/json',
  87. 'token:'.$ret_head['token'],
  88. 'sign:'.$ret_head['sign'],
  89. 'version:'.$ret_head['version'],
  90. ];
  91. curl_setopt_array($ch, [
  92. CURLOPT_POST => true,
  93. CURLOPT_POSTFIELDS => json_encode($params), // 关键:先 json_encode
  94. CURLOPT_HTTPHEADER => $headers,
  95. CURLOPT_RETURNTRANSFER => true, // 把响应作为字符串返回
  96. CURLOPT_TIMEOUT => 10,
  97. // 测试环境临时关闭 SSL 验证(两个都要加)
  98. CURLOPT_SSL_VERIFYPEER => false,
  99. CURLOPT_SSL_VERIFYHOST => 0,
  100. ]);
  101. $response = curl_exec($ch);
  102. $this->logic_ding->sendToDing("云尚快递报文信息【".json_encode($params,JSON_UNESCAPED_UNICODE)."】返回参数[".$response."];访问地址".$url);
  103. if ($response === false) {
  104. curl_close($ch);
  105. return array('x'=>'0','Description'=>'cURL Error: ' . curl_error($ch));
  106. }
  107. curl_close($ch);
  108. // 如果返回的是 JSON,可直接解码
  109. $result = json_decode($response, true);
  110. if(!isset($result['body'])){
  111. return array('x'=>'0','Description'=>$result['message']);
  112. }
  113. if(empty($result['body']['labelUrl'])){
  114. return array('x'=>'0','Description'=>"获取云尚打印快递面单失败!");
  115. }
  116. if(empty($result['body']['oddNo'])){
  117. return array('x'=>'0','Description'=>"获取云尚打印快递单号失败!");
  118. }
  119. $g = array('x'=>'1','waybillid'=>'','waybill'=>$result['body']['oddNo'],'yd'=>$result['body']['labelUrl']);
  120. return $g;
  121. }
  122. //取消运单
  123. public function cancel_yd($waybill){
  124. $url = $this->url."/ois/order/cancel";
  125. $params = [
  126. 'codeType'=>1,
  127. 'noList'=>$waybill
  128. ];
  129. $time = time();
  130. $time = $time.'000';
  131. $token = $this->getToken($time);
  132. if(empty($token)){
  133. return "";
  134. }
  135. $ret_head = $this->getHeaders($token,$time);
  136. $ch = curl_init($url);
  137. $headers= [
  138. 'Content-Type: application/json',
  139. 'token:'.$ret_head['token'],
  140. 'sign:'.$ret_head['sign'],
  141. 'version:'.$ret_head['version'],
  142. ];
  143. curl_setopt_array($ch, [
  144. CURLOPT_POST => true,
  145. CURLOPT_POSTFIELDS => json_encode($params), // 关键:先 json_encode
  146. CURLOPT_HTTPHEADER => $headers,
  147. CURLOPT_RETURNTRANSFER => true, // 把响应作为字符串返回
  148. CURLOPT_TIMEOUT => 10,
  149. // 测试环境临时关闭 SSL 验证(两个都要加)
  150. CURLOPT_SSL_VERIFYPEER => false,
  151. CURLOPT_SSL_VERIFYHOST => 0,
  152. ]);
  153. $response = curl_exec($ch);
  154. if ($response === false) {
  155. curl_close($ch);
  156. return "";
  157. }
  158. return $response;
  159. }
  160. public function getToken($time){
  161. $this->load->driver('cache');
  162. $cache_key = 'yunshangkuaidi_token_3_hours';
  163. $cached = $this->cache->get($cache_key);
  164. if ($cached !== FALSE) {
  165. return $cached;
  166. }
  167. $params = [
  168. 'appKey' => $this->appKey,
  169. 'appSecret' => $this->appSecret
  170. ];
  171. $headers = [
  172. 'Content-Type' => 'application/x-www-form-urlencoded'
  173. ];
  174. $url = $this->url . '/ois/order/getAuth?'.http_build_query($params);
  175. $ch = curl_init();
  176. curl_setopt_array($ch, [
  177. CURLOPT_URL => $url,
  178. CURLOPT_POST => true,
  179. // 关键:用 http_build_query 转成字符串,这样 Content-Type 才是 form-urlencoded
  180. CURLOPT_POSTFIELDS => http_build_query([]),
  181. CURLOPT_RETURNTRANSFER => true,
  182. CURLOPT_TIMEOUT => 30,
  183. // 请求头(可选,显式声明)
  184. CURLOPT_HTTPHEADER => $headers,
  185. // 不验证 SSL 证书
  186. CURLOPT_SSL_VERIFYPEER => false,
  187. CURLOPT_SSL_VERIFYHOST => false,
  188. ]);
  189. $response = curl_exec($ch);
  190. if ($response === false) {
  191. curl_close($ch);
  192. return "";
  193. } else {
  194. curl_close($ch);
  195. // $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  196. // echo "HTTP: {$httpCode}\n";
  197. // echo $response;
  198. $arr = json_decode($response,true);
  199. if(empty($arr['body'])){
  200. return "";
  201. }
  202. if(empty($arr['body']['token'])){
  203. return "";
  204. }
  205. $this->cache->save($cache_key,$arr['body']['token'], 10000); // 缓存3小时 少几分钟
  206. return $arr['body']['token'];
  207. }
  208. }
  209. private function getHeaders($token,$time){
  210. $tokenArr = array(
  211. 'timestamp' => $time,
  212. 'nonce' => $this->nonce,
  213. 'token' => $token,
  214. );
  215. $jsonStr = json_encode($tokenArr);
  216. //var_dump("伪装token json字符串:", $jsonStr);
  217. $tokenStr = base64_encode($jsonStr);
  218. //var_dump('伪装token base64', $tokenStr);
  219. $tokenStr = strtr($tokenStr, array('a' => '-', 'c' => '#', 'x' => '^', 'M' => '$'));
  220. //var_dump('伪装token 替换后', $tokenStr);
  221. $sign = $this->getSign($time,$token);
  222. return [
  223. 'token' => $tokenStr,
  224. 'version' => $this->version,
  225. 'sign' => $sign
  226. ];
  227. }
  228. private function getSign($time,$token){
  229. // 计算签名
  230. $data = [
  231. 'timestamp' => $time,
  232. 'nonce' => $this->nonce,
  233. 'token' => $token,
  234. 'version' => $this->version
  235. ];
  236. ksort($data);
  237. $string = "";
  238. foreach ($data as $key => $value) {
  239. if (strlen($string) > 0) {
  240. $string = $string . "&" . $key . "=" . $value;
  241. } else {
  242. $string = $string . "" . $key . "=" . $value;
  243. }
  244. }
  245. $paramStr = $string;
  246. $base64Str = base64_encode($paramStr);
  247. $md5 = md5($base64Str . $this->appSecret);
  248. $sign = strtoupper($md5);
  249. return $sign;
  250. }
  251. } //end class