Over the last month I have been working on an e-commerce store for our company. One thing I did realize that 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
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
| Attachment | Size |
|---|---|
| class.canadapost.php | 7.25 KB |
| estimate_shipping.php | 4.39 KB |
Comments
Thanks
Nice work. It worked like a charm.
Good Stuff
Thanks for giving this script. Its really good.
Great work.
I have been looking for a script just like this... This made by life a lot easier.
Thank you so much.
Jacob.
Well done!
Thank you very much! I just saved a lot of time thanks to your script!
ReadyToShip
For those who don't want to use pre-saved boxes, here's a line you need to add in the prepareXML() function, just before "$lineItems->appendChild($eachItems);" :
$eachItems->appendChild( $sendXML->createElement('readyToShip') );
Otherwise, I was always getting a "Parcel too large to be shipped with CPC." error.
/Martin
Right.. thank you
Thank you for that addition :).
Very Nice !!!
Good work !!! I can't seem to find the script for Fedex on your blog?
Regards,
Tamim
Haven't had the time to develop Fedex's one
Sorry, I haven't had the time to develop a specific one for Fedex.
Awesome!!!
Thanks you so much!!!!. Keep up the good work.
Maria
Nice work, but lacks advanced features
Nice work and I like it how you made this work so simple by a simple class file, Kudos to you!!. But, it lacks advanced features like shipping insurance.
Joseph
http://www.creativemind.com/
Good work
Thanks for the code, its really simple to use and works great.
Best,
Alex.
That's a nifty script you got
That's a nifty script you got there. As previously commented it lacks shipping insurance. Is there any possibility that you will add that in future ?
Cheers,
Nice script, whats the license on it ?
Whats the license on the script (GPL ?). I want to use it for some of my work.
Mark
Hi There, No specific license for this script, use it freely
Normally, I put GPL license on my code. For this one, I didn't put any license. Feel free to use it, but, I will appreciate if you keep my name at the top of the script.
Thanks,
How to make it work on PHP 4.4?
Nice work, Is there any way to make it work on PHP 4.4?.
Let me know at justin99[AT]hotmail[DOT]com.
Good Job
Good job on the script!.
Michael,
Vancouver.
Thanks for the code.Keep up
Thanks for the code.Keep up the good work.
Hi I am getting Connection
Hi
I am getting Connection Timeout error in this
Can you help me
Connection error usually
Connection error usually happens because of port 30,000 not being opened. Please ensure you have port 30000 opened for this script to work.
Please let me know if you are still facing issues after port 30000 is opened.
Thanks,
This script is really
This script is really awesome. Thank you for sharing this.
Very awsum work . But I
Very awsum work .
But I have question for which I have been searching internet but couldnot got any hint.
How can I have tracking number using canada post sell online and after I get the tracking number How can I track it using sellonline API's
Many thanks
Thank you for sharing this.
Thank you for sharing this. It is an awesome piece of code that saved me days of headaches. You need to get into some SEO so that you can bump up to top spot instead of that crap code offered by the #1 spot on sourceforge!
Awesome script. This is so
Awesome script. This is so much easier to use. I agree with the previous comment that you need to add into some SEO. Your script comes up 4th/5th place on 1st page, but you need to get into 1st/2nd place. The current 1st and 2nd scripts are crap.
Thanks again!
Change the Size to 15 pixels.
Change the Size to 15 pixels.
can u help me with the
can u help me with the integration on site i am not coder but my guy left half the way ...and last moment i left with nothing but whole site whiteout shipping
I have a question - can I
I have a question - can I post this topic?
Yes, feel free to. But, I
Yes, feel free to. But, I would appreciate you could link back to my blog :).
Can I links here?
Can I links here?
Yes, feel free to link to my
Yes, feel free to link to my blog.
Hi! Do you know why the error
Hi!
Do you know why the error "Connection Timeout" happens?
Most likely port 30000 is
Most likely port 30000 is closed, which is why you are getting connection timeout. Make sure port 30000 is opened for this script to work.
It saved me so much time!
It saved me so much time! Thank you!
Great Work!!! I wanna create
Great Work!!!
I wanna create a shipment by this way and also get the printable pdf like this video https://www.canadapost.ca/personal/tools/cst/demo-e.html
Would u help??
Add new comment