|
|
@@ -0,0 +1,439 @@
|
|
|
+<?php
|
|
|
+if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
|
|
+use GuzzleHttp\Client;
|
|
|
+/**
|
|
|
+ * 此类主要是为了服务于云途快递的API接口
|
|
|
+ */
|
|
|
+class Model_yuntuuk extends Lin_Model
|
|
|
+{
|
|
|
+ //public $base_url = "https://openapi-sbx.yunexpress.cn"; //测试环境
|
|
|
+ public $base_url = "https://openapi.yunexpress.cn";//正式环境
|
|
|
+ public $token_url = "/openapi/oauth2/token";
|
|
|
+ //正式环境
|
|
|
+ public $yt_config = [
|
|
|
+ "appId"=> "1fc6c0ca252c",
|
|
|
+ "appSecret"=> "0b6bdc0ecab04b59981c3a18a84919be",
|
|
|
+ "sourceKey"=> "wzmu5q6x"
|
|
|
+ ];
|
|
|
+ //测试环境
|
|
|
+ // public $yt_config = [
|
|
|
+ // "appId"=> "d34f30df34ae",
|
|
|
+ // "appSecret"=> "9ace1fa73c4b4567a6ae5ac7e254b48f",
|
|
|
+ // "sourceKey"=> "wzmu5q6x"
|
|
|
+ // ];
|
|
|
+ function __construct(){
|
|
|
+ parent::__construct();
|
|
|
+ $this->load->_model("Model_logic_ding",'logic_ding');
|
|
|
+ }
|
|
|
+
|
|
|
+ public function get_data($data){
|
|
|
+ $token = $this->getAccessToken();
|
|
|
+
|
|
|
+ if(empty($token)){
|
|
|
+ return [
|
|
|
+ 'x'=>'0',
|
|
|
+ 'Description'=>"请求时token为空,请联系技术!!!",
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ $url = "/v1/order/package/create";
|
|
|
+ //拼接参数
|
|
|
+ $receive_address = [];
|
|
|
+ $receive_address[] = $data['address'];
|
|
|
+ if(!empty($data['address2'])){
|
|
|
+ $receive_address[] = $data['address2'];
|
|
|
+ }
|
|
|
+ if(!empty($data['printnumber'])){
|
|
|
+ $data['printnumber'] = $data['printnumber']*1 + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ $params = [
|
|
|
+ "product_code"=> "JFPHTKR",
|
|
|
+ //"product_code"=> "S1002",
|
|
|
+ "customer_order_number"=> empty($data['printnumber'])?$data['number']: $data['number']."_".$data['printnumber'],
|
|
|
+ "packages"=> [
|
|
|
+ [
|
|
|
+
|
|
|
+ "weight"=> $data['zzl']
|
|
|
+ ],
|
|
|
+
|
|
|
+ ],
|
|
|
+ "receiver"=> [
|
|
|
+ "first_name"=> $data['name'],
|
|
|
+ "country_code"=> $data['lb'],
|
|
|
+ "province"=> $data['province'],
|
|
|
+ "city"=> $data['city'],
|
|
|
+ "address_lines"=> $receive_address,
|
|
|
+ "postal_code"=> $data['zipcode'],
|
|
|
+ "phone_number"=> $data['phone'],
|
|
|
+ "email"=> isset($data['email'])?$data['email']:'',
|
|
|
+ "company"=>$data['client'],
|
|
|
+ ],
|
|
|
+ "declaration_info"=> [
|
|
|
+ [
|
|
|
+ "quantity"=>$data['ts'],
|
|
|
+ "unit_price"=>$data['dtsbjz'],
|
|
|
+ "unit_weight"=>sprintf("%.3f",$data['zzl']/$data['ts']),
|
|
|
+ "name_en"=> $data['sbpm'],
|
|
|
+ "name_local"=>$data['zwpm'],
|
|
|
+ ],
|
|
|
+
|
|
|
+ ],
|
|
|
+ "customs_number"=>""
|
|
|
+ // "sender"=> [
|
|
|
+ // "first_name"=> "first_name",
|
|
|
+ // "last_name"=> "last_name",
|
|
|
+ // "company"=> "company",
|
|
|
+ // "country_code"=> "11",
|
|
|
+ // "province"=> "province",
|
|
|
+ // "city"=> "city",
|
|
|
+ // "address_lines"=> [
|
|
|
+ // "address_lines1"
|
|
|
+ // ],
|
|
|
+ // "postal_code"=> "postal_code",
|
|
|
+ // "phone_number"=> "phone_number",
|
|
|
+ // "email"=> "email",
|
|
|
+
|
|
|
+ // ],
|
|
|
+
|
|
|
+ ];
|
|
|
+
|
|
|
+ // if($data['printcode'] == 'YunExpress_BaoXian'){
|
|
|
+ // $params["extra_services"] =[
|
|
|
+ // [
|
|
|
+ // "extra_code"=>"VAS_IP",
|
|
|
+ // "extra_value"=>"BJFDR",
|
|
|
+ // ]
|
|
|
+ // ];
|
|
|
+ // }
|
|
|
+
|
|
|
+ // if($data['printcode'] == 'YunExpress_JFPHTKR'){
|
|
|
+ // $params["product_code"] = 'JFPHTKR';
|
|
|
+ // $params['customs_number'] = "";
|
|
|
+ // }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ $start_time = time();
|
|
|
+
|
|
|
+ $res = $this->sendNewPost($url,$params,$token);
|
|
|
+
|
|
|
+ // echo "<pre>";
|
|
|
+ // var_dump($params);
|
|
|
+ // var_dump($res);
|
|
|
+ $this->logic_ding->sendToDing($data['number']."云途快递报文信息【".json_encode($params)."】返回参数[".json_encode($res,JSON_UNESCAPED_UNICODE)."]请求域名".$url);
|
|
|
+
|
|
|
+ if(isset($res['code'])&&($res['code'] != 1)){
|
|
|
+ return [
|
|
|
+ 'x'=>'0',
|
|
|
+ 'Description'=>$res['msg'],
|
|
|
+ ];
|
|
|
+ }else{
|
|
|
+ usleep(30);
|
|
|
+ $r = $this->get_label($res['result']['waybill_number']);
|
|
|
+ $end_time = time();
|
|
|
+ if( $end_time - $start_time > 45){
|
|
|
+ $this->logic_ding->addJobs('outtime_order',['number'=>$data['number']]);
|
|
|
+ }
|
|
|
+ //var_dump($res);
|
|
|
+ if($r['x'] != 1){
|
|
|
+ return [
|
|
|
+ 'x'=>'2',
|
|
|
+ 'waybill'=>$res['result']['waybill_number'],
|
|
|
+ "url"=>"",
|
|
|
+ 'Description'=>$r['Description'],
|
|
|
+ ];
|
|
|
+ }else{
|
|
|
+ return [
|
|
|
+ 'x'=>'1',
|
|
|
+ 'waybill'=>$res['result']['waybill_number'],
|
|
|
+ "url"=>$r['url']
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取电子面单
|
|
|
+ */
|
|
|
+ public function get_label($order_number){
|
|
|
+ $token = $this->getAccessToken();
|
|
|
+
|
|
|
+ if(empty($token)){
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'x'=>'0',
|
|
|
+ 'Description'=>"获取token失败",
|
|
|
+ ];
|
|
|
+
|
|
|
+
|
|
|
+ //throw new Exception("获取token失败");
|
|
|
+ }
|
|
|
+
|
|
|
+ $query = [
|
|
|
+ 'order_number'=> $order_number,
|
|
|
+ ];
|
|
|
+ $url ="/v1/order/label/get";
|
|
|
+ $res = $this->sendNewGet($url,$query,$token);
|
|
|
+
|
|
|
+ $this->logic_ding->sendToDing($order_number."云途快递报文信息获取电子面单返回参数[".json_encode($res)."]");
|
|
|
+ if(isset($res['code'])&&($res['code'] != 1)){
|
|
|
+ return [
|
|
|
+ 'x'=>'0',
|
|
|
+ 'Description'=>$res['msg'],
|
|
|
+ ];
|
|
|
+ }else{
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'x'=>'1',
|
|
|
+ 'url'=>$res['result']['url'],
|
|
|
+
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 基于guzzlehttp的get请求
|
|
|
+ */
|
|
|
+ protected function sendNewGet($url,$query,$token = ""){
|
|
|
+ $timestamp = time() . "000";
|
|
|
+
|
|
|
+ $bodyString=null;
|
|
|
+
|
|
|
+ // 设置请求的URL
|
|
|
+ $all_url = $this->base_url.$url."?".http_build_query($query);
|
|
|
+
|
|
|
+ $tmp_sign = $this->generateSignatureContent($timestamp, "GET", $url, $bodyString);
|
|
|
+ $sign= $this->generateSha256Signature($tmp_sign, $this->yt_config['appSecret']);
|
|
|
+
|
|
|
+ // 初始化cURL会话
|
|
|
+ $ch = curl_init($all_url);
|
|
|
+ // 设置cURL选项
|
|
|
+ $options = array(
|
|
|
+ CURLOPT_SSL_VERIFYPEER=>false,
|
|
|
+ CURLOPT_SSL_VERIFYHOST=>false,
|
|
|
+ CURLOPT_RETURNTRANSFER => true,
|
|
|
+ CURLOPT_HTTPHEADER => array(
|
|
|
+ 'Content-Type: application/json',
|
|
|
+ 'token: ' . $token ,
|
|
|
+ 'date: ' . $timestamp,
|
|
|
+ 'sign: ' . $sign
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ // 应用这些选项到cURL会话
|
|
|
+ curl_setopt_array($ch, $options);
|
|
|
+
|
|
|
+ // 执行cURL会话并获取响应
|
|
|
+ $response = curl_exec($ch);
|
|
|
+
|
|
|
+ // 检查是否有错误发生
|
|
|
+ if ($response === false) {
|
|
|
+ $error = curl_error($ch);
|
|
|
+ curl_close($ch);
|
|
|
+ return [
|
|
|
+ "code"=> -1,
|
|
|
+ "msg"=> $error
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 关闭cURL会话
|
|
|
+ curl_close($ch);
|
|
|
+ // 输出响应内容
|
|
|
+ return json_decode($response,true);
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 基于guzzlehttp的post请求
|
|
|
+ */
|
|
|
+
|
|
|
+ protected function sendNewPost($url,$params,$token = ""){
|
|
|
+
|
|
|
+ $timestamp = time() . "000";
|
|
|
+
|
|
|
+ $bodyString=json_encode($params);
|
|
|
+
|
|
|
+
|
|
|
+ // 设置请求的URL
|
|
|
+ $all_url = $this->base_url.$url;
|
|
|
+
|
|
|
+ $tmp_sign = $this->generateSignatureContent($timestamp, "POST", $url, $bodyString);
|
|
|
+ $sign= $this->generateSha256Signature($tmp_sign, $this->yt_config['appSecret']);
|
|
|
+
|
|
|
+ // 初始化cURL会话
|
|
|
+ $ch = curl_init($all_url);
|
|
|
+ // 设置cURL选项
|
|
|
+ $options = array(
|
|
|
+ CURLOPT_SSL_VERIFYPEER=>false,
|
|
|
+ CURLOPT_SSL_VERIFYHOST=>false,
|
|
|
+ CURLOPT_RETURNTRANSFER => true,
|
|
|
+ CURLOPT_POST => true,
|
|
|
+ CURLOPT_POSTFIELDS => $bodyString,
|
|
|
+ CURLOPT_HTTPHEADER => array(
|
|
|
+ 'Content-Type: application/json',
|
|
|
+ 'token: ' . $token ,
|
|
|
+ 'date: ' . $timestamp,
|
|
|
+ 'sign: ' . $sign
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ // 应用这些选项到cURL会话
|
|
|
+ curl_setopt_array($ch, $options);
|
|
|
+
|
|
|
+ // 执行cURL会话并获取响应
|
|
|
+ $response = curl_exec($ch);
|
|
|
+
|
|
|
+ // 检查是否有错误发生
|
|
|
+
|
|
|
+ // 检查是否有错误发生
|
|
|
+ if ($response === false) {
|
|
|
+ $error = curl_error($ch);
|
|
|
+ curl_close($ch);
|
|
|
+ return [
|
|
|
+ "code"=> -1,
|
|
|
+ "msg"=> $error
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 关闭cURL会话
|
|
|
+ curl_close($ch);
|
|
|
+
|
|
|
+ // 输出响应内容
|
|
|
+ return json_decode($response,true);
|
|
|
+
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 基于guzzlehttp的post请求
|
|
|
+ */
|
|
|
+
|
|
|
+ protected function sendPost($url,$params,$token = ""){
|
|
|
+ $all_url = $this->base_url.$url;
|
|
|
+ $jsonData = json_encode($params);
|
|
|
+ // 初始化cURL会话
|
|
|
+ $ch = curl_init($all_url);
|
|
|
+
|
|
|
+ // 设置cURL选项
|
|
|
+ $options = [
|
|
|
+ CURLOPT_SSL_VERIFYPEER=>false,
|
|
|
+ CURLOPT_SSL_VERIFYHOST=>false,
|
|
|
+ CURLOPT_RETURNTRANSFER => true,
|
|
|
+ CURLOPT_POST => true,
|
|
|
+ CURLOPT_POSTFIELDS => $jsonData,
|
|
|
+ CURLOPT_HTTPHEADER => [
|
|
|
+ 'Content-Type: application/json'
|
|
|
+ ],
|
|
|
+ ];
|
|
|
+ curl_setopt_array($ch, $options);
|
|
|
+
|
|
|
+ // 执行cURL会话并获取响应
|
|
|
+
|
|
|
+ $response = curl_exec($ch);
|
|
|
+
|
|
|
+ // 检查是否有错误发生
|
|
|
+ if ($response === false) {
|
|
|
+ $error = curl_error($ch);
|
|
|
+ curl_close($ch);
|
|
|
+ return [
|
|
|
+ "code"=> -1,
|
|
|
+ "msg"=> $error
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 关闭cURL会话
|
|
|
+ curl_close($ch);
|
|
|
+ $data = json_decode($response, true);
|
|
|
+ return $data;
|
|
|
+
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 签名算法
|
|
|
+ */
|
|
|
+ /*
|
|
|
+ * 加签内容构造
|
|
|
+ */
|
|
|
+ private function generateSignatureContent($timestamp, $method, $uri, $body = null) {
|
|
|
+ $params = [
|
|
|
+ 'date' => $timestamp,
|
|
|
+ 'method' => $method,
|
|
|
+ 'uri' => $uri,
|
|
|
+ ];
|
|
|
+ if (!empty($body)) {
|
|
|
+ $params['body'] = $body;
|
|
|
+ }
|
|
|
+ ksort($params);
|
|
|
+ $signatureContent = http_build_query($params, '', '&');
|
|
|
+ return urldecode($signatureContent);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 加签
|
|
|
+ */
|
|
|
+ private function generateSha256Signature($data, $key){
|
|
|
+ //return utf8_encode(base64_encode(hash_hmac('sha256', $data,$key,true)));
|
|
|
+ return mb_convert_encoding(base64_encode(hash_hmac('sha256', $data,$key,true)), 'ISO-8859-1', 'UTF-8');
|
|
|
+ }
|
|
|
+ private function getAccessToken(){
|
|
|
+ $info= $this->setting->find("skey = 'yuntu_express_token'");
|
|
|
+ if(empty($info)){
|
|
|
+ $token = $this->makeToken();
|
|
|
+ $this->setting->insert([
|
|
|
+ "skey"=> "yuntu_express_token",
|
|
|
+ "svalue"=> $token,
|
|
|
+ "expiretime"=> (time() + 7100),
|
|
|
+ "sessionkey"=> "yuntu_express_token"
|
|
|
+ ]);
|
|
|
+ return $token;
|
|
|
+ }
|
|
|
+ if($info['expiretime'] < time()){
|
|
|
+ $token = $this->makeToken();
|
|
|
+ $this->setting->save([
|
|
|
+ "svalue"=> $token,
|
|
|
+ "expiretime"=> (time() + 7100)
|
|
|
+ ],"yuntu_express_token");
|
|
|
+ return $token;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $info['svalue'];
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+ private function makeToken(){
|
|
|
+ $res = $this->sendPost($this->token_url,[
|
|
|
+ "grantType"=>"client_credentials",
|
|
|
+ "appId"=> $this->yt_config['appId'],
|
|
|
+ "appSecret"=>$this->yt_config['appSecret'],
|
|
|
+ "sourceKey"=> $this->yt_config['sourceKey']
|
|
|
+ ]);
|
|
|
+ if(isset($res['accessToken'])){
|
|
|
+ $token = $res['accessToken'];
|
|
|
+ return $token;
|
|
|
+ }else{
|
|
|
+ $this->logic_ding->sendToDing("云途快递获取token失败,返回参数[".json_encode($res)."]");
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 获取运单号
|
|
|
+ */
|
|
|
+ public function getTransferNumber($waybill_numbers){
|
|
|
+ // /v1/order/last-mile/get
|
|
|
+
|
|
|
+ $token = $this->getAccessToken();
|
|
|
+
|
|
|
+ if(empty($token)){
|
|
|
+ throw new Exception("获取token失败");
|
|
|
+ }
|
|
|
+
|
|
|
+ $query = [
|
|
|
+ 'waybill_numbers'=> $waybill_numbers,
|
|
|
+ ];
|
|
|
+ $url ="/v1/order/last-mile/get";
|
|
|
+ $res = $this->sendNewPost($url,$query,$token);
|
|
|
+ return $res;
|
|
|
+
|
|
|
+ }
|
|
|
+}
|