@@ -79,6 +79,13 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
7979 */
8080 public const TRACK_REQUEST_END_POINT = 'track/v1/trackingnumbers ' ;
8181
82+ /**
83+ * REST end point for Rate API
84+ *
85+ * @var string
86+ */
87+ public const RATE_REQUEST_END_POINT = 'rate/v1/rates/quotes ' ;
88+
8289 /**
8390 * REST end point of Tracking API
8491 *
@@ -291,16 +298,6 @@ protected function _createSoapClient($wsdl, $trace = false)
291298 return $ client ;
292299 }
293300
294- /**
295- * Create rate soap client
296- *
297- * @return \SoapClient
298- */
299- protected function _createRateSoapClient ()
300- {
301- return $ this ->_createSoapClient ($ this ->_rateServiceWsdl );
302- }
303-
304301 /**
305302 * Create ship soap client
306303 *
@@ -459,66 +456,76 @@ public function getVersionInfo()
459456 * @param string $purpose
460457 * @return array
461458 */
462- protected function _formRateRequest ($ purpose )
459+ protected function _formRateRequest ($ purpose ) : array
463460 {
464461 $ r = $ this ->_rawRequest ;
465462 $ ratesRequest = [
466- 'WebAuthenticationDetail ' => [
467- 'UserCredential ' => [ ' Key ' => $ r ->getKey (), ' Password ' => $ r -> getPassword ()],
463+ 'accountNumber ' => [
464+ 'value ' => $ r ->getAccount ()
468465 ],
469- 'ClientDetail ' => ['AccountNumber ' => $ r ->getAccount (), 'MeterNumber ' => $ r ->getMeterNumber ()],
470- 'Version ' => $ this ->getVersionInfo (),
471- 'RequestedShipment ' => [
472- 'DropoffType ' => $ r ->getDropoffType (),
473- 'ShipTimestamp ' => date ('c ' ),
474- 'PackagingType ' => $ r ->getPackaging (),
475- 'Shipper ' => [
476- 'Address ' => ['PostalCode ' => $ r ->getOrigPostal (), 'CountryCode ' => $ r ->getOrigCountry ()],
466+ 'requestedShipment ' => [
467+ 'pickupType ' => $ this ->getConfigData ('pickup_type ' ),
468+ 'packagingType ' => $ r ->getPackaging (),
469+ 'shipper ' => [
470+ 'address ' => ['postalCode ' => $ r ->getOrigPostal (), 'countryCode ' => $ r ->getOrigCountry ()],
477471 ],
478- 'Recipient ' => [
479- 'Address ' => [
480- 'PostalCode ' => $ r ->getDestPostal (),
481- 'CountryCode ' => $ r ->getDestCountry (),
482- 'Residential ' => (bool )$ this ->getConfigData ('residence_delivery ' ),
472+ 'recipient ' => [
473+ 'address ' => [
474+ 'postalCode ' => $ r ->getDestPostal (),
475+ 'countryCode ' => $ r ->getDestCountry (),
476+ 'residential ' => (bool )$ this ->getConfigData ('residence_delivery ' ),
483477 ],
484478 ],
485- 'ShippingChargesPayment ' => [
486- 'PaymentType ' => 'SENDER ' ,
487- 'Payor ' => ['AccountNumber ' => $ r ->getAccount (), 'CountryCode ' => $ r ->getOrigCountry ()],
488- ],
489- 'CustomsClearanceDetail ' => [
490- 'CustomsValue ' => ['Amount ' => $ r ->getValue (), 'Currency ' => $ this ->getCurrencyCode ()],
479+ 'customsClearanceDetail ' => [
480+ 'dutiesPayment ' => [
481+ 'payor ' => [
482+ 'responsibleParty ' => [
483+ 'accountNumber ' => [
484+ 'value ' => $ r ->getAccount ()
485+ ],
486+ 'address ' => [
487+ 'countryCode ' => $ r ->getOrigCountry ()
488+ ]
489+ ]
490+ ],
491+ 'paymentType ' => 'SENDER ' ,
492+ ],
493+ 'commodities ' => [
494+ [
495+ 'customsValue ' => ['amount ' => $ r ->getValue (), 'currency ' => $ this ->getCurrencyCode ()]
496+ ]
497+ ]
491498 ],
492- 'RateRequestTypes ' => 'LIST ' ,
493- 'PackageDetail ' => 'INDIVIDUAL_PACKAGES ' ,
494- ],
499+ 'rateRequestType ' => ['LIST ' ]
500+ ]
495501 ];
496502
497503 foreach ($ r ->getPackages () as $ packageNum => $ package ) {
498- $ ratesRequest ['RequestedShipment ' ]['RequestedPackageLineItems ' ][$ packageNum ]['GroupPackageCount ' ] = 1 ;
499- $ ratesRequest ['RequestedShipment ' ]['RequestedPackageLineItems ' ][$ packageNum ]['Weight ' ]['Value ' ]
504+ $ ratesRequest ['requestedShipment ' ]['requestedPackageLineItems ' ][$ packageNum ]['subPackagingType ' ] =
505+ 'PACKAGE ' ;
506+ $ ratesRequest ['requestedShipment ' ]['requestedPackageLineItems ' ][$ packageNum ]['groupPackageCount ' ] = 1 ;
507+ $ ratesRequest ['requestedShipment ' ]['requestedPackageLineItems ' ][$ packageNum ]['weight ' ]['value ' ]
500508 = (double ) $ package ['weight ' ];
501- $ ratesRequest ['RequestedShipment ' ]['RequestedPackageLineItems ' ][$ packageNum ]['Weight ' ]['Units ' ]
509+ $ ratesRequest ['requestedShipment ' ]['requestedPackageLineItems ' ][$ packageNum ]['weight ' ]['units ' ]
502510 = $ this ->getConfigData ('unit_of_measure ' );
503511 if (isset ($ package ['price ' ])) {
504- $ ratesRequest ['RequestedShipment ' ]['RequestedPackageLineItems ' ][$ packageNum ]['InsuredValue ' ]['Amount ' ]
512+ $ ratesRequest ['requestedShipment ' ]['requestedPackageLineItems ' ][$ packageNum ]['declaredValue ' ]['amount ' ]
505513 = (double ) $ package ['price ' ];
506- $ ratesRequest ['RequestedShipment ' ]['RequestedPackageLineItems ' ][$ packageNum ]['InsuredValue ' ][ ' Currency ' ]
507- = $ this ->getCurrencyCode ();
514+ $ ratesRequest ['requestedShipment ' ]['requestedPackageLineItems ' ][$ packageNum ]['declaredValue ' ]
515+ [ ' currency ' ] = $ this ->getCurrencyCode ();
508516 }
509517 }
510518
511- $ ratesRequest ['RequestedShipment ' ]['PackageCount ' ] = count ($ r ->getPackages ());
512-
519+ $ ratesRequest ['requestedShipment ' ]['totalPackageCount ' ] = count ($ r ->getPackages ());
513520 if ($ r ->getDestCity ()) {
514- $ ratesRequest ['RequestedShipment ' ]['Recipient ' ]['Address ' ]['City ' ] = $ r ->getDestCity ();
521+ $ ratesRequest ['requestedShipment ' ]['recipient ' ]['address ' ]['city ' ] = $ r ->getDestCity ();
515522 }
516523
517524 if ($ purpose == self ::RATE_REQUEST_SMARTPOST ) {
518- $ ratesRequest ['RequestedShipment ' ]['ServiceType ' ] = self ::RATE_REQUEST_SMARTPOST ;
519- $ ratesRequest ['RequestedShipment ' ]['SmartPostDetail ' ] = [
520- 'Indicia ' => (double )$ r ->getWeight () >= 1 ? 'PARCEL_SELECT ' : 'PRESORTED_STANDARD ' ,
521- 'HubId ' => $ this ->getConfigData ('smartpost_hubid ' ),
525+ $ ratesRequest ['requestedShipment ' ]['serviceType ' ] = self ::RATE_REQUEST_SMARTPOST ;
526+ $ ratesRequest ['requestedShipment ' ]['smartPostInfoDetail ' ] = [
527+ 'indicia ' => (double )$ r ->getWeight () >= 1 ? 'PARCEL_SELECT ' : 'PRESORTED_STANDARD ' ,
528+ 'hubId ' => $ this ->getConfigData ('smartpost_hubid ' ),
522529 ];
523530 }
524531
@@ -531,29 +538,45 @@ protected function _formRateRequest($purpose)
531538 * @param string $purpose
532539 * @return mixed
533540 */
534- protected function _doRatesRequest ($ purpose )
541+ protected function _doRatesRequest ($ purpose ) : mixed
535542 {
543+ $ response = null ;
544+ $ accessToken = $ this ->_getAccessToken ($ tracking = null );
545+ if (empty ($ accessToken )) {
546+ return null ;
547+ }
548+
536549 $ ratesRequest = $ this ->_formRateRequest ($ purpose );
537- $ ratesRequestNoShipTimestamp = $ ratesRequest ;
538- unset($ ratesRequestNoShipTimestamp ['RequestedShipment ' ]['ShipTimestamp ' ]);
539- $ requestString = $ this ->serializer ->serialize ($ ratesRequestNoShipTimestamp );
550+ $ requestString = $ this ->serializer ->serialize ($ ratesRequest );
540551 $ response = $ this ->_getCachedQuotes ($ requestString );
541552 $ debugData = ['request ' => $ this ->filterDebugData ($ ratesRequest )];
553+
542554 if ($ response === null ) {
555+ $ headers = [
556+ 'Content-Type ' => 'application/json ' ,
557+ 'Authorization ' => 'Bearer ' .$ accessToken ,
558+ 'X-locale ' => 'en_US ' ,
559+
560+ ];
561+ $ url = $ this ->_getBaseUrl () . self ::RATE_REQUEST_END_POINT ;
562+ $ curlClient = $ this ->curlFactory ->create ();
543563 try {
544- $ client = $ this ->_createRateSoapClient ();
545- $ response = $ client ->getRates ($ ratesRequest );
546- $ this ->_setCachedQuotes ($ requestString , $ response );
564+ $ curlClient ->setHeaders ($ headers );
565+ $ curlClient ->setOptions ([CURLOPT_ENCODING => 'gzip,deflate,sdch ' ]);
566+ $ curlClient ->post ($ url , $ requestString );
567+ $ response = $ curlClient ->getBody ();
547568 $ debugData ['result ' ] = $ response ;
569+ $ response = $ this ->serializer ->unserialize ($ response );
570+ $ this ->_setCachedQuotes ($ requestString , $ response );
548571 } catch (\Exception $ e ) {
549572 $ debugData ['result ' ] = ['error ' => $ e ->getMessage (), 'code ' => $ e ->getCode ()];
550573 $ this ->_logger ->critical ($ e );
551574 }
552575 } else {
553576 $ debugData ['result ' ] = $ response ;
554577 }
555- $ this ->_debug ($ debugData );
556578
579+ $ this ->_debug ($ debugData );
557580 return $ response ;
558581 }
559582
@@ -594,41 +617,32 @@ protected function _getQuotes()
594617 * @return Result
595618 * @SuppressWarnings(PHPMD.CyclomaticComplexity)
596619 */
597- protected function _prepareRateResponse ($ response )
620+ protected function _prepareRateResponse ($ response ) : Result
598621 {
599622 $ costArr = [];
600623 $ priceArr = [];
601624 $ errorTitle = 'For some reason we can \'t retrieve tracking info right now. ' ;
602625
603- if (is_object ($ response )) {
604- if ($ response-> HighestSeverity == ' FAILURE ' || $ response -> HighestSeverity == ' ERROR ' ) {
605- if (is_array ($ response-> Notifications )) {
606- $ notification = array_pop ($ response-> Notifications );
607- $ errorTitle = (string )$ notification-> Message ;
626+ if (is_array ($ response )) {
627+ if (! empty ( $ response[ ' errors ' ]) ) {
628+ if (is_array ($ response[ ' errors ' ] )) {
629+ $ notification = reset ($ response[ ' errors ' ] );
630+ $ errorTitle = (string )$ notification[ ' message ' ] ;
608631 } else {
609- $ errorTitle = (string )$ response-> Notifications -> Message ;
632+ $ errorTitle = (string )$ response[ ' errors ' ][ ' message ' ] ;
610633 }
611- } elseif (isset ($ response-> RateReplyDetails )) {
634+ } elseif (isset ($ response[ ' output ' ][ ' rateReplyDetails ' ] )) {
612635 $ allowedMethods = explode (", " , $ this ->getConfigData ('allowed_methods ' ));
613-
614- if (is_array ($ response ->RateReplyDetails )) {
615- foreach ($ response ->RateReplyDetails as $ rate ) {
616- $ serviceName = (string )$ rate ->ServiceType ;
636+ if (is_array ($ response ['output ' ]['rateReplyDetails ' ])) {
637+ foreach ($ response ['output ' ]['rateReplyDetails ' ] as $ rate ) {
638+ $ serviceName = (string )$ rate ['serviceType ' ];
617639 if (in_array ($ serviceName , $ allowedMethods )) {
618640 $ amount = $ this ->_getRateAmountOriginBased ($ rate );
619641 $ costArr [$ serviceName ] = $ amount ;
620642 $ priceArr [$ serviceName ] = $ this ->getMethodPrice ($ amount , $ serviceName );
621643 }
622644 }
623645 asort ($ priceArr );
624- } else {
625- $ rate = $ response ->RateReplyDetails ;
626- $ serviceName = (string )$ rate ->ServiceType ;
627- if (in_array ($ serviceName , $ allowedMethods )) {
628- $ amount = $ this ->_getRateAmountOriginBased ($ rate );
629- $ costArr [$ serviceName ] = $ amount ;
630- $ priceArr [$ serviceName ] = $ this ->getMethodPrice ($ amount , $ serviceName );
631- }
632646 }
633647 }
634648 }
@@ -697,17 +711,18 @@ protected function _getPerorderPrice($cost, $handlingType, $handlingFee)
697711 * @param \stdClass $rate
698712 * @return null|float
699713 */
700- protected function _getRateAmountOriginBased ($ rate )
714+ protected function _getRateAmountOriginBased ($ rate ) : null | float
701715 {
702716 $ amount = null ;
703717 $ currencyCode = '' ;
704718 $ rateTypeAmounts = [];
705- if (is_object ($ rate )) {
719+
720+ if (is_array ($ rate )) {
706721 // The "RATED..." rates are expressed in the currency of the origin country
707- foreach ($ rate-> RatedShipmentDetails as $ ratedShipmentDetail ) {
708- $ netAmount = (string )$ ratedShipmentDetail-> ShipmentRateDetail -> TotalNetCharge -> Amount ;
709- $ currencyCode = (string )$ ratedShipmentDetail-> ShipmentRateDetail -> TotalNetCharge -> Currency ;
710- $ rateType = (string )$ ratedShipmentDetail-> ShipmentRateDetail -> RateType ;
722+ foreach ($ rate[ ' ratedShipmentDetails ' ] as $ ratedShipmentDetail ) {
723+ $ netAmount = (string )$ ratedShipmentDetail[ ' totalNetCharge ' ] ;
724+ $ currencyCode = (string )$ ratedShipmentDetail[ ' shipmentRateDetail ' ][ ' currency ' ] ;
725+ $ rateType = (string )$ ratedShipmentDetail[ ' rateType ' ] ;
711726 $ rateTypeAmounts [$ rateType ] = $ netAmount ;
712727 }
713728
@@ -719,7 +734,7 @@ protected function _getRateAmountOriginBased($rate)
719734 }
720735
721736 if ($ amount === null ) {
722- $ amount = (string )$ rate-> RatedShipmentDetails [ 0 ]-> ShipmentRateDetail -> TotalNetCharge -> Amount ;
737+ $ amount = (string )$ rate[ ' ratedShipmentDetails ' ][ 0 ][ ' totalNetCharge ' ] ;
723738 }
724739
725740 $ amount = (float )$ amount * $ this ->getBaseCurrencyRate ($ currencyCode );
@@ -916,10 +931,10 @@ protected function _parseXmlResponse($response)
916931 *
917932 * @param string $type
918933 * @param string $code
919- * @return array|false
934+ * @return \Magento\Framework\Phrase| array|false
920935 * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
921936 */
922- public function getCode ($ type , $ code = '' )
937+ public function getCode ($ type , $ code = '' ) : \ Magento \ Framework \ Phrase | array | false
923938 {
924939 $ codes = [
925940 'method ' => [
@@ -1058,6 +1073,15 @@ public function getCode($type, $code = '')
10581073 'LB ' => __ ('Pounds ' ),
10591074 'KG ' => __ ('Kilograms ' ),
10601075 ],
1076+ 'pickup_type ' => [
1077+ 'CONTACT_FEDEX_TO_SCHEDULE ' => __ ('Contact Fedex to Schedule ' ),
1078+ 'DROPOFF_AT_FEDEX_LOCATION ' => __ ('DropOff at Fedex Location ' ),
1079+ 'USE_SCHEDULED_PICKUP ' => __ ('Use Scheduled Pickup ' ),
1080+ 'ON_CALL ' => __ ('On Call ' ),
1081+ 'PACKAGE_RETURN_PROGRAM ' => __ ('Package Return Program ' ),
1082+ 'REGULAR_STOP ' => __ ('Regular Stop ' ),
1083+ 'TAG ' => __ ('Tag ' ),
1084+ ]
10611085 ];
10621086
10631087 if (!isset ($ codes [$ type ])) {
0 commit comments