module ActiveMerchant #:nodoc: module Billing #:nodoc: class FederatedCanadaGateway < Gateway # Same URL for both test and live, testing is done by using the test username (demo) and password (password). URL = 'https://secure.federatedgateway.com/api/transact.php' APPROVED, DECLINED, ERROR = 1, 2, 3 # The countries the gateway supports merchants from as 2 digit ISO country codes self.supported_countries = ['CA'] self.default_currency = 'CAD' # The card types supported by the payment gateway self.supported_cardtypes = [:visa, :master, :american_express, :discover] # The homepage URL of the gateway self.homepage_url = 'http://www.federatedcanada.com/' # The name of the gateway self.display_name = 'Federated Canada' def initialize(options = {}) requires!(options, :login, :password) @options = options super end def purchase(money, creditcard, options = {}) post = {} add_invoice(post, options) add_creditcard(post, creditcard) add_address(post, options) add_customer_data(post, options) commit('sale', money, post) end def authorize(money, creditcard, options = {}) post = {} add_invoice(post, options) add_creditcard(post, creditcard) add_address(post, options) add_customer_data(post, options) commit('auth', money, post) end def capture(money, authorization, options = {}) options[:transactionid] = authorization commit('capture', money, options) end def credit(money, identification, options = {}) # also referred to as refund post = { :transactionid => identification} commit('refund', money, post) end def void(authorization, options = {}) options[:transactionid] = authorization commit('void', nil, options) end def refund(money, authorization, options = {}) options[:transactionid] = authorization commit('refund', money, options) end private def add_customer_data(post, options) post[:firstname] = options[:first_name] post[:lastname] = options[:last_name] post[:email] = options[:email] end def add_address(post, options) if address = (options[:billing_address] || options[:address]) post[:company] = address[:company] post[:address1] = address[:address1] post[:address2] = address[:address2] post[:city] = address[:city] post[:state] = address[:state] post[:zip] = address[:zip] post[:country] = address[:country] post[:phone] = address[:phone] end if address = options[:shipping_address] post[:shipping_firstname] = address[:first_name] post[:shipping_lastname] = address[:last_name] post[:shipping_company] = address[:company] post[:shipping_address1] = address[:address1] post[:shipping_address2] = address[:address2] post[:shipping_city] = address[:city] post[:shipping_state] = address[:state] post[:shipping_zip] = address[:zip] post[:shipping_country] = address[:country] post[:shipping_email] = address[:email] end end def add_invoice(post, options) post[:orderid] = options[:order_id] post[:orderdescription] = options[:description] end def add_creditcard(post, creditcard) post[:ccnumber] = creditcard.number post[:ccexp] = expdate(creditcard) post[:cvv] = creditcard.verification_value end def expdate(creditcard) year = sprintf("%.4i", creditcard.year) month = sprintf("%.2i", creditcard.month) "#{month}#{year[-2..-1]}" end def parse(body) body.split('&').inject({}) do |memo, x| k, v = x.split('=') memo[k] = v memo end end def commit(action, money, parameters) parameters[:amount] = amount(money) data = ssl_post(URL, post_data(action, parameters)) response = parse(data) message = message_from(response) test_mode = test? Response.new(success?(response), message, response, :test => test?, :authorization => response['transactionid'], :avs_result => {:code => response['avsresponse']}, :cvv_result => response['cvvresponse'] ) end def success?(response) response['response'] == '1' end def test? (@options[:login].eql?('demo')) && (@options[:password].eql?('password')) end def message_from(response) case response['response'].to_i when APPROVED "Transaction Approved" when DECLINED "Transaction Declined" else "Error in transaction data or system error" end end def post_data(action, parameters = {}) parameters[:type] = action parameters[:username] = @options[:login] parameters[:password] = @options[:password] parameters.map{|k, v| "#{k}=#{CGI.escape(v.to_s)}"}.join('&') end end end end