Accessing FedEx Web Services From Ruby/Rails

I recently played around with adding FedEx shipping services to the active_shipping plugin and found a bit of confusion online in regards to how to hit FedEx depending upon the style of service being exposed. Somewhat confusingly, FedEx has non-SOAP services as well as SOAP services that you can hit restfully in an HTTPS Post. For the SOAP service, FedEx has very specific requirements about how to formulate the payload and HTTP headers that took a bit of tinkering to get working. Non-SOAP FedEx support was recently added to active_shipping prior to the completion of my work, but I figured I would post if for those who want to use what I think are newer SOAP services.

Without much further ado, here are the basics for creating a tracking request:

TEST_DOMAIN = 'gatewaybeta.fedex.com'

def find_tracking_info(tracking_number, options={})        options = @options.update(options)        tracking_request = build_tracking_request(tracking_number, options)        response = commit(:track, save_request(tracking_request),                          (options[:test] || false))        parse_tracking_response(response, options)  end

protected   def build_access_request        xml_request = XmlNode.new('ns:WebAuthenticationDetail') do |access|          access << XmlNode.new('ns:UserCredential') do |user|             user << XmlNode.new('ns:Key', @options[:key])             user << XmlNode.new('ns:Password', @options[:password])          end        end        xml_request      end

      def build_client_detail        xml_request = XmlNode.new('ns:ClientDetail') do |client_detail|          client_detail << XmlNode.new('ns:AccountNumber', @options[:account])          client_detail << XmlNode.new('ns:MeterNumber', @options[:meter])        end        xml_request      end

     def build_tracking_request(tracking_number, options={})        xml_request = XmlNode.new('ns:TrackRequest',                         :'xmlns:ns'=>"http://fedex.com/ws/track/v2",                         :'xmlns:xsi'=>"http://www.w3.org/2001/XMLSchema-instance",                         :'xsi:schemaLocation'=>"http://fedex.com/ws/track/v2") do |root_node|          root_node << build_access_request          root_node << build_client_detail          root_node << XmlNode.new('ns:TransactionDetail') do |detail|            detail << XmlNode.new('ns:CustomerTransactionId', 'Ground Track')          end          root_node <<  XmlNode.new('ns:Version') do |version|            version << XmlNode.new('ns:ServiceId', 'trck')            version << XmlNode.new('ns:Major', '2')            version << XmlNode.new('ns:Intermediate', '0')            version << XmlNode.new('ns:Minor', '0')          end           root_node <<  XmlNode.new('ns:PackageIdentifier') do |package|              package << XmlNode.new('ns:Value', tracking_number.to_s)              package << XmlNode.new('ns:Type', "TRACKING_NUMBER_OR_DOORTAG")          end        end        xml_request.to_xml      end

     def commit(action, request, test = false)        http = Net::HTTP.new((test ? TEST_DOMAIN : LIVE_DOMAIN),                                (USE_SSL[action] ? 443 : 80 ))        http.use_ssl = USE_SSL[action]

        headers = {          'Referer' => 'me',          'Port' => '443',          'Accept' => "image/gif, image/jpeg, image/pjpeg, text/plain, text/html, */*",          'Content-Type' => 'image/gif'        }

        http.verify_mode = OpenSSL::SSL::VERIFY_NONE if USE_SSL[action]        response = http.start do |http|          http.request_post ('/xml', request, headers)        end        response.body      end

 

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Leave a Reply

ray ban wayfarer sizes ray ban repair parts
aldo coupon
Buy shoes online india
replica handbags