activemerchant 1.125.0 → 1.129.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +316 -0
  3. data/lib/active_merchant/billing/check.rb +40 -8
  4. data/lib/active_merchant/billing/credit_card.rb +28 -1
  5. data/lib/active_merchant/billing/credit_card_methods.rb +91 -23
  6. data/lib/active_merchant/billing/gateway.rb +2 -1
  7. data/lib/active_merchant/billing/gateways/adyen.rb +74 -12
  8. data/lib/active_merchant/billing/gateways/airwallex.rb +370 -0
  9. data/lib/active_merchant/billing/gateways/alelo.rb +256 -0
  10. data/lib/active_merchant/billing/gateways/authorize_net.rb +21 -4
  11. data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +2 -1
  12. data/lib/active_merchant/billing/gateways/beanstream.rb +18 -0
  13. data/lib/active_merchant/billing/gateways/blue_pay.rb +1 -1
  14. data/lib/active_merchant/billing/gateways/blue_snap.rb +53 -22
  15. data/lib/active_merchant/billing/gateways/bogus.rb +4 -0
  16. data/lib/active_merchant/billing/gateways/borgun.rb +56 -16
  17. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +6 -1
  18. data/lib/active_merchant/billing/gateways/braintree/token_nonce.rb +113 -0
  19. data/lib/active_merchant/billing/gateways/braintree_blue.rb +151 -32
  20. data/lib/active_merchant/billing/gateways/card_connect.rb +28 -10
  21. data/lib/active_merchant/billing/gateways/card_stream.rb +23 -0
  22. data/lib/active_merchant/billing/gateways/checkout_v2.rb +228 -57
  23. data/lib/active_merchant/billing/gateways/commerce_hub.rb +361 -0
  24. data/lib/active_merchant/billing/gateways/credorax.rb +56 -26
  25. data/lib/active_merchant/billing/gateways/cyber_source/cyber_source_common.rb +36 -0
  26. data/lib/active_merchant/billing/gateways/cyber_source.rb +112 -58
  27. data/lib/active_merchant/billing/gateways/cyber_source_rest.rb +456 -0
  28. data/lib/active_merchant/billing/gateways/d_local.rb +93 -5
  29. data/lib/active_merchant/billing/gateways/decidir.rb +32 -5
  30. data/lib/active_merchant/billing/gateways/decidir_plus.rb +185 -14
  31. data/lib/active_merchant/billing/gateways/ebanx.rb +39 -26
  32. data/lib/active_merchant/billing/gateways/element.rb +21 -1
  33. data/lib/active_merchant/billing/gateways/global_collect.rb +98 -37
  34. data/lib/active_merchant/billing/gateways/ipg.rb +14 -10
  35. data/lib/active_merchant/billing/gateways/iveri.rb +39 -3
  36. data/lib/active_merchant/billing/gateways/kushki.rb +21 -1
  37. data/lib/active_merchant/billing/gateways/litle.rb +118 -6
  38. data/lib/active_merchant/billing/gateways/mastercard.rb +1 -8
  39. data/lib/active_merchant/billing/gateways/mercado_pago.rb +17 -0
  40. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +44 -10
  41. data/lib/active_merchant/billing/gateways/monei.rb +2 -0
  42. data/lib/active_merchant/billing/gateways/moneris.rb +55 -13
  43. data/lib/active_merchant/billing/gateways/mundipagg.rb +3 -0
  44. data/lib/active_merchant/billing/gateways/nmi.rb +12 -7
  45. data/lib/active_merchant/billing/gateways/ogone.rb +35 -7
  46. data/lib/active_merchant/billing/gateways/openpay.rb +20 -3
  47. data/lib/active_merchant/billing/gateways/orbital.rb +378 -335
  48. data/lib/active_merchant/billing/gateways/pay_trace.rb +64 -18
  49. data/lib/active_merchant/billing/gateways/payeezy.rb +59 -4
  50. data/lib/active_merchant/billing/gateways/payflow.rb +62 -0
  51. data/lib/active_merchant/billing/gateways/paymentez.rb +44 -13
  52. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +4 -0
  53. data/lib/active_merchant/billing/gateways/paysafe.rb +37 -29
  54. data/lib/active_merchant/billing/gateways/payu_latam.rb +28 -15
  55. data/lib/active_merchant/billing/gateways/plexo.rb +308 -0
  56. data/lib/active_merchant/billing/gateways/priority.rb +185 -140
  57. data/lib/active_merchant/billing/gateways/rapyd.rb +319 -0
  58. data/lib/active_merchant/billing/gateways/reach.rb +277 -0
  59. data/lib/active_merchant/billing/gateways/redsys.rb +9 -5
  60. data/lib/active_merchant/billing/gateways/safe_charge.rb +1 -4
  61. data/lib/active_merchant/billing/gateways/sage_pay.rb +1 -1
  62. data/lib/active_merchant/billing/gateways/securion_pay.rb +40 -0
  63. data/lib/active_merchant/billing/gateways/shift4.rb +342 -0
  64. data/lib/active_merchant/billing/gateways/simetrik.rb +368 -0
  65. data/lib/active_merchant/billing/gateways/stripe.rb +25 -3
  66. data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +155 -70
  67. data/lib/active_merchant/billing/gateways/tns.rb +2 -5
  68. data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +1 -1
  69. data/lib/active_merchant/billing/gateways/trust_commerce.rb +14 -3
  70. data/lib/active_merchant/billing/gateways/vanco.rb +12 -3
  71. data/lib/active_merchant/billing/gateways/visanet_peru.rb +6 -2
  72. data/lib/active_merchant/billing/gateways/vpos.rb +7 -4
  73. data/lib/active_merchant/billing/gateways/wompi.rb +8 -4
  74. data/lib/active_merchant/billing/gateways/worldpay.rb +117 -9
  75. data/lib/active_merchant/billing/response.rb +15 -1
  76. data/lib/active_merchant/connection.rb +0 -2
  77. data/lib/active_merchant/country.rb +1 -0
  78. data/lib/active_merchant/errors.rb +4 -1
  79. data/lib/active_merchant/version.rb +1 -1
  80. metadata +28 -3
@@ -30,7 +30,7 @@ module ActiveMerchant #:nodoc:
30
30
  class OrbitalGateway < Gateway
31
31
  include Empty
32
32
 
33
- API_VERSION = '8.1'
33
+ API_VERSION = '9.0'
34
34
 
