PHP: USPS rates calculator
The USPS Web Tools allow developers of web-based and shrink-wrapped applications access to the on-line services of the United States Postal Service (USPS). They provide easy access to shipping information and services for your customers. Your customers can utilize the functions provided by the USPS without ever leaving your web site. Once the Web Tools are integrated, your server communicates through the USPS Web Tools server over HTTP using XML (eXtensible Markup Language).
Rates Calculators
Everything in details can be found here:
http://www.usps.com/webtools/rate.htm
First steps:
- Register online (You will get your own user name)
- Test this script (You can use only test data)
- Contact ICCC and go live.
When you have completed your testing, email the USPS Internet Customer Care Center (ICCC). They will switch your profile to allow you access to the production server and will provide you with the production URL.
Domestic and International Rates
Domestic rates
Test 1:
$usps = new USPS;
$usps->setServer("http://testing.shippingapis.com/ShippingAPITest.dll");
$usps->setUserName("?????????");
$usps->setService("PRIORITY");
$usps->setDestZip("20008");
$usps->setOrigZip("10022");
$usps->setWeight(10, 5);
$usps->setContainer("Flat Rate Box");
$usps->setCountry("USA");
$price = $usps->getPrice();
Response 1:
usps Object
(
[server] => http://testing.shippingapis.com/ShippingAPITest.dll
[user] => ???????????
[pass] =>
[service] => PRIORITY
[dest_zip] => 20008
[orig_zip] => 10022
[pounds] => 10
[ounces] => 5
[container] => Flat Rate Box
[size] => REGULAR
[machinable] =>
[country] => USA
[zone] => 3
[list] => Array
(
[0] => price Object
(
[mailservice] => "Priority Mail Flat Rate Box (11.25'' x 8.75'' x 6'')"
[rate] => 7.70
)
[1] => price Object
(
[mailservice] => "Priority Mail Flat Rate Box (14''x 12'' x 3.5'')"
[rate] => 7.70
)
)
)
Test 2:
$usps = new USPS;
$usps->setServer("http://testing.shippingapis.com/ShippingAPITest.dll");
$usps->setUserName("?????????");
$usps->setService("All");
$usps->setDestZip("20008");
$usps->setOrigZip("10022");
$usps->setWeight(10, 5);
$usps->setContainer("Flat Rate Box");
$usps->setCountry("USA");
$usps->setMachinable("true");
$usps->setSize("LARGE");
$price = $usps->getPrice();
Response 2:
usps Object
(
[server] => http://testing.shippingapis.com/ShippingAPITest.dll
[user] => ???????????
[pass] =>
[service] => All
[dest_zip] => 20008
[orig_zip] => 10022
[pounds] => 10
[ounces] => 5
[container] => Flat Rate Box
[size] => LARGE
[machinable] => true
[country] => USA
[zone] => 3
[list] => Array
(
[0] => price Object
(
[mailservice] => "Express Mail to PO Addressee"
[rate] => 39.20
)
[1] => price Object
(
[mailservice] => "Priority Mail"
[rate] => 8.95
)
[2] => price Object
(
[mailservice] => "Parcel Post"
[rate] => 7.80
)
[3] => price Object
(
[mailservice] => "Bound Printed Matter"
[rate] => 3.53
)
[4] => price Object
(
[mailservice] => "Media Mail"
[rate] => 5.14
)
[5] => price Object
(
[mailservice] => "Library Mail"
[rate] => 4.91
)
)
)
International rates:
Test 1:
$usps = new USPS;
$usps->setServer("http://testing.shippingapis.com/ShippingAPITest.dll");
$usps->setUserName("??????????");
$usps->setWeight(2, 0);
$usps->setCountry("Albania");
$price = $usps->getPrice();
Response 1:
usps Object
(
[server] => http://testing.shippingapis.com/ShippingAPITest.dll
[user] => ?????????
[pass] =>
[service] =>
[dest_zip] =>
[orig_zip] =>
[pounds] => 2
[ounces] => 0
[container] => None
[size] => REGULAR
[machinable] =>
[country] => Albania
[list] => Array
(
[0] => intprice Object
(
[id] => 0
[rate] => 87
[pounds] => 2
[ounces] => 0
[mailtype] => "Package"
[country] => "ALBANIA"
[svccommitments] => "See Service Guide"
[svcdescription] => "Global Express Guaranteed (GXG) Document Service"
[maxdimensions] => "Max. length 46'', depth 35'', height 46'' and max. girth 108''"
[maxweight] => 22
)
[1] => intprice Object
(
[id] => 1
[rate] => 96
[pounds] => 2
[ounces] => 0
[mailtype] => "Package"
[country] => "ALBANIA"
[svccommitments] => "See Service Guide"
[svcdescription] => "Global Express Guaranteed (GXG) Non-Document Service"
[maxdimensions] => "Max. length 46'', depth 35'', height 46'' and max. girth 108''"
[maxweight] => 22
)
)
)
Possible errors:
usps Object
(
[server] => http://testing.shippingapis.com/ShippingAPITest.dll
[user] => ???????????
[pass] =>
[service] => Alll
[dest_zip] => 20008
[orig_zip] => 10022
[pounds] => 10
[ounces] => 5
[container] => Flat Rate Box
[size] => LARGE
[machinable] => true
[country] => USA
[error] => error Object
(
[number] => -2147219487
[source] => Rate_Respond;SOLServerRatesTest.RateV2_Respond
[description] => "Invalid value for package size."
[helpcontext] => 1000440
[helpfile] =>
)
)
Downlod this freeware PHP script: USPS rates calculator v1.2
Please make a donation of 1$ if you find our software useful and want to support the continued development.
Thank you.
thanks,Algirdas for reply, i want to know what is the process of implementation of usps after rate calculator.thanks
please provide me way of implementation(process) of usps after rate calculator.actully i want to know about reallty implementation of usps.thanks
Hi,
Domestic rates work fine, but the international don’t.
This is the error Message
API Authorization failure. IntlRate is not a valid API name for this protocol.
Thanks in Advnace
I’m also getting “Please enter a valid ZIP Code for the sender.” I’m on production, so why can’t I enter whatever zip codes I want?
This is not working for me.
It don’t work. Got the valid zip msg. Any idea?
RE Implementation problems some are having: USPS returns an object, which can be converted into an array if you want to get up and running quickly. (PHP 5+ does not do this automatically anymore) Use the objectToArray function found here: http://www.phpro.org/examples/Convert-Object-To-Array-With-PHP.html. (Reposting due to cutoff text)
USPS Rates
setServer(“http://testing.shippingapis.com/ShippingAPITest.dll”);
$usps->setUserName(“650SQUIS8177″);
$usps->setService(“All”);
$usps->setDestZip(“20008″);
$usps->setOrigZip(“10022″);
$usps->setWeight(10, 5);
$usps->setContainer(“Flat Rate Box”);
$usps->setCountry(“USA”);
$usps->setMachinable(“true”);
$usps->setSize(“LARGE”);
$price = $usps->getPrice();
print_r($price);
$arrayprice=objectToArray($price); // convert object to array
echo ‘This is the price for’ . $arrayprice['list'][1]['mailservice'] . ‘: ‘ . . ‘
This is the price for ‘ . $arrayprice['list'][2]['mailservice'] . ‘ :’ . $arrayprice['list'][2]['rate'] . ”;
?>
Hi,
International rates don’t work :(
This is the error Message
API Authorization failure. IntlRate is not a valid API name for this protocol.
Help please:)
I am also getting the same error..
API Authorization failure. IntlRate is not a valid API name for this protocol.
Please help…
International rates don’t work :(
a blank page with USPS Rates title.
please help..
hi, egain.
international rates don’t work…
USPS Object
(
[server] => http://testing.shippingapis.com/ShippingAPITest.dll
[user] => xxxxxxxxxxx
[pass] =>
[service] =>
[dest_zip] =>
[orig_zip] =>
[pounds] => 10
[ounces] => 0
[container] => None
[size] => REGULAR
[machinable] =>
[country] => Albania
[error] => error Object
(
[number] => 80040b1a
[source] => UspsCom::DoAuth
[description] => API Authorization failure. IntlRate is not a valid API name for this protocol.
[helpcontext] =>
[helpfile] =>
)
)
am also getting the same error..
API Authorization failure. IntlRate is not a valid API name for this protocol.
Please help…
i am going to implementing ‘Electronic Merchandise Return Service’ with appropriate xml for request but i am getting same error
[error] => error Object
(
[number] => 80040b1a
[source] => UspsCom::DoAuth
[description] => API Authorization failure. IntlRate is not a valid API name for this protocol.
[helpcontext] =>
[helpfile] =>
)
all three file xmlparser.php,usps.php and index.php put in folder and run
//xmlparser.php
class xmlparser
{
function GetChildren($vals, &$i)
{
$children = array();
if (isset($vals[$i]['value']))
$children['VALUE'] = $vals[$i]['value'];
while (++$i GetChildren($vals, $i));
} else {
$children[$vals[$i]['tag']][] = $this->GetChildren($vals, $i);
}
break;
case ‘close’:
return $children;
}
}
}
function GetXMLTree($xml)
{
$data = $xml;
$parser = xml_parser_create();
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
xml_parse_into_struct($parser, $data, $vals, $index);
xml_parser_free($parser);
//print_r($index);
$tree = array();
$i = 0;
if (isset($vals[$i]['attributes'])) {
$tree[$vals[$i]['tag']][]['ATTRIBUTES'] = $vals[$i]['attributes'];
$index = count($tree[$vals[$i]['tag']])-1;
$tree[$vals[$i]['tag']][$index] = array_merge($tree[$vals[$i]['tag']][$index], $this->GetChildren($vals, $i));
}
else
$tree[$vals[$i]['tag']][] = $this->GetChildren($vals, $i);
return $tree;
}
function printa($obj) {
global $__level_deep;
if (!isset($__level_deep)) $__level_deep = array();
if (is_object($obj))
print ‘[obj]‘;
elseif (is_array($obj)) {
foreach(array_keys($obj) as $keys) {
array_push($__level_deep, “[".$keys."]“);
$this->printa($obj[$keys]);
array_pop($__level_deep);
}
}
else print implode(” “,$__level_deep).” = $obj\n”;
}
}
//usps.php
require_once(“xmlparser.php”);
class USPS {
var $server = “”;
var $user = “”;
var $pass = “”;
var $service = “”;
var $dest_zip;
var $orig_zip;
var $pounds;
var $ounces;
var $container = “None”;
var $size = “REGULAR”;
var $machinable;
var $country = “USA”;
function setServer($server) {
$this->server = $server;
}
function setUserName($user) {
$this->user = $user;
}
function setPass($pass) {
$this->pass = $pass;
}
function setService($service) {
/* Must be: Express, Priority, or Parcel */
$this->service = $service;
}
function setDestZip($sending_zip) {
/* Must be 5 digit zip (No extension) */
$this->dest_zip = $sending_zip;
}
function setOrigZip($orig_zip) {
$this->orig_zip = $orig_zip;
}
function setWeight($pounds, $ounces=0) {
/* Must weight less than 70 lbs. */
$this->pounds = $pounds;
$this->ounces = $ounces;
}
function setContainer($cont) {
$this->container = $cont;
}
function setSize($size) {
$this->size = $size;
}
function setMachinable($mach) {
/* Required for Parcel Post only, set to True or False */
$this->machinable = $mach;
}
function setCountry($country) {
$this->country = $country;
}
function getPrice() {
if($this->country==”USA”){
// may need to urlencode xml portion
$str = $this->server. “?API=RateV2&XML=user . “\”%20PASSWORD=\”" . $this->pass . “\”>”;
$str .= $this->service . “” . $this->orig_zip . “”;
$str .= “” . $this->dest_zip . “”;
$str .= “” . $this->pounds . “” . $this->ounces . “”;
$str .= “” . urlencode($this->container) . “” . $this->size . “”;
$str .= “” . $this->machinable . “”;
}
else {
$str = $this->server. “?API=IntlRate&XML=user . “\”%20PASSWORD=\”" . $this->pass . “\”>”;
$str .= “” . $this->pounds . “” . $this->ounces . “”;
$str .= “Package”.urlencode($this->country).”";
}
$ch = curl_init();
// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, $str);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// grab URL and pass it to the browser
$ats = curl_exec($ch);
// close curl resource, and free up system resources
curl_close($ch);
$xmlParser = new xmlparser();
$array = $xmlParser->GetXMLTree($ats);
//$xmlParser->printa($array);
if(count($array['ERROR'])) { // If it is error
$error = new error();
$error->number = $array['ERROR'][0]['NUMBER'][0]['VALUE'];
$error->source = $array['ERROR'][0]['SOURCE'][0]['VALUE'];
$error->description = $array['ERROR'][0]['DESCRIPTION'][0]['VALUE'];
$error->helpcontext = $array['ERROR'][0]['HELPCONTEXT'][0]['VALUE'];
$error->helpfile = $array['ERROR'][0]['HELPFILE'][0]['VALUE'];
$this->error = $error;
} else if(count($array['RATEV2RESPONSE'][0]['PACKAGE'][0]['ERROR'])) {
$error = new error();
$error->number = $array['RATEV2RESPONSE'][0]['PACKAGE'][0]['ERROR'][0]['NUMBER'][0]['VALUE'];
$error->source = $array['RATEV2RESPONSE'][0]['PACKAGE'][0]['ERROR'][0]['SOURCE'][0]['VALUE'];
$error->description = $array['RATEV2RESPONSE'][0]['PACKAGE'][0]['ERROR'][0]['DESCRIPTION'][0]['VALUE'];
$error->helpcontext = $array['RATEV2RESPONSE'][0]['PACKAGE'][0]['ERROR'][0]['HELPCONTEXT'][0]['VALUE'];
$error->helpfile = $array['RATEV2RESPONSE'][0]['PACKAGE'][0]['ERROR'][0]['HELPFILE'][0]['VALUE'];
$this->error = $error;
} else if(count($array['INTLRATERESPONSE'][0]['PACKAGE'][0]['ERROR'])){ //if it is international shipping error
$error = new error($array['INTLRATERESPONSE'][0]['PACKAGE'][0]['ERROR']);
$error->number = $array['INTLRATERESPONSE'][0]['PACKAGE'][0]['ERROR'][0]['NUMBER'][0]['VALUE'];
$error->source = $array['INTLRATERESPONSE'][0]['PACKAGE'][0]['ERROR'][0]['SOURCE'][0]['VALUE'];
$error->description = $array['INTLRATERESPONSE'][0]['PACKAGE'][0]['ERROR'][0]['DESCRIPTION'][0]['VALUE'];
$error->helpcontext = $array['INTLRATERESPONSE'][0]['PACKAGE'][0]['ERROR'][0]['HELPCONTEXT'][0]['VALUE'];
$error->helpfile = $array['INTLRATERESPONSE'][0]['PACKAGE'][0]['ERROR'][0]['HELPFILE'][0]['VALUE'];
$this->error = $error;
} else if(count($array['RATEV2RESPONSE'])){ // if everything OK
//print_r($array['RATEV2RESPONSE']);
$this->zone = $array['RATEV2RESPONSE'][0]['PACKAGE'][0]['ZONE'][0]['VALUE'];
foreach ($array['RATEV2RESPONSE'][0]['PACKAGE'][0]['POSTAGE'] as $value){
$price = new price();
$price->mailservice = $value['MAILSERVICE'][0]['VALUE'];
$price->rate = $value['RATE'][0]['VALUE'];
$this->list[] = $price;
}
} else if (count($array['INTLRATERESPONSE'][0]['PACKAGE'][0]['SERVICE'])) { // if it is international shipping and it is OK
foreach($array['INTLRATERESPONSE'][0]['PACKAGE'][0]['SERVICE'] as $value) {
$price = new intPrice();
$price->id = $value['ATTRIBUTES']['ID'];
$price->pounds = $value['POUNDS'][0]['VALUE'];
$price->ounces = $value['OUNCES'][0]['VALUE'];
$price->mailtype = $value['MAILTYPE'][0]['VALUE'];
$price->country = $value['COUNTRY'][0]['VALUE'];
$price->rate = $value['POSTAGE'][0]['VALUE'];
$price->svccommitments = $value['SVCCOMMITMENTS'][0]['VALUE'];
$price->svcdescription = $value['SVCDESCRIPTION'][0]['VALUE'];
$price->maxdimensions = $value['MAXDIMENSIONS'][0]['VALUE'];
$price->maxweight = $value['MAXWEIGHT'][0]['VALUE'];
$this->list[] = $price;
}
}
return $this;
}
}
class error
{
var $number;
var $source;
var $description;
var $helpcontext;
var $helpfile;
}
class price
{
var $mailservice;
var $rate;
}
class intPrice
{
var $id;
var $rate;
}
//index.php
require(“usps.php”);
function objectToArray( $object )
{
if( !is_object( $object ) && !is_array( $object ) )
{
return $object;
}
if( is_object( $object ) )
{
$object = get_object_vars( $object );
}
return array_map( ‘objectToArray’, $object );
}
$usps = new USPS;
//$usps->setServer(“http://testing.shippingapis.com/ShippingAPITest.dll”);
$usps->setServer(“http://production.shippingapis.com/ShippingAPI.dll”);
$usps->setUserName(“xxxxxxxxxxxx”);
$usps->setService(“All”);
$usps->setDestZip(“90805″);
$usps->setOrigZip(“10022″);
$usps->setWeight(10, 5);
$usps->setContainer(“Flat Rate Box”);
$usps->setCountry(“USA”);
$usps->setMachinable(“true”);
$usps->setSize(“REGULAR”);
$price = $usps->getPrice();
//print_r($price);
$arrayprice=objectToArray($price); // convert object to array
$val=count($arrayprice['list']);
?>
Sr.
Available Option
Post Office Price
<?php
$i=1;
for($i=1;$i<$val;$i++)
{
echo "”;
echo “”.$i.”";
echo ” .html_entity_decode($arrayprice['list'][$i]['mailservice']). ‘ ‘ .html_entity_decode($arrayprice['list'][$i]['rate']).”";
echo “”;
}
echo “”;
?>
about International shipment
what if i want to get in response all valid services according to specific weight and dimensions
For Example
———–
Request
——-
size : Large
container: Rectangular
mailType : Envelope
weight : ( ex : 2 ounces )
Dimensions : ( L X W X H )
and so on the rest of parameters ….
Response
———-
List of services filtered according to the weight (sent in request) .