January 2, 2009
Canada Post Rates and Services Request
To get Canada Post Rates and Services, you need to post request formatted in XML to: http://206.191.4.228:30000 or http://sellonline.canadapost.ca:30000.
The XML example:
<?xml version="1.0" ?> <eparcel> <language>en</language> <ratesAndServicesRequest> <merchantCPCID>amerchantid</merchantCPCID> <lineItems> <item> <quantity>1</quantity> <weight>0.001</weight> <length>1</length> <width>1</width> <height>1</height> <description>My Item #1</description> </item> <item> <quantity>1</quantity> <weight>0.003</weight> <length>1</length> <width>1</width> <height>1</height> <description>My Item #2</description> </item> </lineItems> <city>beverly hills</city> <provOrState>CA</provOrState> <country>US</country> <postalCode>90210</postalCode> </ratesAndServicesRequest> </eparcel>
Set the above XML to a variable (e.g. CP_postdata) and post it:
Set srvCPXmlHttp = Server.CreateObject ("Msxml2.ServerXMLHTTP") srvCPXmlHttp.open "POST", "http://sellonline.canadapost.ca:30000", false srvCPXmlHttp.send(CP_postdata) CP_result = srvCPXmlHttp.responseText
XML response wil be returned and saved to CP_result variable. Here is the response example:
<?xml version="1.0"?> <!DOCTYPE eparcel [ <!-- EVERY REQUEST CONTAIN THE eparcel TAG --> <!ELEMENT eparcel (ratesAndServicesResponse)> <!-- ********************************************************* --> <!-- * Standard response for request for rates and services * --> <!-- ********************************************************* --> <!ELEMENT ratesAndServicesResponse (statusCode, statusMessage+, requestID, handling, language, product+, packing*, emptySpace*, shippingOptions, comment, nearestPostalOutlet*)> <!ELEMENT statusCode (#PCDATA)> <!ELEMENT statusMessage (#PCDATA)> <!ELEMENT requestID (#PCDATA)> <!ELEMENT handling (#PCDATA)> <!ELEMENT language (#PCDATA)> <!ELEMENT product (name, rate, shippingDate, deliveryDate, deliveryDayOfWeek, nextDayAM?, packingID)> <!ATTLIST product id CDATA #REQUIRED sequence CDATA #REQUIRED > <!ELEMENT name (#PCDATA)> <!ELEMENT rate (#PCDATA)> <!ELEMENT shippingDate (#PCDATA)> <!ELEMENT deliveryDate (#PCDATA)> <!ELEMENT deliveryDayOfWeek (#PCDATA)> <!ELEMENT nextDayAM (#PCDATA)> <!ELEMENT packingID (#PCDATA)> <!ELEMENT packing (packingID, box+)> <!ELEMENT box (name, weight, expediterWeight, length, width, height, packedItem+)> <!ELEMENT weight (#PCDATA)> <!ELEMENT expediterWeight (#PCDATA)> <!ELEMENT length (#PCDATA)> <!ELEMENT width (#PCDATA)> <!ELEMENT height (#PCDATA)> <!ELEMENT packedItem (quantity, description)> <!ELEMENT quantity (#PCDATA)> <!ELEMENT description (#PCDATA)> <!ELEMENT emptySpace (length, width, height, weight)> <!ELEMENT shippingOptions (insurance, deliveryConfirmation, signature, flexiblePaymentAvailable?)> <!ELEMENT insurance (#PCDATA)> <!ELEMENT deliveryConfirmation (#PCDATA)> <!ELEMENT signature (#PCDATA)> <!ELEMENT flexiblePaymentAvailable EMPTY> <!ELEMENT comment (#PCDATA)> <!-- ********************************************************* --> <!-- * 'nearestPostalOutlet' is optional and is returned * --> <!-- * only if the merchant profile has this option enabled * --> <!-- ********************************************************* --> <!ELEMENT nearestPostalOutlet (postalOutletSequenceNo, distance, outletName, businessName, postalAddress, phoneNumber, businessHours+)> <!ELEMENT postalOutletSequenceNo (#PCDATA)> <!ELEMENT distance (#PCDATA)> <!ELEMENT outletName (#PCDATA)> <!ELEMENT businessName (#PCDATA)> <!ELEMENT postalAddress (addressLine+, postalCode, municipality, province?)> <!ELEMENT addressLine (#PCDATA)> <!ELEMENT postalCode (#PCDATA)> <!ELEMENT municipality (#PCDATA)> <!ELEMENT province (#PCDATA)> <!ELEMENT phoneNumber (#PCDATA)> <!ELEMENT businessHours (dayId, dayOfWeek, time)> <!ELEMENT dayId (#PCDATA)> <!ELEMENT dayOfWeek (#PCDATA)> <!ELEMENT time (#PCDATA)> ]> <eparcel> <ratesAndServicesResponse> <statusCode>1</statusCode> <statusMessage>OK</statusMessage> <requestID>999999</requestID> <handling>3.0</handling> <language>0</language> <product id="2040" sequence="1"> <name>Priority Worldwide USA</name> <rate>91.16</rate> <shippingDate>2008-10-17</shippingDate> <deliveryDate>www.canadapost.ca/?Lang=en</deliveryDate> <deliveryDayOfWeek>4</deliveryDayOfWeek> <nextDayAM>false</nextDayAM> <packingID>P_0</packingID> </product> <product id="2030" sequence="2"> <name>Xpresspost USA</name> <rate>28.64</rate> <shippingDate>2008-10-17</shippingDate> <deliveryDate>2008-10-22</deliveryDate> <deliveryDayOfWeek>4</deliveryDayOfWeek> <nextDayAM>false</nextDayAM> <packingID>P_0</packingID> </product> <product id="2025" sequence="3"> <name>Expedited US Commercial</name> <rate>17.55</rate> <shippingDate>2008-10-17</shippingDate> <deliveryDate>2008-10-29</deliveryDate> <deliveryDayOfWeek>4</deliveryDayOfWeek> <nextDayAM>false</nextDayAM> <packingID>P_0</packingID> </product> <packing> <packingID>P_0</packingID> <box> <name>Dummy Box - Change or Delete me.</name> <weight>1.66</weight> <expediterWeight>0.501</expediterWeight> <length>25.0</length> <width>20.0</width> <height>20.0</height> <packedItem> <quantity>1</quantity> <description>My Item #1</description> </packedItem> </box> </packing> <shippingOptions> <insurance>No</insurance> <deliveryConfirmation>Yes</deliveryConfirmation> <signature>No</signature> </shippingOptions> <comment>* For major centres only. Add 1 to 3 business days for other destinations.</comment> </ratesAndServicesResponse> </eparcel> <!--END_OF_EPARCEL-->
Please note that the response example is not retrieved from the request example (I think I got the response example from another request).
You can then parse the XML response:
Set CPXMLdoc = Server.CreateObject("Msxml2.DOMDocument")
Make sure you have set up the Box sizes on the http://sellonline.canadapost.ca/servlet/LogonServlet (login, click Add / Modify / Delete Boxes).
You need to have a box that will fit the item you want to ship. Otherwise and the item you’re trying to ship is too large, you’ll get this error -4004, “Item is too large to be packed”, the XML response is:
<?xml version="1.0" ?> <!DOCTYPE eparcel [ <!ELEMENT eparcel (error)> <!ELEMENT error (statusCode,statusMessage*, requestID)> <!ELEMENT statusCode (#PCDATA)> <!ELEMENT statusMessage (#PCDATA)> <!ELEMENT requestID (#PCDATA)> ]> <eparcel> <error> <statusCode>-4004</statusCode> <statusMessage>Item is too large to be packed. </statusMessage> <requestID>999999</requestID> </error> </eparcel> <!--END_OF_EPARCEL-->
Below is the Add / Modify / Delete Boxes screen.
Update #1 (Jan 27th 2009):
I accidentally added a semicolon:
Set srvCPXmlHttp = Server.CreateObject ("Msxml2.ServerXMLHTTP");
It should be:
Set srvCPXmlHttp = Server.CreateObject ("Msxml2.ServerXMLHTTP")
I also changed the length, width, height to 1 after I notice the dimension I specified would return a 4004 error.
All are corrected above.
Update #2 (Jan 27th 2009):
If you use non registered Merchant CPC Id (e.g. <merchantCPCID>amerchantid</merchantCPCID>), you’ll get the following response:
-2001 Merchant CPC Id not found on server. 2515904
Update #3 (Jan 27th 2009):
For testing, you can copy/paste the following code, save as an ASP file to your web server, and run the page. Please change the value inside <merchantCPCID>. You can even run it from you local web server. To see the XML, see the HTML code (e.g. on IE 7, click Page>>View Source)
<% dim CP_postdata CP_postdata = "" CP_postdata = CP_postdata & "<?xml version=""1.0"" ?>" CP_postdata = CP_postdata & "<eparcel>" CP_postdata = CP_postdata & " <language>en</language>" CP_postdata = CP_postdata & " <ratesAndServicesRequest>" CP_postdata = CP_postdata & " <merchantCPCID>amerchantid</merchantCPCID>" CP_postdata = CP_postdata & " <lineItems>" CP_postdata = CP_postdata & " <item>" CP_postdata = CP_postdata & " <quantity>1</quantity>" CP_postdata = CP_postdata & " <weight>0.001</weight>" CP_postdata = CP_postdata & " <length>1</length>" CP_postdata = CP_postdata & " <width>1</width>" CP_postdata = CP_postdata & " <height>1</height>" CP_postdata = CP_postdata & " <description>My Item #1</description>" CP_postdata = CP_postdata & " </item>" CP_postdata = CP_postdata & " <item>" CP_postdata = CP_postdata & " <quantity>1</quantity>" CP_postdata = CP_postdata & " <weight>0.003</weight>" CP_postdata = CP_postdata & " <length>1</length>" CP_postdata = CP_postdata & " <width>1</width>" CP_postdata = CP_postdata & " <height>1</height>" CP_postdata = CP_postdata & " <description>My Item #2</description>" CP_postdata = CP_postdata & " </item>" CP_postdata = CP_postdata & " </lineItems>" CP_postdata = CP_postdata & " <city>beverly hills</city>" CP_postdata = CP_postdata & " <provOrState>CA</provOrState>" CP_postdata = CP_postdata & " <country>US</country>" CP_postdata = CP_postdata & " <postalCode>90210</postalCode>" CP_postdata = CP_postdata & " </ratesAndServicesRequest>" CP_postdata = CP_postdata & "</eparcel>" dim srvCPXmlHttp, CP_result Set srvCPXmlHttp = Server.CreateObject ("Msxml2.ServerXMLHTTP") srvCPXmlHttp.open "POST", "http://sellonline.canadapost.ca:30000", false srvCPXmlHttp.send(CP_postdata) CP_result = srvCPXmlHttp.responseText response.write CP_result %>
How to use Eval on ImageUrl
I was converting the <img> into ASP.NET Image Control, I learnt new thing on the way.
Here is the code before I changed it:
<td> <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="#"> <img height="140px" width="140px" src='images/catalog/<%# Eval("smallimageurl") %>' /> </asp:HyperLink> </td>
And I modified like so:
<td> <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="#"> <asp:Image Height="140" Width="140" ID="Image4" runat="server" ImageUrl='~/images/catalog/<%# Eval("smallimageurl") %>' /> </asp:HyperLink> </td>
But the the Eval didn’t resolve correctly, here is the resulting HTML:
<img style="border-width: 0px; height: 140px; width: 140px;" src="../images/catalog/%3C%25#%20Eval(%22smallimageurl%22)%20%25%3E" id="ctl00_ContentPlaceHolder1_viewcategory1_DataList1_ctl00_Image4"/>
After doing some googling I found a solution to this.
The simple solution:
ImageUrl='<%# "~/images/catalog/" + Eval("smallimageurl") %>'
A more elegant solution:
ImageUrl='<%# Eval("smallimageurl", "~/images/catalog/{0}") %>'
And the correct HTML is:
<img style="border-width: 0px; height: 140px; width: 140px;" src="../images/catalog/MM54.jpg" id="ctl00_ContentPlaceHolder1_viewcategory1_DataList1_ctl00_Image4"/>