class ActiveMerchant::Billing::NexioGateway

Constants

OneTimeToken
STANDARD_ERROR_CODE_MAPPING

Public Class Methods

new(options = {}) click to toggle source
Calls superclass method
# File lib/active_merchant/billing/gateways/nexio.rb, line 22
def initialize(options = {})
  requires!(options, :merchant_id, :auth_token)
  super
end

Public Instance Methods

authorize(money, payment, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 53
def authorize(money, payment, options = {})
  purchase(money, payment, options.merge(payload: options.fetch(:payload, {}).merge(isAuthOnly: true)))
end
capture(money, authorization, _options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 57
def capture(money, authorization, _options = {})
  commit('capture', { id: authorization, data: { amount: amount(money).to_f } })
end
credit(money, authorization, _options = {})
Alias for: refund
generate_token(options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 27
def generate_token(options = {})
  post = build_payload(options)
  post[:data][:allowedCardTypes] = %w(amex discover jcb mastercard visa)
  add_currency(post, options)
  add_order_data(post, options)
  add_card_data(post, options)
  resp = commit('token', post)
  return unless resp.success?

  token, expiration, fraud_url = resp.params.values_at('token', 'expiration', 'fraudUrl')
  OneTimeToken.new(token, Time.parse(expiration), fraud_url)
end
get_transaction(id) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 116
def get_transaction(id)
  parse(ssl_get(action_url("/transaction/v3/paymentId/#{id}"), base_headers))
rescue ResponseError => e
end
purchase(money, payment, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 40
def purchase(money, payment, options = {})
  post = build_payload(options)
  post[:processingOptions] ||= {}
  post[:processingOptions][:verboseResponse] = true if test?
  post[:processingOptions][:customerRedirectUrl] = options[:three_d_callback_url] if options.key?(:three_d_callback_url)
  post[:processingOptions][:check3ds] = options[:three_d_secure]
  post[:processingOptions][:paymentType] = options[:payment_type] if options.key?(:payment_type)
  add_invoice(post, money, options)
  add_payment(post, payment, options)
  add_order_data(post, options)
  commit('process', post)
end
refund(money, authorization, _options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 61
def refund(money, authorization, _options = {})
  commit('refund', { id: authorization, data: { amount: amount(money).to_f } })
end
Also aliased as: credit
scrub(transcript) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 81
def scrub(transcript)
  transcript
end
set_secret() click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 112
def set_secret
  commit('secret', { merchantId: options[:merchant_id].to_s }).params['secret']
end
set_webhooks(data) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 96
def set_webhooks(data)
  post = { merchantId: options[:merchant_id].to_s }
  if data.is_a?(String)
    post[:webhooks] = {
      TRANSACTION_AUTHORIZED: { url: data },
      TRANSACTION_CAPTURED: { url: data }
    }
  else
    webhooks = {}
    webhooks[:TRANSACTION_AUTHORIZED] = { url: data[:authorized] } if data.key?(:authorized)
    webhooks[:TRANSACTION_CAPTURED] = { url: data[:captured] } if data.key?(:captured)
    post[:webhooks] = webhooks
  end
  commit('webhook', post)
end
store(payment, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 85
def store(payment, options = {})
  post = build_payload(options)
  add_card_details(post, payment, options)
  add_currency(post, options)
  add_order_data(post, options)
  resp = commit('saveCard', post)
  return unless resp.success?

  resp.params.fetch('token', {}).fetch('token', nil)
end
supports_scrubbing?() click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 77
def supports_scrubbing?
  false
end
verify(credit_card, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 70
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
void(authorization, _options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 66
def void(authorization, _options = {})
  commit('void', { id: authorization })
end

Private Instance Methods

action_url(path) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 294
def action_url(path)
  "#{test? ? test_url : live_url}#{path}"
end
add_address(post, data, prefix) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 172
def add_address(post, data, prefix)
  return post if data.blank?

  post[:data][:customer].merge!({
                                  "#{prefix}AddressOne": data[:address1],
                                  "#{prefix}AddressTwo": data[:address2],
                                  "#{prefix}City": data[:city],
                                  "#{prefix}Country": data[:country],
                                  "#{prefix}Phone": data[:phone],
                                  "#{prefix}Postal": data[:zip],
                                  "#{prefix}State": data[:state]
                                })
end
add_card_data(post, options) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 209
def add_card_data(post, options)
  if card = options[:card]
    post[:card] = {
      cardHolderName: card[:name],
      expirationMonth: card[:month],
      expirationYear: card[:year]
    }
  end
end
add_card_details(post, payment, _options) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 219
def add_card_details(post, payment, _options)
  if payment.is_a?(EncryptedNexioCard)
    raise ArgumentError, 'The provided card is invalid' unless payment.valid?

    post[:card] = {
      cardHolderName: payment.name,
      encryptedNumber: payment.encrypted_number,
      expirationMonth: payment.month,
      expirationYear: payment.short_year,
      cardType: payment.brand,
      securityCode: payment.verification_value
    }
    post[:token] = payment.one_time_token
  else
    raise ArgumentError, "Only #{EncryptedNexioCard} payment method is supported to store cards"
  end
end
add_cart(post, list) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 159
def add_cart(post, list)
  items = list.map do |item|
    {
      item: item[:id],
      description: item[:description],
      quantity: item.fetch(:quantity, 1),
      price: amount(item[:price]).to_f,
      type: item.fetch(:type, :sale)
    }
  end
  post[:data][:cart] = { items: items }
end
add_currency(post, options) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 128
def add_currency(post, options)
  post[:data][:currency] = options[:currency] if options.key?(:currency)
end
add_invoice(post, money, options) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 123
def add_invoice(post, money, options)
  post[:data][:amount] = amount(money).to_f
  add_currency(post, options)
end
add_order_data(post, options) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 132
def add_order_data(post, options)
  if customer = options[:customer]
    case customer
    when String
      post[:data][:customer][:email] = customer
    when Hash
      post[:data][:customer].merge!({
                                      firstName: customer[:first_name],
                                      lastName: customer[:last_name],
                                      email: customer[:email]
                                    })
    end
  end

  if order = options[:order]
    add_cart(post, order[:line_items]) if order.key?(:line_items)
    post[:data][:customer][:orderNumber] = order[:number] if order.key?(:number)
    post[:data][:customer][:orderDate] = order[:date] if order.key?(:date)
  end

  add_address(post, options[:billing_address], :billTo)
  add_address(post, options[:address], :shipTo)
  if phone = options.fetch(:address, options.fetch(:billing_address, {}))[:phone]
    post[:data][:customer][:phone] = phone
  end
end
add_payment(post, payment, options) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 186
def add_payment(post, payment, options)
  post[:tokenex] = token_from(payment)
  if payment.is_a?(Spree::CreditCard)
    post[:card] = {
      cardHolderName: payment.name,
      cardType: payment.brand
    }
  end
  post[:processingOptions] ||= {}
  post[:processingOptions][:merchantId] = self.options[:merchant_id].to_s
  post[:processingOptions][:saveCardToken] = options[:save_credit_card] if options.key?(:save_credit_card)
end
authorization_from(payload) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 276
def authorization_from(payload)
  payload.fetch('id', nil)
end
base_headers(custom = {}) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 314
def base_headers(custom = {})
  { Authorization: "Basic #{options[:auth_token]}" }
end
build_avs_result(data) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 298
def build_avs_result(data)
  return if data.blank?

  AVSResult.new(street_match: data['matchAddress'], postal_match: data['matchPostal'])
end
build_cvv_result(data) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 304
def build_cvv_result(data)
  return if data.blank?

  CVVResult.new(data.fetch('gatewayMessage', {}).fetch('cvvresponse', nil))
end
build_payload(params) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 310
def build_payload(params)
  { data: { customer: {} } }.merge!(params.fetch(:payload, {}))
end
commit(action, parameters) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 243
def commit(action, parameters)
  payload = parse(ssl_post(commit_action_url(action, parameters), post_data(action, parameters), base_headers))

  Response.new(
    response_status(action, payload),
    nil,
    payload,
    authorization: authorization_from(payload),
    avs_result: build_avs_result(payload['avsResults']),
    cvv_result: build_cvv_result(payload['cvcResults']),
    test: test?,
    network_transaction_id: payload['id']
  )
rescue ResponseError => e
  logger&.error e.response.body
  error_payload = parse(e.response.body)
  Response.new(
    false,
    error_payload['message'],
    {},
    test: test?,
    error_code: error_payload['error'] || e.response.code.to_i
  )
end
commit_action_url(action, _parameters) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 284
def commit_action_url(action, _parameters)
  path = case action
  when 'webhook' then '/webhook/v3/config'
  when 'secret' then '/webhook/v3/secret'
  else
    "/pay/v3/#{action}"
  end
  action_url(path)
end
parse(body) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 237
def parse(body)
  JSON.parse(body)
rescue StandardError
  {}
end
post_data(_action, parameters = {}) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 280
def post_data(_action, parameters = {})
  { merchantId: options[:merchant_id] }.merge(parameters).to_json
end
response_status(action, payload) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 268
def response_status(action, payload)
  case action
  when 'process' then authorization_from(payload).present?
  else
    true
  end
end
token_from(payment) click to toggle source
# File lib/active_merchant/billing/gateways/nexio.rb, line 199
def token_from(payment)
  return { token: payment } if payment.is_a?(String)

  {
    token: payment.gateway_payment_profile_id,
    lastFour: payment.last_digits,
    cardType: payment.brand
  }
end