Permalink
Browse files

Ruby wrapper for the Stamps.com Web Services API

  • Loading branch information...
0 parents commit 479eadb2a82da494ac61d61f5f15e3986431167f @mattsears committed Apr 19, 2011
@@ -0,0 +1,5 @@
+coverage/*
+pkg/*
+*.gem
+.bundle
+runner.rb
1 .rvmrc
@@ -0,0 +1 @@
+rvm 1.9.2@stamps --create
@@ -0,0 +1,4 @@
+source "http://rubygems.org"
+
+# Specify your gem's dependencies in stamps.gemspec
+gemspec
@@ -0,0 +1,47 @@
+PATH
+ remote: .
+ specs:
+ stamps (0.0.1)
+ hashie (~> 1.0.0)
+ httpi (= 0.7.9)
+ json (~> 1.5.1)
+ multi_json (~> 0.0.5)
+ savon (>= 0.8.6)
+
+GEM
+ remote: http://rubygems.org/
+ specs:
+ addressable (2.2.4)
+ builder (2.1.2)
+ crack (0.1.8)
+ gyoku (0.4.2)
+ builder (>= 2.1.2)
+ hashie (1.0.0)
+ httpi (0.7.9)
+ rack
+ json (1.5.1)
+ mocha (0.9.12)
+ multi_json (0.0.5)
+ rack (1.2.2)
+ savon (0.8.6)
+ builder (>= 2.1.2)
+ crack (~> 0.1.8)
+ gyoku (>= 0.3.0)
+ httpi (>= 0.7.8)
+ shoulda (2.11.3)
+ simplecov (0.4.1)
+ simplecov-html (~> 0.4.3)
+ simplecov-html (0.4.3)
+ webmock (1.6.2)
+ addressable (>= 2.2.2)
+ crack (>= 0.1.7)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ mocha (~> 0.9.11)
+ shoulda (~> 2.11.3)
+ simplecov (~> 0.4.0)
+ stamps!
+ webmock (~> 1.6.2)
122 README.md
@@ -0,0 +1,122 @@
+Stamps
+==========
+
+** Work in Progress **
+
+Stamps is Stamps.com backed library for creating shipping labels,
+calculate the shipping cost of packages, standardize domestic
+addresses via USPS CASS certified Address Matching Software, and track
+shipments.
+
+Pre-requisites
+----------
+Register for the Stamps.com [Developer
+Program](http://developer.stamps.com/developer) to receive you free
+test account.
+
+Sample Workflow
+----------
+
+1. Standardize Shipping Address - Ship-to addresses must be
+standardized based on USPS rules for proper address conventions before
+a shipping label can be issued.
+
+2. Get Rates - allow users to view and select the best shipping
+service for their needs.
+
+3. Generate the Shipping Label - after choosing a shipping
+service and ship-to address is standardized, the `Stamps.create` method
+will generate the indicium required to ship the item. If
+the customer changes their mind, they may want to select an option
+that initiates a `Stamps.cancel`. `Stamps.cancel` refunds postage and
+voids the shipping label.
+
+4. Print the Shipping Label - Call the returned URL to obtain the shipping label image.
+A URL is returned by the `Stamps.create` call in the :url item. The
+integration will connect to this URL to retrieve their shipping label
+and customs forms for printing.
+
+Getting Started
+----------
+Once you have a test account with integration id, we can simple pass
+them to the configure block:
+
+ # Authenticate you stamps.com credentials
+ Stamps.configure do |config|
+ config.integration_id = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXX'
+ config.username = 'STAMPS USERNAME'
+ config.password = 'STAMPS PASSWORD'
+ end
+
+Now we can now be able to retrieve information about our account:
+
+ Stamps.account
+
+Standardized Shipping Address
+----------
+Standardizes shipping address that complies with the USPS address
+formatting guidelines
+
+ standardized_address = Stamps.clean_address(
+ :address => {
+ :full_name => 'The White House',
+ :address1 => '1600 Pennsylvania Avenue, NW',
+ :city => 'Washington',
+ :state => 'DC',
+ :zip_code => '20500'
+ })
+
+Get Rates
+----------
+To get a list of rates for all available USPS services based on the
+ZIP Code or the foreign country being shipped to for a given package
+weight and size.
+
+ rates = Stamps.get_rates(
+ :from_zip_code => '45440',
+ :to_zip_code => '20500',
+ :weight_lb => '0.5',
+ :ship_date => '2011-04-07'
+ )
+
+Creating a shipping label
+----------
+To generate the postage based on the shipping information provided in the request.
+The `create!` method will return a URL that references either an image of the
+domestic shipping label or a multi-page PDF document for international
+labels with customs forms.
+
+ stamp = Stamps.create!(
+ :tracking_number => true,
+ :rate => rates.first,
+ :to => standardized_address,
+ :from => {
+ :full_name => 'Littlelines',
+ :address1 => '50 Chestnut Street',
+ :address2 => 'Suite 234',
+ :city => 'Beavervcreek',
+ :state => 'OH',
+ :zip_code => '45440'
+ },
+ :memo => 'Thanks for shopping with us!'
+ )
+
+Now we can view or print the postage label:
+
+ stamp.url
+
+Installation Stamps
+----------
+First install the gem
+
+ gem install stamps
+
+
+
+
+
+
+
+
+
+
@@ -0,0 +1,13 @@
+require 'bundler'
+Bundler::GemHelper.install_tasks
+
+require 'rake/testtask'
+task :default => :test
+
+desc 'Run tests (default)'
+Rake::TestTask.new(:test) do |t|
+ t.test_files = FileList['test/**/*_test.rb']
+ t.ruby_opts = ['-Itest']
+ t.libs << "lib" << "test"
+ t.ruby_opts << '-rubygems' if defined? Gem
+end
@@ -0,0 +1,32 @@
+require 'stamps/errors'
+require 'stamps/trash'
+require 'stamps/configuration'
+require 'stamps/api'
+require 'stamps/mapping'
+require 'stamps/types'
+require 'stamps/client'
+
+module Stamps
+ extend Configuration
+
+ API_VERSION = '1_0' # Stamps API version
+
+ # Alias for Stamps::Client.new
+ #
+ # @return [Stamps::Client]
+ def self.client(options={})
+ Stamps::Client.new(options)
+ end
+
+ # Delegate to Stamps::Client
+ def self.method_missing(method, *args, &block)
+ return super unless client.respond_to?(method)
+ client.send(method, *args, &block)
+ end
+
+ # Delegate to Stamps::Client
+ def self.respond_to?(method)
+ return client.respond_to?(method) || super
+ end
+
+end
@@ -0,0 +1,20 @@
+require File.expand_path('../request', __FILE__)
+require File.expand_path('../connection', __FILE__)
+
+module Stamps
+ # @private
+ class API
+ # @private
+ attr_accessor *Configuration::VALID_OPTIONS_KEYS
+
+ # Creates a new API
+ def initialize(options={})
+ options = Stamps.options.merge(options)
+ Configuration::VALID_OPTIONS_KEYS.each do |key|
+ send("#{key}=", options[key])
+ end
+ end
+ include Connection
+ include Request
+ end
+end
@@ -0,0 +1,12 @@
+module Stamps
+ # Wrapper for the Stamps Web Services API
+ #
+ class Client < API
+ Dir[File.expand_path('../client/*.rb', __FILE__)].each{|f| require f}
+ include Stamps::Mapping
+ include Stamps::Client::Account
+ include Stamps::Client::Address
+ include Stamps::Client::Rate
+ include Stamps::Client::Stamp
+ end
+end
@@ -0,0 +1,36 @@
+module Stamps
+ class Client
+ module Account
+
+ # Returns information about the stamps account
+ #
+ # @param params [Hash] authenticator, address, rates.
+ # @return [Hash]
+ #
+ def account(params = {})
+ params[:authenticator] = authenticator_token
+ response = request('GetAccountInfo', Stamps::Mapping::Account.new(params) )
+ response[:get_account_info_response][:account_info] if response
+ end
+
+ # Add funds to postage account
+ #
+ def purchase_postage(params = {})
+ params[:authenticator] = authenticator_token
+ response = request('PurchasePostage', Stamps::Mapping::PurchasePostage.new(params))
+ response[:purchase_postage_response] if response
+ end
+
+ # Request carrier pickup
+ # TODO: Should this go somewhere else?
+ #
+ def carrier_pickup(params = {})
+ params[:authenticator] = authenticator_token
+ response = request('CarrierPickup', Stamps::Mapping::CarrierPickup.new(params))
+ response
+ end
+
+ end
+ end
+end
+
@@ -0,0 +1,19 @@
+module Stamps
+ class Client
+ module Address
+
+ # Authorizes the User and returns authenticator token
+ #
+ def clean_address(params = {})
+ params[:authenticator] = authenticator_token
+ response = request('CleanseAddress ', Stamps::Mapping::CleanseAddress.new(params))
+ if response.errors.empty?
+ return response[:cleanse_address_response]
+ end
+ response
+ end
+
+ end
+ end
+end
+
@@ -0,0 +1,26 @@
+module Stamps
+ class Client
+ module Rate
+
+ def get_rates(params = {})
+ rates = Stamps::Mapping::Rates.new({
+ :authenticator => authenticator_token,
+ :rate => Stamps::Mapping::Rate.new(params)
+ })
+ response = request('GetRates', rates)
+ if response.valid?
+ return [response[:get_rates_response][:rates][:rate]].flatten
+ end
+ response
+ end
+
+ def get_rate(params = {})
+ rates = get_rates(params)
+ return rates.first if rates.is_a?(Array)
+ rates
+ end
+
+ end
+ end
+end
+
Oops, something went wrong.

0 comments on commit 479eadb

Please sign in to comment.