35
35
  POST_HEADERS = {
36
36
  'MIME-Version' => '1.1',
@@ -98,6 +98,7 @@ module ActiveMerchant #:nodoc:
98
98
  'NZD' => '554',
99
99
  'NOK' => '578',
100
100
  'SGD' => '702',
101
+ 'ZAR' => '710',
101
102
  'SEK' => '752',
102
103
  'CHF' => '756',
103
104
  'GBP' => '826',
@@ -119,6 +120,7 @@ module ActiveMerchant #:nodoc:
119
120
  'NZD' => '2',
120
121
  'NOK' => '2',
121
122
  'SGD' => '2',
123
+ 'ZAR' => '2',
122
124
  'SEK' => '2',
123
125
  'CHF' => '2',
124
126
  'GBP' => '2',
@@ -196,6 +198,7 @@ module ActiveMerchant #:nodoc:
196
198
  requires!(options, :login, :password) unless options[:ip_authentication]
197
199
  super
198
200
  @options[:merchant_id] = @options[:merchant_id].to_s
201
+ @use_secondary_url = false
199
202
  end
200
203
 
201
204
  # A – Authorization request
@@ -203,40 +206,25 @@ module ActiveMerchant #:nodoc:
203
206
  # ECP for Orbital requires $0 prenotes so ensure
204
207
  # if we are doing a force capture with a check, that
205
208
  # we do a purchase here
206
- if options[:force_capture] && payment_source.is_a?(Check) &&
207
- (options[:action_code].include?('W8') || options[:action_code].include?('W9') || options[:action_code].include?('ND'))
208
- return purchase(money, payment_source, options)
209
- end
209
+ return purchase(money, payment_source, options) if force_capture_with_echeck?(payment_source, options)
210
+
211
+ order = build_new_auth_purchase_order(AUTH_ONLY, money, payment_source, options)
210
212
 
211
- order = build_new_order_xml(AUTH_ONLY, money, payment_source, options) do |xml|
212
- add_payment_source(xml, payment_source, options)
213
- add_address(xml, payment_source, options)
214
- if @options[:customer_profiles]
215
- add_customer_data(xml, payment_source, options)
216
- add_managed_billing(xml, options)
217
- end
218
- end
219
213
  commit(order, :authorize, options[:retry_logic], options[:trace_number])
220
214
  end
221
215
 
222
- def verify(creditcard, options = {})
223
- amount = allow_0_auth?(creditcard) ? 0 : 100
216
+ def verify(credit_card, options = {})
217
+ amount = options[:verify_amount] ? options[:verify_amount].to_i : default_verify_amount(credit_card)
224
218
  MultiResponse.run(:use_first_response) do |r|
225
- r.process { authorize(amount, creditcard, options) }
226
- r.process(:ignore_result) { void(r.authorization) }
219
+ r.process { authorize(amount, credit_card, options) }
220
+ r.process(:ignore_result) { void(r.authorization) } unless amount == 0
227
221
  end
228
222
  end
229
223
 
230
224
  # AC – Authorization and Capture
231
225
  def purchase(money, payment_source, options = {})
232
- order = build_new_order_xml(options[:force_capture] ? FORCE_AUTH_AND_CAPTURE : AUTH_AND_CAPTURE, money, payment_source, options) do |xml|
233
- add_payment_source(xml, payment_source, options)
234
- add_address(xml, payment_source, options)
235
- if @options[:customer_profiles]
236
- add_customer_data(xml, payment_source, options)
237
- add_managed_billing(xml, options)
238
- end
239
- end
226
+ action = options[:force_capture] ? FORCE_AUTH_AND_CAPTURE : AUTH_AND_CAPTURE
227
+ order = build_new_auth_purchase_order(action, money, payment_source, options)
240
228
 
241
229
  commit(order, :purchase, options[:retry_logic], options[:trace_number])
242
230
  end
@@ -250,13 +238,10 @@ module ActiveMerchant #:nodoc:
250
238
  def refund(money, authorization, options = {})
251
239
  payment_method = options[:payment_method]
252
240
  order = build_new_order_xml(REFUND, money, payment_method, options.merge(authorization: authorization)) do |xml|
253
- if payment_method.is_a?(Check)
254
- add_echeck(xml, payment_method, options)
255
- else
256
- add_refund(xml, options[:currency])
257
- end
241
+ add_payment_source(xml, payment_method, options)
258
242
  xml.tag! :CustomerRefNum, options[:customer_ref_num] if @options[:customer_profiles] && options[:profile_txn]
259
243
  end
244
+
260
245
  commit(order, :refund, options[:retry_logic], options[:trace_number])
261
246
  end
262
247
 
@@ -264,6 +249,7 @@ module ActiveMerchant #:nodoc:
264
249
  order = build_new_order_xml(REFUND, money, payment_method, options) do |xml|
265
250
  add_payment_source(xml, payment_method, options)
266
251
  end
252
+
267
253
  commit(order, :refund, options[:retry_logic], options[:trace_number])
268
254
  end
269
255
 
@@ -274,10 +260,15 @@ module ActiveMerchant #:nodoc:
274
260
  end
275
261
 
276
262
  order = build_void_request_xml(authorization, options)
263
+
277
264
  commit(order, :void, options[:retry_logic], options[:trace_number])
278
265
  end
279
266
 
280
- def allow_0_auth?(credit_card)
267
+ def default_verify_amount(credit_card)
268
+ allow_zero_auth?(credit_card) ? 0 : 100
269
+ end
270
+
271
+ def allow_zero_auth?(credit_card)
281
272
  # Discover does not support a $0.00 authorization instead use $1.00
282
273
  %w(visa master american_express diners_club jcb).include?(credit_card.brand)
283
274
  end
@@ -303,15 +294,15 @@ module ActiveMerchant #:nodoc:
303
294
  # 'I' - Inactive
304
295
  # 'MS' - Manual Suspend
305
296
 
306
- def add_customer_profile(creditcard, options = {})
297
+ def add_customer_profile(credit_card, options = {})
307
298
  options[:customer_profile_action] = CREATE
308
- order = build_customer_request_xml(creditcard, options)
299
+ order = build_customer_request_xml(credit_card, options)
309
300
  commit(order, :add_customer_profile)
310
301
  end
311
302
 
312
- def update_customer_profile(creditcard, options = {})
303
+ def update_customer_profile(credit_card, options = {})
313
304
  options[:customer_profile_action] = UPDATE
314
- order = build_customer_request_xml(creditcard, options)
305
+ order = build_customer_request_xml(credit_card, options)
315
306
  commit(order, :update_customer_profile)
316
307
  end
317
308
 
@@ -327,6 +318,10 @@ module ActiveMerchant #:nodoc:
327
318
  commit(order, :delete_customer_profile)
328
319
  end
329
320
 
321
+ def supports_network_tokenization?
322
+ true
323
+ end
324
+
330
325
  def supports_scrubbing?
331
326
  true
332
327
  end
@@ -349,6 +344,42 @@ module ActiveMerchant #:nodoc:
349
344
 
350
345
  private
351
346
 
347
+ def force_capture_with_echeck?(payment_source, options)
348
+ return false unless options[:force_capture]
349
+ return false unless payment_source.is_a?(Check)
350
+
351
+ %w(W8 W9 ND).include?(options[:action_code])
352
+ end
353
+
354
+ #=====REFERENCE FIELDS=====
355
+
356
+ def add_customer_data(xml, credit_card, options)
357
+ add_customer_ref_num(xml, options)
358
+
359
+ return if options[:profile_txn]
360
+
361
+ xml.tag! :CustomerProfileFromOrderInd, profile_number(options) if add_profile_number?(options, credit_card)
362
+ xml.tag! :CustomerProfileOrderOverrideInd, options[:customer_profile_order_override_ind] || NO_MAPPING_TO_ORDER_DATA
363
+ end
364
+
365
+ def add_profile_number?(options, credit_card)
366
+ return true unless options[:customer_ref_num] && credit_card.nil?
367
+ end
368
+
369
+ def profile_number(options)
370
+ options[:customer_ref_num] ? USE_CUSTOMER_REF_NUM : AUTO_GENERATE
371
+ end
372
+
373
+ def add_customer_ref_num(xml, options)
374
+ xml.tag! :CustomerRefNum, options[:customer_ref_num] if options[:customer_ref_num]
375
+ end
376
+
377
+ def add_tx_ref_num(xml, authorization)
378
+ return unless authorization
379
+
380
+ xml.tag! :TxRefNum, split_authorization(authorization).first
381
+ end
382
+
352
383
  def authorization_string(*args)
353
384
  args.compact.join(';')
354
385
  end
@@ -357,21 +388,22 @@ module ActiveMerchant #:nodoc:
357
388
  authorization.split(';')
358
389
  end
359
390
 
360
- def add_customer_data(xml, creditcard, options)
361
- if options[:profile_txn]
362
- xml.tag! :CustomerRefNum, options[:customer_ref_num]
363
- else
364
- if options[:customer_ref_num]
365
- xml.tag! :CustomerProfileFromOrderInd, USE_CUSTOMER_REF_NUM if creditcard
366
- xml.tag! :CustomerRefNum, options[:customer_ref_num]
367
- else
368
- xml.tag! :CustomerProfileFromOrderInd, AUTO_GENERATE
369
- end
370
- xml.tag! :CustomerProfileOrderOverrideInd, options[:customer_profile_order_override_ind] || NO_MAPPING_TO_ORDER_DATA
371
- end
391
+ #=====DESCRIPTOR FIELDS=====
392
+
393
+ def add_soft_descriptors(xml, descriptors)
394
+ return unless descriptors
395
+
396
+ add_soft_descriptors_from_specialized_class(xml, descriptors) if descriptors.is_a?(OrbitalSoftDescriptors)
397
+ add_soft_descriptors_from_hash(xml, descriptors) if descriptors.is_a?(Hash)
398
+ end
399
+
400
+ def add_payment_action_ind(xml, payment_action_ind)
401
+ return unless payment_action_ind
402
+
403
+ xml.tag! :PaymentActionInd, payment_action_ind
372
404
  end
373
405
 
374
- def add_soft_descriptors(xml, soft_desc)
406
+ def add_soft_descriptors_from_specialized_class(xml, soft_desc)
375
407
  xml.tag! :SDMerchantName, soft_desc.merchant_name if soft_desc.merchant_name
376
408
  xml.tag! :SDProductDescription, soft_desc.product_description if soft_desc.product_description
377
409
  xml.tag! :SDMerchantCity, soft_desc.merchant_city if soft_desc.merchant_city
@@ -455,31 +487,52 @@ module ActiveMerchant #:nodoc:
455
487
  end
456
488
  end
457
489
 
458
- def add_card_indicators(xml, options)
459
- xml.tag! :CardIndicators, options[:card_indicators] if options[:card_indicators]
460
- end
490
+ #=====ADDRESS FIELDS=====
461
491
 
462
492
  def add_address(xml, payment_source, options)
463
- address = get_address(options)
464
-
465
- unless address.blank?
466
- avs_supported = AVS_SUPPORTED_COUNTRIES.include?(address[:country].to_s) || empty?(address[:country])
467
-
468
- if avs_supported
469
- xml.tag! :AVSzip, byte_limit(format_address_field(address[:zip]), 10)
470
- xml.tag! :AVSaddress1, byte_limit(format_address_field(address[:address1]), 30)
471
- xml.tag! :AVSaddress2, byte_limit(format_address_field(address[:address2]), 30)
472
- xml.tag! :AVScity, byte_limit(format_address_field(address[:city]), 20)
473
- xml.tag! :AVSstate, byte_limit(format_address_field(address[:state]), 2)
474
- xml.tag! :AVSphoneNum, (address[:phone] ? address[:phone].scan(/\d/).join.to_s[0..13] : nil)
475
- end
493
+ return unless (address = get_address(options))
494
+
495
+ if avs_supported?(address[:country]) || empty?(address[:country])
496
+ xml.tag! :AVSzip, byte_limit(format_address_field(address[:zip]), 10)
497
+ xml.tag! :AVSaddress1, byte_limit(format_address_field(address[:address1]), 30)
498
+ xml.tag! :AVSaddress2, byte_limit(format_address_field(address[:address2]), 30)
499
+ xml.tag! :AVScity, byte_limit(format_address_field(address[:city]), 20)
500
+ xml.tag! :AVSstate, byte_limit(format_address_field(address[:state]), 2)
501
+ xml.tag! :AVSphoneNum, (address[:phone] ? address[:phone].scan(/\d/).join.to_s[0..13] : nil)
502
+ end
476
503
 
477
- xml.tag! :AVSname, billing_name(payment_source, options)
478
- xml.tag! :AVScountryCode, (avs_supported ? byte_limit(format_address_field(address[:country]), 2) : '')
504
+ xml.tag! :AVSname, billing_name(payment_source, options)
505
+ xml.tag! :AVScountryCode, byte_limit(format_address_field(filter_unsupported_countries(address[:country])), 2)
479
506
 
480
- # Needs to come after AVScountryCode
481
- add_destination_address(xml, address) if avs_supported
482
- end
507
+ # Needs to come after AVScountryCode
508
+ add_destination_address(xml, address) if avs_supported?(address[:country]) || empty?(address[:country])
509
+ end
510
+
511
+ def add_destination_address(xml, address)
512
+ return unless address[:dest_zip]
513
+
514
+ xml.tag! :AVSDestzip, byte_limit(format_address_field(address[:dest_zip]), 10)
515
+ xml.tag! :AVSDestaddress1, byte_limit(format_address_field(address[:dest_address1]), 30)
516
+ xml.tag! :AVSDestaddress2, byte_limit(format_address_field(address[:dest_address2]), 30)
517
+ xml.tag! :AVSDestcity, byte_limit(format_address_field(address[:dest_city]), 20)
518
+ xml.tag! :AVSDeststate, byte_limit(format_address_field(address[:dest_state]), 2)
519
+ xml.tag! :AVSDestphoneNum, (address[:dest_phone] ? address[:dest_phone].scan(/\d/).join.to_s[0..13] : nil)
520
+ xml.tag! :AVSDestname, byte_limit(address[:dest_name], 30)
521
+ xml.tag! :AVSDestcountryCode, filter_unsupported_countries(address[:dest_country])
522
+ end
523
+
524
+ # For Profile requests
525
+ def add_customer_address(xml, options)
526
+ return unless (address = get_address(options))
527
+
528
+ xml.tag! :CustomerAddress1, byte_limit(format_address_field(address[:address1]), 30)
529
+ xml.tag! :CustomerAddress2, byte_limit(format_address_field(address[:address2]), 30)
530
+ xml.tag! :CustomerCity, byte_limit(format_address_field(address[:city]), 20)
531
+ xml.tag! :CustomerState, byte_limit(format_address_field(address[:state]), 2)
532
+ xml.tag! :CustomerZIP, byte_limit(format_address_field(address[:zip]), 10)
533
+ xml.tag! :CustomerEmail, byte_limit(address[:email], 50) if address[:email]
534
+ xml.tag! :CustomerPhone, (address[:phone] ? address[:phone].scan(/\d/).join.to_s : nil)
535
+ xml.tag! :CustomerCountryCode, filter_unsupported_countries(address[:country])
483
536
  end
484
537
 
485
538
  def billing_name(payment_source, options)
@@ -490,80 +543,47 @@ module ActiveMerchant #:nodoc:
490
543
  end
491
544
  end
492
545
 
493
- def add_destination_address(xml, address)
494
- if address[:dest_zip]
495
- avs_supported = AVS_SUPPORTED_COUNTRIES.include?(address[:dest_country].to_s)
496
-
497
- xml.tag! :AVSDestzip, byte_limit(format_address_field(address[:dest_zip]), 10)
498
- xml.tag! :AVSDestaddress1, byte_limit(format_address_field(address[:dest_address1]), 30)
499
- xml.tag! :AVSDestaddress2, byte_limit(format_address_field(address[:dest_address2]), 30)
500
- xml.tag! :AVSDestcity, byte_limit(format_address_field(address[:dest_city]), 20)
501
- xml.tag! :AVSDeststate, byte_limit(format_address_field(address[:dest_state]), 2)
502
- xml.tag! :AVSDestphoneNum, (address[:dest_phone] ? address[:dest_phone].scan(/\d/).join.to_s[0..13] : nil)
503
-
504
- xml.tag! :AVSDestname, byte_limit(address[:dest_name], 30)
505
- xml.tag! :AVSDestcountryCode, (avs_supported ? address[:dest_country] : '')
506
- end
546
+ def avs_supported?(address)
547
+ AVS_SUPPORTED_COUNTRIES.include?(address.to_s)
507
548
  end
508
549
 
509
- # For Profile requests
510
- def add_customer_address(xml, options)
511
- address = get_address(options)
512
-
513
- unless address.blank?
514
- avs_supported = AVS_SUPPORTED_COUNTRIES.include?(address[:country].to_s)
515
-
516
- xml.tag! :CustomerAddress1, byte_limit(format_address_field(address[:address1]), 30)
517
- xml.tag! :CustomerAddress2, byte_limit(format_address_field(address[:address2]), 30)
518
- xml.tag! :CustomerCity, byte_limit(format_address_field(address[:city]), 20)
519
- xml.tag! :CustomerState, byte_limit(format_address_field(address[:state]), 2)
520
- xml.tag! :CustomerZIP, byte_limit(format_address_field(address[:zip]), 10)
521
- xml.tag! :CustomerEmail, byte_limit(address[:email], 50) if address[:email]
522
- xml.tag! :CustomerPhone, (address[:phone] ? address[:phone].scan(/\d/).join.to_s : nil)
523
- xml.tag! :CustomerCountryCode, (avs_supported ? address[:country] : '')
524
- end
550
+ def filter_unsupported_countries(address)
551
+ avs_supported?(address) ? address.to_s : ''
525
552
  end
526
553
 
554
+ def get_address(options)
555
+ options[:billing_address] || options[:address]
556
+ end
557
+
558
+ #=====PAYMENT SOURCE FIELDS=====
559
+
527
560
  # Payment can be done through either Credit Card or Electronic Check
528
561
  def add_payment_source(xml, payment_source, options = {})
529
- if payment_source.is_a?(Check)
530
- add_echeck(xml, payment_source, options)
531
- else
532
- add_creditcard(xml, payment_source, options[:currency])
533
- end
562
+ payment_source.is_a?(Check) ? add_echeck(xml, payment_source, options) : add_credit_card(xml, payment_source, options)
534
563
  end
535
564
 
536
- # Adds Electronic Check attributes
537
565
  def add_echeck(xml, check, options = {})
538
- xml.tag! :CardBrand, 'EC'
539
- xml.tag! :CurrencyCode, currency_code(options[:currency])
540
- xml.tag! :CurrencyExponent, currency_exponents(options[:currency])
541
- unless check.nil?
542
-
543
- xml.tag! :BCRtNum, check.routing_number
544
- xml.tag! :CheckDDA, check.account_number if check.account_number
545
- xml.tag! :BankAccountType, ACCOUNT_TYPE[check.account_type] if ACCOUNT_TYPE[check.account_type]
546
- xml.tag! :ECPAuthMethod, options[:auth_method] if options[:auth_method]
547
-
548
- if options[:payment_delivery]
549
- xml.tag! :BankPmtDelv, options[:payment_delivery]
550
- else
551
- xml.tag! :BankPmtDelv, 'B'
552
- end
566
+ return unless check
553
567
 
554
- xml.tag! :AVSname, (check&.name ? check.name[0..29] : nil) if get_address(options).blank?
555
- end
568
+ xml.tag! :CardBrand, 'EC'
569
+ add_currency_fields(xml, options[:currency])
570
+ xml.tag! :BCRtNum, check.routing_number
571
+ xml.tag! :CheckDDA, check.account_number if check.account_number
572
+ add_bank_account_type(xml, check)
573
+ xml.tag! :ECPAuthMethod, options[:auth_method] if options[:auth_method]
574
+ xml.tag! :BankPmtDelv, options[:payment_delivery] || 'B'
575
+ xml.tag! :AVSname, (check&.name ? check.name[0..29] : nil) if get_address(options).blank?
556
576
  end
557
577
 
558
- # Adds Credit Card attributes
559
- def add_creditcard(xml, creditcard, currency = nil)
560
- unless creditcard.nil?
561
- xml.tag! :AccountNum, creditcard.number
562
- xml.tag! :Exp, expiry_date(creditcard)
563
- end
578
+ def add_credit_card(xml, credit_card, options)
579
+ xml.tag! :AccountNum, credit_card.number if credit_card
580
+ xml.tag! :Exp, expiry_date(credit_card) if credit_card
581
+ add_currency_fields(xml, options[:currency])
582
+ add_verification_value(xml, credit_card) if credit_card
583
+ end
564
584
 
565
- xml.tag! :CurrencyCode, currency_code(currency)
566
- xml.tag! :CurrencyExponent, currency_exponents(currency)
585
+ def add_verification_value(xml, credit_card)
586
+ return unless credit_card&.verification_value?
567
587
 
568
588
  # If you are trying to collect a Card Verification Number
569
589
  # (CardSecVal) for a Visa or Discover transaction, pass one of these values:
@@ -574,131 +594,227 @@ module ActiveMerchant #:nodoc:
574
594
  # Null-fill this attribute OR
575
595
  # Do not submit the attribute at all.
576
596
  # - http://download.chasepaymentech.com/docs/orbital/orbital_gateway_xml_specification.pdf
577
- unless creditcard.nil?
578
- if creditcard.verification_value?
579
- xml.tag! :CardSecValInd, '1' if %w(visa master discover).include?(creditcard.brand)
580
- xml.tag! :CardSecVal, creditcard.verification_value
597
+ xml.tag! :CardSecValInd, '1' if %w(visa discover diners_club).include?(credit_card.brand)
598
+ xml.tag! :CardSecVal, credit_card.verification_value
599
+ end
600
+
601
+ def add_currency_fields(xml, currency)
602
+ xml.tag! :CurrencyCode, currency_code(currency)
603
+ xml.tag! :CurrencyExponent, currency_exponents(currency)
604
+ end
605
+
606
+ def add_bank_account_type(xml, check)
607
+ bank_account_type =
608
+ if check.account_holder_type == 'business'
609
+ 'X'
610
+ else
611
+ ACCOUNT_TYPE[check.account_type]
581
612
  end
582
- end
613
+
614
+ xml.tag! :BankAccountType, bank_account_type if bank_account_type
583
615
  end
584
616
 
585
- def add_eci(xml, creditcard, three_d_secure)
586
- eci = if three_d_secure
587
- three_d_secure[:eci]
588
- elsif creditcard.is_a?(NetworkTokenizationCreditCard)
589
- creditcard.eci
590
- end
617
+ def add_card_indicators(xml, options)
618
+ xml.tag! :CardIndicators, options[:card_indicators] if options[:card_indicators]
619
+ end
591
620
 
592
- xml.tag!(:AuthenticationECIInd, eci) if eci
621
+ def currency_code(currency)
622
+ CURRENCY_CODES[(currency || self.default_currency)].to_s
593
623
  end
594
624
 
595
- def add_xid(xml, creditcard, three_d_secure)
596
- return unless three_d_secure && creditcard.brand == 'visa'
625
+ def currency_exponents(currency)
626
+ CURRENCY_EXPONENTS[(currency || self.default_currency)].to_s
627
+ end
597
628
 
598
- xml.tag!(:XID, three_d_secure[:xid]) if three_d_secure[:xid]
629
+ def expiry_date(credit_card)
630
+ "#{format(credit_card.month, :two_digits)}#{format(credit_card.year, :two_digits)}"
599
631
  end
600
632
 
601
- def add_cavv(xml, creditcard, three_d_secure)
602
- return unless three_d_secure && creditcard.brand == 'visa'
633
+ def bin
634
+ @options[:bin] || (salem_mid? ? '000001' : '000002')
635
+ end
636
+
637
+ def salem_mid?
638
+ @options[:merchant_id].length == 6
639
+ end
640
+
641
+ #=====BRAND-SPECIFIC FIELDS=====
642
+
643
+ def add_cavv(xml, credit_card, three_d_secure)
644
+ return unless three_d_secure && credit_card.brand == 'visa'
603
645
 
604
646
  xml.tag!(:CAVV, three_d_secure[:cavv])
605
647
  end
606
648
 
607
- def add_aav(xml, creditcard, three_d_secure)
608
- return unless three_d_secure && creditcard.brand == 'master'
649
+ def add_aav(xml, credit_card, three_d_secure)
650
+ return unless three_d_secure && credit_card.brand == 'master'
609
651
 
610
652
  xml.tag!(:AAV, three_d_secure[:cavv])
611
653
  end
612
654
 
613
- def add_mc_program_protocol(xml, creditcard, three_d_secure)
614
- return unless three_d_secure && creditcard.brand == 'master'
615
- return unless three_d_secure[:version]
655
+ def add_aevv(xml, credit_card, three_d_secure)
656
+ return unless three_d_secure && credit_card.brand == 'american_express'
616
657
 
617
- truncated_version = three_d_secure[:version].to_s[0]
618
- xml.tag!(:MCProgramProtocol, truncated_version)
658
+ xml.tag!(:AEVV, three_d_secure[:cavv])
619
659
  end
620
660
 
621
- def add_mc_directory_trans_id(xml, creditcard, three_d_secure)
622
- return unless three_d_secure && creditcard.brand == 'master'
661
+ def add_xid(xml, credit_card, three_d_secure)
662
+ return unless three_d_secure && credit_card.brand == 'visa'
623
663
 
624
- xml.tag!(:MCDirectoryTransID, three_d_secure[:ds_transaction_id]) if three_d_secure[:ds_transaction_id]
664
+ xml.tag!(:XID, three_d_secure[:xid]) if three_d_secure[:xid]
625
665
  end
626
666
 
627
- def add_mc_ucafind(xml, creditcard, three_d_secure)
628
- return unless three_d_secure && creditcard.brand == 'master'
667
+ def add_pymt_brand_program_code(xml, credit_card, three_d_secure)
668
+ return unless three_d_secure && credit_card.brand == 'american_express'
629
669
 
630
- xml.tag! :UCAFInd, '4'
670
+ xml.tag!(:PymtBrandProgramCode, 'ASK')
631
671
  end
632
672
 
633
- def add_mc_scarecurring(xml, creditcard, parameters, three_d_secure)
634
- return unless parameters && parameters[:sca_recurring] && creditcard.brand == 'master'
673
+ def mastercard?(payment_source)
674
+ payment_source.is_a?(CreditCard) && payment_source.brand == 'master'
675
+ end
635
676
 
636
- valid_eci = three_d_secure && three_d_secure[:eci] && three_d_secure[:eci] == '7'
677
+ def add_mastercard_fields(xml, credit_card, parameters, three_d_secure)
678
+ add_mc_sca_merchant_initiated(xml, credit_card, parameters, three_d_secure)
679
+ add_mc_sca_recurring(xml, credit_card, parameters, three_d_secure)
680
+ add_mc_program_protocol(xml, credit_card, three_d_secure)
681
+ add_mc_directory_trans_id(xml, credit_card, three_d_secure)
682
+ add_mc_ucafind(xml, credit_card, three_d_secure)
683
+ end
637
684
 
638
- xml.tag!(:SCARecurringPayment, parameters[:sca_recurring]) if valid_eci
685
+ def add_mc_sca_merchant_initiated(xml, credit_card, parameters, three_d_secure)
686
+ return unless parameters.try(:[], :sca_merchant_initiated)
687
+ return unless three_d_secure.try(:[], :eci) == '7'
688
+
689
+ xml.tag!(:SCAMerchantInitiatedTransaction, parameters[:sca_merchant_initiated])
639
690
  end
640
691
 
641
- def add_mc_sca_merchant_initiated(xml, creditcard, parameters, three_d_secure)
642
- return unless parameters && parameters[:sca_merchant_initiated] && creditcard.brand == 'master'
692
+ def add_mc_sca_recurring(xml, credit_card, parameters, three_d_secure)
693
+ return unless parameters.try(:[], :sca_recurring)
694
+ return unless three_d_secure.try(:[], :eci) == '7'
695
+
696
+ xml.tag!(:SCARecurringPayment, parameters[:sca_recurring])
697
+ end
643
698
 
644
- valid_eci = three_d_secure && three_d_secure[:eci] && three_d_secure[:eci] == '7'
699
+ def add_mc_program_protocol(xml, credit_card, three_d_secure)
700
+ return unless version = three_d_secure.try(:[], :version)
645
701
 
646
- xml.tag!(:SCAMerchantInitiatedTransaction, parameters[:sca_merchant_initiated]) if valid_eci
702
+ xml.tag!(:MCProgramProtocol, version.to_s[0])
647
703
  end
648
704
 
649
- def add_dpanind(xml, creditcard)
650
- return unless creditcard.is_a?(NetworkTokenizationCreditCard)
705
+ def add_mc_directory_trans_id(xml, credit_card, three_d_secure)
706
+ return unless three_d_secure
651
707
 
652
- xml.tag! :DPANInd, 'Y'
708
+ xml.tag!(:MCDirectoryTransID, three_d_secure[:ds_transaction_id]) if three_d_secure[:ds_transaction_id]
653
709
  end
654
710
 
655
- def add_digital_token_cryptogram(xml, creditcard)
656
- return unless creditcard.is_a?(NetworkTokenizationCreditCard)
711
+ def add_mc_ucafind(xml, credit_card, three_d_secure)
712
+ return unless three_d_secure
657
713
 
658
- xml.tag! :DigitalTokenCryptogram, creditcard.payment_cryptogram
714
+ xml.tag! :UCAFInd, '4'
659
715
  end
660
716
 
661
- def add_aevv(xml, creditcard, three_d_secure)
662
- return unless three_d_secure && creditcard.brand == 'american_express'
717
+ #=====SCA (STORED CREDENTIAL) FIELDS=====
663
718
 
664
- xml.tag!(:AEVV, three_d_secure[:cavv])
719
+ def add_stored_credentials(xml, parameters)
720
+ return unless parameters[:mit_stored_credential_ind] == 'Y' || parameters[:stored_credential] && !parameters[:stored_credential].values.all?(&:nil?)
721
+
722
+ if msg_type = get_msg_type(parameters)
723
+ xml.tag! :MITMsgType, msg_type
724
+ end
725
+ xml.tag! :MITStoredCredentialInd, 'Y'
726
+ if parameters[:mit_submitted_transaction_id]
727
+ xml.tag! :MITSubmittedTransactionID, parameters[:mit_submitted_transaction_id]
728
+ elsif parameters.dig(:stored_credential, :network_transaction_id) && parameters.dig(:stored_credential, :initiator) == 'merchant'
729
+ xml.tag! :MITSubmittedTransactionID, parameters[:stored_credential][:network_transaction_id]
730
+ end
665
731
  end
666
732
 
667
- def add_pymt_brand_program_code(xml, creditcard, three_d_secure)
668
- return unless three_d_secure && creditcard.brand == 'american_express'
733
+ def get_msg_type(parameters)
734
+ return parameters[:mit_msg_type] if parameters[:mit_msg_type]
735
+ return 'CSTO' if parameters[:stored_credential][:initial_transaction]
736
+ return unless parameters[:stored_credential][:initiator] && parameters[:stored_credential][:reason_type]
669
737
 
670
- xml.tag!(:PymtBrandProgramCode, 'ASK')
738
+ initiator =
739
+ case parameters[:stored_credential][:initiator]
740
+ when 'cardholder', 'customer' then 'C'
741
+ when 'merchant' then 'M'
742
+ end
743
+ reason =
744
+ case parameters[:stored_credential][:reason_type]
745
+ when 'recurring' then 'REC'
746
+ when 'installment' then 'INS'
747
+ when 'unscheduled' then 'USE'
748
+ end
749
+
750
+ "#{initiator}#{reason}"
671
751
  end
672
752
 
673
- def add_refund(xml, currency = nil)
674
- xml.tag! :AccountNum, nil
753
+ #=====NETWORK TOKENIZATION FIELDS=====
675
754
 
676
- xml.tag! :CurrencyCode, currency_code(currency)
677
- xml.tag! :CurrencyExponent, currency_exponents(currency)
755
+ def add_eci(xml, credit_card, three_d_secure)
756
+ eci = if three_d_secure
757
+ three_d_secure[:eci]
758
+ elsif credit_card.is_a?(NetworkTokenizationCreditCard)
759
+ credit_card.eci
760
+ end
761
+
762
+ xml.tag!(:AuthenticationECIInd, eci) if eci
763
+ end
764
+
765
+ def add_dpanind(xml, credit_card, industry_type = nil)
766
+ return unless credit_card.is_a?(NetworkTokenizationCreditCard)
767
+
768
+ xml.tag! :DPANInd, 'Y' unless industry_type == 'RC'
769
+ end
770
+
771
+ def add_digital_token_cryptogram(xml, credit_card, three_d_secure)
772
+ return unless credit_card.is_a?(NetworkTokenizationCreditCard) || three_d_secure && credit_card.brand == 'discover'
773
+
774
+ cryptogram =
775
+ if three_d_secure && credit_card.brand == 'discover'
776
+ three_d_secure[:cavv]
777
+ else
778
+ credit_card.payment_cryptogram
779
+ end
780
+
781
+ xml.tag!(:DigitalTokenCryptogram, cryptogram)
782
+ end
783
+
784
+ #=====OTHER FIELDS=====
785
+
786
+ # For Canadian transactions on PNS Tampa on New Order
787
+ # RF - First Recurring Transaction
788
+ # RS - Subsequent Recurring Transactions
789
+ def set_recurring_ind(xml, parameters)
790
+ return unless parameters[:recurring_ind]
791
+ raise 'RecurringInd must be set to either "RF" or "RS"' unless %w(RF RS).include?(parameters[:recurring_ind])
792
+
793
+ xml.tag! :RecurringInd, parameters[:recurring_ind]
678
794
  end
679
795
 
680
796
  def add_managed_billing(xml, options)
681
- if mb = options[:managed_billing]
682
- ActiveMerchant.deprecated RECURRING_DEPRECATION_MESSAGE
683
-
684
- # default to recurring (R). Other option is deferred (D).
685
- xml.tag! :MBType, mb[:type] || RECURRING
686
- # default to Customer Reference Number
687
- xml.tag! :MBOrderIdGenerationMethod, mb[:order_id_generation_method] || 'IO'
688
- # By default use MBRecurringEndDate, set to N.
689
- # MMDDYYYY
690
- xml.tag! :MBRecurringStartDate, mb[:start_date].scan(/\d/).join.to_s if mb[:start_date]
691
- # MMDDYYYY
692
- xml.tag! :MBRecurringEndDate, mb[:end_date].scan(/\d/).join.to_s if mb[:end_date]
693
- # By default listen to any value set in MBRecurringEndDate.
694
- xml.tag! :MBRecurringNoEndDateFlag, mb[:no_end_date_flag] || 'N' # 'Y' || 'N' (Yes or No).
695
- xml.tag! :MBRecurringMaxBillings, mb[:max_billings] if mb[:max_billings]
696
- xml.tag! :MBRecurringFrequency, mb[:frequency] if mb[:frequency]
697
- xml.tag! :MBDeferredBillDate, mb[:deferred_bill_date] if mb[:deferred_bill_date]
698
- xml.tag! :MBMicroPaymentMaxDollarValue, mb[:max_dollar_value] if mb[:max_dollar_value]
699
- xml.tag! :MBMicroPaymentMaxBillingDays, mb[:max_billing_days] if mb[:max_billing_days]
700
- xml.tag! :MBMicroPaymentMaxTransactions, mb[:max_transactions] if mb[:max_transactions]
701
- end
797
+ return unless mb = options[:managed_billing]
798
+
799
+ ActiveMerchant.deprecated RECURRING_DEPRECATION_MESSAGE
800
+
801
+ # default to recurring (R). Other option is deferred (D).
802
+ xml.tag! :MBType, mb[:type] || RECURRING
803
+ # default to Customer Reference Number
804
+ xml.tag! :MBOrderIdGenerationMethod, mb[:order_id_generation_method] || 'IO'
805
+ # By default use MBRecurringEndDate, set to N.
806
+ # MMDDYYYY
807
+ xml.tag! :MBRecurringStartDate, mb[:start_date].scan(/\d/).join.to_s if mb[:start_date]
808
+ # MMDDYYYY
809
+ xml.tag! :MBRecurringEndDate, mb[:end_date].scan(/\d/).join.to_s if mb[:end_date]
810
+ # By default listen to any value set in MBRecurringEndDate.
811
+ xml.tag! :MBRecurringNoEndDateFlag, mb[:no_end_date_flag] || 'N' # 'Y' || 'N' (Yes or No).
812
+ xml.tag! :MBRecurringMaxBillings, mb[:max_billings] if mb[:max_billings]
813
+ xml.tag! :MBRecurringFrequency, mb[:frequency] if mb[:frequency]
814
+ xml.tag! :MBDeferredBillDate, mb[:deferred_bill_date] if mb[:deferred_bill_date]
815
+ xml.tag! :MBMicroPaymentMaxDollarValue, mb[:max_dollar_value] if mb[:max_dollar_value]
816
+ xml.tag! :MBMicroPaymentMaxBillingDays, mb[:max_billing_days] if mb[:max_billing_days]
817
+ xml.tag! :MBMicroPaymentMaxTransactions, mb[:max_transactions] if mb[:max_transactions]
702
818
  end
703
819
 
704
820
  def add_ews_details(xml, payment_source, parameters = {})
@@ -737,61 +853,20 @@ module ActiveMerchant #:nodoc:
737
853
  end
738
854
  end
739
855
 
740
- def add_stored_credentials(xml, parameters)
741
- return unless parameters[:mit_stored_credential_ind] == 'Y' || parameters[:stored_credential] && !parameters[:stored_credential].values.all?(&:nil?)
742
-
743
- if msg_type = get_msg_type(parameters)
744
- xml.tag! :MITMsgType, msg_type
745
- end
746
- xml.tag! :MITStoredCredentialInd, 'Y'
747
- if parameters[:mit_submitted_transaction_id]
748
- xml.tag! :MITSubmittedTransactionID, parameters[:mit_submitted_transaction_id]
749
- elsif parameters.dig(:stored_credential, :network_transaction_id) && parameters.dig(:stored_credential, :initiator) == 'merchant'
750
- xml.tag! :MITSubmittedTransactionID, parameters[:stored_credential][:network_transaction_id]
856
+ def add_xml_credentials(xml)
857
+ unless ip_authentication?
858
+ xml.tag! :OrbitalConnectionUsername, @options[:login]
859
+ xml.tag! :OrbitalConnectionPassword, @options[:password]
751
860
  end
752
861
  end
753
862
 
754
- def get_msg_type(parameters)
755
- return parameters[:mit_msg_type] if parameters[:mit_msg_type]
756
- return 'CSTO' if parameters[:stored_credential][:initial_transaction]
757
- return unless parameters[:stored_credential][:initiator] && parameters[:stored_credential][:reason_type]
758
-
759
- initiator =
760
- case parameters[:stored_credential][:initiator]
761
- when 'cardholder', 'customer' then 'C'
762
- when 'merchant' then 'M'
763
- end
764
- reason =
765
- case parameters[:stored_credential][:reason_type]
766
- when 'recurring' then 'REC'
767
- when 'installment' then 'INS'
768
- when 'unscheduled' then 'USE'
769
- end
770
-
771
- "#{initiator}#{reason}"
863
+ def add_bin_merchant_and_terminal(xml, parameters)
864
+ xml.tag! :BIN, bin
865
+ xml.tag! :MerchantID, @options[:merchant_id]
866
+ xml.tag! :TerminalID, parameters[:terminal_id] || '001'
772
867
  end
773
868
 
774
- def parse(body)
775
- response = {}
776
- xml = REXML::Document.new(strip_invalid_xml_chars(body))
777
- root = REXML::XPath.first(xml, '//Response') ||
778
- REXML::XPath.first(xml, '//ErrorResponse')
779
- if root
780
- root.elements.to_a.each do |node|
781
- recurring_parse_element(response, node)
782
- end
783
- end
784
-
785
- response.delete_if { |k, _| SENSITIVE_FIELDS.include?(k) }
786
- end
787
-
788
- def recurring_parse_element(response, node)
789
- if node.has_elements?
790
- node.elements.each { |e| recurring_parse_element(response, e) }
791
- else
792
- response[node.name.underscore.to_sym] = node.text
793
- end
794
- end
869
+ #=====REQUEST/RESPONSE METHODS=====
795
870
 
796
871
  def commit(order, message_type, retry_logic = nil, trace_number = nil)
797
872
  headers = POST_HEADERS.merge('Content-length' => order.size.to_s)
@@ -804,6 +879,8 @@ module ActiveMerchant #:nodoc:
804
879
  # Failover URL will be attempted in the event of a connection error
805
880
  response =
806
881
  begin
882
+ raise ConnectionError.new 'Should use secondary url', 500 if @use_secondary_url
883
+
807
884
  request.call(remote_url)
808
885
  rescue ConnectionError
809
886
  request.call(remote_url(:secondary))
@@ -826,6 +903,28 @@ module ActiveMerchant #:nodoc:
826
903
  end
827
904
  end
828
905
 
906
+ def parse(body)
907
+ response = {}
908
+ xml = REXML::Document.new(strip_invalid_xml_chars(body))
909
+ root = REXML::XPath.first(xml, '//Response') ||
910
+ REXML::XPath.first(xml, '//ErrorResponse')
911
+ if root
912
+ root.elements.to_a.each do |node|
913
+ recurring_parse_element(response, node)
914
+ end
915
+ end
916
+
917
+ response.delete_if { |k, _| SENSITIVE_FIELDS.include?(k) }
918
+ end
919
+
920
+ def recurring_parse_element(response, node)
921
+ if node.has_elements?
922
+ node.elements.each { |e| recurring_parse_element(response, e) }
923
+ else
924
+ response[node.name.underscore.to_sym] = node.text
925
+ end
926
+ end
927
+
829
928
  def success?(response, message_type)
830
929
  if %i[void].include?(message_type)
831
930
  response[:proc_status] == SUCCESS
@@ -847,24 +946,27 @@ module ActiveMerchant #:nodoc:
847
946
  @options[:ip_authentication] == true
848
947
  end
849
948
 
949
+ #=====BUILDER METHODS=====
950
+
951
+ def build_new_auth_purchase_order(action, money, payment_source, options)
952
+ build_new_order_xml(action, money, payment_source, options) do |xml|
953
+ add_payment_source(xml, payment_source, options)
954
+ add_address(xml, payment_source, options)
955
+ if @options[:customer_profiles]
956
+ add_customer_data(xml, payment_source, options)
957
+ add_managed_billing(xml, options)
958
+ end
959
+ end
960
+ end
961
+
850
962
  def build_new_order_xml(action, money, payment_source, parameters = {})
851
963
  requires!(parameters, :order_id)
964
+ @use_secondary_url = parameters[:use_secondary_url] if parameters[:use_secondary_url]
852
965
  xml = xml_envelope
853
966
  xml.tag! :Request do
854
967
  xml.tag! :NewOrder do
855
968
  add_xml_credentials(xml)
856
- # EC - Ecommerce transaction
857
- # RC - Recurring Payment transaction
858
- # MO - Mail Order Telephone Order transaction
859
- # IV - Interactive Voice Response
860
- # IN - Interactive Voice Response
861
969
  xml.tag! :IndustryType, parameters[:industry_type] || ECOMMERCE_TRANSACTION
862
- # A - Auth Only No Capture
863
- # AC - Auth and Capture
864
- # F - Force Auth No Capture and no online authorization
865
- # FR - Force Auth No Capture and no online authorization
866
- # FC - Force Auth and Capture no online authorization
867
- # R - Refund and Capture no online authorization
868
970
  xml.tag! :MessageType, action
869
971
  add_bin_merchant_and_terminal(xml, parameters)
870
972
 
@@ -886,25 +988,18 @@ module ActiveMerchant #:nodoc:
886
988
  add_aav(xml, payment_source, three_d_secure)
887
989
  # CustomerAni, AVSPhoneType and AVSDestPhoneType could be added here.
888
990
 
889
- if parameters[:soft_descriptors].is_a?(OrbitalSoftDescriptors)
890
- add_soft_descriptors(xml, parameters[:soft_descriptors])
891
- elsif parameters[:soft_descriptors].is_a?(Hash)
892
- add_soft_descriptors_from_hash(xml, parameters[:soft_descriptors])
893
- end
894
-
895
- add_dpanind(xml, payment_source)
991
+ add_soft_descriptors(xml, parameters[:soft_descriptors])
992
+ add_payment_action_ind(xml, parameters[:payment_action_ind])
993
+ add_dpanind(xml, payment_source, parameters[:industry_type])
896
994
  add_aevv(xml, payment_source, three_d_secure)
897
- add_digital_token_cryptogram(xml, payment_source)
995
+ add_digital_token_cryptogram(xml, payment_source, three_d_secure)
898
996
 
899
997
  xml.tag! :ECPSameDayInd, parameters[:same_day] if parameters[:same_day] && payment_source.is_a?(Check)
900
998
 
901
999
  set_recurring_ind(xml, parameters)
902
1000
 
903
1001
  # Append Transaction Reference Number at the end for Refund transactions
904
- if action == REFUND && parameters[:authorization]
905
- tx_ref_num, = split_authorization(parameters[:authorization])
906
- xml.tag! :TxRefNum, tx_ref_num
907
- end
1002
+ add_tx_ref_num(xml, parameters[:authorization]) if action == REFUND && payment_source.nil?
908
1003
 
909
1004
  add_level2_purchase(xml, parameters)
910
1005
  add_level3_purchase(xml, parameters)
@@ -914,27 +1009,12 @@ module ActiveMerchant #:nodoc:
914
1009
  add_card_indicators(xml, parameters)
915
1010
  add_stored_credentials(xml, parameters)
916
1011
  add_pymt_brand_program_code(xml, payment_source, three_d_secure)
917
- add_mc_sca_merchant_initiated(xml, payment_source, parameters, three_d_secure)
918
- add_mc_scarecurring(xml, payment_source, parameters, three_d_secure)
919
- add_mc_program_protocol(xml, payment_source, three_d_secure)
920
- add_mc_directory_trans_id(xml, payment_source, three_d_secure)
921
- add_mc_ucafind(xml, payment_source, three_d_secure)
1012
+ add_mastercard_fields(xml, payment_source, parameters, three_d_secure) if mastercard?(payment_source)
922
1013
  end
923
1014
  end
924
1015
  xml.target!
925
1016
  end
926
1017
 
927
- # For Canadian transactions on PNS Tampa on New Order
928
- # RF - First Recurring Transaction
929
- # RS - Subsequent Recurring Transactions
930
- def set_recurring_ind(xml, parameters)
931
- if parameters[:recurring_ind]
932
- raise 'RecurringInd must be set to either "RF" or "RS"' unless %w(RF RS).include?(parameters[:recurring_ind])
933
-
934
- xml.tag! :RecurringInd, parameters[:recurring_ind]
935
- end
936
- end
937
-
938
1018
  def build_mark_for_capture_xml(money, authorization, parameters = {})
939
1019
  tx_ref_num, order_id = split_authorization(authorization)
940
1020
  xml = xml_envelope
@@ -974,49 +1054,12 @@ module ActiveMerchant #:nodoc:
974
1054
  xml.target!
975
1055
  end
976
1056
 
977
- def currency_code(currency)
978
- CURRENCY_CODES[(currency || self.default_currency)].to_s
979
- end
980
-
981
- def currency_exponents(currency)
982
- CURRENCY_EXPONENTS[(currency || self.default_currency)].to_s
983
- end
984
-
985
- def expiry_date(credit_card)
986
- "#{format(credit_card.month, :two_digits)}#{format(credit_card.year, :two_digits)}"
987
- end
988
-
989
- def bin
990
- @options[:bin] || (salem_mid? ? '000001' : '000002')
991
- end
992
-
993
1057
  def xml_envelope
994
1058
  xml = Builder::XmlMarkup.new(indent: 2)
995
1059
  xml.instruct!(:xml, version: '1.0', encoding: 'UTF-8')
996
1060
  xml
997
1061
  end
998
1062
 
999
- def add_xml_credentials(xml)
1000
- unless ip_authentication?
1001
- xml.tag! :OrbitalConnectionUsername, @options[:login]
1002
- xml.tag! :OrbitalConnectionPassword, @options[:password]
1003
- end
1004
- end
1005
-
1006
- def add_bin_merchant_and_terminal(xml, parameters)
1007
- xml.tag! :BIN, bin
1008
- xml.tag! :MerchantID, @options[:merchant_id]
1009
- xml.tag! :TerminalID, parameters[:terminal_id] || '001'
1010
- end
1011
-
1012
- def salem_mid?
1013
- @options[:merchant_id].length == 6
1014
- end
1015
-
1016
- def get_address(options)
1017
- options[:billing_address] || options[:address]
1018
- end
1019
-
1020
1063
  # Null characters are possible in some responses (namely, the respMsg field), causing XML parsing errors
1021
1064
  # Prevent by substituting these with a valid placeholder string
1022
1065
  def strip_invalid_xml_chars(xml)
@@ -1056,7 +1099,7 @@ module ActiveMerchant #:nodoc:
1056
1099
  limited_value
1057
1100
  end
1058
1101
 
1059
- def build_customer_request_xml(creditcard, options = {})
1102
+ def build_customer_request_xml(credit_card, options = {})
1060
1103
  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.'
1061
1104
  xml = xml_envelope
1062
1105
  xml.tag! :Request do
@@ -1065,7 +1108,7 @@ module ActiveMerchant #:nodoc:
1065
1108
  xml.tag! :OrbitalConnectionPassword, @options[:password] unless ip_authentication?
1066
1109
  xml.tag! :CustomerBin, bin
1067
1110
  xml.tag! :CustomerMerchantID, @options[:merchant_id]
1068
- xml.tag! :CustomerName, creditcard.name if creditcard
1111
+ xml.tag! :CustomerName, credit_card.name if credit_card
1069
1112
  xml.tag! :CustomerRefNum, options[:customer_ref_num] if options[:customer_ref_num]
1070
1113
 
1071
1114
  add_customer_address(xml, options)
@@ -1093,8 +1136,8 @@ module ActiveMerchant #:nodoc:
1093
1136
  xml.tag! :Status, options[:status] || ACTIVE # Active
1094
1137
  end
1095
1138
 
1096
- xml.tag! :CCAccountNum, creditcard.number if creditcard
1097
- xml.tag! :CCExpireDate, creditcard.expiry_date.expiration.strftime('%m%y') if creditcard
1139
+ xml.tag! :CCAccountNum, credit_card.number if credit_card
1140
+ xml.tag! :CCExpireDate, credit_card.expiry_date.expiration.strftime('%m%y') if credit_card
1098
1141
 
1099
1142
  # This has to come after CCExpireDate.
1100
1143
  add_managed_billing(xml, options)