Model_fedexv1.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. <?php
  2. class Model_Fedexv1 extends Lin_Model {
  3. function __construct(){
  4. parent::__construct();
  5. $this->load->_model('Model_aapeizhi','aapeizhi');
  6. $this->load->_model("Model_logic_ding",'logic_ding');
  7. }
  8. public $base_url = "https://apis.fedex.com.cn";
  9. public $f_config = [
  10. "account"=>"692362136",
  11. "key"=>"l7c6ae3d27cce34bdca31cf6e0ff4af125",
  12. 'secret' =>'475eb390bf334bda8b5f44f1c07b7c10',
  13. "client_id"=>"l7c6ae3d27cce34bdca31cf6e0ff4af125",
  14. "client_secret"=>"475eb390bf334bda8b5f44f1c07b7c10",
  15. //追物流轨迹的
  16. 'track_key'=>"l71bded23966b144df9fc01956f6dd655d",
  17. 'track_secret'=>"61730ddbae764dcba70f4737cdaaa6e7"
  18. ];
  19. public function getAccessToken(){
  20. $res = $this->setting->find("skey='fedex_v1_access_token'");
  21. if($res){
  22. if(time() > $res['expiretime']){
  23. $this->setting->query("DELETE FROM `crowd_setting` WHERE `skey`='fedex_v1_access_token'");
  24. return $this->makeAccessToken();
  25. }
  26. return $res['svalue'];
  27. }else{
  28. return $this->makeAccessToken();
  29. }
  30. }
  31. public function makeAccessToken(){
  32. $url = "/oauth/token";
  33. $headers = [
  34. "Content-Type:application/x-www-form-urlencoded",
  35. ];
  36. $params = [
  37. "grant_type"=>"client_credentials",
  38. "client_id"=> $this->f_config['client_id'],
  39. "client_secret"=> $this->f_config['client_secret'],
  40. ];
  41. $params=http_build_query($params);
  42. $res = $this->sendPost($url,$params,$headers);
  43. if(isset($res['access_token'])){
  44. $this->setting->insert([
  45. 'skey'=>"fedex_v1_access_token",
  46. 'svalue' => $res['access_token'],
  47. 'expiretime' => time() + 3600 -10
  48. ]);
  49. }
  50. return $res['access_token'];
  51. }
  52. public function getTrackToken(){
  53. $res = $this->setting->find("skey='fedex_v1_track_access_token'");
  54. if($res){
  55. if(time() > $res['expiretime']){
  56. $this->setting->query("DELETE FROM `crowd_setting` WHERE `skey`='fedex_v1_track_access_token'");
  57. return $this->makeTrackToken();
  58. }
  59. return $res['svalue'];
  60. }else{
  61. return $this->makeTrackToken();
  62. }
  63. }
  64. public function makeTrackToken(){
  65. $url = "/oauth/token";
  66. $headers = [
  67. "Content-Type:application/x-www-form-urlencoded",
  68. ];
  69. $params = [
  70. "grant_type"=>"client_credentials",
  71. "client_id"=> $this->f_config['track_key'],
  72. "client_secret"=> $this->f_config['track_secret'],
  73. ];
  74. $params=http_build_query($params);
  75. $res = $this->sendPost($url,$params,$headers);
  76. if(isset($res['access_token'])){
  77. $this->setting->insert([
  78. 'skey'=>"fedex_v1_track_access_token",
  79. 'svalue' => $res['access_token'],
  80. 'expiretime' => time() + 3600 -10
  81. ]);
  82. }
  83. return $res['access_token'];
  84. }
  85. private function setData($order_info){
  86. $customer_streets = [];
  87. $customer_streets[] = $order_info['address'];
  88. if(!empty($order_info['address2'])){
  89. $customer_streets[] = $order_info['address2'];
  90. }
  91. $state_codes = $this->aapeizhi->getFedexStateCode();
  92. $hgbm = 67041900;
  93. if(isset($order_info['hgbm']))
  94. {
  95. if($order_info['hgbm'] != '')
  96. {
  97. $hgbm = $order_info['hgbm'];
  98. }
  99. }
  100. $params = [
  101. "labelResponseOptions"=>"URL_ONLY",
  102. "accountNumber"=>[
  103. "value"=> (int)$this->f_config['account']
  104. ],
  105. "requestedShipment"=>[
  106. "shipper"=>[
  107. "contact"=>[
  108. "personName"=>"LONGYI",
  109. "phoneNumber"=>"18539006340",
  110. "companyName"=>"LONGYI",
  111. ],
  112. "address"=>[
  113. "streetLines"=> [
  114. "1403, Buliding C, Bodi Center",
  115. "NingWei Street, XiaoShan"
  116. ],
  117. "city"=>"Hangzhou",
  118. "stateOrProvinceCode"=>"",
  119. "postalCode"=>310000,//杭州邮编
  120. "countryCode"=>$order_info['warehouse']['lb']
  121. ],
  122. ],
  123. "recipients"=>[
  124. [
  125. "contact" => [
  126. "personName"=>$order_info['name'],
  127. "phoneNumber"=>$order_info['phone'],
  128. "companyName"=>$order_info['client']
  129. ],
  130. "address"=>[
  131. "streetLines" =>$customer_streets,
  132. "city"=>$order_info['city'],
  133. "stateOrProvinceCode"=>strlen($order_info['province'])==2?strtoupper($order_info['province']):$state_codes[strtolower($order_info['province'])],
  134. "postalCode"=>(string)$order_info['zipcode'],
  135. "countryCode"=>$order_info['lb'],
  136. ],
  137. ]
  138. ],
  139. "shipDatestamp"=>date("Y-m-d"),
  140. "serviceType"=>($order_info['js'] == 3)?"FEDEX_INTERNATIONAL_PRIORITY":"FEDEX_INTERNATIONAL_CONNECT_PLUS",
  141. "packagingType"=> "FEDEX_PAK",
  142. "pickupType"=>"DROPOFF_AT_FEDEX_LOCATION",
  143. "blockInsightVisibility"=>false,
  144. "shippingChargesPayment"=>[
  145. "paymentType"=>"SENDER" //运费承担人
  146. ],
  147. "shipmentSpecialServices"=>[
  148. "specialServiceTypes"=>[
  149. "ELECTRONIC_TRADE_DOCUMENTS",
  150. ],
  151. "etdDetail"=>[
  152. "requestedDocumentTypes"=>[
  153. "COMMERCIAL_INVOICE"
  154. ]
  155. ]
  156. ],
  157. "shippingDocumentSpecification"=>[
  158. "shippingDocumentTypes"=>[
  159. "COMMERCIAL_INVOICE"
  160. ],
  161. "commercialInvoiceDetail"=>[
  162. "documentFormat"=>[
  163. "docType"=>"PDF",
  164. "stockType"=>"PAPER_LETTER"
  165. ],
  166. "customerImageUsages"=>[
  167. [
  168. "id"=> "IMAGE_1",
  169. "type"=> "SIGNATURE",
  170. "providedImageType"=> "SIGNATURE"
  171. ],
  172. [
  173. "id"=> "IMAGE_2",
  174. "type"=> "LETTER_HEAD",
  175. "providedImageType"=> "LETTER_HEAD"
  176. ]
  177. ]
  178. ]
  179. ],
  180. "rateRequestType"=>['LIST'],
  181. "labelSpecification"=>[
  182. "imageType"=>"PDF",
  183. "labelStockType"=>"STOCK_4X6",
  184. "customerSpecifiedDetail"=>[
  185. "docTabContent"=>[
  186. "docTabContentType"=>"STANDARD"
  187. ]
  188. ]
  189. ],
  190. "customsClearanceDetail"=>[
  191. "dutiesPayment"=>[
  192. "paymentType"=>"SENDER",//税费承担方
  193. ],
  194. "documentContent"=>"COMMODITY",
  195. "commodities"=>[
  196. [
  197. "numberOfPieces"=>$order_info['zjs'],
  198. "description"=>"CNHLT1403HAN/".$order_info['sbbm']."/".$order_info['sbpm'].'-'.$order_info['ts'].'PCS',
  199. "countryOfManufacture"=> "CN",
  200. 'harmonizedCode'=> $hgbm,//海关编码
  201. "quantity"=> $order_info['ts'],
  202. "quantityUnits"=> "cm",
  203. "unitPrice"=> [
  204. "amount"=> $order_info['dtsbjz'],
  205. "currency"=> "USD"
  206. ],
  207. "customsValue"=> [
  208. "amount"=>$order_info['zsbjz'],
  209. "currency"=> "USD"
  210. ],
  211. "weight"=> [
  212. "units"=> "KG",
  213. "value"=> 0.4
  214. ]
  215. ]
  216. ]
  217. ],
  218. "requestedPackageLineItems"=>[
  219. [
  220. "weight"=>[
  221. "units"=>"KG",
  222. "value"=>0.4
  223. ],
  224. "customerReferences"=>[
  225. [
  226. "customerReferenceType"=>"CUSTOMER_REFERENCE",
  227. "value"=>$order_info['number']
  228. ]
  229. ],
  230. // "packageSpecialServices"=>[
  231. // // "signatureOptionType"=>($order_info['qm']==1)?"ADULT":"",
  232. // ]
  233. ],
  234. ]
  235. ]
  236. ];
  237. if($order_info['qm']==1){
  238. $params['requestedShipment']['requestedPackageLineItems'][0]["packageSpecialServices"]= [
  239. "signatureOptionType"=>"ADULT",
  240. ];
  241. }
  242. // echo "<pre>";
  243. // var_dump($params);
  244. // die;
  245. return $params;
  246. }
  247. //上传货物信息 获取运单 托运
  248. public function get_data($order_info){
  249. try{
  250. $url = "/ship/v1/shipments";
  251. $headers = [
  252. "x-customer-transaction-id"=>$order_info['number'],
  253. "Content-Type:application/json",
  254. "Authorization: Bearer ".$this->getAccessToken(),
  255. "x-locale" => "en_US",//这个是语种加国家
  256. "Accept: application/json",
  257. ];
  258. // echo "<pre>";
  259. // var_dump("Bearer ".$this->getAccessToken());
  260. $params = $this->setData($order_info);
  261. $this->logic_ding->sendToDing("fedex发货单请求的参数".json_encode($params));
  262. //var_dump($params);
  263. $params=json_encode($params);
  264. //var_dump($params);
  265. $start_time = time();
  266. $res = $this->sendPost($url,$params,$headers);
  267. //var_dump(json_encode($res,JSON_UNESCAPED_UNICODE));
  268. $this->logic_ding->sendToDing("fedex发货单回执参数"."【".$order_info['number']."】".json_encode($res,JSON_UNESCAPED_UNICODE));
  269. //var_dump($res);
  270. //die;
  271. if(isset($res['code']) && $res['code'] == -1){
  272. return array('x'=>'0','Description'=>$res['msg']);
  273. }
  274. if(!isset($res["transactionId"])){
  275. return array('x'=>'0','Description'=>'请求异常');
  276. }
  277. if(isset($res["errors"])){
  278. return array('x'=>'0','Description'=>json_encode($res["errors"]));
  279. }
  280. $invoice_url = "";
  281. foreach($res['output']['transactionShipments'][0]['shipmentDocuments'] as $v){
  282. if($v['contentType'] == "COMMERCIAL_INVOICE"){
  283. $invoice_url = $v['url'];
  284. }
  285. }
  286. $end_time = time();
  287. if( $end_time - $start_time > 45){
  288. $this->logic_ding->addJobs('outtime_order',['number'=>$order_info['number']]);
  289. }
  290. return
  291. [
  292. 'x'=>'1',
  293. 'waybill'=>$res['output']['transactionShipments'][0]['masterTrackingNumber'],
  294. 'label'=>$res['output']['transactionShipments'][0]['pieceResponses'][0]['packageDocuments'][0]['url'],
  295. 'invoice'=>$invoice_url,
  296. ];
  297. }catch(Exception $e){
  298. $error_msg = "error:[fedexv1]创建发货单出错".$e->getMessage()."|".$e->getLine()."|".$e->getFile()."|请求参数".json_encode($order_info,JSON_UNESCAPED_UNICODE);
  299. $this->logic_ding->sendToDing($error_msg);
  300. if(isset($res)){
  301. $error_msg = "error:[fedexv1]创建发货单出错".$e->getMessage()."|".$e->getLine()."|".$e->getFile()."|返回参数".json_encode($res,JSON_UNESCAPED_UNICODE);
  302. $this->logic_ding->sendToDing($error_msg);
  303. }
  304. }
  305. }
  306. //根据单号获取 快递信息
  307. public function get_logistics($number){
  308. $url = "/track/v1/trackingnumbers";
  309. $params = [
  310. "includeDetailedScans"=>false,
  311. "trackingInfo"=>[
  312. [
  313. "trackingNumberInfo"=>[
  314. "trackingNumber"=> $number['waybill']
  315. ]
  316. ]
  317. ]
  318. ];
  319. $headers = [
  320. "Content-Type:application/json",
  321. "Authorization: Bearer ".$this->getTrackToken(),
  322. "x-locale" => "en_US",//这个是语种加国家
  323. "Accept: application/json",
  324. ];
  325. $params=json_encode($params);
  326. var_dump(json_encode($headers));
  327. var_dump($params);
  328. var_dump($this->getTrackToken());
  329. $res = $this->sendPost($url,$params,$headers);
  330. var_dump(json_encode($res));
  331. echo "<pre>";
  332. var_dump($res);
  333. }
  334. public function sendPost($url,$params,$headers){
  335. // var_dump($bodyString);
  336. // 设置请求的URL
  337. $all_url = $this->base_url.$url;
  338. //var_dump($all_url);
  339. // 初始化cURL会话
  340. $ch = curl_init($all_url);
  341. // 设置cURL选项
  342. $options = array(
  343. CURLOPT_SSL_VERIFYPEER=>false,
  344. CURLOPT_SSL_VERIFYHOST=>false,
  345. CURLOPT_RETURNTRANSFER => true,
  346. CURLOPT_POST => true,
  347. CURLOPT_POSTFIELDS => $params,
  348. CURLOPT_HTTPHEADER => $headers,
  349. CURLOPT_ENCODING => "gzip,deflate"
  350. );
  351. // 应用这些选项到cURL会话
  352. curl_setopt_array($ch, $options);
  353. // 执行cURL会话并获取响应
  354. $response = curl_exec($ch);
  355. // 检查是否有错误发生
  356. if ($response === false) {
  357. $error = curl_error($ch);
  358. curl_close($ch);
  359. return [
  360. "code"=> -1,
  361. "msg"=> $error
  362. ];
  363. }
  364. // 关闭cURL会话
  365. curl_close($ch);
  366. // 输出响应内容
  367. return json_decode($response,true);
  368. }
  369. //上传数字签名 和 信头 接口在 文件上传api 主要就传一次 用postman传就行 不费事了 etd 必须先传
  370. public function upload_img(){
  371. $all_url = "https://documentapitest.prod.fedex.com/sandbox/documents/v1/lhsimages/upload";
  372. }
  373. public function send_sign(){
  374. $params = [
  375. "document"=>[
  376. "referenceId"=>"1234",
  377. "name"=>"sign.png",
  378. "contentType"=>"image/png",
  379. "meta"=>[
  380. "imageType"=>"SIGNATURE",
  381. "imageIndex"=>"IMAGE_1"
  382. ]
  383. ],
  384. "rules"=>[
  385. "workflowName"=> "LetterheadSignature"
  386. ]
  387. ];
  388. $body = [
  389. 'document'=>json_encode($params),
  390. 'attachment'=>new CURLFile("D:\wwwroot\cerp.wepolicy.cn\sign.png")
  391. ];
  392. $headers = [
  393. "x-customer-transaction-id"=>time(),
  394. "Content-Type:multipart/form-data",
  395. "Authorization: Bearer ".$this->getAccessToken(),
  396. "x-locale" => "en_US",//这个是语种加国家
  397. "Accept: application/json",
  398. ];
  399. $r = $this->send_img_post($body,$headers);
  400. echo "<pre>";
  401. var_dump($r);
  402. }
  403. public function send_xintou(){
  404. $params = [
  405. "document"=>[
  406. "referenceId"=>"1234",
  407. "name"=>"Logo.png",
  408. "contentType"=>"image/png",
  409. "meta"=>[
  410. "imageType"=>"LETTERHEAD",
  411. "imageIndex"=>"IMAGE_2"
  412. ]
  413. ],
  414. "rules"=>[
  415. "workflowName"=> "LetterheadSignature"
  416. ]
  417. ];
  418. $body = [
  419. 'document'=>json_encode($params),
  420. 'attachment'=>new CURLFile("D:\wwwroot\cerp.wepolicy.cn\Logo.png")
  421. ];
  422. $headers = [
  423. "x-customer-transaction-id"=>time(),
  424. "Content-Type:multipart/form-data",
  425. "Authorization: Bearer ".$this->getAccessToken(),
  426. "x-locale" => "en_US",//这个是语种加国家
  427. "Accept: application/json",
  428. ];
  429. $r = $this->send_img_post($body,$headers);
  430. echo "<pre>";
  431. var_dump($r);
  432. }
  433. public function send_img_post($body,$headers){
  434. $upload_img_url = "/documents/v1/lhsimages/upload";
  435. $all_url = "https://documentapi.prod.fedex.com/documents/v1/lhsimages/upload";
  436. var_dump($all_url);
  437. var_dump($body);
  438. // 初始化cURL会话
  439. $ch = curl_init($all_url);
  440. // 设置cURL选项
  441. $options = array(
  442. CURLOPT_SSL_VERIFYPEER=>false,
  443. CURLOPT_SSL_VERIFYHOST=>false,
  444. CURLOPT_RETURNTRANSFER => true,
  445. CURLOPT_POST => true,
  446. CURLOPT_POSTFIELDS => $body,
  447. CURLOPT_HTTPHEADER => $headers,
  448. CURLOPT_ENCODING => "gzip,deflate"
  449. );
  450. // 应用这些选项到cURL会话
  451. curl_setopt_array($ch, $options);
  452. // 执行cURL会话并获取响应
  453. $response = curl_exec($ch);
  454. // 检查是否有错误发生
  455. if ($response === false) {
  456. $error = curl_error($ch);
  457. curl_close($ch);
  458. return [
  459. "code"=> -1,
  460. "msg"=> $error
  461. ];
  462. }
  463. // 关闭cURL会话
  464. curl_close($ch);
  465. // 输出响应内容
  466. return json_decode($response,true);
  467. }
  468. }