<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,5 +1,6 @@
 .DS_Store
-
+test.xml
+sample.rb
 *.orig
 
 .dotest
\ No newline at end of file</diff>
      <filename>.gitignore</filename>
    </modified>
    <modified>
      <diff>@@ -91,6 +91,26 @@ Gem and tarball forthcoming on rubyforge.
     #     [&quot;USPS GXG Envelopes&quot;, 9400],
     #     [&quot;USPS Global Express Guaranteed Non-Document Rectangular&quot;, 9400],
     #     [&quot;USPS Global Express Guaranteed&quot;, 9400]]
+    
+    # FedEx
+    # As of now, ground and express rates require two separate requests. I may combine them into one method call in the future.
+    # Default is FedEx Ground
+    fdx = FedEx.new(:account_number =&gt; '999999999', :meter_number =&gt; '7777777')
+    
+    # FedEx Ground
+    response = fdx.find_rates(origin, destination, packages, :test =&gt; true)
+    response.rates.sort_by(&amp;:price).collect {|rate| [rate.service_name, rate.price]}
+    # =&gt; [[&quot;FedEx Ground&quot;, 588], [&quot;FedEx Ground Home Delivery&quot;, 793]]
+    
+    # FedEx Express
+    response = fdx.find_rates(origin, destination, packages, :test =&gt; true, :carrier_code =&gt; 'fedex_express')
+    response.rates.sort_by(&amp;:price).collect {|rate| [rate.service_name, rate.price]}
+    # =&gt; [[&quot;FedEx Express Saver&quot;, 1492], 
+    # [&quot;FedEx 2 Day&quot;, 1689], 
+    # [&quot;FedEx Standard Overnight&quot;, 3029], 
+    # [&quot;FedEx Priority Overnight&quot;, 6160], 
+    # [&quot;FedEx First Overnight&quot;, 6698]]
+    
 
 ## TODO
 </diff>
      <filename>README.markdown</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,7 @@
 require 'active_shipping/shipping/carriers/bogus_carrier'
 require 'active_shipping/shipping/carriers/ups'
 require 'active_shipping/shipping/carriers/usps'
+require 'active_shipping/shipping/carriers/fedex'
 
 module ActiveMerchant
   module Shipping</diff>
      <filename>lib/active_shipping/shipping/carriers.rb</filename>
    </modified>
    <modified>
      <diff>@@ -4,13 +4,173 @@ module ActiveMerchant
       cattr_reader :name
       @@name = &quot;FedEx&quot;
       
