_errorMap[self::ERROR_SHIPPER_COUNTRY_IS_NOT_US] = 'Shipper Country Code must be US'; $this->_errorMap[self::ERROR_COUNTRY_CODE] = 'Country Code is not valid'; return $this; } public function getRate() { return $this->_getServiceResponse(); } protected function _getServiceResponse() { if (null == $this->_response->getData()) { if (true === ($errors = $this->_validateRateFields())) { // The origin address(shipper) must be only in USA try { $this->_prepareXml(); if (!($serviceResponse = $this->_callService()) instanceof Qs_Exception) { $this->_response->setShipToCountryCode($this->getOption('shipToCountry')); $this->_response->prepareServiceResponse($serviceResponse); } else { $this->_response->setIsSuccess(false)->setData([ 'errorCode' => self::ERROR_SERVICE_CONNECTION, 'errorText' => sprintf( $this->_errorMap[self::ERROR_SERVICE_CONNECTION], $this->getServiceName() ), ]); } } catch (App_Service_Shipping_Usps_Exception $e) { $this->_response->setIsSuccess(false)->setData([ 'errorCode' => $e->getCode(), 'errorText' => $e->getMessage(), ]); } } else { $this->_response->setIsSuccess(false)->setData([ 'errorCode' => self::ERROR_VALIDATE_REQUIRED_PARAMS, 'errorText' => implode('
', $errors), ]); } } return $this->_response; } /** * Documentation: * https://www.usps.com/webtools/htm/Rate-Calculators-v1-5.htm - not found * https://www.usps.com/business/web-tools-apis/price-calculators.htm */ protected function _prepareXml() { if ($this->_isUSCountry($this->getOption('shipToCountry'))) { $mainWriter = new SimpleXMLElement(''); $mainWriter->addAttribute('USERID', $this->getConfig()->userId); /** * According to usps v4 documentation * For full RateV4 functionality use Revision='2' */ $mainWriter->addChild('Revision', self::RATE_V4_REVISION); foreach ($this->_getPackagesInformation() as $key => $packageInformation) { $packageWriter = $mainWriter->addChild('Package'); $packageWriter->addAttribute('ID', $key); $service = $this->getOption('serviceCode'); if (in_array($this->getConfig()->container, $this->_priorityContainers)) { $service = self::SERVICE_PRIORITY; } $packageWriter->addChild('Service', $service); // no matter Letter, Flat or Parcel, use Parcel if (in_array($this->getOption('serviceCode'), $this->_parcelFirstClassMailTypeServices)) { $packageWriter->addChild('FirstClassMailType', self::FIRST_CLASS_MAIL_TYPE_PARCEL); } $packageWriter->addChild('ZipOrigination', $this->getOption('shipperPostalCode')); $packageWriter->addChild('ZipDestination', $this->getOption('shipToPostalCode')); $weight = $this->_prepareWeight($packageInformation['weight']); $packageWriter->addChild('Pounds', floor($weight)); $packageWriter->addChild('Ounces', Zend_Locale_Math::round(16 * ($weight - floor($weight)), 2)); // Because some methods don't accept VARIABLE and (NON)RECTANGULAR containers $packageWriter->addChild('Container', $this->getConfig()->container); $packageWriter->addChild('Size', $this->getConfig()->size); if ($this->getConfig()->size == self::SIZE_LARGE) { $packageWriter->addChild('Width', $this->getOption('width')); $packageWriter->addChild('Length', $this->getOption('length')); $packageWriter->addChild('Height', $this->getOption('height')); if (in_array($this->getConfig()->container, $this->_girthContainers)) { $packageWriter->addChild('Girth', $this->getOption('girth')); } } $packageWriter->addChild('Machinable', $this->getConfig()->machinable); } } else { $mainWriter = new SimpleXMLElement(''); $mainWriter->addAttribute('USERID', $this->getConfig()->userId); /** * According to usps v4 documentation * For full RateV4 functionality use Revision='2' */ $mainWriter->addChild('Revision', self::RATE_V4_REVISION); $packageWriter = $mainWriter->addChild('Package'); $packageWriter->addAttribute('ID', 0); $weight = 0; //NEED CHANGED FOR INTERNATIONAL SHIPPING !!! $packageWriter->addChild('Pounds', floor($weight)); $packageWriter->addChild('Ounces', Zend_Locale_Math::round(16 * ($weight - floor($weight)), 2)); $packageWriter->addChild('MailType', $this->getConfig()->mailType); $packageWriter->addChild('ValueOfContents', $this->getOption('valueOfContents')); $packageWriter->addChild('Country', $this->_getUSPSCountryName($this->getOption('shipToCountry'))); $packageWriter->addChild('Container', $this->getConfig()->container); $packageWriter->addChild('Size', $this->getConfig()->size); $width = $length = $height = $girth = 0; if ($this->getConfig()->size == self::SIZE_LARGE) { $width = $this->getOption('width'); $length = $this->getOption('length'); $height = $this->getOption('height'); if ($this->getConfig()->container == self::CONTAINER_NONRECTANGULAR) { $girth = $this->getOption('girth'); } } $packageWriter->addChild('Width', $width); $packageWriter->addChild('Length', $length); $packageWriter->addChild('Height', $height); $packageWriter->addChild('Girth', $girth); } $this->_xml = $mainWriter->asXML(); return $this; } protected function _getUSPSCountryName($countryCode) { $countries = $this->getConfig()->countries->toArray(); if (!array_key_exists($countryCode, $countries)) { throw new App_Service_Shipping_Usps_Exception( $this->_errorMap[self::ERROR_COUNTRY_CODE], self::ERROR_COUNTRY_CODE ); } return $countries[$countryCode]; } protected function _callService() { try { $client = new Zend_Http_Client(); $client->setUri($this->getConfig()->location); $client->setConfig($this->getConfig()->httpOptions->toArray()); $client->setParameterGet( 'API', $this->_isUSCountry($this->getOption('shipToCountry')) ? $this->getConfig()->US_API : $this->getConfig()->NOT_US_API ); $client->setParameterGet('XML', $this->_xml); $response = $client->request(); if ($response->getStatus() == self::HTTP_CODE_OK) { $response = $response->getBody(); } else { return new App_Service_Shipping_Usps_Exception( $this->_errorMap[self::ERROR_SERVICE_CONNECTION], self::ERROR_SERVICE_CONNECTION ); } $this->_writeLog('>', $client->getUri()->getUri(), $client->getLastRequest()); } catch (App_Service_Shipping_Usps_Exception $e) { return $e; } $this->_writeLog('<', $response); return $response; } protected function _validateRateFields() { $errors = $this->_validateRequiredRateFields(); if (!$this->_isUSCountry($this->getOption('shipperCountry'))) { $shipperCountryError = $this->_errorMap[self::ERROR_SHIPPER_COUNTRY_IS_NOT_US]; $errors = $this->_prepareErrors($errors, $shipperCountryError); } $countries = $this->getConfig()->countries->toArray(); if (!array_key_exists($this->getOption('shipToCountry'), $countries)) { $shipToCountryError = $this->_errorMap[self::ERROR_COUNTRY_CODE]; $errors = $this->_prepareErrors($errors, $shipToCountryError); } return $errors; } protected function _prepareErrors($errors, $newError) { if (is_array($errors)) { $errors[] = $newError; } else { $errors = [$newError]; } return $errors; } protected function _isUSCountry($countryCode) { return ($countryCode == self::COUNTRY_CODE_US) ? true : false; } }