Monday, January 08, 2007

UPS Shipping Rates XML and ASP Sample Code

Update 09/10/2012 Big thanks to sumnone for submitting bugfixes for this code. His comments have been added to the code and the noted problems have been fixed in the examples.
Update 04/15/2007: If you're looking for an ASP solution for live shipping rates you might want to try reading this post too.

I recently ran into a forum post that had some great sample code for posting and retrieving data to the UPS XML provider. It condensed nicely a few hundred pages of documents outlining the complete XML specification from UPS into a few simple lines of code. I cleaned it up and added some functionality so that this could all be called quite nicely through a sub and it'd return a nice drop-down menu.

You'll have to provide your own license numbers, but you can obtain them for free from the UPS website. The signup process can seem a bit convoluted. You get a username, password, account number, developer key and XML/HTML Access Key.  Keep track of them all because you’ll need certain ones to sign up for certain services on the UPS website.

After you’re all signed up, plug your username, password and XML/HTML access key into this code and you can send and receive shipping quotes right from UPS. This code uses the built in Windows components from Microsoft to do all the dirty work, so no need to pay for components or libraries.

Also notice that the “BuildUPSXML” function has the shipper URL built in. If you’re going to need quote shipping dynamically from different locations, you’ll have to change this section.

<% Response.Buffer=True %>
<%
sAccessLicenseNumber = "XXXXXXXXXXXXXXXX"
sUserID = "xxxxxx"
sPassword = "xxxxxx"

DrawUPSRates "33", "50021"


Sub DrawUPSRates(sWeight, sDestinationPostalCode)

  sUPSXML = BuildUPSXML(sWeight, sDestinationPostalCode)

  'Now pass the request to UPS
  Set xmlhttp = Server.CreateObject("MSXML2.ServerXMLHTTP")
  xmlhttp.Open "POST","https://www.ups.com/ups.app/xml/Rate?",false
  xmlhttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
  xmlhttp.send sUPSXML

  sResponseXML = xmlhttp.responseText
  Set mydoc=Server.CreateObject("Microsoft.xmlDOM")
  mydoc.loadxml(sResponseXML)
  'Create a select table from the response xml
  response.Write("<select name='shipping'>")
  'Create A Nodelist of All The RatedShipments
  Set NodeList = mydoc.documentElement.selectNodes("RatedShipment")
  For x = 0 To NodeList.length - 1
    sDisplayString = _
    GetFriendlyUPSName(NodeList.Item(x).selectSingleNode("Service/Code").Text) & _

    " - $" & NodeList.Item(x).selectSingleNode("TotalCharges/MonetaryValue").Text
    Response.Write("<option>")
    Response.Write sDisplayString
    Response.Write("</option>")
  Next
  Response.Write("</select>")
End Sub

Function BuildUPSXML(sWeight, sDestinationPostalCode)
  sShipperPostalCode = "63126"
 
  sXML = sXML & "<?xml version='1.0'?>"
  sXML = sXML & "    <AccessRequest xml:lang='en-US'>"
  sXML = sXML & "        <AccessLicenseNumber>" & sAccessLicenseNumber & _
                "</AccessLicenseNumber>"

  sXML = sXML & "        <UserId>" & sUserID & "</UserId>"
  sXML = sXML & "        <Password>" & sPassword & "</Password>"
  sXML = sXML & "    </AccessRequest>"
  sXML = sXML & "<?xml version='1.0'?>"
  sXML = sXML & "    <RatingServiceSelectionRequest xml:lang='en-US'>"
  sXML = sXML & "        <Request>"
  sXML = sXML & "            <TransactionReference>"
  sXML = sXML & "                <CustomerContext>Rating and " & _
                "Service</CustomerContext>"

  sXML = sXML & "                <XpciVersion>1.0001</XpciVersion>"
  sXML = sXML & "            </TransactionReference>"
  sXML = sXML & "            <RequestAction>Rate</RequestAction>"
  sXML = sXML & "            <RequestOption>shop</RequestOption>"
  sXML = sXML & "        </Request>"
  sXML = sXML & "        <PickupType>"
  sXML = sXML & "            <Code>01</Code>"
  sXML = sXML & "        </PickupType>"
  sXML = sXML & "        <Shipment>"
  sXML = sXML & "            <Shipper>"
  sXML = sXML & "                <Address>"
  sXML = sXML & "                    <PostalCode>" & sShipperPostalCode & _
                "</PostalCode>"

  sXML = sXML & "                </Address>"
  sXML = sXML & "            </Shipper>"
  sXML = sXML & "            <ShipTo>"
  sXML = sXML & "                <Address>"
  sXML = sXML & "                    <PostalCode>" & sDestinationPostalCode & _
                "</PostalCode>"

  sXML = sXML & "                </Address>"
  sXML = sXML & "            </ShipTo>"
  sXML = sXML & "            <Service>"
  sXML = sXML & "                <Code>11</Code>"
  sXML = sXML & "            </Service>"
  sXML = sXML & "            <Package>"
  sXML = sXML & "                <PackagingType>"
  sXML = sXML & "                    <Code>02</Code>"
  sXML = sXML & "                    <Description>Package</Description>"
  sXML = sXML & "                </PackagingType>"
  sXML = sXML & "                <Description>Rate Shopping</Description>"
  sXML = sXML & "                <PackageWeight>"
  sXML = sXML & "                    <Weight>" & sWeight & "</Weight>"
  sXML = sXML & "                </PackageWeight>"
  sXML = sXML & "            </Package>"
  sXML = sXML & "            <ShipmentServiceOptions/>"
  sXML = sXML & "        </Shipment>"
  sXML = sXML & "</RatingServiceSelectionRequest>"
 
  BuildUPSXML = Replace(sXML, vbTab, "")
