PHP Shipping Modules (Canada Post)

Over the last month I have been working on an e-commerce store for our company and realized most of the shipping modules out there are quite complex to use. So, I decided to create a simple Canada Post PHP Class.

Canada Post’s specification requires parsing of XML files to retrieve values, hence I have used PHP-5’s new features like DomDocument, DomXPath and stream functions which will only work with PHP-5 (you would need additional libraries to run it in PHP-4)

The class provided is called class.canadapost.php and I below I will provide instructions on how to use it.

(note: To use Canada Post, Port 30000 must be opened.)

Instructions on How to use the class

At first make sure you include the class using require or include..

include 'path/to/class/class.canadapost.php';

Then Initialize the class and set your information (your as in the store’s postal code, and canada posts’ merchant CPCID) and the customer Information.

$cPost = new CanadaPost();

/* Set your manufacturer CPCID, postal code by calling the function setManufacturer and passing in associative array 
 * format shown below, pass the total Cost of the item to be shipped in itemsPrice.
 */
$cPost->setManufacturer( array (
      'merchantCPCID' => CPC_DEMO_XML, // use your merchantCPCID
      'fromPostalCode' => YOUR_POSTAL_CODE, // use your postal code from where the item will be shipped
      'turnAroundTime' => 24,
      'itemsPrice' => 14 // put the total cost of item to be shipped.
    )
); 

/* Then set the Customer address in the format shown below, again in associative array format.
 *  Note: you dont need to pass the city and provOrState, they are actually optional. You only need the Postal Code 
 *  and country. 
 */
$cPost->setCustomer( array (
     'city' => 'Brampton', [CUSTOMER_CITY]
     'provOrState' => 'Ontario', [CUSTOMER_STATE_PROVINCE]
     'country' => CA, [2 Digit Code, see Canada Post Specs for more Info]
     'postalCode' => 'L1JK9' [CUSTOMER_POSTAL_OR_ZIP_CODE]
   )
);

I have developed the Class by keeping in mind that we could have several stores in different location, from where we could be shipping items. However, if you have just one store, then you don’t have to call the function setManufacturer every time, instead you can modify the class.canadapost.php’s constructor and hardcode the items there. So, then, after initializing the class, all you need to do is call the setPrice function to set the total Price.

$cPost->setPrice(15);

Now, add the Products you want to ship. Weights are in KG and dimension should be in CM. In the quantity, pass the
number of same products you wish to ship.

$cPost->addProduct(  array (
   'quantity' => 1,
   'weight'=> 2,
   'length' => 3,
   'width' => 1,
   'height' => 8,
  'description' => 'some Description about Product'
  )
 );

/** To add additional product, just call the same function i.e. addProduct again passing information about product as shown above **/

Now, the final part. To get the rates. You can either receive the entire XML response from Canada Post and do the parsing yourself, or you could ask the function to return you the response in associative array format, which would make it easier for you to fetch the information.

To receive in XML, do the following:

$responseXML = $cPost->getRates(); // returns in XML format. 

To receive in Associative Array, do the following:

$responseArray = $cPost->getRates('array');

If any error happens, the function getRates( ) would return false, and you can get the Error message from the function getErrorMessage( ), as shown below:

$rXML = $cPost->getRates(); // or $rXML= $cPost->getRates('array);
if( $rXML === false ) {
  echo $cPost->getErrorMessage();
}

When you receive the response in associative format, here’s a var_dump how the array returns information:

array(2) {
  ["product"]=>
  array(3) {
    [0]=>
    array(7) {
      ["name"]=>
      string(16) "Priority Courier"
      ["rate"]=>
      string(5) "16.26"
      ["shippingDate"]=>
      string(10) "2008-09-29"
      ["deliveryDate"]=>
      string(10) "2008-09-30"
      ["deliveryDayOfWeek"]=>
      string(1) "3"
      ["nextDayAM"]=>
      string(4) "true"
      ["packingID"]=>
      string(3) "P_0"
    }
    [1]=>
    array(7) {
      ["name"]=>
      string(9) "Expedited"
      ["rate"]=>
      string(4) "7.34"
      ["shippingDate"]=>
      string(10) "2008-09-29"
      ["deliveryDate"]=>
      string(10) "2008-09-30"
      ["deliveryDayOfWeek"]=>
      string(1) "3"
      ["nextDayAM"]=>
      string(5) "false"
      ["packingID"]=>
      string(3) "P_0"
    }
    [2]=>
    array(7) {
      ["name"]=>
      string(7) "Regular"
      ["rate"]=>
      string(4) "7.34"
      ["shippingDate"]=>
      string(10) "2008-09-29"
      ["deliveryDate"]=>
      string(10) "2008-10-01"
      ["deliveryDayOfWeek"]=>
      string(1) "4"
      ["nextDayAM"]=>
      string(5) "false"
      ["packingID"]=>
      string(3) "P_0"
    }
  }
  ["shippingOptions"]=>
  array(3) {
    ["insurance"]=>
    string(2) "No"
    ["deliveryConfirmation"]=>
    string(3) "Yes"
    ["signature"]=>
    string(2) "No"
  }
}

As seen above, the response contains array of 2 elements, products and shippingOptions, and within products contains array of the different shipping rates available. Within shippingOptions, contains the shipping insurance, and other features. Insurance options can be selected from your Canada Posts account’s page on the Canada Post Server.

I have attached 2 files, class.canadapost.php and estimate_shipping.php. Once again make sure you have port 30000 opened for it to function. Please rename the files from *.txt to *.php

Download from Github