class ActiveMerchant::Billing::MercuryGateway
The Mercury gateway integration by default requires that the Mercury account being used has tokenization turned. This enables the use of capture/refund/void without having to pass the credit card back in each time. Only the “OneTime” tokenization is used; there is no use of “Recurring” tokenization.
If you don't wish to enable Mercury tokenization, you can pass :tokenization => false
as an option when creating the gateway. If you do so, then passing a :credit_card
option to capture
and refund
will become mandatory.
Constants
- CARD_CODES
- ENVELOPE_NAMESPACES
- STANDARD_ERROR_CODE_MAPPING
- SUCCESS_CODES
- URLS
Public Class Methods
new(options = {})
click to toggle source
Calls superclass method
ActiveMerchant::Billing::Gateway::new
# File lib/active_merchant/billing/gateways/mercury.rb, line 31 def initialize(options = {}) requires!(options, :login, :password) @use_tokenization = (!options.has_key?(:tokenization) || options[:tokenization]) super end
Public Instance Methods
capture(money, authorization, options = {})
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 58 def capture(money, authorization, options = {}) requires!(options, :credit_card) unless @use_tokenization request = build_authorized_request('PreAuthCapture', money, authorization, options[:credit_card], options.merge(:authorized => money)) commit('PreAuthCapture', request) end
credit(money, credit_card, options = {})
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 44 def credit(money, credit_card, options = {}) requires!(options, :order_id) request = build_non_authorized_request('Return', money, credit_card, options) commit('Return', request) end
purchase(money, credit_card, options = {})
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 37 def purchase(money, credit_card, options = {}) requires!(options, :order_id) request = build_non_authorized_request('Sale', money, credit_card, options) commit('Sale', request) end
refund(money, authorization, options = {})
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 65 def refund(money, authorization, options = {}) requires!(options, :credit_card) unless @use_tokenization request = build_authorized_request('Return', money, authorization, options[:credit_card], options) commit('Return', request) end
scrub(transcript)
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 88 def scrub(transcript) transcript. gsub(%r(<), '<'). gsub(%r(>), '>'). gsub(%r((<pw>).*(</pw>))i, '\1[FILTERED]\2'). gsub(%r((<AcctNo>)(\d|x)*(</AcctNo>))i, '\1[FILTERED]\3'). gsub(%r((<CVVData>)\d*(</CVVData>))i, '\1[FILTERED]\2') end
store(credit_card, options={})
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 79 def store(credit_card, options={}) request = build_card_lookup_request(credit_card, options) commit('CardLookup', request) end
supports_scrubbing?()
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 84 def supports_scrubbing? true end
void(authorization, options={})
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 72 def void(authorization, options={}) requires!(options, :credit_card) unless @use_tokenization request = build_authorized_request('VoidSale', nil, authorization, options[:credit_card], options) commit('VoidSale', request) end
Private Instance Methods
add_address(xml, options)
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 240 def add_address(xml, options) if billing_address = options[:billing_address] || options[:address] xml.tag! 'AVS' do xml.tag! 'Address', billing_address[:address1] xml.tag! 'Zip', billing_address[:zip] end end end
add_amount(xml, money, options = {})
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 190 def add_amount(xml, money, options = {}) xml.tag! 'Amount' do xml.tag! 'Purchase', amount(money) xml.tag! 'Tax', options[:tax] if options[:tax] xml.tag! 'Authorize', amount(options[:authorized]) if options[:authorized] xml.tag! 'Gratuity', amount(options[:tip]) if options[:tip] end end
add_credit_card(xml, credit_card, action)
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 208 def add_credit_card(xml, credit_card, action) xml.tag! 'Account' do if credit_card.track_data.present? # Track 1 has a start sentinel (STX) of '%' and track 2 is ';' # Track 1 and 2 have identical end sentinels (ETX) of '?' # Tracks may or may not have checksum (LRC) after the ETX # If the track has no STX or is corrupt, we send it as track 1, to let Mercury # handle with the validation error as it sees fit. # Track 2 requires having the STX and ETX stripped. Track 1 does not. # Max-length track 1s require having the STX and ETX stripped. Max is 79 bytes including LRC. is_track_2 = credit_card.track_data[0] == ';' etx_index = credit_card.track_data.rindex('?') || credit_card.track_data.length is_max_track1 = etx_index >= 77 if is_track_2 xml.tag! 'Track2', credit_card.track_data[1...etx_index] elsif is_max_track1 xml.tag! 'Track1', credit_card.track_data[1...etx_index] else xml.tag! 'Track1', credit_card.track_data end else xml.tag! 'AcctNo', credit_card.number xml.tag! 'ExpDate', expdate(credit_card) end end xml.tag! 'CardType', CARD_CODES[credit_card.brand] if credit_card.brand include_cvv = !%w(Return PreAuthCapture).include?(action) && !credit_card.track_data.present? xml.tag! 'CVVData', credit_card.verification_value if(include_cvv && credit_card.verification_value) end
add_customer_data(xml, options)
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 180 def add_customer_data(xml, options) xml.tag! 'IpAddress', options[:ip] if options[:ip] if options[:customer] xml.tag! 'TranInfo' do xml.tag! 'CustomerCode', options[:customer] end end xml.tag! 'MerchantID', @options[:login] end
add_invoice(xml, invoice_no, ref_no, options)
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 166 def add_invoice(xml, invoice_no, ref_no, options) xml.tag! 'InvoiceNo', invoice_no xml.tag! 'RefNo', (ref_no || invoice_no) xml.tag! 'OperatorID', options[:merchant] if options[:merchant] xml.tag! 'Memo', options[:description] if options[:description] end
add_reference(xml, record_no)
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 173 def add_reference(xml, record_no) if @use_tokenization xml.tag! 'Frequency', 'OneTime' xml.tag! 'RecordNo', record_no end end
build_card_lookup_request(credit_card, options)
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 149 def build_card_lookup_request(credit_card, options) xml = Builder::XmlMarkup.new xml.tag! 'TStream' do xml.tag! 'Transaction' do xml.tag! 'TranType', 'CardLookup' xml.tag! 'RecordNo', 'RecordNumberRequested' xml.tag! 'Frequency', 'OneTime' xml.tag! 'Memo', options[:description] add_customer_data(xml, options) add_credit_card(xml, credit_card, options) end end xml.target! end
build_header()
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 294 def build_header { 'SOAPAction' => 'http://www.mercurypay.com/CreditTransaction', 'Content-Type' => 'text/xml; charset=utf-8' } end
build_soap_request(body)
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 277 def build_soap_request(body) xml = Builder::XmlMarkup.new xml.instruct! xml.tag! 'soap:Envelope', ENVELOPE_NAMESPACES do xml.tag! 'soap:Body' do xml.tag! 'CreditTransaction', 'xmlns' => homepage_url do xml.tag! 'tran' do xml << escape_xml(body) end xml.tag! 'pw', @options[:password] end end end xml.target! end
commit(action, request)
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 303 def commit(action, request) response = parse(action, ssl_post(endpoint_url, build_soap_request(request), build_header)) success = SUCCESS_CODES.include?(response[:cmd_status]) message = success ? 'Success' : message_from(response) Response.new(success, message, response, :test => test?, :authorization => authorization_from(response), :avs_result => { :code => response[:avs_result] }, :cvv_result => response[:cvv_result], :error_code => success ? nil : STANDARD_ERROR_CODE_MAPPING[response[:dsix_return_code]]) end
endpoint_url()
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 273 def endpoint_url URLS[test? ? :test : :live] end
escape_xml(xml)
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 347 def escape_xml(xml) "\n<![CDATA[\n#{xml}\n]]>\n" end
hashify_xml!(xml, response)
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 255 def hashify_xml!(xml, response) xml = REXML::Document.new(xml) xml.elements.each('//CmdResponse/*') do |node| response[node.name.underscore.to_sym] = node.text end xml.elements.each('//TranResponse/*') do |node| if node.name.to_s == 'Amount' node.elements.each do |amt| response[amt.name.underscore.to_sym] = amt.text end else response[node.name.underscore.to_sym] = node.text end end end
message_from(response)
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 317 def message_from(response) response[:text_response] end
parse(action, body)
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 249 def parse(action, body) response = {} hashify_xml!(unescape_xml(body), response) response end
unescape_xml(escaped_xml)
click to toggle source
# File lib/active_merchant/billing/gateways/mercury.rb, line 351 def unescape_xml(escaped_xml) escaped_xml.gsub(/\>/, '>').gsub(/\</, '<') end