Ruby Cookbook
Authors: Carlson L. Richardson L.
Published year:
Pages: 278-279/399
Buy this book on amazon.com >>

Recipe 16.8. Charging a Credit Card

Problem

You want to charge a credit card from within your Ruby application.

Solution

To charge credit cards online, you need an account with a credit card merchant. Although there are many to choose from, Authorize.Net is one of the best and most widely used. The payment library encapsulates the logic of making a credit card payments with Authorize.Net, and soon it will support other gateways as well. It's available as the payment gem.

require 'rubygems'
	require 'payment/authorize_net'
	
	transaction = Payment::AuthorizeNet.new(
	  :login           => 'username',
	  :transaction_key => 'my_key',
	  :amount          => '49.95',
	  :card_number     => '4012888818888',
	  :expiration      => '0310',
	  :first_name      => 'John',
	  :last_name       => 'Doe'
	)

The submit method sends a payment request. If there's a problem with your payment (probably due to an invalid credit card), the submit method will raise a Payment::PaymentError:

begin
	  transaction.submit
	  puts "Card processed successfully: #{transaction.authorization}"
	rescue Payment::PaymentError
	  puts "Card was rejected: #{transaction.error_message}"
	end
	# Card was rejected: The merchant login ID or password is invalid
	# or the account is inactive.

Discussion

Some of the information sent during initialization of the Payment::AuthorizeNet class represent your account with Authorize.Net, and will never change (at least, not for the lifetime of the account). You can store this information in a YAML file called .payment.yml in your home directory, and have the payment library load it automatically. A .payment.yml file might look like this:

login: username
	transaction_key: my_key

That way you don't have to hardcode login and transaction_key within your Ruby code.

If you're using the payment library from within a Rails application, you might want to put your YAML hash in the config directory with other configuration files, instead of in your home directory. You can override the location for the defaults file by specifying the :prefs key while initializing the object:

payment =  
Payment::AuthorizeNet
	    .new(:prefs => "#/config/payment.yml")
	payment.amount = 20
	payment.card_number = 'bogus'
	payment.submit rescue "That didn't work"

Notice that after the Payment::AuthorizeNet object has been initialized , you can change its configuration with accessor methods .

Like most online merchants, Authorize.Net uses its own XML-formatted responses to do transactions over HTTPS. Some merchants , such as Payflow Pro, use proprietary interfaces to their backend that require a bridge with their Java or C libraries. If you're using Ruby, this approach can be cumbersome and difficult. It's worth investing some time into researching how flexible the backend is before you decide on a merchant platform for your Ruby application.

See Also

  • Recipe 2.17, "Checking a Credit Card Checksum"

  • The online RDoc for the payment library (http://payment. rubyforge .org/)

  • http://authorize.net/



Recipe 16.9. Finding the Cost to Ship Packages via UPS or FedEx

Problem

You want to calculate the cost to ship any item with FedEx or UPS. This is useful if you're running an online store.

Solution

FedEx and UPS provide web services that can query information on pricing as well as retrieve shipping labels. The logic for using these services has been encapsulated within the shipping gem:

require 'rubygems'
	require 'shipping'

	ship = Shipping::Base.new(
	  :fedex_url => 'https://gatewaybeta.fedex.com/GatewayDC',
	  :fedex_account => '123456789',
	  :fedex_meter => '387878',

	  :ups_account => '7B4F74E3075AEEFF',
	  :ups_user => 'username',
	  :ups_password => 'password',

	  :sender_zip => 10001                   # It's shipped from Manhattan.
	)

	ship.weight = 2                             # It weighs two pounds.
	ship.city = 'Portland'
	ship.state = 'OR'
	ship.zip = 97202

	ship.ups.price                              # => 8.77
	ship.fedex.price                            # => 5.49
	ship.ups.valid_address?                     # => true

If you have a UPS account or a FedEx account, but not both, you can omit the account information you don't have, and instantiate a Shipping::UPS or a Shipping::FedEx object.

Discussion

You can either specify your account information during the initialization of the object (as above) or in a YAML hash. It's similar to the payment library described in Recipe 16.8. If you choose to use the YAML hash, you can specify the account information in a file called .shipping.yml within the home directory of the user running the Ruby program:

fedex_url: https://gatewaybeta.fedex.com/GatewayDC
	fedex_account: 1234556
	fedex_meter: 387878

	ups_account: 7B4F74E3075AEEFF
	ups_user: username
	ups_password: password

But your directory is not a good place to keep a file being used by a Rails application. Here's how to move the .shipping file into a Rails application:

ship = Shipping:: 
FedEx.new(:prefs => "#/config/shipping.yml")
	ship.sender_zip = 10001
	ship.zip = 97202
	ship.state = 'OR'
	ship.weight = 2

	ship.price > ship.discount_price                    # => true

Notice the use of ship.discount_price to find the discounted price; if you have an account with FedEx or UPS, you might be eligible for discounts .

See Also

  • http://shipping. rubyforge .org/

  • Recipe 16.8, "Charging a Credit Card"


Ruby Cookbook
Authors: Carlson L. Richardson L.
Published year:
Pages: 278-279/399
Buy this book on amazon.com >>

Similar books on Amazon