You are hereBlogs / alif's blog / PHP Shipping Modules (Canada Post)
PHP Shipping Modules (Canada Post)
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
| Attachment | Size |
|---|---|
| class.canadapost.php | 7.25 KB |
| estimate_shipping.php | 4.39 KB |
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??
It saved me so much time! Thank you!
Hi!
Do you know why the error "Connection Timeout" happens?
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.
Can I links here?
Yes, feel free to link to my blog.
I have a question - can I post this topic?
Yes, feel free to. But, I would appreciate you could link back to my blog :).
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
Change the Size to 15 pixels.
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!
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!
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
This script is really awesome. Thank you for sharing this.
Hi
I am getting Connection Timeout error in this
Can you help me
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,
Thanks for the code.Keep up the good work.
Good job on the script!.
Michael,
Vancouver.
Nice work, Is there any way to make it work on PHP 4.4?.
Let me know at justin99[AT]hotmail[DOT]com.
Whats the license on the script (GPL ?). I want to use it for some of my work.
Mark
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,
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,
Thanks for the code, its really simple to use and works great.
Best,
Alex.
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/
Thanks you so much!!!!. Keep up the good work.
Maria
Good work !!! I can't seem to find the script for Fedex on your blog?
Regards,
Tamim
Sorry, I haven't had the time to develop a specific one for Fedex.
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
Thank you for that addition :).
Thank you very much! I just saved a lot of time thanks to your script!
I have been looking for a script just like this... This made by life a lot easier.
Thank you so much.
Jacob.
Thanks for giving this script. Its really good.
Nice work. It worked like a charm.
Post new comment