class ActiveMerchant::Billing::PriorityGateway

Public Class Methods

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

Public Instance Methods

authorize(amount, credit_card, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 64
def authorize(amount, credit_card, options = {})
  params = {}
  params['authOnly'] = true
  params['isSettleFunds'] = false

  add_merchant_id(params)
  add_amount(params, amount, options)
  add_auth_purchase_params(params, options)
  add_credit_card(params, credit_card, 'purchase', options)

  commit('purchase', params: params)
end
basic_auth() click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 34
def basic_auth
  Base64.strict_encode64("#{@options[:api_key]}:#{@options[:secret]}")
end
capture(amount, authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 100
def capture(amount, authorization, options = {})
  params = {}
  add_merchant_id(params)
  add_amount(params, amount, options)
  params['paymentToken'] = payment_token(authorization) || options[:payment_token]
  add_auth_purchase_params(params, options)

  commit('capture', params: params)
end
close_batch(batch_id) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 126
def close_batch(batch_id)
  commit('close_batch', params: batch_id)
end
create_jwt() click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 130
def create_jwt
  commit('create_jwt', params: @options[:merchant_id])
end
credit(amount, credit_card, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 77
def credit(amount, credit_card, options = {})
  params = {}
  params['authOnly'] = false
  params['isSettleFunds'] = true
  amount = -amount

  add_merchant_id(params)
  add_amount(params, amount, options)
  add_credit_params(params, credit_card, options)
  commit('credit', params: params)
end
get_payment_status(batch_id) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 122
def get_payment_status(batch_id)
  commit('get_payment_status', params: batch_id)
end
purchase(amount, credit_card, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 51
def purchase(amount, credit_card, options = {})
  params = {}
  params['authOnly'] = false
  params['isSettleFunds'] = true

  add_merchant_id(params)
  add_amount(params, amount, options)
  add_auth_purchase_params(params, options)
  add_credit_card(params, credit_card, 'purchase', options)

  commit('purchase', params: params)
end
refund(amount, authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 89
def refund(amount, authorization, options = {})
  params = {}
  add_merchant_id(params)
  params['paymentToken'] = payment_token(authorization) || options[:payment_token]

  # refund amounts must be negative
  params['amount'] = ('-' + localized_amount(amount.to_f, options[:currency])).to_f

  commit('refund', params: params)
end
request_headers() click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 38
def request_headers
  {
    'Content-Type' => 'application/json',
    'Authorization' => "Basic #{basic_auth}"
  }
end
request_verify_headers(jwt) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 45
def request_verify_headers(jwt)
  {
    'Authorization' => "Bearer #{jwt}"
  }
end
scrub(transcript) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 138
def scrub(transcript)
  transcript.
    gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]').
    gsub(%r((number\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]').
    gsub(%r((cvv\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]')
end
supports_scrubbing?() click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 134
def supports_scrubbing?
  true
end
verify(credit_card, _options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 116
def verify(credit_card, _options = {})
  jwt = create_jwt.params['jwtToken']

  commit('verify', card_number: credit_card.number, jwt: jwt)
end
void(authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 110
def void(authorization, options = {})
  params = {}

  commit('void', params: params, iid: payment_id(authorization))
end

Private Instance Methods

add_additional_data(params, options) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 193
def add_additional_data(params, options)
  params['isAuth'] = options[:is_auth].present? ? options[:is_auth] : 'true'
  params['paymentType'] = options[:payment_type].present? ? options[:payment_type] : 'Sale'
  params['tenderType'] = options[:tender_type].present? ? options[:tender_type] : 'Card'
  params['taxExempt'] = options[:tax_exempt].present? ? options[:tax_exempt] : 'false'
  params['taxAmount'] = options[:tax_amount] if options[:tax_amount]
  params['shouldGetCreditCardLevel'] = options[:should_get_credit_card_level] if options[:should_get_credit_card_level]
  params['source'] = options[:source] if options[:source]
  params['invoice'] = options[:invoice] if options[:invoice]
  params['isTicket'] = options[:is_ticket] if options[:is_ticket]
  params['shouldVaultCard'] = options[:should_vault_card] if options[:should_vault_card]
  params['sourceZip'] = options[:source_zip] if options[:source_zip]
  params['authCode'] = options[:auth_code] if options[:auth_code]
  params['achIndicator'] = options[:ach_indicator] if options[:ach_indicator]
  params['bankAccount'] = options[:bank_account] if options[:bank_account]
  params['meta'] = options[:meta] if options[:meta]
end
add_amount(params, amount, options) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 147
def add_amount(params, amount, options)
  params['amount'] = localized_amount(amount.to_f, options[:currency])
end
add_auth_purchase_params(params, options) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 155
def add_auth_purchase_params(params, options)
  add_replay_id(params, options)
  add_purchases_data(params, options)
  add_shipping_data(params, options)
  add_pos_data(params, options)
  add_additional_data(params, options)
end
add_credit_card(params, credit_card, action, options) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 173
def add_credit_card(params, credit_card, action, options)
  return unless credit_card&.is_a?(CreditCard)

  card_details = {}
  card_details['expiryMonth'] = format(credit_card.month, :two_digits).to_s
  card_details['expiryYear'] = format(credit_card.year, :two_digits).to_s
  card_details['cardType'] = credit_card.brand
  card_details['last4'] = credit_card.last_digits
  card_details['cvv'] = credit_card.verification_value unless credit_card.verification_value.nil?
  card_details['number'] = credit_card.number
  card_details['avsStreet'] = options[:billing_address][:address1] if options[:billing_address]
  card_details['avsZip'] =  options[:billing_address][:zip] if !options[:billing_address].nil? && !options[:billing_address][:zip].nil?

  params['cardAccount'] = card_details
end
add_credit_params(params, credit_card, options) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 163
def add_credit_params(params, credit_card, options)
  add_replay_id(params, options)
  add_credit_card(params, credit_card, 'purchase', options)
  add_additional_data(params, options)
end
add_merchant_id(params) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 151
def add_merchant_id(params)
  params['merchantId'] = @options[:merchant_id]
end
add_pos_data(params, options) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 211
def add_pos_data(params, options)
  pos_data = {}
  pos_data['cardholderPresence'] = options.dig(:pos_data, :cardholder_presence) || 'Ecom'
  pos_data['deviceAttendance'] = options.dig(:pos_data, :device_attendance) || 'HomePc'
  pos_data['deviceInputCapability'] = options.dig(:pos_data, :device_input_capability) || 'Unknown'
  pos_data['deviceLocation'] = options.dig(:pos_data, :device_location) || 'HomePc'
  pos_data['panCaptureMethod'] = options.dig(:pos_data, :pan_capture_method) || 'Manual'
  pos_data['partialApprovalSupport'] = options.dig(:pos_data, :partial_approval_support) || 'NotSupported'
  pos_data['pinCaptureCapability'] = options.dig(:pos_data, :pin_capture_capability) || 'Incapable'

  params['posData'] = pos_data
end
add_purchases_data(params, options) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 224
def add_purchases_data(params, options)
  return unless options[:purchases]

  params['purchases'] = []

  options[:purchases].each do |purchase|
    purchase_object = {}

    purchase_object['name'] = purchase[:name] if purchase[:name]
    purchase_object['description'] = purchase[:description] if purchase[:description]
    purchase_object['code'] = purchase[:code] if purchase[:code]
    purchase_object['unitOfMeasure'] = purchase[:unit_of_measure] if purchase[:unit_of_measure]
    purchase_object['unitPrice'] = purchase[:unit_price] if purchase[:unit_price]
    purchase_object['quantity'] = purchase[:quantity] if purchase[:quantity]
    purchase_object['taxRate'] = purchase[:tax_rate] if purchase[:tax_rate]
    purchase_object['taxAmount'] = purchase[:tax_amount] if purchase[:tax_amount]
    purchase_object['discountRate'] = purchase[:discount_rate] if purchase[:discount_rate]
    purchase_object['discountAmount'] = purchase[:discount_amount] if purchase[:discount_amount]
    purchase_object['extendedAmount'] = purchase[:extended_amount] if purchase[:extended_amount]
    purchase_object['lineItemId'] = purchase[:line_item_id] if purchase[:line_item_id]

    params['purchases'].append(purchase_object)
  end
end
add_replay_id(params, options) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 169
def add_replay_id(params, options)
  params['replayId'] = options[:replay_id] if options[:replay_id]
end
add_shipping_data(params, options) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 249
def add_shipping_data(params, options)
  params['shipAmount'] = options[:ship_amount] if options[:ship_amount]

  shipping_country = shipping_country_from(options)
  params['shipToCountry'] = shipping_country if shipping_country

  shipping_zip = shipping_zip_from(options)
  params['shipToZip'] = shipping_zip if shipping_zip
end
authorization_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 380
def authorization_from(response)
  [response['id'], response['paymentToken']].join('|')
end
base_url() click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 328
def base_url
  test? ? test_url : live_url
end
batch_url() click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 340
def batch_url
  test? ? self.test_url_batch : self.live_url_batch
end
commit(action, params: '', iid: '', card_number: nil, jwt: '') click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 281
def commit(action, params: '', iid: '', card_number: nil, jwt: '')
  response =
    begin
      case action
      when 'void'
        parse(ssl_request(:delete, url(action, params, ref_number: iid), nil, request_headers))
      when 'verify'
        parse(ssl_get(url(action, params, credit_card_number: card_number), request_verify_headers(jwt)))
      when 'get_payment_status', 'create_jwt'
        parse(ssl_get(url(action, params, ref_number: iid), request_headers))
      when 'close_batch'
        parse(ssl_request(:put, url(action, params, ref_number: iid), nil, request_headers))
      else
        parse(ssl_post(url(action, params), post_data(params), request_headers))
      end
    rescue ResponseError => e
      # currently Priority returns a 404 with no body on certain calls. In those cases we will substitute the response status from response.message
      gateway_response = e.response.body.presence || e.response.message
      parse(gateway_response)
    end

  success = success_from(response, action)
  Response.new(
    success,
    message_from(response),
    response,
    authorization: success ? authorization_from(response) : nil,
    error_code: success || response == '' ? nil : error_from(response),
    test: test?
  )
end
error_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 384
def error_from(response)
  response['errorCode'] || response['status']
end
exp_date(credit_card) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 189
def exp_date(credit_card)
  "#{format(credit_card.month, :two_digits)}/#{format(credit_card.year, :two_digits)}"
end
handle_response(response) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 344
def handle_response(response)
  case response.code.to_i
  when 204
    { status: 'Success' }.to_json
  when 200...300
    response.body
  else
    raise ResponseError.new(response)
  end
end
jwt_url() click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 336
def jwt_url
  test? ? self.test_url_jwt : self.live_url_jwt
end
message_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 374
def message_from(response)
  return response['details'][0] if response['details'] && response['details'][0]

  response['authMessage'] || response['message'] || response['status']
end
parse(body) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 355
def parse(body)
  return {} if body.blank?

  parsed_response = JSON.parse(body)
  parsed_response.is_a?(String) ? { 'message' => parsed_response } : parsed_response
rescue JSON::ParserError
  message = 'Invalid JSON response received from Priority Gateway. Please contact Priority Gateway if you continue to receive this message.'
  message += " (The raw response returned by the API was #{body.inspect})"
  {
    'message' => message
  }
end
payment_id(authorization) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 274
def payment_id(authorization)
  return unless authorization
  return authorization unless authorization.include?('|')

  authorization.split('|').first
end
payment_token(authorization) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 267
def payment_token(authorization)
  return unless authorization
  return authorization unless authorization.include?('|')

  authorization.split('|').last
end
post_data(params) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 388
def post_data(params)
  params.to_json
end
shipping_country_from(options) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 259
def shipping_country_from(options)
  options[:ship_to_country] || options.dig(:shipping_address, :country) || options.dig(:billing_address, :country)
end
shipping_zip_from(options) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 263
def shipping_zip_from(options)
  options[:ship_to_zip] || options.dig(:shipping_addres, :zip) || options.dig(:billing_address, :zip)
end
success_from(response, action) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 368
def success_from(response, action)
  return !response['bank'].empty? if action == 'verify' && response['bank']

  %w[Approved Open Success Settled Voided].include?(response['status'])
end
url(action, params, ref_number: '', credit_card_number: nil) click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 313
def url(action, params, ref_number: '', credit_card_number: nil)
  case action
  when 'void'
    base_url + "/#{ref_number}?force=true"
  when 'verify'
    (verify_url + '?search=') + credit_card_number.to_s[0..6]
  when 'get_payment_status', 'close_batch'
    batch_url + "/#{params}"
  when 'create_jwt'
    jwt_url + "/#{params}/token"
  else
    base_url + '?includeCustomerMatches=false&echo=true'
  end
end
verify_url() click to toggle source
# File lib/active_merchant/billing/gateways/priority.rb, line 332
def verify_url
  test? ? self.test_url_verify : self.live_url_verify
end