+      TEST_URL = 'https://gatewaybeta.fedex.com/GatewayDC'
+      LIVE_URL = ''
+      
+      USE_SSL = true
+      
+      CarrierCodes = {
+        &quot;fedex_ground&quot; =&gt; &quot;FDXG&quot;,
+        &quot;fedex_express&quot; =&gt; &quot;FDXE&quot;
+      }
+      
+      ServiceTypes = {
+        &quot;FedEx Priority Overnight&quot; =&gt; &quot;PRIORITYOVERNIGHT&quot;,
+        &quot;FedEx 2 Day&quot; =&gt; &quot;FEDEX2DAY&quot;,
+        &quot;FedEx Standard Overnight&quot; =&gt; &quot;STANDARDOVERNIGHT&quot;,
+        &quot;FedEx First Overnight&quot; =&gt; &quot;FIRSTOVERNIGHT&quot;,
+        &quot;FedEx Express Saver&quot; =&gt; &quot;FEDEXEXPRESSSAVER&quot;,
+        &quot;FedEx 1 Day Freight&quot; =&gt; &quot;FEDEX1DAYFREIGHT&quot;,
+        &quot;FedEx 2 Day Freight&quot; =&gt; &quot;FEDEX2DAYFREIGHT&quot;,
+        &quot;FedEx 3 Day Freight&quot; =&gt; &quot;FEDEX3DAYFREIGHT&quot;,
+        &quot;FedEx International Priority&quot; =&gt; &quot;INTERNATIONALPRIORITY&quot;,
+        &quot;FedEx International Economy&quot; =&gt; &quot;INTERNATIONALECONOMY&quot;,
+        &quot;FedEx International First&quot; =&gt; &quot;INTERNATIONALFIRST&quot;,
+        &quot;FedEx International Priority Freight&quot; =&gt; &quot;INTERNATIONALPRIORITYFREIGHT&quot;,
+        &quot;FedEx International Economy Freight&quot; =&gt; &quot;INTERNATIONALECONOMYFREIGHT&quot;,
+        &quot;FedEx Ground Home Delivery&quot; =&gt; &quot;GROUNDHOMEDELIVERY&quot;,
+        &quot;FedEx Ground&quot; =&gt; &quot;FEDEXGROUND&quot;,
+        &quot;FedEx International Ground&quot; =&gt; &quot;INTERNATIONALGROUND&quot;
+      }
+
+      PackageTypes = {
+        &quot;fedex_envelope&quot; =&gt; &quot;FEDEXENVELOPE&quot;,
+        &quot;fedex_pak&quot; =&gt; &quot;FEDEXPAK&quot;,
+        &quot;fedex_box&quot; =&gt; &quot;FEDEXBOX&quot;,
+        &quot;fedex_tube&quot; =&gt; &quot;FEDEXTUBE&quot;,
+        &quot;fedex_10_kg_box&quot; =&gt; &quot;FEDEX10KGBOX&quot;,
+        &quot;fedex_25_kg_box&quot; =&gt; &quot;FEDEX25KGBOX&quot;,
+        &quot;your_packaging&quot; =&gt; &quot;YOURPACKAGING&quot;
+      }
+
+      DropoffTypes = {
+        'regular_pickup' =&gt; 'REGULARPICKUP',
+        'request_courier' =&gt; 'REQUESTCOURIER',
+        'dropbox' =&gt; 'DROPBOX',
+        'business_service_center' =&gt; 'BUSINESSSERVICECENTER',
+        'station' =&gt; 'STATION'
+      }
+
+      PaymentTypes = {
+        'sender' =&gt; 'SENDER',
+        'recipient' =&gt; 'RECIPIENT',
+        'third_party' =&gt; 'THIRDPARTY',
+        'collect' =&gt; 'COLLECT'
+      }
+
       
       def find_rates(origin, destination, packages, options = {})
-        origin = Location.from(origin)
-        destination = Location.from(destination)
+        options = @options.update(options)
         packages = Array(packages)
