Class: ActiveMerchant::Billing::OrbitalGateway

Inherits:
Gateway
  • Object
show all
Includes:
Empty
Defined in:
lib/active_merchant/billing/gateways/orbital.rb

Overview

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.

Defined Under Namespace

Classes: AVSResult, CVVResult

Constant Summary collapse

API_VERSION =
'9.5'
POST_HEADERS =
{
  'MIME-Version' => '1.1',
  'Content-Type' => "application/PTI#{API_VERSION.delete('.')}",
  'Content-transfer-encoding' => 'text',
  'Request-number' => '1',
  'Document-type' => 'Request',
  'Interface-Version' => 'Ruby|ActiveMerchant|Proprietary Gateway'
}
SUCCESS =
'0'
APPROVAL_SUCCESS =
'1'
APPROVED =
[
  '00', # Approved
  '08', # Approved authorization, honor with ID
  '11', # Approved authorization, VIP approval
  '24', # Validated
  '26', # Pre-noted
  '27', # No reason to decline
  '28', # Received and stored
  '29', # Provided authorization
  '31', # Request received
  '32', # BIN alert
  '34', # Approved for partial
  '91', # Approved low fraud
  '92', # Approved medium fraud
  '93', # Approved high fraud
  '94', # Approved fraud service unavailable
  'E7', # Stored
  'PA', # Partial approval
  'P1'  # ECP - AVS - Account Status Verification and/or AOA data is in a positive status.
]
AVS_SUPPORTED_COUNTRIES =
%w[US CA UK GB]
CURRENCY_CODES =
{
  'AUD' => '036',
  'BRL' => '986',
  'CAD' => '124',
  'CLP' => '152',
  'CZK' => '203',
  'DKK' => '208',
  'HKD' => '344',
  'ICK' => '352',
  'JPY' => '392',
  'MXN' => '484',
  'NZD' => '554',
  'NOK' => '578',
  'SGD' => '702',
  'ZAR' => '710',
  'SEK' => '752',
  'CHF' => '756',
  'GBP' => '826',
  'USD' => '840',
  'EUR' => '978'
}
CURRENCY_EXPONENTS =
{
  'AUD' => '2',
  'BRL' => '2',
  'CAD' => '2',
  'CLP' => '2',
  'CZK' => '2',
  'DKK' => '2',
  'HKD' => '2',
  'ICK' => '2',
  'JPY' => '0',
  'MXN' => '2',
  'NZD' => '2',
  'NOK' => '2',
  'SGD' => '2',
  'ZAR' => '2',
  'SEK' => '2',
  'CHF' => '2',
  'GBP' => '2',
  'USD' => '2',
  'EUR' => '2'
}
ECOMMERCE_TRANSACTION =

INDUSTRY TYPES

'EC'
RECURRING_PAYMENT_TRANSACTION =
'RC'
MAIL_ORDER_TELEPHONE_ORDER_TRANSACTION =
'MO'
INTERACTIVE_VOICE_RESPONSE =
'IV'
AUTH_ONLY =

Auth Only No Capture

'A'
AUTH_AND_CAPTURE =

AC - Auth and Capture = ‘AC’

'AC'
FORCE_AUTH_ONLY =

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

'F'
FORCE_AUTH_AND_CAPTURE =

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

'FC'
REFUND =

Refund and Capture no online authorization

'R'
TAX_NOT_PROVIDED =

Tax Inds

0
TAX_INCLUDED =
1
NON_TAXABLE_TRANSACTION =
2
CREATE =

Customer Profile Actions

'C'
RETRIEVE =
'R'
UPDATE =
'U'
DELETE =
'D'
RECURRING =
'R'
DEFERRED =
'D'
ACTIVE =

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

'A'
INACTIVE =
'I'
MANUAL_SUSPEND =
'MS'
NO_MAPPING_TO_ORDER_DATA =

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

'NO'
USE_CRN_FOR_ORDER_ID =
'OI'
USE_CRN_FOR_COMMENTS =
'OD'
USE_CRN_FOR_ORDER_ID_AND_COMMENTS =
'OA'
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:

'A'
USE_CUSTOMER_REF_NUM =

Auto-Generate the CustomerRefNum

'S'
USE_ORDER_ID =

Use CustomerRefNum field

'O'
USE_COMMENTS =

Use OrderID field

'D'
SENSITIVE_FIELDS =

Use Comments field

%i[account_num cc_account_num]
ACCOUNT_TYPE =

Bank account types to be used for check processing

{
  'savings' => 'S',
  'checking' => 'C'
}
GET_TOKEN =

safetech token flags

'GT'
USE_TOKEN =
'UT'

Constants inherited from Gateway

Gateway::CREDIT_DEPRECATION_MESSAGE, Gateway::RECURRING_DEPRECATION_MESSAGE, Gateway::STANDARD_ERROR_CODE

Instance Attribute Summary

Attributes inherited from Gateway

#options

Instance Method Summary collapse

Methods inherited from Gateway

#add_field_to_post_if_present, #add_fields_to_post_if_present, #card_brand, card_brand, #generate_unique_id, inherited, #supported_countries, supported_countries, supported_countries=, supports?, #test?

Methods included from CreditCardFormatting

#expdate, #format, #strftime_yyyymm

Methods included from PostsData

included, #raw_ssl_request, #ssl_get, #ssl_post, #ssl_request

Constructor Details

#initialize(options = {}) ⇒ OrbitalGateway

Returns a new instance of OrbitalGateway.



200
201
202
203
204
205
206
# 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

Instance Method Details

#add_customer_profile(credit_card, options = {}) ⇒ Object

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


306
307
308
309
310
# 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) ⇒ Boolean

Returns:

  • (Boolean)


280
281
282
283
# 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 = {}) ⇒ Object

A – Authorization request



209
210
211
212
213
214
215
216
217
218
# 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 = {}) ⇒ Object

MFC - Mark For Capture



237
238
239
# 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 = {}) ⇒ Object



252
253
254
255
256
257
258
# 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) ⇒ Object



276
277
278
# 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) ⇒ Object



324
325
326
327
328
# 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 = {}) ⇒ Object

AC – Authorization and Capture



229
230
231
232
233
234
# 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 = {}) ⇒ Object

R – Refund request



242
243
244
245
246
247
248
249
250
# 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) ⇒ Object



318
319
320
321
322
# 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) ⇒ Object



338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
# 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 = {}) ⇒ Object

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



261
262
263
# 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?Boolean

Returns:

  • (Boolean)


330
331
332
# File 'lib/active_merchant/billing/gateways/orbital.rb', line 330

def supports_network_tokenization?
  true
end

#supports_scrubbing?Boolean

Returns:

  • (Boolean)


334
335
336
# File 'lib/active_merchant/billing/gateways/orbital.rb', line 334

def supports_scrubbing?
  true
end

#update_customer_profile(credit_card, options = {}) ⇒ Object



312
313
314
315
316
# 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 = {}) ⇒ Object



220
221
222
223
224
225
226
# 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 = {}) ⇒ Object



265
266
267
268
269
270
271
272
273
274
# 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