class ActiveMerchant::Billing::NmiGateway

Constants

DUP_WINDOW_DEPRECATION_MESSAGE

Public Class Methods

duplicate_window() click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 21
def self.duplicate_window
  instance_variable_defined?(:@dup_seconds) ? @dup_seconds : nil
end
duplicate_window=(seconds) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 16
def self.duplicate_window=(seconds)
  ActiveMerchant.deprecated(DUP_WINDOW_DEPRECATION_MESSAGE)
  @dup_seconds = seconds
end
new(options = {}) click to toggle source
Calls superclass method ActiveMerchant::Billing::Gateway::new
# File lib/active_merchant/billing/gateways/nmi.rb, line 25
def initialize(options = {})
  if options.has_key?(:security_key)
    requires!(options, :security_key)
  else
    requires!(options, :login, :password)
  end
  super
end

Public Instance Methods

authorize(amount, payment_method, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 48
def authorize(amount, payment_method, options = {})
  post = {}
  add_invoice(post, amount, options)
  add_payment_method(post, payment_method, options)
  add_stored_credential(post, options)
  add_customer_data(post, options)
  add_vendor_data(post, options)
  add_merchant_defined_fields(post, options)
  add_level3_fields(post, options)
  add_three_d_secure(post, options)
  commit('auth', post)
end
capture(amount, authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 61
def capture(amount, authorization, options = {})
  post = {}
  add_invoice(post, amount, options)
  add_reference(post, authorization)
  add_merchant_defined_fields(post, options)

  commit('capture', post)
end
credit(amount, payment_method, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 87
def credit(amount, payment_method, options = {})
  post = {}
  add_invoice(post, amount, options)
  add_payment_method(post, payment_method, options)
  add_customer_data(post, options)
  add_vendor_data(post, options)
  add_level3_fields(post, options)

  commit('credit', post)
end
purchase(amount, payment_method, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 34
def purchase(amount, payment_method, options = {})
  post = {}
  add_invoice(post, amount, options)
  add_payment_method(post, payment_method, options)
  add_stored_credential(post, options)
  add_customer_data(post, options)
  add_vendor_data(post, options)
  add_merchant_defined_fields(post, options)
  add_level3_fields(post, options)
  add_three_d_secure(post, options)

  commit('sale', post)
end
refund(amount, authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 78
def refund(amount, authorization, options = {})
  post = {}
  add_invoice(post, amount, options)
  add_reference(post, authorization)
  add_payment_type(post, authorization)

  commit('refund', post)
end
scrub(transcript) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 129
def scrub(transcript)
  transcript.
    gsub(%r((password=)[^&\n]*), '\1[FILTERED]').
    gsub(%r((security_key=)[^&\n]*), '\1[FILTERED]').
    gsub(%r((ccnumber=)\d+), '\1[FILTERED]').
    gsub(%r((cvv=)\d+), '\1[FILTERED]').
    gsub(%r((checkaba=)\d+), '\1[FILTERED]').
    gsub(%r((checkaccount=)\d+), '\1[FILTERED]').
    gsub(%r((cavv=)[^&\n]*), '\1[FILTERED]').
    gsub(%r((cryptogram=)[^&]+(&?)), '\1[FILTERED]\2')
end
store(payment_method, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 109
def store(payment_method, options = {})
  post = {}
  add_invoice(post, nil, options)
  add_payment_method(post, payment_method, options)
  add_customer_data(post, options)
  add_vendor_data(post, options)
  add_merchant_defined_fields(post, options)

  commit('add_customer', post)
end
supports_network_tokenization?() click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 141
def supports_network_tokenization?
  true
end
supports_scrubbing?() click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 125
def supports_scrubbing?
  true
end
verify(payment_method, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 98
def verify(payment_method, options = {})
  post = {}
  add_payment_method(post, payment_method, options)
  add_customer_data(post, options)
  add_vendor_data(post, options)
  add_merchant_defined_fields(post, options)
  add_level3_fields(post, options)

  commit('validate', post)
end
verify_credentials() click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 120
def verify_credentials
  response = void('0')
  response.message != 'Authentication Failed'
end
void(authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 70
def void(authorization, options = {})
  post = {}
  add_reference(post, authorization)
  add_payment_type(post, authorization)

  commit('void', post)
end

Private Instance Methods

add_customer_data(post, options) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 232
def add_customer_data(post, options)
  post[:email] = options[:email]
  post[:ipaddress] = options[:ip]
  post[:customer_id] = options[:customer_id] || options[:customer]

  if (billing_address = options[:billing_address] || options[:address])
    post[:company] = billing_address[:company]
    post[:address1] = billing_address[:address1]
    post[:address2] = billing_address[:address2]
    post[:city] = billing_address[:city]
    post[:state] = billing_address[:state]
    post[:country] = billing_address[:country]
    post[:zip] = billing_address[:zip]
    post[:phone] = billing_address[:phone]
  end

  if (shipping_address = options[:shipping_address])
    first_name, last_name = split_names(shipping_address[:name])
    post[:shipping_firstname] = first_name if first_name
    post[:shipping_lastname] = last_name if last_name
    post[:shipping_company] = shipping_address[:company]
    post[:shipping_address1] = shipping_address[:address1]
    post[:shipping_address2] = shipping_address[:address2]
    post[:shipping_city] = shipping_address[:city]
    post[:shipping_state] = shipping_address[:state]
    post[:shipping_country] = shipping_address[:country]
    post[:shipping_zip] = shipping_address[:zip]
    post[:shipping_phone] = shipping_address[:phone]
    post[:shipping_email] = options[:shipping_email] if options[:shipping_email]
  end

  if (descriptor = options[:descriptors])
    post[:descriptor] = descriptor[:descriptor]
    post[:descriptor_phone] = descriptor[:descriptor_phone]
    post[:descriptor_address] = descriptor[:descriptor_address]
    post[:descriptor_city] = descriptor[:descriptor_city]
    post[:descriptor_state] = descriptor[:descriptor_state]
    post[:descriptor_postal] = descriptor[:descriptor_postal]
    post[:descriptor_country] = descriptor[:descriptor_country]
    post[:descriptor_mcc] = descriptor[:descriptor_mcc]
    post[:descriptor_merchant_id] = descriptor[:descriptor_merchant_id]
    post[:descriptor_url] = descriptor[:descriptor_url]
  end
end
add_invoice(post, money, options) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 151
def add_invoice(post, money, options)
  post[:amount] = amount(money)
  post[:surcharge] = options[:surcharge] if options[:surcharge]
  post[:orderid] = options[:order_id]
  post[:orderdescription] = options[:description]
  post[:currency] = options[:currency] || currency(money)
  post[:billing_method] = 'recurring' if options[:recurring]
  if (dup_seconds = (options[:dup_seconds] || self.class.duplicate_window))
    post[:dup_seconds] = dup_seconds
  end
end
add_level3_fields(post, options) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 147
def add_level3_fields(post, options)
  add_fields_to_post_if_present(post, options, %i[tax shipping ponumber])
end
add_merchant_defined_fields(post, options) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 282
def add_merchant_defined_fields(post, options)
  (1..20).each do |each|
    key = "merchant_defined_field_#{each}".to_sym
    post[key] = options[key] if options[key]
  end
end
add_network_token_fields(post, payment_method) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 191
def add_network_token_fields(post, payment_method)
  if payment_method.source == :apple_pay || payment_method.source == :google_pay
    post[:cavv] = payment_method.payment_cryptogram
    post[:eci] = payment_method.eci
    post[:decrypted_applepay_data] = 1
    post[:decrypted_googlepay_data] = 1
  else
    post[:token_cryptogram] = payment_method.payment_cryptogram
  end
end
add_payment_method(post, payment_method, options) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 163
def add_payment_method(post, payment_method, options)
  if payment_method.is_a?(String)
    customer_vault_id, = split_authorization(payment_method)
    post[:customer_vault_id] = customer_vault_id
  elsif payment_method.is_a?(NetworkTokenizationCreditCard)
    post[:ccnumber] = payment_method.number
    post[:ccexp] = exp_date(payment_method)
    add_network_token_fields(post, payment_method)
  elsif card_brand(payment_method) == 'check'
    post[:payment] = 'check'
    post[:firstname] = payment_method.first_name
    post[:lastname] = payment_method.last_name
    post[:checkname] = payment_method.name
    post[:checkaba] = payment_method.routing_number
    post[:checkaccount] = payment_method.account_number
    post[:account_holder_type] = payment_method.account_holder_type
    post[:account_type] = payment_method.account_type
    post[:sec_code] = options[:sec_code] || 'WEB'
  else
    post[:payment] = 'creditcard'
    post[:firstname] = payment_method.first_name
    post[:lastname] = payment_method.last_name
    post[:ccnumber] = payment_method.number
    post[:cvv] = payment_method.verification_value unless empty?(payment_method.verification_value)
    post[:ccexp] = exp_date(payment_method)
  end
end
add_payment_type(post, authorization) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 311
def add_payment_type(post, authorization)
  _, payment_type = split_authorization(authorization)
  post[:payment] = payment_type if payment_type
end
add_reference(post, authorization) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 306
def add_reference(post, authorization)
  transaction_id, = split_authorization(authorization)
  post[:transactionid] = transaction_id
end
add_stored_credential(post, options) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 202
def add_stored_credential(post, options)
  return unless (stored_credential = options[:stored_credential])

  if stored_credential[:initiator] == 'cardholder'
    post[:initiated_by] = 'customer'
  else
    post[:initiated_by] = 'merchant'
  end

  # :reason_type, when provided, overrides anything previously set in
  # post[:billing_method] (see `add_invoice` and the :recurring) option
  case stored_credential[:reason_type]
  when 'recurring'
    post[:billing_method] = 'recurring'
  when 'installment'
    post[:billing_method] = 'installment'
  when 'unscheduled'
    post.delete(:billing_method)
  end

  if stored_credential[:initial_transaction]
    post[:stored_credential_indicator] = 'stored'
  else
    post[:stored_credential_indicator] = 'used'
    # should only send :initial_transaction_id if it is a MIT
    ntid = options[:network_transaction_id] || stored_credential[:network_transaction_id]
    post[:initial_transaction_id] = ntid if post[:initiated_by] == 'merchant'
  end
end
add_three_d_secure(post, options) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 289
def add_three_d_secure(post, options)
  three_d_secure = options[:three_d_secure]
  return unless three_d_secure

  post[:cardholder_auth] = cardholder_auth(three_d_secure[:authentication_response_status])
  post[:cavv] = three_d_secure[:cavv]
  post[:xid] = three_d_secure[:xid]
  post[:three_ds_version] = three_d_secure[:version]
  post[:directory_server_id] = three_d_secure[:ds_transaction_id]
end
add_vendor_data(post, options) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 277
def add_vendor_data(post, options)
  post[:vendor_id] = options[:vendor_id] if options[:vendor_id]
  post[:processor_id] = options[:processor_id] if options[:processor_id]
end
authorization_from(response, payment_type, action) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 340
def authorization_from(response, payment_type, action)
  authorization = (action == 'add_customer' ? response[:customer_vault_id] : response[:transactionid])
  [authorization, payment_type].join('#')
end
cardholder_auth(trans_status) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 300
def cardholder_auth(trans_status)
  return nil if trans_status.nil?

  trans_status == 'Y' ? 'verified' : 'attempted'
end
commit(action, params) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 320
def commit(action, params)
  params[action == 'add_customer' ? :customer_vault : :type] = action
  params[:username] = @options[:login] unless @options[:login].nil?
  params[:password] = @options[:password] unless @options[:password].nil?
  params[:security_key] = @options[:security_key] unless @options[:security_key].nil?
  raw_response = ssl_post(url, post_data(action, params), headers)
  response = parse(raw_response)
  succeeded = success_from(response)

  Response.new(
    succeeded,
    message_from(succeeded, response),
    response,
    authorization: authorization_from(response, params[:payment], action),
    avs_result: AVSResult.new(code: response[:avsresponse]),
    cvv_result: CVVResult.new(response[:cvvresponse]),
    test: test?
  )
end
exp_date(payment_method) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 316
def exp_date(payment_method)
  "#{format(payment_method.month, :two_digits)}#{format(payment_method.year, :two_digits)}"
end
headers() click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 349
def headers
  { 'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8' }
end
message_from(succeeded, response) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 369
def message_from(succeeded, response)
  if succeeded
    'Succeeded'
  else
    response[:responsetext]
  end
end
parse(body) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 361
def parse(body)
  CGI::parse(body).map { |k, v| [k.intern, v.first] }.to_h
end
post_data(action, params) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 353
def post_data(action, params)
  params.map { |k, v| "#{k}=#{CGI.escape(v.to_s)}" }.join('&')
end
split_authorization(authorization) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 345
def split_authorization(authorization)
  authorization.split('#')
end
success_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 365
def success_from(response)
  response[:response] == '1'
end
url() click to toggle source
# File lib/active_merchant/billing/gateways/nmi.rb, line 357
def url
  test? ? test_url : live_url
end