class ActiveMerchant::Billing::OrbitalGateway

For more information on Orbital, visit the integration center

Authentication Options

The Orbital Gateway supports two methods of authenticating incoming requests: Source IP authentication and Connection Username/Password authentication

In addition, these IP addresses/Connection Usernames must be affiliated with the Merchant IDs for which the client should be submitting transactions.

This does allow Third Party Hosting service organizations presenting on behalf of other merchants to submit transactions. However, each time a new customer is added, the merchant or Third-Party hosting organization needs to ensure that the new Merchant IDs or Chain IDs are affiliated with the hosting companies IPs or Connection Usernames.

If the merchant expects to have more than one merchant account with the Orbital Gateway, it should have its IP addresses/Connection Usernames affiliated at the Chain level hierarchy within the Orbital Gateway. Each time a new merchant ID is added, as long as it is placed within the same Chain, it will simply work. Otherwise, the additional MIDs will need to be affiliated with the merchant IPs or Connection Usernames respectively. For example, we generally affiliate all Salem accounts [BIN 000001] with their Company Number [formerly called MA #] number so all MIDs or Divisions under that Company will automatically be affiliated.

Constants

ACCOUNT_TYPE

Bank account types to be used for check processing

ACTIVE

Status Profile Status Flag This field is used to set the status of a Customer Profile.

API_VERSION
APPROVAL_SUCCESS
APPROVED
AUTH_AND_CAPTURE

AC - Auth and Capture = ‘AC’

AUTH_ONLY

Auth Only No Capture

AUTO_GENERATE
CustomerProfileFromOrderInd

Method to use to Generate the Customer Profile Number When Customer Profile Action Type = Create, defines what the Customer Profile Number will be:

AVS_SUPPORTED_COUNTRIES
CREATE

Customer Profile Actions

CURRENCY_CODES
CURRENCY_EXPONENTS
DEFERRED
DELETE
ECOMMERCE_TRANSACTION

INDUSTRY TYPES

FORCE_AUTH_AND_CAPTURE

FR - Force Auth No Capture and no online authorization = ‘FR’ FC - Force Auth and Capture no online authorization = ‘FC’

FORCE_AUTH_ONLY

F - Force Auth No Capture and no online authorization = ‘F’

GET_TOKEN

safetech token flags

INACTIVE
INTERACTIVE_VOICE_RESPONSE
MAIL_ORDER_TELEPHONE_ORDER_TRANSACTION
MANUAL_SUSPEND
NON_TAXABLE_TRANSACTION
NO_MAPPING_TO_ORDER_DATA

CustomerProfileOrderOverrideInd Defines if any Order Data can be pre-populated from the Customer Reference Number (CustomerRefNum)

POST_HEADERS
RECURRING
RECURRING_PAYMENT_TRANSACTION
REFUND

Refund and Capture no online authorization

RETRIEVE
SENSITIVE_FIELDS
SUCCESS
TAX_INCLUDED
TAX_NOT_PROVIDED

Tax Inds

UPDATE
USE_COMMENTS
USE_CRN_FOR_COMMENTS
USE_CRN_FOR_ORDER_ID
USE_CRN_FOR_ORDER_ID_AND_COMMENTS
USE_CUSTOMER_REF_NUM
USE_ORDER_ID
USE_TOKEN

Public Class Methods

new(options = {}) click to toggle source
Calls superclass method ActiveMerchant::Billing::Gateway::new
# File lib/active_merchant/billing/gateways/orbital.rb, line 200
def initialize(options = {})
  requires!(options, :merchant_id)
  requires!(options, :login, :password) unless options[:ip_authentication]
  super
  @options[:merchant_id] = @options[:merchant_id].to_s
  @use_secondary_url = false
end

Public Instance Methods

add_customer_profile(credit_card, options = {}) click to toggle source

Customer Profiles

:customer_ref_num should be set unless you’re happy with Orbital providing one

:customer_profile_order_override_ind can be set to map the CustomerRefNum to OrderID or Comments. Defaults to ‘NO’ - no mapping

'NO' - No mapping to order data
'OI' - Use <CustomerRefNum> for <OrderID>
'OD' - Use <CustomerRefNum> for <Comments>
'OA' - Use <CustomerRefNum> for <OrderID> and <Comments>

:order_default_description can be set optionally. 64 char max.

:order_default_amount can be set optionally. integer as cents.

:status defaults to Active

'A' - Active
'I' - Inactive
'MS'  - Manual Suspend
# File lib/active_merchant/billing/gateways/orbital.rb, line 306
def add_customer_profile(credit_card, options = {})
  options[:customer_profile_action] = CREATE
  order = build_customer_request_xml(credit_card, options)
  commit(order, :add_customer_profile)
end
allow_zero_auth?(credit_card) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 280
def allow_zero_auth?(credit_card)
  # Discover does not support a $0.00 authorization instead use $1.00
  %w(visa master american_express diners_club jcb).include?(credit_card.brand)
end
authorize(money, payment_source, options = {}) click to toggle source

A – Authorization request

# File lib/active_merchant/billing/gateways/orbital.rb, line 209
def authorize(money, payment_source, options = {})
  # ECP for Orbital requires $0 prenotes so ensure
  # if we are doing a force capture with a check, that
  # we do a purchase here
  return purchase(money, payment_source, options) if force_capture_with_echeck?(payment_source, options)

  order = build_new_auth_purchase_order(AUTH_ONLY, money, payment_source, options)

  commit(order, :authorize, options[:retry_logic], options[:trace_number])
end
capture(money, authorization, options = {}) click to toggle source

MFC - Mark For Capture

# File lib/active_merchant/billing/gateways/orbital.rb, line 237
def capture(money, authorization, options = {})
  commit(build_mark_for_capture_xml(money, authorization, options), :capture, options[:retry_logic], options[:trace_number])
end
credit(money, payment_method, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 252
def credit(money, payment_method, options = {})
  order = build_new_order_xml(REFUND, money, payment_method, options) do |xml|
    add_payment_source(xml, payment_method, options)
  end

  commit(order, :refund, options[:retry_logic], options[:trace_number])
end
default_verify_amount(credit_card) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 276
def default_verify_amount(credit_card)
  allow_zero_auth?(credit_card) ? 0 : 100
end
delete_customer_profile(customer_ref_num) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 324
def delete_customer_profile(customer_ref_num)
  options = { customer_profile_action: DELETE, customer_ref_num: customer_ref_num }
  order = build_customer_request_xml(nil, options)
  commit(order, :delete_customer_profile)
end
purchase(money, payment_source, options = {}) click to toggle source

AC – Authorization and Capture

# File lib/active_merchant/billing/gateways/orbital.rb, line 229
def purchase(money, payment_source, options = {})
  action = options[:force_capture] ? FORCE_AUTH_AND_CAPTURE : AUTH_AND_CAPTURE
  order = build_new_auth_purchase_order(action, money, payment_source, options)

  commit(order, :purchase, options[:retry_logic], options[:trace_number])
end
refund(money, authorization, options = {}) click to toggle source

R – Refund request

# File lib/active_merchant/billing/gateways/orbital.rb, line 242
def refund(money, authorization, options = {})
  payment_method = options[:payment_method]
  order = build_new_order_xml(REFUND, money, payment_method, options.merge(authorization: authorization)) do |xml|
    add_payment_source(xml, payment_method, options)
    xml.tag! :CustomerRefNum, options[:customer_ref_num] if @options[:customer_profiles] && options[:profile_txn]
  end

  commit(order, :refund, options[:retry_logic], options[:trace_number])
end
retrieve_customer_profile(customer_ref_num) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 318
def retrieve_customer_profile(customer_ref_num)
  options = { customer_profile_action: RETRIEVE, customer_ref_num: customer_ref_num }
  order = build_customer_request_xml(nil, options)
  commit(order, :retrieve_customer_profile)
end
scrub(transcript) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 338
def scrub(transcript)
  transcript.
    gsub(%r((<OrbitalConnectionUsername>).+(</OrbitalConnectionUsername>)), '\1[FILTERED]\2').
    gsub(%r((<OrbitalConnectionPassword>).+(</OrbitalConnectionPassword>)), '\1[FILTERED]\2').
    gsub(%r((<AccountNum>).+(</AccountNum>)), '\1[FILTERED]\2').
    # the response sometimes contains a new line that cuts off the end of the closing tag
    gsub(%r((<CCAccountNum>).+(</CC)), '\1[FILTERED]\2').
    gsub(%r((<CardSecVal>).+(</CardSecVal>)), '\1[FILTERED]\2').
    gsub(%r((<MerchantID>).+(</MerchantID>)), '\1[FILTERED]\2').
    gsub(%r((<CustomerMerchantID>).+(</CustomerMerchantID>)), '\1[FILTERED]\2').
    gsub(%r((<CustomerProfileMessage>).+(</CustomerProfileMessage>)), '\1[FILTERED]\2').
    gsub(%r((<CheckDDA>).+(</CheckDDA>)), '\1[FILTERED]\2').
    gsub(%r((<BCRtNum>).+(</BCRtNum>)), '\1[FILTERED]\2').
    gsub(%r((<DigitalTokenCryptogram>).+(</DigitalTokenCryptogram>)), '\1[FILTERED]\2')
end
store(creditcard, options = {}) click to toggle source

Orbital save a payment method if the TokenTxnType is ‘GT’, that’s why we use this as the default value for store

# File lib/active_merchant/billing/gateways/orbital.rb, line 261
def store(creditcard, options = {})
  authorize(0, creditcard, options.merge({ token_txn_type: GET_TOKEN }))
end
supports_network_tokenization?() click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 330
def supports_network_tokenization?
  true
end
supports_scrubbing?() click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 334
def supports_scrubbing?
  true
end
update_customer_profile(credit_card, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 312
def update_customer_profile(credit_card, options = {})
  options[:customer_profile_action] = UPDATE
  order = build_customer_request_xml(credit_card, options)
  commit(order, :update_customer_profile)
end
verify(credit_card, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 220
def verify(credit_card, options = {})
  amount = options[:verify_amount] ? options[:verify_amount].to_i : default_verify_amount(credit_card)
  MultiResponse.run(:use_first_response) do |r|
    r.process { authorize(amount, credit_card, options) }
    r.process(:ignore_result) { void(r.authorization) } unless amount == 0
  end
end
void(authorization, options = {}, deprecated = {}) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 265
def void(authorization, options = {}, deprecated = {})
  if !options.kind_of?(Hash)
    ActiveMerchant.deprecated('Calling the void method with an amount parameter is deprecated and will be removed in a future version.')
    return void(options, deprecated.merge(amount: authorization))
  end

  order = build_void_request_xml(authorization, options)

  commit(order, :void, options[:retry_logic], options[:trace_number])
end

Private Instance Methods

add_aav(xml, credit_card, three_d_secure) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 694
def add_aav(xml, credit_card, three_d_secure)
  return unless three_d_secure && credit_card.brand == 'master'

  xml.tag!(:AAV, three_d_secure[:cavv])
end
add_address(xml, payment_source, options) click to toggle source
ADDRESS FIELDS=====
# File lib/active_merchant/billing/gateways/orbital.rb, line 530
def add_address(xml, payment_source, options)
  return unless (address = get_address(options))

  if avs_supported?(address[:country]) || empty?(address[:country])
    xml.tag! :AVSzip, byte_limit(format_address_field(address[:zip]), 10)
    xml.tag! :AVSaddress1, byte_limit(format_address_field(address[:address1]), 30)
    xml.tag! :AVSaddress2, byte_limit(format_address_field(address[:address2]), 30)
    xml.tag! :AVScity, byte_limit(format_address_field(address[:city]), 20)
    xml.tag! :AVSstate, byte_limit(format_address_field(address[:state]), 2)
    xml.tag! :AVSphoneNum, (address[:phone] ? address[:phone].scan(/\d/).join.to_s[0..13] : nil)
  end

  xml.tag! :AVSname, billing_name(payment_source, options)
  xml.tag! :AVScountryCode, byte_limit(format_address_field(filter_unsupported_countries(address[:country])), 2)

  # Needs to come after AVScountryCode
  add_destination_address(xml, address) if avs_supported?(address[:country]) || empty?(address[:country])
end
add_aevv(xml, credit_card, three_d_secure) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 700
def add_aevv(xml, credit_card, three_d_secure)
  return unless three_d_secure && credit_card.brand == 'american_express'

  xml.tag!(:AEVV, three_d_secure[:cavv])
end
add_bank_account_type(xml, check) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 651
def add_bank_account_type(xml, check)
  bank_account_type =
    if check.account_holder_type == 'business'
      'X'
    else
      ACCOUNT_TYPE[check.account_type]
    end

  xml.tag! :BankAccountType, bank_account_type if bank_account_type
end
add_bin_merchant_and_terminal(xml, parameters) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 914
def add_bin_merchant_and_terminal(xml, parameters)
  xml.tag! :BIN, bin
  xml.tag! :MerchantID, @options[:merchant_id]
  xml.tag! :TerminalID, parameters[:terminal_id] || '001'
end
add_card_commodity_code(xml, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 513
def add_card_commodity_code(xml, options = {})
  if (level2 = options[:level_2_data]) && (level2[:commodity_code])
    xml.tag! :PCardCommodityCode, byte_limit(level2[:commodity_code], 4)
  end
end
add_card_indicators(xml, options) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 662
def add_card_indicators(xml, options)
  xml.tag! :CardIndicators, options[:card_indicators] if options[:card_indicators]
end
add_cavv(xml, credit_card, three_d_secure) click to toggle source
BRAND-SPECIFIC FIELDS=====
# File lib/active_merchant/billing/gateways/orbital.rb, line 688
def add_cavv(xml, credit_card, three_d_secure)
  return unless three_d_secure && credit_card.brand == 'visa'

  xml.tag!(:CAVV, three_d_secure[:cavv])
end
add_credit_card(xml, credit_card, options) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 623
def add_credit_card(xml, credit_card, options)
  xml.tag! :AccountNum, credit_card.number if credit_card.is_a?(CreditCard)
  xml.tag! :Exp, expiry_date(credit_card) if credit_card.is_a?(CreditCard)
  add_currency_fields(xml, options[:currency])
  add_verification_value(xml, credit_card) if credit_card.is_a?(CreditCard)
end
add_currency_fields(xml, currency) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 646
def add_currency_fields(xml, currency)
  xml.tag! :CurrencyCode, currency_code(currency)
  xml.tag! :CurrencyExponent, currency_exponents(currency)
end
add_customer_address(xml, options) click to toggle source

For Profile requests

# File lib/active_merchant/billing/gateways/orbital.rb, line 563
def add_customer_address(xml, options)
  return unless (address = get_address(options))

  xml.tag! :CustomerAddress1, byte_limit(format_address_field(address[:address1]), 30)
  xml.tag! :CustomerAddress2, byte_limit(format_address_field(address[:address2]), 30)
  xml.tag! :CustomerCity, byte_limit(format_address_field(address[:city]), 20)
  xml.tag! :CustomerState, byte_limit(format_address_field(address[:state]), 2)
  xml.tag! :CustomerZIP, byte_limit(format_address_field(address[:zip]), 10)
  xml.tag! :CustomerEmail, byte_limit(address[:email], 50) if address[:email]
  xml.tag! :CustomerPhone, (address[:phone] ? address[:phone].scan(/\d/).join.to_s : nil)
  xml.tag! :CustomerCountryCode, filter_unsupported_countries(address[:country])
end
add_customer_data(xml, credit_card, options) click to toggle source
REFERENCE FIELDS=====
# File lib/active_merchant/billing/gateways/orbital.rb, line 365
def add_customer_data(xml, credit_card, options)
  add_customer_ref_num(xml, options)

  return if options[:profile_txn]

  xml.tag! :CustomerProfileFromOrderInd, profile_number(options) if add_profile_number?(options, credit_card)
  xml.tag! :CustomerProfileOrderOverrideInd, options[:customer_profile_order_override_ind] || NO_MAPPING_TO_ORDER_DATA
end
add_customer_ref_num(xml, options) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 382
def add_customer_ref_num(xml, options)
  xml.tag! :CustomerRefNum, options[:customer_ref_num] if options[:customer_ref_num]
end
add_destination_address(xml, address) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 549
def add_destination_address(xml, address)
  return unless address[:dest_zip]

  xml.tag! :AVSDestzip,         byte_limit(format_address_field(address[:dest_zip]), 10)
  xml.tag! :AVSDestaddress1,    byte_limit(format_address_field(address[:dest_address1]), 30)
  xml.tag! :AVSDestaddress2,    byte_limit(format_address_field(address[:dest_address2]), 30)
  xml.tag! :AVSDestcity,        byte_limit(format_address_field(address[:dest_city]), 20)
  xml.tag! :AVSDeststate,       byte_limit(format_address_field(address[:dest_state]), 2)
  xml.tag! :AVSDestphoneNum,    (address[:dest_phone] ? address[:dest_phone].scan(/\d/).join.to_s[0..13] : nil)
  xml.tag! :AVSDestname,        byte_limit(address[:dest_name], 30)
  xml.tag! :AVSDestcountryCode, filter_unsupported_countries(address[:dest_country])
end
add_digital_token_cryptogram(xml, credit_card, three_d_secure) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 822
def add_digital_token_cryptogram(xml, credit_card, three_d_secure)
  return unless credit_card.is_a?(NetworkTokenizationCreditCard) || three_d_secure && credit_card.brand == 'discover'

  cryptogram =
    if three_d_secure && credit_card.brand == 'discover'
      three_d_secure[:cavv]
    else
      credit_card.payment_cryptogram
    end

  xml.tag!(:DigitalTokenCryptogram, cryptogram)
end
add_dpanind(xml, credit_card, industry_type = nil) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 816
def add_dpanind(xml, credit_card, industry_type = nil)
  return unless credit_card.is_a?(NetworkTokenizationCreditCard)

  xml.tag! :DPANInd, 'Y' unless industry_type == 'RC'
end
add_echeck(xml, check, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 610
def add_echeck(xml, check, options = {})
  return unless check

  xml.tag! :CardBrand, 'EC'
  add_currency_fields(xml, options[:currency])
  xml.tag! :BCRtNum, check.routing_number
  xml.tag! :CheckDDA, check.account_number if check.account_number
  add_bank_account_type(xml, check)
  xml.tag! :ECPAuthMethod, options[:auth_method] if options[:auth_method]
  xml.tag! :BankPmtDelv, options[:payment_delivery] || 'B'
  xml.tag! :AVSname, (check&.name ? check.name[0..29] : nil) if get_address(options).blank?
end
add_eci(xml, credit_card, three_d_secure) click to toggle source
NETWORK TOKENIZATION FIELDS=====
# File lib/active_merchant/billing/gateways/orbital.rb, line 806
def add_eci(xml, credit_card, three_d_secure)
  eci = if three_d_secure
          three_d_secure[:eci]
        elsif credit_card.is_a?(NetworkTokenizationCreditCard)
          credit_card.eci
        end

  xml.tag!(:AuthenticationECIInd, eci) if eci
end
add_ecp_details(xml, payment_source, parameters = {}) click to toggle source

Adds ECP conditional attributes depending on other attribute values

# File lib/active_merchant/billing/gateways/orbital.rb, line 892
def add_ecp_details(xml, payment_source, parameters = {})
  requires!(payment_source.account_number) if parameters[:auth_method]&.eql?('A') || parameters[:auth_method]&.eql?('P')
  xml.tag! :ECPActionCode, parameters[:action_code] if parameters[:action_code]
  xml.tag! :ECPCheckSerialNumber, payment_source.account_number if parameters[:auth_method]&.eql?('A') || parameters[:auth_method]&.eql?('P')
  if parameters[:auth_method]&.eql?('P')
    xml.tag! :ECPTerminalCity, parameters[:terminal_city] if parameters[:terminal_city]
    xml.tag! :ECPTerminalState, parameters[:terminal_state] if parameters[:terminal_state]
    xml.tag! :ECPImageReferenceNumber, parameters[:image_reference_number] if parameters[:image_reference_number]
  end
  if parameters[:action_code]&.eql?('W3') || parameters[:action_code]&.eql?('W5') ||
     parameters[:action_code]&.eql?('W7') || parameters[:action_code]&.eql?('W9')
    add_ews_details(xml, payment_source, parameters)
  end
end
add_ews_details(xml, payment_source, parameters = {}) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 871
def add_ews_details(xml, payment_source, parameters = {})
  split_name = payment_source.first_name.split if payment_source.first_name
  xml.tag! :EWSFirstName, split_name[0]
  xml.tag! :EWSMiddleName, split_name[1..-1].join(' ')
  xml.tag! :EWSLastName, payment_source.last_name
  xml.tag! :EWSBusinessName, parameters[:company] if payment_source.first_name.empty? && payment_source.last_name.empty?

  if (address = (parameters[:billing_address] || parameters[:address]))
    xml.tag! :EWSAddressLine1, byte_limit(format_address_field(address[:address1]), 30)
    xml.tag! :EWSAddressLine2, byte_limit(format_address_field(address[:address2]), 30)
    xml.tag! :EWSCity, byte_limit(format_address_field(address[:city]), 20)
    xml.tag! :EWSState, byte_limit(format_address_field(address[:state]), 2)
    xml.tag! :EWSZip, byte_limit(format_address_field(address[:zip]), 10)
  end

  xml.tag! :EWSPhoneType, parameters[:phone_type]
  xml.tag! :EWSPhoneNumber, parameters[:phone_number]
  xml.tag! :EWSCheckSerialNumber, payment_source.account_number unless parameters[:auth_method].eql?('I')
end
add_level2_advice_addendum(xml, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 449
def add_level2_advice_addendum(xml, options = {})
  if (level2 = options[:level_2_data])
    xml.tag! :AMEXTranAdvAddn1, byte_limit(level2[:advice_addendum_1], 40) if level2[:advice_addendum_1]
    xml.tag! :AMEXTranAdvAddn2, byte_limit(level2[:advice_addendum_2], 40) if level2[:advice_addendum_2]
    xml.tag! :AMEXTranAdvAddn3, byte_limit(level2[:advice_addendum_3], 40) if level2[:advice_addendum_3]
    xml.tag! :AMEXTranAdvAddn4, byte_limit(level2[:advice_addendum_4], 40) if level2[:advice_addendum_4]
  end
end
add_level2_card_and_more_tax(xml, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 499
def add_level2_card_and_more_tax(xml, options = {})
  if (level2 = options[:level_2_data])
    xml.tag! :PCardRequestorName, byte_limit(level2[:requestor_name], 38) if level2[:requestor_name]
    xml.tag! :PCardLocalTaxRate, byte_limit(level2[:local_tax_rate], 5) if level2[:local_tax_rate]
    # Canadian Merchants Only
    xml.tag! :PCardNationalTax, byte_limit(level2[:national_tax], 12) if level2[:national_tax]
    xml.tag! :PCardPstTaxRegNumber, byte_limit(level2[:pst_tax_reg_number], 15) if level2[:pst_tax_reg_number]
    xml.tag! :PCardCustomerVatRegNumber, byte_limit(level2[:customer_vat_reg_number], 13) if level2[:customer_vat_reg_number]
    # Canadian Merchants Only
    xml.tag! :PCardMerchantVatRegNumber, byte_limit(level2[:merchant_vat_reg_number], 20) if level2[:merchant_vat_reg_number]
    xml.tag! :PCardTotalTaxAmount, byte_limit(level2[:total_tax_amount], 12) if level2[:total_tax_amount]
  end
end
add_level2_purchase(xml, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 458
def add_level2_purchase(xml, options = {})
  if (level2 = options[:level_2_data])
    xml.tag! :PCOrderNum,       byte_limit(level2[:purchase_order], 17) if level2[:purchase_order]
    xml.tag! :PCDestZip,        byte_limit(format_address_field(level2[:zip]), 10) if level2[:zip]
    xml.tag! :PCDestName,       byte_limit(format_address_field(level2[:name]), 30) if level2[:name]
    xml.tag! :PCDestAddress1,   byte_limit(format_address_field(level2[:address1]), 30) if level2[:address1]
    xml.tag! :PCDestAddress2,   byte_limit(format_address_field(level2[:address2]), 30) if level2[:address2]
    xml.tag! :PCDestCity,       byte_limit(format_address_field(level2[:city]), 20) if level2[:city]
    xml.tag! :PCDestState,      byte_limit(format_address_field(level2[:state]), 2) if level2[:state]
  end
end
add_level2_tax(xml, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 433
def add_level2_tax(xml, options = {})
  if (level2 = options[:level_2_data])
    xml.tag! :TaxInd, level2[:tax_indicator] if [TAX_NOT_PROVIDED, TAX_INCLUDED, NON_TAXABLE_TRANSACTION].include?(level2[:tax_indicator].to_i)
    xml.tag! :Tax, level2[:tax].to_i if level2[:tax]
  end
end
add_level3_purchase(xml, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 470
def add_level3_purchase(xml, options = {})
  if (level3 = options[:level_3_data])
    xml.tag! :PC3FreightAmt,    byte_limit(level3[:freight_amount], 12) if level3[:freight_amount]
    xml.tag! :PC3DutyAmt,       byte_limit(level3[:duty_amount], 12) if level3[:duty_amount]
    xml.tag! :PC3DestCountryCd, byte_limit(level3[:dest_country], 3) if level3[:dest_country]
    xml.tag! :PC3ShipFromZip,   byte_limit(level3[:ship_from_zip], 10) if level3[:ship_from_zip]
    xml.tag! :PC3DiscAmt,       byte_limit(level3[:discount_amount], 12) if level3[:discount_amount]
  end
end
add_level3_tax(xml, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 440
def add_level3_tax(xml, options = {})
  if (level3 = options[:level_3_data])
    xml.tag! :PC3VATtaxAmt, byte_limit(level3[:vat_tax], 12) if level3[:vat_tax]
    xml.tag! :PC3VATtaxRate, byte_limit(level3[:vat_rate], 4) if level3[:vat_rate]
    xml.tag! :PC3AltTaxInd, byte_limit(level3[:alt_ind], 15) if level3[:alt_ind]
    xml.tag! :PC3AltTaxAmt, byte_limit(level3[:alt_tax], 9) if level3[:alt_tax]
  end
end
add_level3_vat_fields(xml, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 519
def add_level3_vat_fields(xml, options = {})
  if (level3 = options[:level_3_data])
    xml.tag! :PC3InvoiceDiscTreatment, byte_limit(level3[:invoice_discount_treatment], 1) if level3[:invoice_discount_treatment]
    xml.tag! :PC3TaxTreatment, byte_limit(level3[:tax_treatment], 1) if level3[:tax_treatment]
    xml.tag! :PC3UniqueVATInvoiceRefNum, byte_limit(level3[:unique_vat_invoice_ref], 15) if level3[:unique_vat_invoice_ref]
    xml.tag! :PC3ShipVATRate, byte_limit(level3[:ship_vat_rate], 4) if level3[:ship_vat_rate]
  end
end
add_line_items(xml, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 480
def add_line_items(xml, options = {})
  xml.tag! :PC3LineItemCount, byte_limit(options[:line_items].count, 2)
  xml.tag! :PC3LineItemArray do
    options[:line_items].each_with_index do |line_item, index|
      xml.tag! :PC3LineItem do
        xml.tag! :PC3DtlIndex,  byte_limit(index + 1, 2)
        line_item.each do |key, value|
          if [:line_tot, 'line_tot'].include? key
            formatted_key = :PC3Dtllinetot
          else
            formatted_key = "PC3Dtl#{key.to_s.camelize}".to_sym
          end
          xml.tag! formatted_key, value
        end
      end
    end
  end
end
add_managed_billing(xml, options) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 847
def add_managed_billing(xml, options)
  return unless mb = options[:managed_billing]

  ActiveMerchant.deprecated RECURRING_DEPRECATION_MESSAGE

  # default to recurring (R).  Other option is deferred (D).
  xml.tag! :MBType, mb[:type] || RECURRING
  # default to Customer Reference Number
  xml.tag! :MBOrderIdGenerationMethod,     mb[:order_id_generation_method] || 'IO'
  # By default use MBRecurringEndDate, set to N.
  # MMDDYYYY
  xml.tag! :MBRecurringStartDate,          mb[:start_date].scan(/\d/).join.to_s if mb[:start_date]
  # MMDDYYYY
  xml.tag! :MBRecurringEndDate,            mb[:end_date].scan(/\d/).join.to_s if mb[:end_date]
  # By default listen to any value set in MBRecurringEndDate.
  xml.tag! :MBRecurringNoEndDateFlag,      mb[:no_end_date_flag] || 'N' # 'Y' || 'N' (Yes or No).
  xml.tag! :MBRecurringMaxBillings,        mb[:max_billings]       if mb[:max_billings]
  xml.tag! :MBRecurringFrequency,          mb[:frequency]          if mb[:frequency]
  xml.tag! :MBDeferredBillDate,            mb[:deferred_bill_date] if mb[:deferred_bill_date]
  xml.tag! :MBMicroPaymentMaxDollarValue,  mb[:max_dollar_value]   if mb[:max_dollar_value]
  xml.tag! :MBMicroPaymentMaxBillingDays,  mb[:max_billing_days]   if mb[:max_billing_days]
  xml.tag! :MBMicroPaymentMaxTransactions, mb[:max_transactions]   if mb[:max_transactions]
end
add_mastercard_fields(xml, credit_card, parameters, three_d_secure) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 722
def add_mastercard_fields(xml, credit_card, parameters, three_d_secure)
  add_mc_sca_merchant_initiated(xml, credit_card, parameters, three_d_secure)
  add_mc_sca_recurring(xml, credit_card, parameters, three_d_secure)
  add_mc_program_protocol(xml, credit_card, three_d_secure)
  add_mc_directory_trans_id(xml, credit_card, three_d_secure)
  add_mc_ucafind(xml, credit_card, three_d_secure, parameters)
end
add_mc_directory_trans_id(xml, credit_card, three_d_secure) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 750
def add_mc_directory_trans_id(xml, credit_card, three_d_secure)
  return unless three_d_secure

  xml.tag!(:MCDirectoryTransID, three_d_secure[:ds_transaction_id]) if three_d_secure[:ds_transaction_id]
end
add_mc_program_protocol(xml, credit_card, three_d_secure) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 744
def add_mc_program_protocol(xml, credit_card, three_d_secure)
  return unless version = three_d_secure.try(:[], :version)

  xml.tag!(:MCProgramProtocol, version.to_s[0])
end
add_mc_sca_merchant_initiated(xml, credit_card, parameters, three_d_secure) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 730
def add_mc_sca_merchant_initiated(xml, credit_card, parameters, three_d_secure)
  return unless parameters.try(:[], :sca_merchant_initiated)
  return unless three_d_secure.try(:[], :eci) == '7'

  xml.tag!(:SCAMerchantInitiatedTransaction, parameters[:sca_merchant_initiated])
end
add_mc_sca_recurring(xml, credit_card, parameters, three_d_secure) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 737
def add_mc_sca_recurring(xml, credit_card, parameters, three_d_secure)
  return unless parameters.try(:[], :sca_recurring)
  return unless three_d_secure.try(:[], :eci) == '7'

  xml.tag!(:SCARecurringPayment, parameters[:sca_recurring])
end
add_mc_ucafind(xml, credit_card, three_d_secure, options) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 756
def add_mc_ucafind(xml, credit_card, three_d_secure, options)
  return unless three_d_secure

  if options[:alternate_ucaf_flow]
    return unless %w(4 6 7).include?(three_d_secure[:eci])

    xml.tag! :UCAFInd, options[:ucaf_collection_indicator] if options[:ucaf_collection_indicator]
  else
    xml.tag! :UCAFInd, options[:ucaf_collection_indicator] || '4'
  end
end
add_payment_action_ind(xml, payment_action_ind) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 409
def add_payment_action_ind(xml, payment_action_ind)
  return unless payment_action_ind

  xml.tag! :PaymentActionInd, payment_action_ind
end
add_payment_source(xml, payment_source, options = {}) click to toggle source

Payment can be done through either Credit Card or Electronic Check

# File lib/active_merchant/billing/gateways/orbital.rb, line 605
def add_payment_source(xml, payment_source, options = {})
  add_safetech_token_data(xml, payment_source, options) if payment_source.is_a?(String)
  payment_source.is_a?(Check) ? add_echeck(xml, payment_source, options) : add_credit_card(xml, payment_source, options)
end
add_profile_number?(options, credit_card) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 374
def add_profile_number?(options, credit_card)
  return true unless options[:customer_ref_num] && credit_card.nil?
end
add_pymt_brand_program_code(xml, credit_card, three_d_secure) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 712
def add_pymt_brand_program_code(xml, credit_card, three_d_secure)
  return unless three_d_secure && credit_card.brand == 'american_express'

  xml.tag!(:PymtBrandProgramCode, 'ASK')
end
add_safetech_token_data(xml, payment_source, options) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 596
def add_safetech_token_data(xml, payment_source, options)
  payment_source_token = split_authorization(payment_source).values_at(2).first
  xml.tag! :CardBrand, options[:card_brand]
  xml.tag! :AccountNum, payment_source_token
end
add_soft_descriptors(xml, descriptors) click to toggle source
DESCRIPTOR FIELDS=====
# File lib/active_merchant/billing/gateways/orbital.rb, line 402
def add_soft_descriptors(xml, descriptors)
  return unless descriptors

  add_soft_descriptors_from_specialized_class(xml, descriptors) if descriptors.is_a?(OrbitalSoftDescriptors)
  add_soft_descriptors_from_hash(xml, descriptors) if descriptors.is_a?(Hash)
end
add_soft_descriptors_from_hash(xml, soft_desc) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 424
def add_soft_descriptors_from_hash(xml, soft_desc)
  xml.tag! :SDMerchantName, soft_desc[:merchant_name] || nil
  xml.tag! :SDProductDescription, soft_desc[:product_description] || nil
  xml.tag! :SDMerchantCity, soft_desc[:merchant_city] || nil
  xml.tag! :SDMerchantPhone, soft_desc[:merchant_phone] || nil
  xml.tag! :SDMerchantURL, soft_desc[:merchant_url] || nil
  xml.tag! :SDMerchantEmail, soft_desc[:merchant_email] || nil
end
add_soft_descriptors_from_specialized_class(xml, soft_desc) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 415
def add_soft_descriptors_from_specialized_class(xml, soft_desc)
  xml.tag! :SDMerchantName, soft_desc.merchant_name             if soft_desc.merchant_name
  xml.tag! :SDProductDescription, soft_desc.product_description if soft_desc.product_description
  xml.tag! :SDMerchantCity, soft_desc.merchant_city             if soft_desc.merchant_city
  xml.tag! :SDMerchantPhone, soft_desc.merchant_phone           if soft_desc.merchant_phone
  xml.tag! :SDMerchantURL, soft_desc.merchant_url               if soft_desc.merchant_url
  xml.tag! :SDMerchantEmail, soft_desc.merchant_email           if soft_desc.merchant_email
end
add_stored_credentials(xml, parameters) click to toggle source
SCA (STORED CREDENTIAL) FIELDS=====
# File lib/active_merchant/billing/gateways/orbital.rb, line 770
def add_stored_credentials(xml, parameters)
  return unless parameters[:mit_stored_credential_ind] == 'Y' || parameters[:stored_credential] && !parameters[:stored_credential].values.all?(&:nil?)

  if msg_type = get_msg_type(parameters)
    xml.tag! :MITMsgType, msg_type
  end
  xml.tag! :MITStoredCredentialInd, 'Y'
  if parameters[:mit_submitted_transaction_id]
    xml.tag! :MITSubmittedTransactionID, parameters[:mit_submitted_transaction_id]
  elsif parameters.dig(:stored_credential, :network_transaction_id) && parameters.dig(:stored_credential, :initiator) == 'merchant'
    xml.tag! :MITSubmittedTransactionID, parameters[:stored_credential][:network_transaction_id]
  end
end
add_tx_ref_num(xml, authorization) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 386
def add_tx_ref_num(xml, authorization)
  return unless authorization

  xml.tag! :TxRefNum, split_authorization(authorization).first
end
add_verification_value(xml, credit_card) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 630
def add_verification_value(xml, credit_card)
  return unless credit_card&.verification_value?

  # If you are trying to collect a Card Verification Number
  # (CardSecVal) for a Visa or Discover transaction, pass one of these values:
  #   1 Value is Present
  #   2 Value on card but illegible
  #   9 Cardholder states data not available
  # If the transaction is not a Visa or Discover transaction:
  #   Null-fill this attribute OR
  #   Do not submit the attribute at all.
  # - http://download.chasepaymentech.com/docs/orbital/orbital_gateway_xml_specification.pdf
  xml.tag! :CardSecValInd, '1' if %w(visa discover diners_club).include?(credit_card.brand)
  xml.tag! :CardSecVal, credit_card.verification_value
end
add_xid(xml, credit_card, three_d_secure) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 706
def add_xid(xml, credit_card, three_d_secure)
  return unless three_d_secure && credit_card.brand == 'visa'

  xml.tag!(:XID, three_d_secure[:xid]) if three_d_secure[:xid]
end
add_xml_credentials(xml) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 907
def add_xml_credentials(xml)
  unless ip_authentication?
    xml.tag! :OrbitalConnectionUsername, @options[:login]
    xml.tag! :OrbitalConnectionPassword, @options[:password]
  end
end
authorization_string(*args) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 392
def authorization_string(*args)
  args.compact.join(';')
end
avs_supported?(address) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 584
def avs_supported?(address)
  AVS_SUPPORTED_COUNTRIES.include?(address.to_s)
end
billing_name(payment_source, options) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 576
def billing_name(payment_source, options)
  if !payment_source.is_a?(String) && payment_source&.name.present?
    payment_source.name[0..29]
  elsif options[:billing_address] && options[:billing_address][:name].present?
    options[:billing_address][:name][0..29]
  end
end
bin() click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 678
def bin
  @options[:bin] || (salem_mid? ? '000001' : '000002')
end
build_customer_request_xml(credit_card, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 1161
def build_customer_request_xml(credit_card, options = {})
  ActiveMerchant.deprecated 'Customer Profile support in Orbital is non-conformant to the ActiveMerchant API and will be removed in its current form in a future version. Please contact the ActiveMerchant maintainers if you have an interest in modifying it to conform to the store/unstore/update API.'
  xml = xml_envelope
  xml.tag! :Request do
    xml.tag! :Profile do
      xml.tag! :OrbitalConnectionUsername, @options[:login] unless ip_authentication?
      xml.tag! :OrbitalConnectionPassword, @options[:password] unless ip_authentication?
      xml.tag! :CustomerBin, bin
      xml.tag! :CustomerMerchantID, @options[:merchant_id]
      xml.tag! :CustomerName, credit_card.name if credit_card
      xml.tag! :CustomerRefNum, options[:customer_ref_num] if options[:customer_ref_num]

      add_customer_address(xml, options)

      xml.tag! :CustomerProfileAction, options[:customer_profile_action] # C, R, U, D
      # NO No mapping to order data
      # OI Use <CustomerRefNum> for <OrderID>
      # OD Use <CustomerReferNum> for <Comments>
      # OA Use <CustomerRefNum> for <OrderID> and <Comments>
      xml.tag! :CustomerProfileOrderOverrideInd, options[:customer_profile_order_override_ind] || NO_MAPPING_TO_ORDER_DATA

      if options[:customer_profile_action] == CREATE
        # A Auto-Generate the CustomerRefNum
        # S Use CustomerRefNum field
        # O Use OrderID field
        # D Use Comments field
        xml.tag! :CustomerProfileFromOrderInd, (options[:customer_ref_num] ? USE_CUSTOMER_REF_NUM : AUTO_GENERATE)
      end

      xml.tag! :OrderDefaultDescription, options[:order_default_description][0..63] if options[:order_default_description]
      xml.tag! :OrderDefaultAmount, options[:order_default_amount] if options[:order_default_amount]

      if [CREATE, UPDATE].include? options[:customer_profile_action]
        xml.tag! :CustomerAccountType, 'CC' # Only credit card supported
        xml.tag! :Status, options[:status] || ACTIVE # Active
      end

      xml.tag! :CCAccountNum, credit_card.number if credit_card
      xml.tag! :CCExpireDate, credit_card.expiry_date.expiration.strftime('%m%y') if credit_card

      # This has to come after CCExpireDate.
      add_managed_billing(xml, options)
    end
  end
  xml.target!
end
build_mark_for_capture_xml(money, authorization, parameters = {}) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 1074
def build_mark_for_capture_xml(money, authorization, parameters = {})
  tx_ref_num, order_id = split_authorization(authorization)
  xml = xml_envelope
  xml.tag! :Request do
    xml.tag! :MarkForCapture do
      add_xml_credentials(xml)
      xml.tag! :OrderID, format_order_id(order_id)
      xml.tag! :Amount, amount(money)
      add_level2_tax(xml, parameters)
      add_bin_merchant_and_terminal(xml, parameters)
      xml.tag! :TxRefNum, tx_ref_num
      add_level2_purchase(xml, parameters)
      add_level2_advice_addendum(xml, parameters)
      add_level3_purchase(xml, parameters)
      add_level3_tax(xml, parameters)
      add_line_items(xml, parameters) if parameters[:line_items]
      add_level2_card_and_more_tax(xml, parameters)
      add_card_commodity_code(xml, parameters)
      add_level3_vat_fields(xml, parameters)
    end
  end
  xml.target!
end
build_new_auth_purchase_order(action, money, payment_source, options) click to toggle source
BUILDER METHODS=====
# File lib/active_merchant/billing/gateways/orbital.rb, line 1008
def build_new_auth_purchase_order(action, money, payment_source, options)
  build_new_order_xml(action, money, payment_source, options) do |xml|
    add_payment_source(xml, payment_source, options)
    add_address(xml, payment_source, options)
    if @options[:customer_profiles]
      add_customer_data(xml, payment_source, options)
      add_managed_billing(xml, options)
    end
  end
end
build_new_order_xml(action, money, payment_source, parameters = {}) { |xml| ... } click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 1019
def build_new_order_xml(action, money, payment_source, parameters = {})
  requires!(parameters, :order_id)
  @use_secondary_url = parameters[:use_secondary_url] if parameters[:use_secondary_url]
  xml = xml_envelope
  xml.tag! :Request do
    xml.tag! :NewOrder do
      add_xml_credentials(xml)
      xml.tag! :IndustryType, parameters[:industry_type] || ECOMMERCE_TRANSACTION
      xml.tag! :MessageType, action
      add_bin_merchant_and_terminal(xml, parameters)

      yield xml if block_given?

      three_d_secure = parameters[:three_d_secure]

      add_eci(xml, payment_source, three_d_secure)
      add_cavv(xml, payment_source, three_d_secure)
      add_xid(xml, payment_source, three_d_secure)

      xml.tag! :OrderID, format_order_id(parameters[:order_id])
      xml.tag! :Amount, amount(money)
      xml.tag! :Comments, parameters[:comments] if parameters[:comments]
      add_level2_tax(xml, parameters)
      add_level2_advice_addendum(xml, parameters)
      add_aav(xml, payment_source, three_d_secure)
      # CustomerAni, AVSPhoneType and AVSDestPhoneType could be added here.
      add_soft_descriptors(xml, parameters[:soft_descriptors])
      set_recurring_ind(xml, parameters)

      # Append Transaction Reference Number at the end for Refund transactions
      add_tx_ref_num(xml, parameters[:authorization]) if action == REFUND && payment_source.nil?
      add_level2_purchase(xml, parameters)
      add_level3_purchase(xml, parameters)
      add_level3_tax(xml, parameters)
      add_line_items(xml, parameters) if parameters[:line_items]
      add_card_indicators(xml, parameters)
      add_payment_action_ind(xml, parameters[:payment_action_ind])
      add_dpanind(xml, payment_source, parameters[:industry_type])
      add_aevv(xml, payment_source, three_d_secure)
      add_level2_card_and_more_tax(xml, parameters)
      add_digital_token_cryptogram(xml, payment_source, three_d_secure)
      xml.tag! :ECPSameDayInd, parameters[:same_day] if parameters[:same_day] && payment_source.is_a?(Check)
      add_ecp_details(xml, payment_source, parameters) if payment_source.is_a?(Check)

      add_stored_credentials(xml, parameters)
      add_pymt_brand_program_code(xml, payment_source, three_d_secure)
      xml.tag! :TokenTxnType, parameters[:token_txn_type] if parameters[:token_txn_type]
      add_mastercard_fields(xml, payment_source, parameters, three_d_secure) if mastercard?(payment_source)
      add_card_commodity_code(xml, parameters)
      add_level3_vat_fields(xml, parameters)
    end
  end
  xml.target!
end
build_void_request_xml(authorization, parameters = {}) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 1098
def build_void_request_xml(authorization, parameters = {})
  tx_ref_num, order_id = split_authorization(authorization)
  xml = xml_envelope
  xml.tag! :Request do
    xml.tag! :Reversal do
      add_xml_credentials(xml)
      xml.tag! :TxRefNum, tx_ref_num
      xml.tag! :TxRefIdx, parameters[:transaction_index]
      xml.tag! :AdjustedAmt, parameters[:amount] # setting adjusted amount to nil will void entire amount
      xml.tag! :OrderID, format_order_id(order_id || parameters[:order_id])
      add_bin_merchant_and_terminal(xml, parameters)
      xml.tag! :ReversalRetryNumber, parameters[:reversal_retry_number] if parameters[:reversal_retry_number]
      xml.tag! :OnlineReversalInd,   parameters[:online_reversal_ind]   if parameters[:online_reversal_ind]
    end
  end
  xml.target!
end
byte_limit(value, byte_length) click to toggle source

Field lengths should be limited by byte count instead of character count Returns the truncated value or nil

# File lib/active_merchant/billing/gateways/orbital.rb, line 1149
def byte_limit(value, byte_length)
  limited_value = ''

  value.to_s.each_char do |c|
    break if (limited_value.bytesize + c.bytesize) > byte_length

    limited_value << c
  end

  limited_value
end
commit(order, message_type, retry_logic = nil, trace_number = nil) click to toggle source
REQUEST/RESPONSE METHODS=====
# File lib/active_merchant/billing/gateways/orbital.rb, line 922
def commit(order, message_type, retry_logic = nil, trace_number = nil)
  headers = POST_HEADERS.merge('Content-length' => order.size.to_s)
  if (@options[:retry_logic] || retry_logic) && trace_number
    headers['Trace-number'] = trace_number.to_s
    headers['Merchant-Id'] = @options[:merchant_id]
  end
  request = ->(url) { parse(ssl_post(url, order, headers)) }

  # Failover URL will be attempted in the event of a connection error
  response =
    begin
      raise ConnectionError.new 'Should use secondary url', 500 if @use_secondary_url

      request.call(remote_url)
    rescue ConnectionError
      request.call(remote_url(:secondary))
    end

  authorization = authorization_string(response[:tx_ref_num], response[:order_id], response[:safetech_token], response[:card_brand])

  Response.new(
    success?(response, message_type),
    message_from(response),
    response,
    {
      authorization: authorization,
      test: self.test?,
      avs_result: OrbitalGateway::AVSResult.new(response[:avs_resp_code]),
      cvv_result: OrbitalGateway::CVVResult.new(response[:cvv2_resp_code])
    }
  )
end
currency_code(currency) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 666
def currency_code(currency)
  CURRENCY_CODES[(currency || self.default_currency)].to_s
end
currency_exponents(currency) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 670
def currency_exponents(currency)
  CURRENCY_EXPONENTS[(currency || self.default_currency)].to_s
end
expiry_date(credit_card) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 674
def expiry_date(credit_card)
  "#{format(credit_card.month, :two_digits)}#{format(credit_card.year, :two_digits)}"
end
filter_unsupported_countries(address) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 588
def filter_unsupported_countries(address)
  avs_supported?(address) ? address.to_s : ''
end
force_capture_with_echeck?(payment_source, options) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 356
def force_capture_with_echeck?(payment_source, options)
  return false unless options[:force_capture]
  return false unless payment_source.is_a?(Check)

  %w(W8 W9 ND).include?(options[:action_code])
end
format_address_field(value) click to toggle source

Address-related fields cannot contain % | ^ \ / Returns the value with these characters removed, or nil

# File lib/active_merchant/billing/gateways/orbital.rb, line 1143
def format_address_field(value)
  value.gsub(/[%\|\^\\\/]/, '') if value.respond_to?(:gsub)
end
format_order_id(order_id) click to toggle source

The valid characters include:

  1. all letters and digits

    • , $ @ & and a space character, though the space character cannot be the leading character

  2. PINless Debit transactions can only use uppercase and lowercase alpha (A-Z, a-z) and numeric (0-9)

# File lib/active_merchant/billing/gateways/orbital.rb, line 1133
def format_order_id(order_id)
  illegal_characters = /[^,$@&\- \w]/
  order_id = order_id.to_s.tr('.', '-')
  order_id.gsub!(illegal_characters, '')
  order_id.lstrip!
  order_id[0...22]
end
get_address(options) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 592
def get_address(options)
  options[:billing_address] || options[:address]
end
get_msg_type(parameters) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 784
def get_msg_type(parameters)
  return parameters[:mit_msg_type] if parameters[:mit_msg_type]
  return 'CSTO' if parameters[:stored_credential][:initial_transaction]
  return unless parameters[:stored_credential][:initiator] && parameters[:stored_credential][:reason_type]

  initiator =
    case parameters[:stored_credential][:initiator]
    when 'cardholder', 'customer' then 'C'
    when 'merchant' then 'M'
    end
  reason =
    case parameters[:stored_credential][:reason_type]
    when 'recurring' then 'REC'
    when 'installment' then 'INS'
    when 'unscheduled' then 'USE'
    end

  "#{initiator}#{reason}"
end
ip_authentication?() click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 1002
def ip_authentication?
  @options[:ip_authentication] == true
end
mastercard?(payment_source) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 718
def mastercard?(payment_source)
  payment_source.is_a?(CreditCard) && payment_source.brand == 'master'
end
message_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 998
def message_from(response)
  response[:resp_msg] || response[:status_msg] || response[:customer_profile_message]
end
parse(body) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 963
def parse(body)
  response = {}
  xml = REXML::Document.new(strip_invalid_xml_chars(body))
  root = REXML::XPath.first(xml, '//Response') ||
         REXML::XPath.first(xml, '//ErrorResponse')
  if root
    root.elements.to_a.each do |node|
      recurring_parse_element(response, node)
    end
  end

  response.delete_if { |k, _| SENSITIVE_FIELDS.include?(k) }
end
profile_number(options) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 378
def profile_number(options)
  options[:customer_ref_num] ? USE_CUSTOMER_REF_NUM : AUTO_GENERATE
end
recurring_parse_element(response, node) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 977
def recurring_parse_element(response, node)
  if node.has_elements?
    node.elements.each { |e| recurring_parse_element(response, e) }
  else
    response[node.name.underscore.to_sym] = node.text
  end
end
remote_url(url = :primary) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 955
def remote_url(url = :primary)
  if url == :primary
    (self.test? ? self.test_url : self.live_url)
  else
    (self.test? ? self.secondary_test_url : self.secondary_live_url)
  end
end
salem_mid?() click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 682
def salem_mid?
  @options[:merchant_id].length == 6
end
set_recurring_ind(xml, parameters) click to toggle source

For Canadian transactions on PNS Tampa on New Order RF - First Recurring Transaction RS - Subsequent Recurring Transactions

# File lib/active_merchant/billing/gateways/orbital.rb, line 840
def set_recurring_ind(xml, parameters)
  return unless parameters[:recurring_ind]
  raise 'RecurringInd must be set to either "RF" or "RS"' unless %w(RF RS).include?(parameters[:recurring_ind])

  xml.tag! :RecurringInd, parameters[:recurring_ind]
end
split_authorization(authorization) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 396
def split_authorization(authorization)
  authorization.split(';')
end
strip_invalid_xml_chars(xml) click to toggle source

Null characters are possible in some responses (namely, the respMsg field), causing XML parsing errors Prevent by substituting these with a valid placeholder string

# File lib/active_merchant/billing/gateways/orbital.rb, line 1124
def strip_invalid_xml_chars(xml)
  xml.gsub(/\u0000/, '[null]')
end
success?(response, message_type) click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 985
def success?(response, message_type)
  if %i[void].include?(message_type)
    response[:proc_status] == SUCCESS
  elsif %i[refund].include?(message_type)
    response[:proc_status] == SUCCESS && response[:approval_status] == APPROVAL_SUCCESS
  elsif response[:customer_profile_action]
    response[:profile_proc_status] == SUCCESS
  else
    response[:proc_status] == SUCCESS &&
      APPROVED.include?(response[:resp_code])
  end
end
xml_envelope() click to toggle source
# File lib/active_merchant/billing/gateways/orbital.rb, line 1116
def xml_envelope
  xml = Builder::XmlMarkup.new(indent: 2)
  xml.instruct!(:xml, version: '1.0', encoding: 'UTF-8')
  xml
end