1

I've been working to get the Enterprise_Rma module configured to print return labels using UPS.

I've run into a handful of somewhat odd hiccups thus far.

  • The Mode parameter doesn't have to be set to Live in order to be in Live mode. It seems to only affect whether or not CURLOPT_SSL_VERIFYPEER is used in the cURL request.
  • I've had to flip UPS Type back and forth a bit between United Parcel Service and United Parcel Service XML in order to get rates to show up when creating a shipping label. At first, it didn't show any rates when using the latter.

But the main question I have right now is how to properly change the ShipAccept and ShipConfirm API endpoint URLs from their default sandbox (might also be called Customer Integration Environment by UPS) values to the production values.

The sandbox values are:

'ShipConfirm' => 'https://wwwcie.ups.com/ups.app/xml/ShipConfirm',
'ShipAccept'  => 'https://wwwcie.ups.com/ups.app/xml/ShipAccept',

And the production values need to be:

'ShipConfirm' => 'https://onlinetools.ups.com/ups.app/xml/ShipConfirm',
'ShipAccept'  => 'https://onlinetools.ups.com/ups.app/xml/ShipAccept',

The ShipConfirm endpoint can be configured with the config path carriers/ups/url but the ShipAccept doesn't seem possible to change in any way other than modifying Mage_Usa_Model_Shipping_Carrier_Ups directly.

2 Answers 2

3

The Mage_Usa carrier models are half-baked.. I suggest core replacement in app/code/local/Mage/Usa/... E.g. I replaced their protected properties with:

protected $_apiUrls = array(
    self::DEVELOPMENT => array(
        'ShipConfirm' => 'https://wwwcie.ups.com/ups.app/xml/ShipConfirm',
        'ShipAccept'  => 'https://wwwcie.ups.com/ups.app/xml/ShipAccept',
        'XAV'  => 'https://wwwcie.ups.com/ups.app/xml/XAV',  // Only works for NY or CA addresses
        'Void'  => 'https://wwwcie.ups.com/ups.app/xml/Void',
    ),
    self::PRODUCTION => array(
        'ShipConfirm' => 'https://onlinetools.ups.com/ups.app/xml/ShipConfirm',
        'ShipAccept'  => 'https://onlinetools.ups.com/ups.app/xml/ShipAccept',
        'XAV'  => 'https://onlinetools.ups.com/ups.app/xml/XAV',
        'Void'  => 'https://onlinetools.ups.com/ups.app/xml/Void',
    )
);

Then change the code to fetch the URL like:

$url = $this->_apiUrls[(int)$this->getConfigFlag(self::IS_PRODUCTION)]['ShipConfirm'];
4
  • Gotcha. Wow, crazy they'd be so half baked. Why local code pool replacement instead of a class rewrite though? Sep 25, 2013 at 17:50
  • A class rewrite might confuse others, especially if the site is updated to a newer version that "finishes the baking". If you'd rather do a class rewrite, make sure you provide adequate commenting.
    – pspahn
    Sep 26, 2013 at 1:13
  • Personally, I went for a rewrite. I think the customization footprint is a lot smaller than a local code pool class. Oct 1, 2013 at 15:26
  • I used class rewrite because I made (and it is likely the more you use it that you will make) changes that would break backwards compatibility. If it isn't compatible with the parent class then why override? E.g. there are lots of PHP Notices logged that I prefer to fix (noisy logs make problems harder to spot), and I need to take advantage of other API features that Magento doesn't use or are hard-coded.
    – ColinM
    Oct 1, 2013 at 15:41
2

As an alternative to Colin's suggestion to use a local code pool override, I went with a class rewrite. The rewrite is pretty clean as you can overload the two methods in question pretty neatly, keeping the parent calls in tact.

class Clean_Shipping_Model_Usa_Shipping_Carrier_Ups extends Mage_Usa_Model_Shipping_Carrier_Ups
{
    protected function _setEndpointUrls()
    {
        if (Mage::helper('cleanship')->isUpsApiInProductionMode()) {
            $this->_defaultUrls = array(
                'ShipConfirm' => 'https://onlinetools.ups.com/ups.app/xml/ShipConfirm',
                'ShipAccept'  => 'https://onlinetools.ups.com/ups.app/xml/ShipAccept',
            );
        }

        return $this;
    }

    protected function _doShipmentRequest(Varien_Object $request)
    {
        $this->_setEndpointUrls();
        return parent::_doShipmentRequest($request);
    }

    protected function _sendShipmentAcceptRequest(SimpleXMLElement $shipmentConfirmResponse)
    {
        $this->_setEndpointUrls();
        return parent::_sendShipmentAcceptRequest($shipmentConfirmResponse);
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.