Tracking UPS Packages with PHP
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, ‘dtk_TrackXML_V1.zip‘. 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:
require("upsTrack.php");
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:
upsTrack($trackingNumber);
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:
echo $someArray['TRACKRESPONSE']['SHIPMENT']['SCHEDULEDDELIVERYDATE'];
If you are wondering how I knew how the array was structred you can do:
print_r($someArray);
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, ‘dtk_TrackXML_V1.zip‘.
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'>
<AccessLicenseNumber>ACCESSNUMBER</AccessLicenseNumber>
<UserId>USERNAME</UserId>
<Password>PASSWORD</Password>
</AccessRequest>
<?xml version=\"1.0\"?>
<TrackRequest>
<Request>
<TransactionReference>
<CustomerContext>
<InternalKey>blah</InternalKey>
</CustomerContext>
<XpciVersion>1.0</XpciVersion>
</TransactionReference>
<RequestAction>Track</RequestAction>
</Request>
<TrackingNumber>$trackingNumber</TrackingNumber>
</TrackRequest>";
$ch = curl_init("https://www.ups.com/ups.app/xml/Track");
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("https://www.ups.com/ups.app/xml/Track");
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_TIMEOUT, 60);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
$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);
xml_parser_free($xml_parser);
$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.']]';
$start_level++;
}
$php_stmt .= '[$xml_elem[\'tag\']] = $xml_elem[\'value\'];';
eval($php_stmt);
}
}
curl_close($ch);
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.








[...] can also integrate UPS Tracking features on your site once you get a handle on [...]
Mark – thanks for your UPS API explanation. Have you ever come across the need to get the DETAILED tracking information for a UPS package (detailed, meaning each of the scan locations, as opposed to just a confirmation of delivery)? If so, what would CHANGE in your script to get this to work?
Neil Marriott, if you do a print_r on the response array you will see all the detailed information. All you have to do is reference those array hashes for the information you want to see.
[...] Track UPS Packages with cURL and PHP [...]
Hi Mark,
Thanks for your both articles. I was trying to find the code in PHP to calculate the UPS shipping rate. Finally i found your code. It is fine. I need one clarifications.
I have one e-commerce site in PHP and have UPS account. When my users purchase any products, they will give the “shipment going address” (Shipping Address). I have “shipment coming from address” (This is my shop address). Using this and other information (product weight.width, height….), is it any API for handling the UPS shipping functionality through our application?
I am awaiting for your reply.
Thanks,
Senthil.
This is great. But how do you get the package progress? I don’t see it in the XML development documents.