class ActiveMerchant::Billing::VantivExpressGateway

Constants

CARD_HOLDER_PRESENT_CODE
CARD_INPUT_CODE
CARD_PRESENT_CODE
CVV_PRESENCE_CODE
LODGING_CHARGE_TYPE
LODGING_PPC
LODGING_SPC
MARKET_CODE
NETWORK_TOKEN_TYPE
PAYMENT_TYPE
REVERSAL_TYPE
SERVICE_LIVE_URL
SERVICE_TEST_URL
SUBMISSION_TYPE
TERMINAL_CAPABILITY_CODE
TERMINAL_ENVIRONMENT_CODE
TERMINAL_TYPE

Public Class Methods

new(options = {}) click to toggle source
Calls superclass method ActiveMerchant::Billing::Gateway::new
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 153
def initialize(options = {})
  requires!(options, :account_id, :account_token, :application_id, :acceptor_id, :application_name, :application_version)
  super
end

Public Instance Methods

authorize(money, payment, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 176
def authorize(money, payment, options = {})
  eci = parse_eci(payment)

  request = build_xml_request do |xml|
    xml.CreditCardAuthorization(xmlns: live_url) do
      add_credentials(xml)
      add_payment_method(xml, payment)
      add_transaction(xml, money, options, eci)
      add_terminal(xml, options, eci)
      add_address(xml, options)
      add_lodging(xml, options)
    end
  end

  commit(request, money, payment)
end
capture(money, authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 193
def capture(money, authorization, options = {})
  trans_id, _, eci = authorization.split('|')
  options[:trans_id] = trans_id

  request = build_xml_request do |xml|
    xml.CreditCardAuthorizationCompletion(xmlns: live_url) do
      add_credentials(xml)
      add_transaction(xml, money, options, eci)
      add_terminal(xml, options, eci)
    end
  end

  commit(request, money)
end
credit(money, payment, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 223
def credit(money, payment, options = {})
  eci = parse_eci(payment)

  request = build_xml_request do |xml|
    xml.CreditCardCredit(xmlns: live_url) do
      add_credentials(xml)
      add_payment_method(xml, payment)
      add_transaction(xml, money, options, eci)
      add_terminal(xml, options, eci)
    end
  end

  commit(request, money, payment)
end
purchase(money, payment, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 158
def purchase(money, payment, options = {})
  action = payment.is_a?(Check) ? 'CheckSale' : 'CreditCardSale'
  eci = parse_eci(payment)

  request = build_xml_request do |xml|
    xml.send(action, xmlns: live_url) do
      add_credentials(xml)
      add_payment_method(xml, payment)
      add_transaction(xml, money, options, eci)
      add_terminal(xml, options, eci)
      add_address(xml, options)
      add_lodging(xml, options)
    end
  end

  commit(request, money, payment)
end
refund(money, authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 208
def refund(money, authorization, options = {})
  trans_id, _, eci = authorization.split('|')
  options[:trans_id] = trans_id

  request = build_xml_request do |xml|
    xml.CreditCardReturn(xmlns: live_url) do
      add_credentials(xml)
      add_transaction(xml, money, options, eci)
      add_terminal(xml, options, eci)
    end
  end

  commit(request, money)
end
scrub(transcript) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 286
def scrub(transcript)
  transcript.
    gsub(%r((<AccountToken>).+?(</AccountToken>))i, '\1[FILTERED]\2').
    gsub(%r((<CardNumber>).+?(</CardNumber>))i, '\1[FILTERED]\2').
    gsub(%r((<CVV>).+?(</CVV>))i, '\1[FILTERED]\2').
    gsub(%r((<AccountNumber>).+?(</AccountNumber>))i, '\1[FILTERED]\2').
    gsub(%r((<RoutingNumber>).+?(</RoutingNumber>))i, '\1[FILTERED]\2')
end
store(payment, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 253
def store(payment, options = {})
  request = build_xml_request do |xml|
    xml.PaymentAccountCreate(xmlns: SERVICE_LIVE_URL) do
      add_credentials(xml)
      add_payment_method(xml, payment)
      add_payment_account(xml, payment, options[:payment_account_reference_number] || SecureRandom.hex(20))
      add_address(xml, options)
    end
  end

  commit(request, payment, nil, :store)
end
supports_scrubbing?() click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 282
def supports_scrubbing?
  true
end
verify(payment, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 266
def verify(payment, options = {})
  eci = parse_eci(payment)

  request = build_xml_request do |xml|
    xml.CreditCardAVSOnly(xmlns: live_url) do
      add_credentials(xml)
      add_payment_method(xml, payment)
      add_transaction(xml, 0, options, eci)
      add_terminal(xml, options, eci)
      add_address(xml, options)
    end
  end

  commit(request)
end
void(authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 238
def void(authorization, options = {})
  trans_id, trans_amount, eci = authorization.split('|')
  options.merge!({ trans_id: trans_id, trans_amount: trans_amount, reversal_type: 1 })

  request = build_xml_request do |xml|
    xml.CreditCardReversal(xmlns: live_url) do
      add_credentials(xml)
      add_transaction(xml, trans_amount, options, eci)
      add_terminal(xml, options, eci)
    end
  end

  commit(request, trans_amount)
end

Private Instance Methods

add_address(xml, options) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 437
def add_address(xml, options)
  address = address = options[:billing_address] || options[:address]
  shipping_address = options[:shipping_address]

  if address || shipping_address
    xml.Address do
      if address
        address[:email] ||= options[:email]

        xml.BillingAddress1 address[:address1] if address[:address1]
        xml.BillingAddress2 address[:address2] if address[:address2]
        xml.BillingCity address[:city] if address[:city]
        xml.BillingState address[:state] if address[:state]
        xml.BillingZipcode address[:zip] if address[:zip]
        xml.BillingEmail address[:email] if address[:email]
        xml.BillingPhone address[:phone_number] if address[:phone_number]
      end

      if shipping_address
        xml.ShippingAddress1 shipping_address[:address1] if shipping_address[:address1]
        xml.ShippingAddress2 shipping_address[:address2] if shipping_address[:address2]
        xml.ShippingCity shipping_address[:city] if shipping_address[:city]
        xml.ShippingState shipping_address[:state] if shipping_address[:state]
        xml.ShippingZipcode shipping_address[:zip] if shipping_address[:zip]
        xml.ShippingEmail shipping_address[:email] if shipping_address[:email]
        xml.ShippingPhone shipping_address[:phone_number] if shipping_address[:phone_number]
      end
    end
  end
end
add_credentials(xml) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 297
def add_credentials(xml)
  xml.Credentials do
    xml.AccountID @options[:account_id]
    xml.AccountToken @options[:account_token]
    xml.AcceptorID @options[:acceptor_id]
  end
  xml.Application do
    xml.ApplicationID @options[:application_id]
    xml.ApplicationName @options[:application_name]
    xml.ApplicationVersion @options[:application_version]
  end
end
add_credit_card(xml, payment) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 408
def add_credit_card(xml, payment)
  xml.Card do
    xml.CardNumber payment.number
    xml.ExpirationMonth format(payment.month, :two_digits)
    xml.ExpirationYear format(payment.year, :two_digits)
    xml.CardholderName "#{payment.first_name} #{payment.last_name}"
    xml.CVV payment.verification_value
  end
end
add_echeck(xml, payment) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 418
def add_echeck(xml, payment)
  xml.DemandDepositAccount do
    xml.AccountNumber payment.account_number
    xml.RoutingNumber payment.routing_number
    xml.DDAAccountType payment.account_type == 'checking' ? 0 : 1
  end
end
add_lodging(xml, options) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 367
def add_lodging(xml, options)
  if options[:lodging]
    lodging = parse_lodging(options[:lodging])
    xml.ExtendedParameters do
      xml.Lodging do
        xml.LodgingAgreementNumber lodging[:agreement_number] if lodging[:agreement_number]
        xml.LodgingCheckInDate lodging[:check_in_date] if lodging[:check_in_date]
        xml.LodgingCheckOutDate lodging[:check_out_date] if lodging[:check_out_date]
        xml.LodgingRoomAmount lodging[:room_amount] if lodging[:room_amount]
        xml.LodgingRoomTax lodging[:room_tax] if lodging[:room_tax]
        xml.LodgingNoShowIndicator lodging[:no_show_indicator] if lodging[:no_show_indicator]
        xml.LodgingDuration lodging[:duration] if lodging[:duration]
        xml.LodgingCustomerName lodging[:customer_name] if lodging[:customer_name]
        xml.LodgingClientCode lodging[:client_code] if lodging[:client_code]
        xml.LodgingExtraChargesDetail lodging[:extra_charges_detail] if lodging[:extra_charges_detail]
        xml.LodgingExtraChargesAmounts lodging[:extra_charges_amounts] if lodging[:extra_charges_amounts]
        xml.LodgingPrestigiousPropertyCode lodging[:prestigious_property_code] if lodging[:prestigious_property_code]
        xml.LodgingSpecialProgramCode lodging[:special_program_code] if lodging[:special_program_code]
        xml.LodgingChargeType lodging[:charge_type] if lodging[:charge_type]
      end
    end
  end
end
add_network_tokenization_card(xml, payment) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 426
def add_network_tokenization_card(xml, payment)
  xml.Card do
    xml.CardNumber payment.number
    xml.ExpirationMonth format(payment.month, :two_digits)
    xml.ExpirationYear format(payment.year, :two_digits)
    xml.CardholderName "#{payment.first_name} #{payment.last_name}"
    xml.Cryptogram payment.payment_cryptogram
    xml.WalletType NETWORK_TOKEN_TYPE[payment.source]
  end
end
add_payment_account(xml, payment, payment_account_reference_number) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 322
def add_payment_account(xml, payment, payment_account_reference_number)
  xml.PaymentAccount do
    xml.PaymentAccountType payment_account_type(payment)
    xml.PaymentAccountReferenceNumber payment_account_reference_number
  end
end
add_payment_account_id(xml, payment) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 329
def add_payment_account_id(xml, payment)
  xml.PaymentAccount do
    xml.PaymentAccountID payment
  end
end
add_payment_method(xml, payment) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 310
def add_payment_method(xml, payment)
  if payment.is_a?(String)
    add_payment_account_id(xml, payment)
  elsif payment.is_a?(Check)
    add_echeck(xml, payment)
  elsif payment.is_a?(NetworkTokenizationCreditCard)
    add_network_tokenization_card(xml, payment)
  else
    add_credit_card(xml, payment)
  end
end
add_terminal(xml, options, network_token_eci = nil) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 391
def add_terminal(xml, options, network_token_eci = nil)
  options = parse_terminal(options)

  xml.Terminal do
    xml.TerminalID options[:terminal_id] || '01'
    xml.TerminalType options[:terminal_type] if options[:terminal_type]
    xml.CardPresentCode options[:card_present_code] || 0
    xml.CardholderPresentCode options[:card_holder_present_code] || 0
    xml.CardInputCode options[:card_input_code] || 0
    xml.CVVPresenceCode options[:cvv_presence_code] || 0
    xml.TerminalCapabilityCode options[:terminal_capability_code] || 0
    xml.TerminalEnvironmentCode options[:terminal_environment_code] || 0
    xml.MotoECICode network_token_eci || 7
    xml.PartialApprovedFlag options[:partial_approved_flag] if options[:partial_approved_flag]
  end
end
add_transaction(xml, money, options = {}, network_token_eci = nil) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 335
def add_transaction(xml, money, options = {}, network_token_eci = nil)
  xml.Transaction do
    xml.ReversalType REVERSAL_TYPE[options[:reversal_type]] || options[:reversal_type] if options[:reversal_type]
    xml.TransactionID options[:trans_id] if options[:trans_id]
    xml.TransactionAmount amount(money.to_i) if money
    xml.MarketCode market_code(money, options, network_token_eci) if options[:market_code] || money
    xml.ReferenceNumber options[:order_id].present? ? options[:order_id][0, 50] : SecureRandom.hex(20)
    xml.TicketNumber options[:ticket_number] || rand(1..999999)
    xml.MerchantSuppliedTransactionID options[:merchant_supplied_transaction_id] if options[:merchant_supplied_transaction_id]
    xml.PaymentType PAYMENT_TYPE[options[:payment_type]] || options[:payment_type] if options[:payment_type]
    xml.SubmissionType SUBMISSION_TYPE[options[:submission_type]] || options[:submission_type] if options[:submission_type]
    xml.DuplicateCheckDisableFlag 1 if options[:duplicate_check_disable_flag].to_s == 'true' || options[:duplicate_override_flag].to_s == 'true'
  end
end
authorization_from(action, response, amount, payment) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 528
def authorization_from(action, response, amount, payment)
  return response.dig('paymentaccount', 'paymentaccountid') if action == :store

  if response['transaction']
    authorization = "#{response.dig('transaction', 'transactionid')}|#{amount}"
    authorization << "|#{parse_eci(payment)}" if parse_eci(payment)
    authorization
  end
end
avs_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 546
def avs_from(response)
  AVSResult.new(code: response['card']['avsresponsecode']) if response['card']
end
build_xml_request(&block) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 554
def build_xml_request(&block)
  builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8', &block)

  builder.to_xml
end
commit(xml, amount = nil, payment = nil, action = nil) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 513
def commit(xml, amount = nil, payment = nil, action = nil)
  response = parse(ssl_post(url(action), xml, headers))
  success = success_from(response)

  Response.new(
    success,
    message_from(response),
    response,
    authorization: authorization_from(action, response, amount, payment),
    avs_result: success ? avs_from(response) : nil,
    cvv_result: success ? cvv_from(response) : nil,
    test: test?
  )
end
cvv_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 550
def cvv_from(response)
  CVVResult.new(response['card']['cvvresponsecode']) if response['card']
end
headers() click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 580
def headers
  {
    'Content-Type' => 'text/xml'
  }
end
market_code(money, options, network_token_eci) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 361
def market_code(money, options, network_token_eci)
  return 3 if network_token_eci

  MARKET_CODE[options[:market_code]] || options[:market_code] || 0
end
message_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 542
def message_from(response)
  response['expressresponsemessage']
end
parse(xml) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 468
def parse(xml)
  response = {}

  doc = Nokogiri::XML(xml)
  doc.remove_namespaces!
  root = doc.root.xpath('//response/*')

  root = doc.root.xpath('//Response/*') if root.empty?

  root.each do |node|
    if node.elements.empty?
      response[node.name.downcase] = node.text
    else
      node_name = node.name.downcase
      response[node_name] = {}

      node.elements.each do |childnode|
        response[node_name][childnode.name.downcase] = childnode.text
      end
    end
  end

  response
end
parse_eci(payment) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 350
def parse_eci(payment)
  return nil unless payment.is_a?(NetworkTokenizationCreditCard)

  if (eci = payment.eci)
    eci = eci[0] == '0' ? eci.sub!(/^0/, '') : eci
    return eci
  else
    payment.brand == 'american_express' ? '9' : '6'
  end
end
parse_lodging(lodging) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 493
def parse_lodging(lodging)
  lodging[:prestigious_property_code] = LODGING_PPC[lodging[:prestigious_property_code]] || lodging[:prestigious_property_code] if lodging[:prestigious_property_code]
  lodging[:special_program_code] = LODGING_SPC[lodging[:special_program_code]] || lodging[:special_program_code] if lodging[:special_program_code]
  lodging[:charge_type] = LODGING_CHARGE_TYPE[lodging[:charge_type]] || lodging[:charge_type] if lodging[:charge_type]

  lodging
end
parse_terminal(options) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 501
def parse_terminal(options)
  options[:terminal_type] = TERMINAL_TYPE[options[:terminal_type]] || options[:terminal_type]
  options[:card_present_code] = CARD_PRESENT_CODE[options[:card_present_code]] || options[:card_present_code]
  options[:card_holder_present_code] = CARD_HOLDER_PRESENT_CODE[options[:card_holder_present_code]] || options[:card_holder_present_code]
  options[:card_input_code] = CARD_INPUT_CODE[options[:card_input_code]] || options[:card_input_code]
  options[:cvv_presence_code] = CVV_PRESENCE_CODE[options[:cvv_presence_code]] || options[:cvv_presence_code]
  options[:terminal_capability_code] = TERMINAL_CAPABILITY_CODE[options[:terminal_capability_code]] || options[:terminal_capability_code]
  options[:terminal_environment_code] = TERMINAL_ENVIRONMENT_CODE[options[:terminal_environment_code]] || options[:terminal_environment_code]

  options
end
payment_account_type(payment) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 560
def payment_account_type(payment)
  return 0 unless payment.is_a?(Check)

  if payment.account_type == 'checking'
    1
  elsif payment.account_type == 'savings'
    2
  else
    3
  end
end
success_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 538
def success_from(response)
  response['expressresponsecode'] == '0'
end
url(action) click to toggle source
# File lib/active_merchant/billing/gateways/vantiv_express.rb, line 572
def url(action)
  if action == :store
    test? ? SERVICE_TEST_URL : SERVICE_LIVE_URL
  else
    test? ? test_url : live_url
  end
end