Development with the Canada Post shipping API

If you are developing a shopping cart and require real time shipping estimates via Canada Post, they provide an excellent and simple API you can use via CURL.

The first step to using the API is to contact Canada Post and let them know you want to use their API. The website related to this service is located at http://sellonline.canadapost.ca/ and, the FAQ says you must contact them via email at sellonline@canadapost.ca to register your account on the Sell Online server.

Once registered, they will give you a merchant ID, which you will use with the code below to request shipping estimates ( replace the ‘XXXXX_THIS_IS_YOUR_MERCHANT_ID_XXXX’ code below with the merchant ID they provide.).
You will also set up your shipping location, so they know where you are shipping items from.

Back on your website, for each product you are including in your shipping estimate request, you must include some basic info, like Height, Weight, Depth, Width, Name and Quantity.

Next, you must also supply the shipping destination ( where the items are going ). This includes City, Province, Country and Postal Code…

If Everything goes well with the request, Canada Post should return you your Shipping Options available for the order! The example is below…

// array_of_products we want shipping options for
$products = array( array( "Title"=>"Comapct Discs", "Height"=>5, "Width"=>5, "Depth"=>2, "Weight"=>1, "Qty"=>5 ),
                   array( "Title"=>"Bricks", "Height"=>3, "Width"=>5, "Depth"=>3, "Weight"=>10, "Qty"=>4 ) 
				 );
// call our canada post function with merchant id, 
// destination shipping address info ( City, Province, Country and Postal Code ),
// along with the products info...		 
$response = get_shipping_options( "XXXXX_THIS_IS_YOUR_MERCHANT_ID_XXXX", "Toronto", "ON", "CANADA", "M4B1B5", $products );

// check the response! if its an array it was successfull, a string is an error message
if ( !is_array( $response ) ) echo " ERROR: " . $response;
else echo " SUCCESS! Options are: " . print_r( $response, true );


// here is our function ....				 
function get_shipping_options( $merchantCPCID, $city, $province, $country,  $postalcode, $products ) {
		$options = array();
		
		ob_start();
		foreach( $products as $item ) {
			
			
			?>
				<item>
					<quantity><?=$item["Qty"]?></quantity>
					<weight><?=$item["Weight"]?></weight>
					<length><?=$item["Depth"]?></length>
				    <width><?=$item[ "Width"]?></width>
					<height><?=$item["Height"]?></height>
					<description><?=$item["Title"]?></description>
				</item>
            <?php
		}
	
		$items = ob_get_clean();
		
		if ( $items ) {
			
			$xmlDocument = "<?xml version=\"1.0\" ?><eparcel>
								<language>en</language>
								<ratesAndServicesRequest>
									<merchantCPCID>" . $merchantCPCID . "</merchantCPCID>
									<lineItems>" . $items  . "</lineItems>
									<city>" . $city . "</city>
									<provOrState>" . $province . "</provOrState>
									<country>" . $country . "</country>
									<postalCode>" . $postalcode . "</postalCode>
								</ratesAndServicesRequest>
						   </eparcel>";
		
			set_time_limit(10);
			$ch = curl_init("sellonline.canadapost.ca:30000");
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
			curl_setopt($ch, CURLOPT_URL, "sellonline.canadapost.ca:30000");
			curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
			curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
			
			curl_setopt($ch, CURLOPT_DNS_CACHE_TIMEOUT, 2678400);
			curl_setopt( $ch, CURLOPT_HEADER, 0 );
												   
			//curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
			curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlDocument);
			curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
			$response = "";
			$response = curl_exec($ch);
			curl_close( $ch );
			
			//convert the result to an array
			if ( $response != "" ) $response = json_decode(json_encode((array) simplexml_load_string($response)),1);
			
			//check for errors
			if ( !is_array( $response ) || isset( $response[ "error" ] ) ) {
				if ( !is_array( $response ) ) $message = "WARNING: Unable to Connect To Canada Post.";
				else $message = "WARNING: Canada Post Response Error<BR>" .
				                " Status Code: " . $response[ "error" ][ "statusCode" ] . "<br>" .
							    " Status Message: " . $response[ "error" ][ "statusMessage" ] . "<br>" .
								" requestID: " . $response[ "error" ][ "requestID" ] . "<br>";
				return $message;
			}
			// everything ok ?
			else {
				if ( isset( $response[ "ratesAndServicesResponse" ][ "product" ] ) ) {
					
					foreach( $response[ "ratesAndServicesResponse" ][ "product" ]  as $option ) {
						// add each of the options to the array
						$options[ $option["@attributes"]["id"] ] = array(  "ShippingName"=>$option[ "name" ],
																		   "ShippingRate"=> $option[ "rate" ],
																		   "ShippingDate"=>$option["shippingDate"], 
																		   "DeliveryDate"=>$option["deliveryDate"], 
																		   "ShippingCode"=>$option["@attributes"]["id"],
																		   "DeliveryDayOfWeek"=>$option["deliveryDayOfWeek"], 
																		   "NextDayAM"=>$option["nextDayAM"] == "true" ? 1 : 0
																		
																	  );
					
					} // end foreach options
				} // end isset options
			} // end result success
		} // end items exist
		return $options; 
	}

When you execute this code, you should receive back an array response similar to:

[1040] => Array
        (
            [ShippingName] => Priority Courier
            [ShippingRate] => 74.36
            [ShippingDate] => 2011-10-17
            [DeliveryDate] => 2011-10-18
            [ShippingCode] => 1040
            [DeliveryDayOfWeek] => 3
            [NextDayAM] => 1
        )

    [1020] => Array
        (
            [ShippingName] => Expedited
            [ShippingRate] => 43.24
            [ShippingDate] => 2011-10-17
            [DeliveryDate] => 2011-10-18
            [ShippingCode] => 1020
            [DeliveryDayOfWeek] => 3
            [NextDayAM] => 0
        )

    [1010] => Array
        (
            [ShippingName] => Regular
            [ShippingRate] => 43.24
            [ShippingDate] => 2011-10-17
            [DeliveryDate] => 2011-10-19
            [ShippingCode] => 1010
            [DeliveryDayOfWeek] => 4
            [NextDayAM] => 0
        )

Which are in fact, the three shipping options Canada Post has replied with. Good Luck!

Bookmark the permalink.
There are to Development with the Canada Post shipping API

  1. Thanks a lot, very helpful!


  2. Hello, I’m trying to develop a shipping example at darrencaldwellwebdesign.ca/transaction. I’m at the part where I need to calculate shipping costs for the item to get a full purchase price.

    I keep seeing SOAP/REST/XML, I kind of know what these are. Is there a way to do a $.post() or $.get in javascript and get back an array, or even just text that I can string splice for the value?

    I looked at examples of php but I see ‘ -> ‘ this all over the place and I’m not sure what it means or examples of how I should call it with javascript to get a value back.


Leave a Reply

Your email address will not be published. Required fields are marked *