require 'nokogiri' module ActiveMerchant #:nodoc: module Billing #:nodoc: class NcrSecurePayGateway < Gateway self.test_url = 'https://testbox.monetra.com:8665/' self.live_url = 'https://portal.ncrsecurepay.com:8444/' self.supported_countries = ['US'] self.default_currency = 'USD' self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://www.ncrretailonline.com' self.display_name = 'NCR Secure Pay' def initialize(options={}) requires!(options, :username, :password) super end def purchase(money, payment, options={}) post = {} add_invoice(post, money, options) add_payment(post, payment) add_address(post, payment, options) commit('sale', post) end def authorize(money, payment, options={}) post = {} add_invoice(post, money, options) add_payment(post, payment) add_address(post, payment, options) commit('preauth', post) end def capture(money, authorization, options={}) post = {} add_reference(post, authorization) add_invoice(post, money, options) commit('preauthcomplete', post) end def refund(money, authorization, options={}) post = {} add_reference(post, authorization) add_invoice(post, money, options) commit('credit', post) end def void(authorization, options={}) post = {} add_reference(post, authorization) commit('void', post) end def verify(credit_card, options={}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } end end def supports_scrubbing? true end def scrub(transcript) transcript.gsub(%r(()[^<]*())i, '\1[FILTERED]\2'). gsub(%r(()[^<]*())i, '\1[FILTERED]\2'). gsub(%r(()[^<]*())i, '\1[FILTERED]\2') end private def add_reference(post, reference) post[:ttid] = reference end def add_address(post, payment, options) address = options[:billing_address] || options[:address] post[:zip] = address[:zip] post[:street] = address[:address1] end def add_invoice(post, money, options) post[:amount] = amount(money) post[:currency] = (options[:currency] || currency(money)) post[:descmerch] = options[:merchant] if options[:merchant] post[:ordernum] = options[:order_id] if options[:order_id] post[:comments] = options[:description] if options[:description] end def add_payment(post, payment) post[:cardholdername] = payment.name post[:account] = payment.number post[:cv] = payment.verification_value post[:expdate] = expdate(payment) end def parse(body) doc = Nokogiri::XML(body) doc.remove_namespaces! response = doc.xpath('/MonetraResp/Resp')[0] resp_params = {} response.elements.each do |node| resp_params[node.name.downcase.to_sym] = node.text end resp_params end def commit(action, parameters) url = (test? ? test_url : live_url) response = parse(ssl_post(url, request_body(action, parameters))) Response.new( success_from(response), message_from(response), response, authorization: authorization_from(response), test: test?, error_code: error_code_from(response) ) end def success_from(response) response[:code] == 'AUTH' end def message_from(response) response[:verbiage] end def authorization_from(response) response[:ttid] end def request_body(action, parameters = {}) Nokogiri::XML::Builder.new(encoding: 'utf-8') do |xml| xml.MonetraTrans do xml.Trans(identifier: parameters.delete(:identifier) || '1') do xml.username(options[:username]) xml.password(options[:password]) xml.action(action) parameters.each do |name, value| xml.send(name, value) end end end end.to_xml end def error_code_from(response) response[:msoft_code] || response[:phard_code] unless success_from(response) end end end end