End Function

Function GetFriendlyUPSName(vCode)
  Select Case vCode
    Case "01"
      GetFriendlyUPSName = "UPS Next Day Air"
    Case "02"
      GetFriendlyUPSName = "UPS 2nd Day Air"
    Case "03"
      GetFriendlyUPSName = "UPS Ground"
    Case "07"
      GetFriendlyUPSName = "UPS Worldwide Express"
    Case "08"
      GetFriendlyUPSName = "UPS Worldwide Expedited"
    Case "11"
      GetFriendlyUPSName = "UPS Standard"
    Case "12"
      GetFriendlyUPSName = "UPS 3 Day Select"
    Case "13"
      GetFriendlyUPSName = "UPS Next Day Air Saver"
    Case "14"
      GetFriendlyUPSName = "UPS Next Day Air Early A.M."
    Case "54"
      GetFriendlyUPSName = "UPS Worldwide Express Plus"
    Case "59"
      GetFriendlyUPSName = "UPS 2nd Day Air A.M."
    Case "65"
      GetFriendlyUPSName = "UPS Saver"
  End Select
End Function
%>
Send this to:                          

Comments

fred said...

Can you provide same code for a free SOAP services retrieved a cheap shipping rates from CShip.eu ?
Please check WSDL at
href="http://www.cship.eu/services/ShippingRatesWebServiceImpl?wsdl" title="Compare Shipping Rates SOAP web service" rel="external">Shipping Rates SOAP web service

2/28/2007 11:00:03 AM

Garrett said...

What variables in this routine do I have to alter in order to make it purr on my site?

3/23/2007 6:07:31 PM

Nate Rice said...

This will obviously be changed to whatever zipcode you're shipping from:


sShipperPostalCode = "63126"


These will obviously be your personal info for UPS:


sAccessLicenseNumber = "XXXXXXXXXXXXXXXX"
sUserID = "xxxxxx"
sPassword = "xxxxxx"



That is it. Once those values are changed it should be plug and play.

3/24/2007 10:31:22 AM

Jeff Frye said...

Doesn't appear to work for international shipping. No variable for ship to country. Also where do you specify residential or business?

4/18/2007 8:54:46 PM

Nate+Rice said...

Try the link at the top of the page. This code works fine for domestic shipping but you'll have to add an extra XML tag and variable if you'd like to specify countries other than the US.

This is basic code, feel free to expound and contribute if you don't like it.

4/19/2007 5:28:15 AM

TAF said...

When I place this code in my page, it just makes a blank select.

Do I need it in the head and then place the call in the body or something?

11/1/2007 11:23:56 AM

said...

Can anybody please provide XML Request and Response for the ''UML Shipping'' online tools?

Thanks in advance

8/4/2008 11:36:42 AM

said...

this is Greate,
I need somithing for UPS HundredWeight.
can you please help me on this.

8/27/2008 6:24:56 AM

said...

how can someone use "HundredWeight" in XML , when the weight is over 200l ?

4/1/2009 12:03:15 PM

said...

hi nate, thanks for the post and the open source. so far looks pretty good!

im curious (because i''m all new to this), where we get this information below? do we have to contact UPS directly to setup some type of account with them?

sUPSAccessLiscenseNumber = "xxxxxxxxxxxxxxx"
sUPSUserID = "xxxxxx"
sUPSPassword = "xxxxxx"

thanks,

kelly.

5/15/2010 3:46:35 PM

said...

when plugged into my website, called the sub but got no values inside my combobox. Any ideas?

7/2/2010 7:01:23 PM

said...

If a copy past the code as is and of course add in my UPS I get a blank select what am I missing?!

Thanks

4/20/2011 4:59:15 PM

said...

Thanks for the examples Nate! The general code is still good here. However, here are the problems:

1) line 33 should read "Response.Write sDisplayString"
2) "sAccessLicenseNumber" is spelled wrong on line 44

9/9/2012 5:50:27 AM

said...

Cool! That''s a cvleer way of looking at it!

12/14/2012 11:36:53 AM

Name
URL
Email
Email address is not published
Remember Me
Comments

CAPTCHA
Write the characters in the image above