Tracking UPS Packages with PHP

Last updated: Jul 29, 2008
Update: For a no fuss, 100% complete UPS Online Tools script with label printing support, integration support and automatic certification generation (required by UPS), I have created, RocketShipIt.

By now you should know how to look up a UPS rate with PHP. Now we are going to look into tracking the package using the UPS tracking XML API. This tool uses the same process as the rate selection tool so it should look familiar to you.

This article is going to be laid out a little bit different than my previous UPS articles. Instead of simply walking your through the code and providing an example I am going to try to break down the code in pieces and explain how each part works so you have a deep understanding of the code when you go to customize it for your application.

Things you will need

UPS Online Tool Account - free but requires registration UPS Access Key - Comes with the online tool account cURL - Most LAMP (Linux, Apache, Mysql, PHP) web hosts have this installed by default. If you are using Dreamhost you already have this installed. PHP - You must know a little bit about using php. After all you are about to create a custom UPS shipping calculator. XML - If you know what PHP is you should know what this is. If not read about it here. SSH access - Many web hosts offer this. You don’t HAVE to have it but it makes troubleshooting easier (another reason i like Dreamhost).

If you want some more detailed information about customizing the request with different XML paramaters you can check out their manual called, ‘’. You will have access to it once you sign up for the free UPS Online Tool Account.

Setting it up

Copy the UPS Tracking PHP Function I have created into a new .txt file and name it upsTrack.php. Go through this function and find the parts in the XML file that are in CAPS, You will need to add your access key, username, password, etc…

Then create another .php file and make sure to include upsTrack.php.

It might look something like this:


Now all you have to do to get an tracking information for a package is call the upsTrack function.

The basic syntax for the function is:


Since this function returns an array it is often useful to put it into a variable:

$someArray = upsTrack('YourTrackingNumberHere');

This way you can return any portion of the xml data you wish. For example if you wanted to find out the scheduled delivery date of the package you could simply do:


If you are wondering how I knew how the array was structred you can do:


This will give you all the possible data fields from the XML response.

Breaking down the code

The first part of the code creates the function called, ‘upsTrack’. This function is setup to accept the variable, ‘$trackingNumber’. The rest of this snippet is the XML data that we will be sending to the UPS API servers. If you need to modify this part of the code you will need to check out the UPS Tracking manual in, ‘’.

Remember to change the the ACCESSNUMBER, USERNAME, and PASSWORD to the your actual values.

function upsTrack($trackingNumber) {
$data ="<?xml version=\"1.0\"?>
<AccessRequest xml:lang='en-US'>
<?xml version=\"1.0\"?>
$ch = curl_init("");

This next part of the code is where we setup cURL. cURL is the program we use to send the XML request data in our, ‘$data’ variable (the stuff above).

Note: You can uncomment the echo if you want to see the raw XML data response in the HTML comments.

$ch = curl_init("");
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch,CURLOPT_TIMEOUT, 60);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
$result=curl_exec ($ch);
// echo '<!-- '. $result. ' -->';
$data = strstr($result, '<?');

The rest of the code simply puts the XML into an array with values that correspond to the XML tags. This makes it eash to extract specific values. Unless you know what you are doing I would stay away from editing this part of the code.

$xml_parser = xml_parser_create();
xml_parse_into_struct($xml_parser, $data, $vals, $index);
$params = array();
$level = array();
foreach ($vals as $xml_elem) {
 if ($xml_elem['type'] == 'open') {
if (array_key_exists('attributes',$xml_elem)) {
         list($level[$xml_elem['level']],$extra) = array_values($xml_elem['attributes']);
} else {
         $level[$xml_elem['level']] = $xml_elem['tag'];
 if ($xml_elem['type'] == 'complete') {
$start_level = 1;
$php_stmt = '$params';
while($start_level < $xml_elem['level']) {
         $php_stmt .= '[$level['.$start_level.']]';
$php_stmt .= '[$xml_elem[\'tag\']] = $xml_elem[\'value\'];';
return $params;

A working example

To prove this code works as is I copied and pasted it and added a form. Here is the working model of the UPS tracking function.

Need to print shipping labels on your site?

Checkout my product RocketShipIt for simple easy-to-use developer tools for UPS™ FedEx™ USPS™ and more.

Get notified on new posts or other things I'm working on