class ActiveMerchant::Billing::PlexoGateway

Constants

AMOUNT_IN_RESPONSE
APPENDED_URLS
APPROVED_STATUS

Public Class Methods

new(options = {}) click to toggle source
Calls superclass method ActiveMerchant::Billing::Gateway::new
# File lib/active_merchant/billing/gateways/plexo.rb, line 18
def initialize(options = {})
  requires!(options, :client_id, :api_key)
  @credentials = options
  super
end

Public Instance Methods

authorize(money, payment, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 31
def authorize(money, payment, options = {})
  post = {}
  build_auth_purchase_request(money, post, payment, options)
  add_capture_type(post, options)

  commit('authonly', post, options)
end
capture(money, authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 39
def capture(money, authorization, options = {})
  post = {}
  post[:ReferenceId] = options[:reference_id] || generate_unique_id
  post[:Amount] = amount(money)

  commit("/#{authorization}/captures", post, options)
end
purchase(money, payment, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 24
def purchase(money, payment, options = {})
  post = {}
  build_auth_purchase_request(money, post, payment, options)

  commit('purchase', post, options)
end
refund(money, authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 47
def refund(money, authorization, options = {})
  post = {}
  post[:ReferenceId] = options[:reference_id] || generate_unique_id
  post[:Type] = options[:refund_type] || 'refund'
  post[:Description] = options[:description]
  post[:Reason] = options[:reason]
  post[:Amount] = amount(money)

  commit("/#{authorization}/refunds", post, options)
end
scrub(transcript) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 89
def scrub(transcript)
  transcript.
    gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]').
    gsub(%r(("Number\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]').
    gsub(%r(("Cvc\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]').
    gsub(%r(("InvoiceNumber\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]').
    gsub(%r(("MerchantId\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]').
    gsub(%r(("Cryptogram\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]')
end
supports_scrubbing?() click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 85
def supports_scrubbing?
  true
end
verify(credit_card, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 67
def verify(credit_card, options = {})
  post = {}
  post[:ReferenceId] = options[:reference_id] || generate_unique_id
  post[:Flow] = 'direct'
  post[:MerchantId] = options[:merchant_id] || @credentials[:merchant_id]
  post[:StatementDescriptor] = options[:statement_descriptor] if options[:statement_descriptor]
  post[:CustomerId] = options[:customer_id] if options[:customer_id]
  money = options[:verify_amount].to_i || 100

  add_payment_method(post, credit_card, options)
  add_metadata(post, options[:metadata])
  add_amount(money, post, options)
  add_browser_details(post, options)
  add_invoice_number(post, options)

  commit('/verify', post, options)
end
void(authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 58
def void(authorization, options = {})
  post = {}
  post[:ReferenceId] = options[:reference_id] || generate_unique_id
  post[:Description] = options[:description]
  post[:Reason] = options[:reason]

  commit("/#{authorization}/cancellations", post, options)
end

Private Instance Methods

add_amount(money, post, amount_options) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 158
def add_amount(money, post, amount_options)
  post[:Amount] = {}

  post[:Amount][:Currency] = amount_options[:currency] || self.default_currency
  post[:Amount][:Total] = amount(money)
  post[:Amount][:Details] = {}
  add_amount_details(post[:Amount][:Details], amount_options[:amount_details]) if amount_options[:amount_details]
end
add_amount_details(amount_details, options) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 167
def add_amount_details(amount_details, options)
  return unless options

  amount_details[:TaxedAmount] = options[:taxed_amount] if options[:taxed_amount]
  amount_details[:TipAmount] = options[:tip_amount] if options[:tip_amount]
  amount_details[:DiscountAmount] = options[:discount_amount] if options[:discount_amount]
  amount_details[:TaxableAmount] = options[:taxable_amount] if options[:taxable_amount]
  add_tax(amount_details, options[:tax])
end
add_billing_address(cardholder, options) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 259
def add_billing_address(cardholder, options)
  return unless address = options[:billing_address]

  cardholder[:BillingAddress] = {}
  cardholder[:BillingAddress][:City] = address[:city]
  cardholder[:BillingAddress][:Country] = address[:country]
  cardholder[:BillingAddress][:Line1] = address[:address1]
  cardholder[:BillingAddress][:Line2] = address[:address2]
  cardholder[:BillingAddress][:PostalCode] = address[:zip]
  cardholder[:BillingAddress][:State] = address[:state]
end
add_browser_details(post, browser_details) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 186
def add_browser_details(post, browser_details)
  return unless browser_details

  post[:BrowserDetails] = {}
  post[:BrowserDetails][:DeviceFingerprint] = browser_details[:finger_print] if browser_details[:finger_print]
  post[:BrowserDetails][:IpAddress] = browser_details[:ip] if browser_details[:ip]
end
add_capture_type(post, options) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 128
def add_capture_type(post, options)
  post[:Capture] = {}
  post[:Capture][:Method] = options.dig(:capture_type, :method) || 'manual'
end
add_card_holder(card, payment, options) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 243
def add_card_holder(card, payment, options)
  requires!(options, :email)

  cardholder = {}
  cardholder[:FirstName] = payment.first_name if payment.first_name
  cardholder[:LastName] = payment.last_name if payment.last_name
  cardholder[:Email] = options[:email]
  cardholder[:Birthdate] = options[:cardholder_birthdate] if options[:cardholder_birthdate]
  cardholder[:Identification] = {}
  cardholder[:Identification][:Type] = options[:identification_type] if options[:identification_type]
  cardholder[:Identification][:Value] = options[:identification_value] if options[:identification_value]
  add_billing_address(cardholder, options)

  card[:Cardholder] = cardholder
end
add_invoice_number(post, options) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 194
def add_invoice_number(post, options)
  post[:InvoiceNumber] = options[:invoice_number] if options[:invoice_number]
end
add_items(post, items) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 133
def add_items(post, items)
  return unless items&.kind_of?(Array)

  post[:Items] = []

  items.each do |option_item|
    item = {}
    item[:ReferenceId] = option_item[:reference_id] || generate_unique_id
    item[:Name] = option_item[:name] if option_item[:name]
    item[:Description] = option_item[:description] if option_item[:description]
    item[:Quantity] = option_item[:quantity] if option_item[:quantity]
    item[:Price] = option_item[:price] if option_item[:price]
    item[:Discount] = option_item[:discount] if option_item[:discount]

    post[:Items].append(item)
  end
end
add_metadata(post, metadata) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 151
def add_metadata(post, metadata)
  return unless metadata&.kind_of?(Hash)

  metadata.transform_keys! { |key| key.to_s.camelize.to_sym }
  post[:Metadata] = metadata
end
add_payment_method(post, payment, options) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 198
def add_payment_method(post, payment, options)
  payment_method = build_payment_method(payment)

  if payment_method.present?
    add_card_holder(payment_method[:NetworkToken] || payment_method[:Card], payment, options)
    post[:paymentMethod] = payment_method
  end
end
add_tax(post, tax) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 177
def add_tax(post, tax)
  return unless tax

  post[:Tax] = {}
  post[:Tax][:Type] = tax[:type] if tax[:type]
  post[:Tax][:Amount] = tax[:amount] if tax[:amount]
  post[:Tax][:Rate] = tax[:rate] if tax[:rate]
end
authorization_from(response, action = nil) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 331
def authorization_from(response, action = nil)
  if action.include?('captures')
    get_authorization_from_url(action)
  else
    response['id']
  end
end
build_auth_purchase_request(money, post, payment, options) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 105
def build_auth_purchase_request(money, post, payment, options)
  post[:ReferenceId] = options[:reference_id] || generate_unique_id
  post[:MerchantId] = options[:merchant_id] || @credentials[:merchant_id]
  post[:Installments] = options[:installments] if options[:installments]
  post[:StatementDescriptor] = options[:statement_descriptor] if options[:statement_descriptor]
  post[:CustomerId] = options[:customer_id] if options[:customer_id]
  post[:Flow] = 'direct'

  add_payment_method(post, payment, options)
  add_items(post, options[:items])
  add_metadata(post, options[:metadata])
  add_amount(money, post, options)
  add_browser_details(post, options)
  add_invoice_number(post, options)
end
build_payment_method(payment) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 207
def build_payment_method(payment)
  case payment
  when NetworkTokenizationCreditCard
    {
      source: 'network-token',
      id: payment.brand,
      NetworkToken: {
        Number: payment.number,
        Bin: get_last_eight_digits(payment.number),
        Last4: get_last_four_digits(payment.number),
        ExpMonth: (format(payment.month, :two_digits) if payment.month),
        ExpYear: (format(payment.year, :two_digits) if payment.year),
        Cryptogram: payment.payment_cryptogram
      }
    }
  when CreditCard
    {
      type: 'card',
      Card: {
        Number: payment.number,
        ExpMonth: (format(payment.month, :two_digits) if payment.month),
        ExpYear: (format(payment.year, :two_digits) if payment.year),
        Cvc: payment.verification_value
      }
    }
  end
end
build_url(action, base) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 277
def build_url(action, base)
  url = base
  url += action if APPENDED_URLS.any? { |key| action.include?(key) }
  url
end
commit(action, parameters, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 297
def commit(action, parameters, options = {})
  base_url = (test? ? test_url : live_url)
  url = build_url(action, base_url)
  response = parse(ssl_post(url, parameters.to_json, header(options)))
  response = reorder_amount_fields(response) if AMOUNT_IN_RESPONSE.include?(action)

  Response.new(
    success_from(response),
    message_from(response),
    response,
    authorization: authorization_from(response, action),
    test: test?,
    error_code: error_code_from(response)
  )
end
encoded_credentials() click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 101
def encoded_credentials
  Base64.encode64("#{@credentials[:client_id]}:#{@credentials[:api_key]}").delete("\n")
end
error_code_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 339
def error_code_from(response)
  return if success_from(response)

  response = response['transactions']&.first if response['transactions']&.is_a?(Array)
  response['resultCode'] || response['status']
end
get_authorization_from_url(url) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 283
def get_authorization_from_url(url)
  url.split('/')[1]
end
get_last_eight_digits(number) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 235
def get_last_eight_digits(number)
  number[-8..-1]
end
get_last_four_digits(number) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 239
def get_last_four_digits(number)
  number[-4..-1]
end
handle_response(response) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 313
def handle_response(response)
  case response.code.to_i
  when 200...300, 400, 401
    response.body
  else
    raise ResponseError.new(response)
  end
end
header(parameters = {}) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 121
def header(parameters = {})
  {
    'Content-Type' => 'application/json',
    'Authorization' => "Basic #{encoded_credentials}"
  }
end
message_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 326
def message_from(response)
  response = response['transactions']&.first if response['transactions']&.is_a?(Array)
  response['resultMessage'] || response['message']
end
parse(body) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 271
def parse(body)
  return {} if body == ''

  JSON.parse(body)
end
reorder_amount_fields(response) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 287
def reorder_amount_fields(response)
  return response unless response['amount']

  amount_obj = response['amount']
  response['amount'] = amount_obj['total'].to_i if amount_obj['total']
  response['currency'] = amount_obj['currency'] if amount_obj['currency']
  response['amount_details'] = amount_obj['details'] if amount_obj['details']
  response
end
success_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/plexo.rb, line 322
def success_from(response)
  APPROVED_STATUS.include?(response['status'])
end