UPS Shipping Tools XML Integration


#1

Hello! I’m relatively new to Rails and in over my head…

I’d like to integrate the XML UPS Shipping tools into an online cart
so that a user can select a shipping method based on availability and
price. I understand what UPS wants and what I should get back from
them…but I’m failing at the most basic level. How can I do the
following:

  1. send UPS an XML Post request,
  2. parse the XML that they send back, and
  3. use their response in my next view template?

It seems like this should be so basic, but I’ve searched with no
luck. Any help is greatly appreciated.

-Kyle


#2

Kyle,
This may be something that is along the lines of what you are looking
for. It’s a rubygem that handles both UPS and FedEx shipping rates.

http://shipping.rubyforge.org/

-Will


#3

Well, I finally got it. I’m not sure that this is the best way, but
here’s what I did:


require ‘net/http’
require ‘net/https’

def get_ups_rates
url = “wwwcie.ups.com” # for testing
path = “/ups.app/xml/Rate”
headers = {“Content-Type” => “text/xml”}

h = Net::HTTP.new(url, 443)
h.use_ssl = true

xmlrequest = "<?xml version='1.0' ?>
<AccessRequest xml:lang='en-US'>
    <AccessLicenseNumber>xxxxxxxx</AccessLicenseNumber>
    <UserId>xxxxxxxx</UserId>
    <Password>xxxxxxxxx</Password>
</AccessRequest>
<?xml version='1.0' ?>
<RatingServiceSelectionRequest>
    <Request>
         <RequestAction>rate</RequestAction>
         <RequestOption>Shop</RequestOption>
    </Request>
    <PickupType>
         <Code>01</Code>
    </PickupType>
    <Shipment>
         <Shipper>
              <Name>Mass Street Music</Name>
              <PhoneNumber>7858433535</PhoneNumber>
              <FaxNumber>7858434999</FaxNumber>
              <ShipperNumber>xxxxxx</ShipperNumber>
              <Address>
                  <AddressLine1>1347 Massachusetts Street</

AddressLine1>
Lawrence
KS
66044
US




#{@ship_street_1 ||
@bill_street_1}
#{@ship_street_2 ||
@bill_street_2}
#{@ship_city || @bill_city}
#{@ship_state ||
@bill_state}
#{@ship_zip || @bill_zip}</
PostalCode>
US
Yes</
ResidentialAddressIndicator>




LBS

#{@cart.total_weight}



xxxxxx</
AccountNumber>




02



LBS

#{@cart.total_weight}



"

@resp, @data = h.post(path, xmlrequest, headers)

doc = REXML::Document.new(@data)
  REXML::XPath.each(doc, "/RatingServiceSelectionResponse/

RatedShipment"){ |service|
@code = service.elements[“Service”].elements[“Code”]
if @code.text == “03”
@upsg =
@code.parent.parent.elements[“TotalCharges”].elements[“MonetaryValue”].text
end
if @code.text == “12”
@ups3 =
@code.parent.parent.elements[“TotalCharges”].elements[“MonetaryValue”].text
end
if @code.text == “02”
@ups2 =
@code.parent.parent.elements[“TotalCharges”].elements[“MonetaryValue”].text
end
if @code.text == “01”
@ups1 =
@code.parent.parent.elements[“TotalCharges”].elements[“MonetaryValue”].text
end
}

session[:upsg] = @upsg if @upsg
session[:ups3] = @ups3 if @ups3
session[:ups2] = @ups2 if @ups2
session[:ups1] = @ups1 if @ups1

end


I use this to find the rates for UPS Ground, 3-Day, 2-Day, and Next-
Day. The view (template) then takes these rates and plops them into a
selection list. It’s not exactly pretty, but it seems to work.

I hope that somebody might find this useful! I know that I could have
used it when I was trying things out…

-Kyle


#4

Thanks for the link. I had looked at the shipping gem, but it appears
that it hasn’t been maintained since 2005. I’m also not quite savvy
enough to implement a gem like this by looking only at the source.
Hopefully the solution I came up with will continue to work. I
haven’t looked at the FedEx tools yet, but UPS (technically speaking)
won’t allow a programmer to use their API and display a competitor’s
rates side by side.

-Kyle