I've been trying to access the Canada Post Sell Online API (if it's even still called that, in 2014) and I'm having lots of trouble. I'm using an Ubercart module (uc_canadapost) and it doesn't seem to work or something. It looks like you used to get a Merchant ID when you used Sell Online, and with Canada Post's new APIs you get a username and password as your API key.
It took me a good 2 hours to figure out how to successfully use curl to access the REST API. I'm now going to document the examples of successful curl commands that have actually worked.
First, go to https://www.canadapost.ca/cpotools/apps/drc/registered?execution=e4s1 and get your API Key. I'm using my development API key, which is broken into a username field and a password field, separated by a colon. I tried using the -H flag to curl to send the Basic Authorization header, which didn't work. I must have done it wrong. It was much easier (and more successful) to use the -u flag for the authentication bit.
This page https://www.canadapost.ca/cpo/mc/business/productsservices/developers/s… was a bunch of helpful information sandwiched between useless information. The relevant bit was that you can't just find a URL and send an HTTP GET and get your response. There are mandatory and optional HTTP headers; I'm reproducing the mandatory ones here:
HTTP Header Variable | Applicable Methods | Mandatory / Optional | Value | Description |
---|---|---|---|---|
Authorization |
GET, POST, DELETE |
Mandatory |
Basic userid:password |
|
Content-Type |
POST |
Mandatory |
Unique per service group. See service documentation for details. |
This is the XML version of the body you are sending in the POST. ( Note: */* in place of the header value will return an error) |
Accept |
GET |
Mandatory |
Unique per service group. See service documentation for details or use "media-type" from the provided link. |
This is the XML version of the response that you are expecting to receive. ( Note: */* in place of the header value will return an error) |
So for a HTTP GET, you need the Authorization header and the Accept header.
Let's try this for a simple query. There is a list of queries here: http://www.canadapost.ca/cpo/mc/business/productsservices/developers/se…
Here's how I did that for a simple query to "discover services" using GET(documentation for this call is here: http://www.canadapost.ca/cpo/mc/business/productsservices/developers/se…).
curl -u "edc2833333333335:dc167444444444444444a3" -H "Accept: application/vnd.cpc.ship.rate-v3+xml" 'https://ct.soa-gw.canadapost.ca/rs/ship/service?country=CA'
This was the magic. I used my development API Key (you can see I've obscured most of it with 3s and 4s) and I sent the request to the development version of the URL (ct.soa-gw.canadapost.ca instead of just soa-gw.canadapost.ca). I got this response back:
<?xml version="1.0" encoding="UTF-8"?> <services xmlns="http://www.canadapost.ca/ws/ship/rate-v3"> <service><service-code>DOM.EP</service-code><service-name>Expedited Parcel</service-name><link rel="service" href="https://ct.soa-gw.canadapost.ca/rs/ship/service/DOM.EP?country=CA" media-type="application/vnd.cpc.ship.rate-v3+xml"/></service> <service><service-code>DOM.RP</service-code><service-name>Regular Parcel</service-name><link rel="service" href="https://ct.soa-gw.canadapost.ca/rs/ship/service/DOM.RP?country=CA" media-type="application/vnd.cpc.ship.rate-v3+xml"/></service> <service><service-code>DOM.PC</service-code><service-name>Priority</service-name><link rel="service" href="https://ct.soa-gw.canadapost.ca/rs/ship/service/DOM.PC?country=CA" media-type="application/vnd.cpc.ship.rate-v3+xml"/></service> <service><service-code>DOM.XP</service-code><service-name>Xpresspost</service-name><link rel="service" href="https://ct.soa-gw.canadapost.ca/rs/ship/service/DOM.XP?country=CA" media-type="application/vnd.cpc.ship.rate-v3+xml"/></service> </services>
Woohoo! Now to get rates via POST. The Canada Post documentation is here: http://www.canadapost.ca/cpo/mc/business/productsservices/developers/se…. I've translated it into curl syntax:
curl -X POST -u "edc2833333333335:dc167444444444444444a3" -H "Accept: application/vnd.cpc.ship.rate-v3+xml" -H "Content-Type: application/vnd.cpc.ship.rate-v3+xml" -d @post.xml https://ct.soa-gw.canadapost.ca/rs/ship/price
Now the rubber hits the road here: -d @post.xml means I'm sending the data contained in the post.xml file in my current directory. You can include it as a big string (e.g. -d '
<?xml version="1.0" encoding="utf-8"?> <mailing-scenario xmlns="http://www.canadapost.ca/ws/ship/rate-v3"> <quote-type>counter</quote-type> <origin-postal-code>N2G1V6</origin-postal-code> <destination> <domestic><postal-code>K0J1X0</postal-code></domestic> </destination> <services> <service-code>DOM.RP</service-code> <service-code>DOM.EP</service-code> <service-code>DOM.XP</service-code> </services> <parcel-characteristics> <weight>2</weight> </parcel-characteristics> </mailing-scenario>
...and that beast, sent along with the CURL POST above it, gives us the following response. We did it!
<?xml version="1.0" encoding="UTF-8"?> <price-quotes xmlns="http://www.canadapost.ca/ws/ship/rate-v3"> <price-quote> <service-code>DOM.RP</service-code> <service-link rel="service" href="https://ct.soa-gw.canadapost.ca/rs/ship/service/DOM.RP?country=CA" media-type="application/vnd.cpc.ship.rate-v3+xml"/> <service-name>Regular Parcel</service-name> <price-details> <base>12.88</base> <taxes><gst>0.00</gst><pst>0.00</pst><hst percent="13.000">1.79</hst></taxes> <due>15.54</due> <options><option><option-code>DC</option-code><option-name>Delivery confirmation</option-name><option-price>0</option-price><qualifier><included>true</included></qualifier></option></options> <adjustments><adjustment><adjustment-code>FUELSC</adjustment-code><adjustment-name>Fuel surcharge</adjustment-name><adjustment-cost>0.87</adjustment-cost><qualifier><percent>6.75</percent></qualifier></adjustment></adjustments> </price-details> <weight-details></weight-details> <service-standard><am-delivery>false</am-delivery><guaranteed-delivery>false</guaranteed-delivery><expected-transit-time>3</expected-transit-time><expected-delivery-date>2014-09-26</expected-delivery-date></service-standard> </price-quote> <price-quote> <service-code>DOM.XP</service-code> <service-link rel="service" href="https://ct.soa-gw.canadapost.ca/rs/ship/service/DOM.XP?country=CA" media-type="application/vnd.cpc.ship.rate-v3+xml"/> <service-name>Xpresspost</service-name> <price-details> <base>16.19</base> <taxes><gst>0.00</gst><pst>0.00</pst><hst percent="13.000">2.35</hst></taxes> <due>20.44</due> <options><option><option-code>DC</option-code><option-name>Delivery confirmation</option-name><option-price>0</option-price></option></options> <adjustments><adjustment><adjustment-code>FUELSC</adjustment-code><adjustment-name>Fuel surcharge</adjustment-name><adjustment-cost>1.90</adjustment-cost><qualifier><percent>11.75</percent></qualifier></adjustment></adjustments> </price-details> <weight-details></weight-details> <service-standard><am-delivery>false</am-delivery><guaranteed-delivery>true</guaranteed-delivery><expected-transit-time>2</expected-transit-time><expected-delivery-date>2014-09-25</expected-delivery-date></service-standard> </price-quote> </price-quotes>