fedex

Description

This Rails plugin will enable you to integrate with Fedex’s Web Services platform for the purpose of obtaining shipping rate quotes, generating shipping labels, and cancelling shipments. Web Services is Fedex’s new web service platform that replaces Web Integration. It is quite robust. The plugin we’re providing here attempts to make using this new system as simple as you’ve come to expect from Rails itself. It does not implement Web Services in its entirety, but it provides the two core services (Rate and Ship) most applicable to e-commerce.

This is a fork of Mighty Interactive’s Fedex plugin that has been updated to be compatible with the latest version (v7 as of 10/22/2009) of the Fedex API.

Using as a gem

(I’ll be revising the Installation section below, but this is how to do it now:)

Insert this in config/environment.rb, just like when using this as a plugin:

config.gem "soap4r", :lib => "soap/soap", :version => ">= 1.5.8"

And also this:

config.gem "fedex"

Get your hands on the v8 WSDL files and toss them in lib/fedex_wsdl/ in your application. You’ll need to use an initializer to tell the gem where to look.

mkdir config/initializers
cat >> config/initializers/fedex_wsdl.rb
Fedex::Base::WSDL_PATHS.merge!({
	:rate => "#{RAILS_ROOT}/lib/fedex_wsdl/RateService_v8.wsdl",
	:ship => "#{RAILS_ROOT}/lib/fedex_wsdl/ShipService_v8.wsdl",
})
^D

That should do it.

Installation

This plugin depends upon NaHi’s excellent SOAP4R library. Just add this line to config/environment.rb:

config.gem "soap4r", :lib => "soap/soap", :version => ">= 1.5.8"

and then run:

$ sudo rake gems:install

and then if you want to:

$ rake gems:unpack

To install the plugin itself, simply navigate to your project directory and run:

script/plugin install git://github.com/mcmire/fedex.git

Due to copyright reasons we cannot distribute the associated WSDL files; you will need to apply for a developer account with Fedex to begin working on your integration. Once you’ve created your account, head to the “Get Started” section, where you can find documentation and the individual WSDLs for all of the available services. For our purposes you need only two: Rate (RateService_v7.wsdl as of 10/22/2009) and Ship (ShipService_v7.wsdl as of 10/22/2009). Download these WSDLs and put them in the vendor/plugins/fedex/lib/wsdl/ directory.

Usage

Using the plugin is straightforward:

Start out by defining constants to hold the authentication parameters. To use Fedex Web Services you will need four pieces of information: Account Number, Authorization Key, Security Code, and Meter Number. You will receive all four when you create your developer account. An ideal place to put these constants is in an initializer under config/initializers.

AUTH_KEY       = 'YOUR_AUTHORIZATION_KEY'
SECURITY_CODE  = 'YOUR_SECURITY_CODE'
ACCOUNT_NUMBER = 'YOUR_ACCOUNT_NUMBER'
METER_NUMBER   = 'YOUR_METER_NUMBER'

Before you can get a rate or create a label, you must first create a Fedex object. Here you pass in the constants you just created, along with any other options that apply (see lib/fedex.rb).

fedex = Fedex::Base.new(
  :auth_key => AUTH_KEY,
  :security_code => SECURITY_CODE,
  :account_number => ACCOUNT_NUMBER,
  :meter_number => METER_NUMBER
)

Note that leaving out one or more required pieces of information for any method will result in an exception being thrown:

> fedex = Fedex::Base.new
Fedex::MissingInformationError: Missing :auth_key, :security_code, :account_number, :meter_number
       from ./lib/fedex.rb:204:in `check_required_options'
       from ./lib/fedex.rb:37:in `initialize'

For the purpose of demonstration we’re using the PDF label type, which is the default. PDFs are nice because they’ll print onto a regular 8.5“x11” sheet of paper exactly the way Fedex needs them. Additional options for printing are available. See Fedex::LabelSpecificationImageTypes (defined in lib/{rate|ship}_constants.rb) for a list, which includes PNG and special formats designed for thermal printers.

Now let’s get a Rate quote. Define your origin, destination, number of packages, total weight, and shipping method.

shipper = {
  :name => "Your Name",
  :phone_number => '5205551212'
}
recipient = {
  :name => "Fedex",
  :phone_number => '9013693600'
}
origin = {
  :street => '80 E. Rio Salado Pkwy. #711', # Off Madison Ave
  :city => 'Tempe',
  :state => 'AZ',
  :zip => '85281',
  :country => 'US'
}
destination = {
  :street => '942 South Shady Grove Road',  # Fedex
  :city => 'Memphis',
  :state => 'TN',
  :zip => '38120',
  :country => 'US',
  :residential => false
}
pkg_count = 1
weight = 10
service_type = Fedex::ServiceTypes::STANDARD_OVERNIGHT

Pass these to your Fedex object:

price = fedex.price(
  :shipper => { :contact => shipper, :address => origin },
  :recipient => { :contact => recipient, :address => destination },
  :count => pkg_count,
  :weight => weight,
  :service_type => service_type
)
price #=> 8644

Note that rate quotes are returned as whole integers in cents (so the charge in this case is $86.44).

Shipping is just as easy:

price, label, tracking_number = fedex.label(
  :shipper => { :contact => shipper, :address => origin },
  :recipient => { :contact => recipient, :address => destination },
  :count => pkg_count,
  :weight => weight,
  :service_type => service_type
)

If everything goes well, price, label, and tracking_number will all be populated accordingly. label is the Base64-decoded label as returned from Fedex. By default the Fedex plugin requests the label to be returned as a PDF file suitable for laser printing. Store this in a :binary column in your database, or write it out to a file.

And that’s it! There are quite a few additional configuration options which you can find by looking in the documentation in the source code itself, but this should be enough to get you started.

Support

I (Elliot) use this plugin at work and right now we are only using the ‘price’ feature of this plugin. However, I realize that other people may be using the other features. If you encounter any bugs while using this, I am happy to fix the plugin for you; however, I rely on you to give me as much information as possible to do so. You can help me by:

  • going to the ‘Issues’ tab in Github and adding an issue

  • creating the patch yourself and sending me a pull request

  • sending me an email (elliot.winkler [at] gmail [dot] com)

Author/Contributors

  • Joseph Jamarillo, josephj [at] offmadisonave [dot] com (original author)

  • Elliot Winkler, elliot.winkler [at] gmail [dot] com (fork for v5 compatibility)

  • Laurence A. Lee, lalee [at] pobox [dot] com (additional fixes for v5 compatibility)

  • Matthew Boeh, matt [at] copiousinc [dot] com (janitorial work)

Copyright © 2007 Joseph Jaramillo

This plugin is made available under the MIT license.