Fun Times With Shipping APIs

I’ve been hard at work creating a special e-commerce promotional website.  One of the task was to be able to calculate shipping cost from USPS and UPS given the destination and originating zipcodes as well as weight. This involves using 3rd party APIs and tapping their server for the information that I needed. It was painful at first, but once I got things working, it became very exciting.


USPS Web Tools

First you need to register an account with the United States Postal Service under the USPS Web Tools program. They have a whole bunch of APIs, but the one I will focus on is the Rate Calculator APIs

You’ll get an email once you sign up that contains your username and password along with a phone number to call when you’re ready to have your account authorized to switch over to their production servers. I recommend you calling them right away to switch over to their production server since I don’t think their sandbox server works at all. This was the case for me, and I spend 2 painful days working and reworking my code only to find out that everything worked fine when I was switched over to production.

Once you talk to a rep and you’re now switched over to the production server, you’ll get an email to the URL of the production server APIs. So, by now you should have your USPS Webtools username and password as well as the URL of the location of the production server APIs.

Now for the “fun” to begin. First, construct your XML to send over to USPS. You’ll need to follow the DTD schema here: http://www.usps.com/webtools/htm/Rate-Calculators-v1-2a.htm Specifically you’ll need to look at 2.1.2 Request Diagram. Depending on the type of shipping options you provide, you may or may not need all the fields. The ones that are dotted are optional fields. To determine if you need to fill in the optional fields, you’ll need to look at the shipping table. That can be found under 2.1.4 RateV4 Service Request Matrix.

ProTip: Under container, when it says “ignored” and “variable/null”, don’t put those values in. Instead leave it blank! Under service, when it says “All & Online”, just put “ALL”.

Here’s an example to get every type of shipping available.

$usps = array(
array(Service => "ALL",
Size => "REGULAR",
Container => "",
Machinable => "TRUE" ,
)
);

And here’s an example that would allow you to pick and choose. Remove which ever shipping type you do not want.

$usps = array(
array(Service => "PRIORITY",
Size => "REGULAR",
Container => "LG FLAT RATE BOX",
Machinable => NULL ,
),
array(Service => "PRIORITY",
Size => "REGULAR",
Container => "MD FLAT RATE BOX",
Machinable => NULL
),
array(Service => "PRIORITY",
Size => "REGULAR",
Container => "SM FLAT RATE BOX",
Machinable => NULL
),
array(Service => "PRIORITY",
Size => "REGULAR",
Container => "",
Machinable => NULL
),
array(Service => "EXPRESS",
Size => "REGULAR",
Container => "FLAT RATE ENVELOPE",
Machinable => NULL
),
array(Service => "EXPRESS",
Size => "REGULAR",
Container => "",
Machinable => NULL
),
array(Service => "PARCEL POST",
Size => "REGULAR",
Container => "",
Machinable => "TRUE"
),
array(Service => "MEDIA MAIL",
Size => "REGULAR",
Container => "",
Machinable => NULL
)
);

Once the XML is constructed, its now time to shoot if off over to USPS’s server to get a response.

try {
$APIRequest = "http://production.shippingapis.com/ShippingAPI.dll?API=RateV4&XML=".urlencode($XMLString);
$response = simplexml_load_file($APIRequest) or die("feed not loading"); //ping usps server
} catch (Exception $e) {
// --- ? do what ever you want when error occurs ? ---
}

Once you get a response XML. It’s now time to parse it out and do whatever you need to do with it. Here’s a simple loop to just show on the screen.

<table border="1">
<tr>
<td>ID</td>
<td>Mail Service</td>
<td>Rate</td>
</tr>
<? foreach ($response->Package->Postage as $node) { ?>
<tr>
<td><?= $node->attributes() ?></td>
<td><?= html_entity_decode($node->MailService) ?></td>
<td><?= $node->Rate ?></td>
</tr>
<? } ?>
</table>

 


UPS Developers Kit

For UPS’s shipping calculator, I found Chris Lee’s script and it works perfectly and easy to integrate into an existing project.

UPS XML Rate PHP script

In case the precious code is no longer available on the original site, you can downloaded it here.

When using the UPS code, don’t forget to register and get your API credentials from UPS. You can do that here, https://www.ups.com/upsdeveloperkit

In the code you’ll have to insert your credentials in ups.php for the $userid, $passwd, and $accesskey (lines 88-90)  The jist of the UPS code and how you interact with the 3rd party server is similar to the USPS code above.  Assemble the XML schema according to the given specs, shoot it over the server, and parse out the response XML.  The only differences between the USPS code I created and the one from Chris Lee’s site from above is that I sent my XML off to the other server using simplexml_load_file while he uses cURL (which may require an add-on library for PHP).

So there you have it, great code to help you integrate 3rd party shipping APIs. I didn’t have to do FedEx so that I don’t have any code for that, but I don’t think its all that different. If you have any example of good FedEx API integration how-tos I’ll definitely appreciate the hookup in case I might need to use it in the future.

Downloads (incase you missed it)

UPS XML Rate PHP script