+        rate_request = build_rate_request(origin, destination, packages, options)
+        response = commit(save_request(rate_request), (options[:test] || false))
+        parse_rate_response(origin, destination, packages, response, options)
+      end
+      
+      
+      protected
+      def build_rate_request(origin, destination, packages, options={})
+        xml_request = XmlNode.new('FDXRateAvailableServicesRequest', 'xmlns:api' =&gt; 'http://www.fedex.com/fsmapi', 'xmlns:xsi' =&gt; 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:noNamespaceSchemaLocation' =&gt; 'FDXRateAvailableServicesRequest.xsd') do |root_node|
+          root_node &lt;&lt; build_request_header(CarrierCodes[options[:carrier_code] || &quot;fedex_ground&quot;])
+          # root_node &lt;&lt; build_rate_options(packages)
+          
+          root_node &lt;&lt; XmlNode.new('ShipDate', @options[:ship_date] || Time.now.strftime(&quot;%Y-%m-%d&quot;))
+          root_node &lt;&lt; XmlNode.new('DropoffType', @options[:dropoff_type] || DropoffTypes['regular_pickup'])
+          root_node &lt;&lt; XmlNode.new('Packaging', @options[:packaging] || PackageTypes['your_packaging'])
+          root_node &lt;&lt; XmlNode.new('WeightUnits', @options[:weight_units] || 'LBS')
+          root_node &lt;&lt; XmlNode.new('Weight', '10.0')
+          
+          root_node &lt;&lt; XmlNode.new('ListRate', 'false')
+          
+          
+          
+          root_node &lt;&lt; build_location_node('OriginAddress', origin)
+          root_node &lt;&lt; build_location_node('DestinationAddress', destination)
+          root_node &lt;&lt; XmlNode.new('Payment') do |payment_node|
+            payment_node &lt;&lt; XmlNode.new('PayorType', PaymentTypes[options[:payment_type] || 'sender'])
+          end
+          root_node &lt;&lt; XmlNode.new('PackageCount', packages.count.to_s)
+          
+        end
+        puts xml_request.to_xml
+        xml_request.to_xml
       end
       
+      def build_request_header(carrier_code)
+        xml_request = XmlNode.new('RequestHeader') do |access_request|
+          access_request &lt;&lt; XmlNode.new('AccountNumber', @options[:account_number])
+          access_request &lt;&lt; XmlNode.new('MeterNumber', @options[:meter_number])
+          access_request &lt;&lt; XmlNode.new('CarrierCode', carrier_code)
+        end
+        xml_request
+      end
+      
+      def build_location_node(name, location)
+        location_node = XmlNode.new(name) do |xml_node|
+          xml_node &lt;&lt; XmlNode.new('StateOrProvinceCode', state_or_province(location))
+          xml_node &lt;&lt; XmlNode.new('PostalCode', zip_or_postal_code(location))
+          xml_node &lt;&lt; XmlNode.new(&quot;CountryCode&quot;, location.country_code(:alpha2)) unless location.country_code(:alpha2).blank?
+        end
+      end
+      
+      def parse_rate_response(origin, destination, packages, response, options)
+        rates = []
+        
+        xml_hash = Hash.from_xml(response)['FDXRateAvailableServicesReply']
+        success = response_hash_success?(xml_hash)
+        message = response_hash_message(xml_hash)
+        
+        if success
+          rate_estimates = []
+          
+          xml_hash['Entry'].each do |rated_shipment|
+            rate_estimates &lt;&lt; RateEstimate.new(origin, destination, @@name,
+                                ServiceTypes.invert[rated_shipment['Service']],
+                                :total_price =&gt; rated_shipment['EstimatedCharges']['DiscountedCharges']['NetCharge'].to_f,
+                                :currency =&gt; rated_shipment['EstimatedCharges']['CurrencyCode'],
+                                :packages =&gt; packages)
+          end
+        end
+        RateResponse.new(success, message, xml_hash, :rates =&gt; rate_estimates, :xml =&gt; response, :request =&gt; last_request)
+      end
+      
+      def response_hash_success?(xml_hash)
+        ! xml_hash['Error']
+      end
+      
+      def response_hash_message(xml_hash)
+        response_hash_success?(xml_hash) ? '' : &quot;FedEx Error Code: #{xml_hash['Error']['Code']}: #{xml_hash['Error']['Message']}&quot;
+      end
+      
+      def state_or_province(location)
+        case
+        when location.country == 'US' || location.country == 'USA' then
+          location.state || location.province
+        else
+          location.province || location.state
+        end
+      end
+      
+      def zip_or_postal_code(location)
+        case
+        when location.country == 'US' || location.country == 'USA' then
+          location.zip || location.postal_code
+        else
+          location.postal_code || location.zip
+        end
+      end
+      
+      def commit(request, test = false)
+        uri = URI.parse(test ? TEST_URL : LIVE_URL)
+        http = Net::HTTP.new uri.host, uri.port
+        if USE_SSL
+          http.use_ssl = true
+          http.verify_mode = OpenSSL::SSL::VERIFY_NONE
+        end
+        response = http.post(uri.path, request.gsub(&quot;\n&quot;,''))
+        response.body
+      end
+    
     end
   end
 end</diff>
      <filename>lib/active_shipping/shipping/carriers/fedex.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>444b828bbef622122164a858817193e70a41d844</id>
    </parent>
  </parents>
  <author>
    <name>Jimmy Baker</name>
    <email>jimmybaker@jimmy.tol.lan</email>
  </author>
  <url>http://github.com/Shopify/active_shipping/commit/64a1348e069f975994c6d0ce5d379cc33537ac04</url>
  <id>64a1348e069f975994c6d0ce5d379cc33537ac04</id>
  <committed-date>2009-02-05T10:52:10-08:00</committed-date>
  <authored-date>2008-12-03T15:07:55-08:00</authored-date>
  <message>FedEx carrier class now returns rates for both Ground and Express services.</message>
  <tree>e15741509d2264942dcc1dd153df240035ae7382</tree>
  <committer>
    <name>James MacAulay</name>
    <email>james@jadedpixel.com</email>
  </committer>
</commit>
