PHP/AJAX Shipping Calculator for UPS: getting a list of the available shipping services between locations
There are already guides available for building a general UPS shipping calculator form, and with a little knowledge of PHP, one can modify the sample to have the shipping calculated on one’s own shopping cart. The problem with such a static form is that it lists all shipping services that UPS provides anywhere.
<select name="selService">
<option value="1DM">Next Day Air Early AM</option>
<option value="1DA">Next Day Air</option>
<option value="1DP">Next Day Air Saver</option>
<option value="2DM">2nd Day Air AM</option>
<option value="2DA">2nd Day Air</option>
<option value="3DS">3 Day Select</option>
<option value="GND">Ground</option>
<option value="STD">Canada Standard</option>
<option value="XPR">Worldwide Express</option>
<option value="XDM">Worldwide Express Plus</option>
<option value="XPD">Worldwide Expedited</option>
<option value="WXS">Worldwide Saver</option>
</select>
This, however, makes it difficult for the user. If I am mailing a package within the United States, and I select “Worldwide Saver”, UPS will respond with an error message that this service is not available between the specified locations. To make the form more usable, the select should only list the services that are actually available. The question for the developer is — how do I know which of the services are actually available, given the origin and destination locations?
This article discusses how to request the list of available rates from UPS and how to read the response. Once this is accomplished, someone with who knows PHP and AJAX can easily put the code in the form to have the select list generated automatically.
Sending Request to UPS
Just as in the basic shipping calculator, the URL to request information from UPS is http://www.ups.com/using/services/rave/qcostcgi.cgi. Here, however, since the request is to get a list of available rates, the parameter “10_action” should be set to “4”.
The other required parameters are:
accept_UPS_license_agreement – must be set to “yes”
14_origCountry – the country the package is being sent from
15_origPostal – the zip code (postal code) the package is being sent from
origCity – the city the package is being sent from
23_weight – required, but for our purposes, you can use any number.
47_rateChart – required, can be any of the following: Regular+Daily+Pickup, OP_WEB, OP_PHONE, One+Time+Pickup, Letter+Center, or Customer+Counter. Not important which one.
48_container – Since this is also required but not significant for this query, I use the value “00”.
49_residential – 01 (residential) or 02 (commercial) required but not significant
13_product required but can be anything of 3 letters. I use “qqq”. The purpose of our request is to get the available values when you pass this to the price request, so by definition you never know what it should be.
19_destPostal – the zip code (postal code) the package is being sent to
20_destCity – the city the package is being sent to
22_destCountry – the country the package is being sent to
Hence, we can build a function to request the list of available rates as follows:
<?php
function request_ups_available_services($orig_city, $orig_postal, $orig_country, $dest_city, $dest_postal, $dest_country)
{
$ups_request=’http://ww.ups.com/using/services/rave/qcostcgi.cgi ‘
.’?accept_UPS_license_agreement=yes’
.’&10_action=4′
.’&23_weight=1′
.’&48_container=00′
.’&49_residential=01′
.’&13_product=qqq’
.’&47_rateChart=Regular+Daily+Pickup’
.’&origCity=’.$orig_city
.’&14_origCountry=’.$orig_country
.’&15_origPostal=’.$orig_postal
.’&19_destPostal=’.$dest_postal.
.’&20_destCity=’.$dest_city
.’&22_destCountry=’.$dest_country;
return file_get_contents($ups_request);
}
?>
Reading UPS response
The response string should look something like this:
UPSOnLine4%1DA%50665%US%88000%US%106%1%43.39%0.00%43.39%End of Day%
4%2DA%50665%US%88000%US%206%1%18.99%0.00%18.99%End of Day%
4%3DS%50665%US%88000%US%306%1%13.59%0.00%13.59%End of Day%
4%GND%50665%US%88000%US%006%1%8.21%0.00%8.21%End of Day%
How do we read the string and translate it into a list of services? There may be an official method, but this works for me. All services are 3 characters, and from the general form, we have a list of all available services:
<select name="selService">
<option value="1DM">Next Day Air Early AM</option>
<option value="1DA">Next Day Air</option>
<option value="1DP">Next Day Air Saver</option>
<option value="2DM">2nd Day Air AM</option>
<option value="2DA">2nd Day Air</option>
<option value="3DS">3 Day Select</option>
<option value="GND">Ground</option>
<option value="STD">Canada Standard</option>
<option value="XPR">Worldwide Express</option>
<option value="XDM">Worldwide Express Plus</option>
<option value="XPD">Worldwide Expedited</option>
<option value="WXS">Worldwide Saver</option>
</select>
Hence, we split the response by the separator character (“%”) and check each entry if it is a service type.
Here is a function that takes the response from UPS and generates a list of available services.
<?php
function generate_service_list_from_ups_response($ups_response)
{
$master_ups_service_list=array(
‘1DM’=>’Next Day Air Early AM’,
‘1DA’=>’Next Day Air’,
‘1DP’=>’Next Day Air Saver’,
‘2DM’=>’2nd Day Air AM’,
‘2DA’=>’2nd Day Air’,
‘3DS’=>’3 Day Select’,
‘GND’=>’Ground’,
‘STD’=>’Canada Standard’,
‘XPR’=>’Worldwide Express’,
‘XDM’=>’Worldwide Express Plus’,
‘XPD’=>’Worldwide Expedited’,
‘WXS’=>’Worldwide Saver’
);
$ups_service_list=array();
$ups_server_list=split(‘%’, $ups_response);
foreach($ups_server_list as $this_service)
{
if(isset($master_ups_service_list[$this_service]))
$ups_service_list[$this_service]=$master_ups_service_list[$this_service];
}
return $ups_service_list;
}
?>
Nicely done!
Reply