load->_model("Model_logic_ding","logic_ding"); } public $appKey = 'LY3600_80601'; public $appSecret = 'ee19055cef434ea8a17532df25dc033a'; public $nonce = 'slnkda'; public $version = '1.0'; public $url = "https://pos.mailiancn.com"; public function get_data($data)//海外 { $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'); $printnumber = ($data['printnumber']==0)?'':'-'.$cs[$data['printnumber']]; //其中 FED_PB_CA=US-FED-GD-LAX-XY 邮编开头4-9 FED_PB_CA=US-FED-GD-JFK-XY 邮编开头0-3 $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')); $channel_code = ''; if(!isset($code[$data['printcode']])){ return array('x'=>'0','Description'=>'渠道未设置,请联系技术'); }else{ if($data['printcode'] == 'FEDEX_G'){ $channel_code = $code[$data['printcode']][0]; }elseif($data['printcode'] == 'FedEx_GD'){ $first_zipcode = substr($data['zipcode'], 0, 1); if($first_zipcode >= 4){ $channel_code = 'US-FED-GD-LAX-XY'; }else{ $channel_code = 'US-FED-GD-JFK-XY'; } } } $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'); $data['province'] = preg_replace('/( | | |\s)/',' ',$data['province']); $data['province'] = trim($data['province'],' '); $dataprovince = strlen($data['province'])==2?$data['province']:$ToState[strtolower($data['province'])]; $params = [ 'platformType'=>'ZYXT', 'referenceno'=>$data['number'].$printnumber,//参考编号(订单号码) 'hubInCode'=>$channel_code,//指定路线 'weig'=>$data['zzl'],//重量[KG]( 'reName'=>$data['name'],//收件人 'reCompany'=>$data['client'],//收件人公司 'reTel'=>preg_replace('/\D/s','',$data['phone']),//收件人电话 'reAddr'=>$data['address'].' '.$data['address2'],//500个字符 'reCountryCode'=>$data['lb'],//收件国家二字码 'reState'=> $dataprovince,//收件州/省 'reCity'=>$data['city'],//收件城市 'reDistrict'=>$data['street'],//收件区县 'reZip'=>trim($data['zipcode'],' '),//收件邮编 'reEmail'=>trim($data['email']),//收件邮箱 'sdName'=>'Kenny Kwok',//寄件人 'sdCompany'=>'Long Human Hair Factory Inc- Kenny Kwok',// 'sdTel'=>'929-389-8183',//寄件电话 'sdAddr'=>'819 6th Avenue Store front',//寄件地址 120个字符 'sdCountryCode'=>'US',//寄件国家简码 'sdState'=>'NY',//寄件州/省 'sdCity'=>'New York',//寄件城市 'sdDistrict'=>'',//寄件区县 'sdZip'=>'10001',//寄件邮编 //'sdEmail'=>'',//寄件邮箱 'ccPayment'=>'PP',//付款方式 'cctaxPayment'=>'PP',//税金支付方式 'decValueCur'=>'USD',//申报币别 'oisInvoices'=>[ [ 'descrName'=>$data['zwpm'],//中文品名 'eDescrNamee'=>$data['sbpm'].'*'.$data['ts'],//英文品名 'qty'=>$data['ts'],//申报数量 'price'=>$data['dtsbjz'],//申报单价 'hsCode'=>isset($data['sbbm'])? $data['sbbm'] : "", ] ] ]; $time = time(); $time = $time.'000'; $token = $this->getToken($time); if(empty($token)){ return array('x'=>'0','Description'=>'获取token,请重试。如果还不行,请联系技术'); } $this->logic_ding->sendToDing("云尚快递V1erp请求参数【".json_encode($params,JSON_UNESCAPED_UNICODE)."】"); $ret_head = $this->getHeaders($token,$time); $url = $this->url."/ois/order"; $ch = curl_init($url); $headers= [ 'Content-Type: application/json', 'token:'.$ret_head['token'], 'sign:'.$ret_head['sign'], 'version:'.$ret_head['version'], ]; curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($params), // 关键:先 json_encode CURLOPT_HTTPHEADER => $headers, CURLOPT_RETURNTRANSFER => true, // 把响应作为字符串返回 CURLOPT_TIMEOUT => 10, // 测试环境临时关闭 SSL 验证(两个都要加) CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => 0, ]); $response = curl_exec($ch); $this->logic_ding->sendToDing("云尚快递报文信息【".json_encode($params,JSON_UNESCAPED_UNICODE)."】返回参数[".$response."];访问地址".$url); if ($response === false) { curl_close($ch); return array('x'=>'0','Description'=>'cURL Error: ' . curl_error($ch)); } curl_close($ch); // 如果返回的是 JSON,可直接解码 $result = json_decode($response, true); if(!isset($result['body'])){ return array('x'=>'0','Description'=>$result['message']); } if(empty($result['body']['labelUrl'])){ return array('x'=>'0','Description'=>"获取云尚打印快递面单失败!"); } if(empty($result['body']['oddNo'])){ return array('x'=>'0','Description'=>"获取云尚打印快递单号失败!"); } $g = array('x'=>'1','waybillid'=>'','waybill'=>$result['body']['oddNo'],'yd'=>$result['body']['labelUrl']); return $g; } //取消运单 public function cancel_yd($waybill){ $url = $this->url."/ois/order/cancel"; $params = [ 'codeType'=>1, 'noList'=>$waybill ]; $time = time(); $time = $time.'000'; $token = $this->getToken($time); if(empty($token)){ return ""; } $ret_head = $this->getHeaders($token,$time); $ch = curl_init($url); $headers= [ 'Content-Type: application/json', 'token:'.$ret_head['token'], 'sign:'.$ret_head['sign'], 'version:'.$ret_head['version'], ]; curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($params), // 关键:先 json_encode CURLOPT_HTTPHEADER => $headers, CURLOPT_RETURNTRANSFER => true, // 把响应作为字符串返回 CURLOPT_TIMEOUT => 10, // 测试环境临时关闭 SSL 验证(两个都要加) CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => 0, ]); $response = curl_exec($ch); if ($response === false) { curl_close($ch); return ""; } return $response; } public function getToken($time){ $this->load->driver('cache'); $cache_key = 'yunshangkuaidi_token_3_hours'; $cached = $this->cache->get($cache_key); if ($cached !== FALSE) { return $cached; } $params = [ 'appKey' => $this->appKey, 'appSecret' => $this->appSecret ]; $headers = [ 'Content-Type' => 'application/x-www-form-urlencoded' ]; $url = $this->url . '/ois/order/getAuth?'.http_build_query($params); $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url, CURLOPT_POST => true, // 关键:用 http_build_query 转成字符串,这样 Content-Type 才是 form-urlencoded CURLOPT_POSTFIELDS => http_build_query([]), CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30, // 请求头(可选,显式声明) CURLOPT_HTTPHEADER => $headers, // 不验证 SSL 证书 CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, ]); $response = curl_exec($ch); if ($response === false) { curl_close($ch); return ""; } else { curl_close($ch); // $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); // echo "HTTP: {$httpCode}\n"; // echo $response; $arr = json_decode($response,true); if(empty($arr['body'])){ return ""; } if(empty($arr['body']['token'])){ return ""; } $this->cache->save($cache_key,$arr['body']['token'], 10000); // 缓存3小时 少几分钟 return $arr['body']['token']; } } private function getHeaders($token,$time){ $tokenArr = array( 'timestamp' => $time, 'nonce' => $this->nonce, 'token' => $token, ); $jsonStr = json_encode($tokenArr); //var_dump("伪装token json字符串:", $jsonStr); $tokenStr = base64_encode($jsonStr); //var_dump('伪装token base64', $tokenStr); $tokenStr = strtr($tokenStr, array('a' => '-', 'c' => '#', 'x' => '^', 'M' => '$')); //var_dump('伪装token 替换后', $tokenStr); $sign = $this->getSign($time,$token); return [ 'token' => $tokenStr, 'version' => $this->version, 'sign' => $sign ]; } private function getSign($time,$token){ // 计算签名 $data = [ 'timestamp' => $time, 'nonce' => $this->nonce, 'token' => $token, 'version' => $this->version ]; ksort($data); $string = ""; foreach ($data as $key => $value) { if (strlen($string) > 0) { $string = $string . "&" . $key . "=" . $value; } else { $string = $string . "" . $key . "=" . $value; } } $paramStr = $string; $base64Str = base64_encode($paramStr); $md5 = md5($base64Str . $this->appSecret); $sign = strtoupper($md5); return $sign; } } //end class