require 'nokogiri' module ActiveMerchant #:nodoc: module Billing #:nodoc: class GlobalTransportGateway < Gateway self.test_url = 'https://certapia.globalpay.com/GlobalPay/transact.asmx/ProcessCreditCard' self.live_url = 'https://api.globalpay.com/GlobalPay/transact.asmx/ProcessCreditCard' self.supported_countries = %w(CA PR US) self.default_currency = 'USD' self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb] self.homepage_url = 'https://www.globalpaymentsinc.com' self.display_name = 'Global Transport' # Public: Create a new Global Transport gateway. # # options - A hash of options: # :global_user_name - Your Global user name # :global_password - Your Global password # :term_type - 3 character field assigned by Global Transport after # - your application is certified. def initialize(options={}) requires!(options, :global_user_name, :global_password, :term_type) super end def purchase(money, payment_method, options={}) post = {} add_invoice(post, money, options) add_payment_method(post, payment_method) add_address(post, options) commit('Sale', post, options) end def authorize(money, payment_method, options={}) post = {} add_invoice(post, money, options) add_payment_method(post, payment_method) add_address(post, options) commit('Auth', post, options) end def capture(money, authorization, options={}) post = {} add_invoice(post, money, options) add_auth(post, authorization) commit('Force', post, options) end def refund(money, authorization, options={}) post = {} add_invoice(post, money, options) add_auth(post, authorization) commit('Return', post, options) end def void(authorization, options={}) post = {} add_auth(post, authorization) commit('Void', post, options) end def verify(payment_method, options={}) post = {} add_payment_method(post, payment_method) add_address(post, options) commit('CardVerify', post, options) end def supports_scrubbing? true end def scrub(transcript) transcript. gsub(%r((&?CardNum=)[^&]*)i, '\1[FILTERED]'). gsub(%r((&?CVNum=)[^&]*)i, '\1[FILTERED]'). gsub(%r((&?GlobalPassword=)[^&]*)i, '\1[FILTERED]') end private def add_address(post, options) if address = (options[:billing_address] || options[:address]) post[:Street] = address[:address1] post[:Zip] = address[:zip] end end def add_auth(post, authorization) post[:PNRef] = authorization end def add_invoice(post, money, options) currency = (options[:currency] || currency(money)) post[:Amount] = localized_amount(money, currency) post[:InvNum] = truncate(options[:order_id], 16) end def add_payment_method(post, payment_method) post[:CardNum] = payment_method.number post[:ExpDate] = expdate(payment_method) post[:NameOnCard] = payment_method.name post[:CVNum] = payment_method.verification_value end def parse(body) response = {} Nokogiri::XML(body).root.xpath('*').each do |node| response[node.name.downcase.to_sym] = node.text end ext_data = Nokogiri::HTML.parse(response[:extdata]) response[:approved_amount] = ext_data.xpath("//approvedamount").text response[:balance_due] = ext_data.xpath("//balancedue").text response end def commit(action, parameters, options) raw = parse(ssl_post(url, post_data(action, parameters, options))) Response.new( success_from(raw), message_from(raw), raw, authorization: authorization_from(raw), test: test?, avs_result: avs_from(raw), cvv_result: cvv_from(raw) ) end def post_data(action, params, options) post = default_params post[:GlobalUserName] = @options[:global_user_name] post[:GlobalPassword] = @options[:global_password] post[:TransType] = action post[:ExtData] = "#{@options[:term_type]}" post.merge(params).map { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&") end def url (test? ? test_url : live_url) end def success_from(response) response[:result] == "0" || response[:result] == "200" end def message_from(response) response[:respmsg] end def authorization_from(response) response[:pnref] end def avs_from(response) { code: response[:getavsresult] } end def cvv_from(response) response[:getcvresult] end def default_params { CardNum: '', ExpDate: '', NameOnCard: '', Amount: '', PNRef: '', Zip: '', Street: '', CVNum: '', MagData: '', InvNum: '', ExtData: '' } end end end end