Model_fedexv1.php 19 KB

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