activemerchant 1.116.0 → 1.121.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +148 -1
  3. data/README.md +4 -2
  4. data/lib/active_merchant/billing/check.rb +10 -0
  5. data/lib/active_merchant/billing/credit_card.rb +3 -0
  6. data/lib/active_merchant/billing/credit_card_methods.rb +80 -15
  7. data/lib/active_merchant/billing/gateways/adyen.rb +29 -8
  8. data/lib/active_merchant/billing/gateways/authorize_net.rb +37 -1
  9. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +4 -0
  10. data/lib/active_merchant/billing/gateways/blue_snap.rb +3 -1
  11. data/lib/active_merchant/billing/gateways/braintree_blue.rb +54 -7
  12. data/lib/active_merchant/billing/gateways/cashnet.rb +7 -2
  13. data/lib/active_merchant/billing/gateways/checkout_v2.rb +33 -2
  14. data/lib/active_merchant/billing/gateways/credorax.rb +30 -14
  15. data/lib/active_merchant/billing/gateways/cyber_source.rb +51 -8
  16. data/lib/active_merchant/billing/gateways/d_local.rb +1 -1
  17. data/lib/active_merchant/billing/gateways/decidir.rb +22 -2
  18. data/lib/active_merchant/billing/gateways/elavon.rb +54 -2
  19. data/lib/active_merchant/billing/gateways/eway_rapid.rb +13 -0
  20. data/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb +17 -6
  21. data/lib/active_merchant/billing/gateways/forte.rb +12 -0
  22. data/lib/active_merchant/billing/gateways/global_collect.rb +25 -6
  23. data/lib/active_merchant/billing/gateways/hps.rb +65 -2
  24. data/lib/active_merchant/billing/gateways/litle.rb +21 -5
  25. data/lib/active_merchant/billing/gateways/mercado_pago.rb +2 -2
  26. data/lib/active_merchant/billing/gateways/netbanx.rb +37 -2
  27. data/lib/active_merchant/billing/gateways/orbital.rb +178 -45
  28. data/lib/active_merchant/billing/gateways/payeezy.rb +53 -11
  29. data/lib/active_merchant/billing/gateways/payment_express.rb +10 -5
  30. data/lib/active_merchant/billing/gateways/paymentez.rb +21 -1
  31. data/lib/active_merchant/billing/gateways/paypal.rb +10 -2
  32. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +1 -0
  33. data/lib/active_merchant/billing/gateways/paypal_express.rb +1 -0
  34. data/lib/active_merchant/billing/gateways/payway_dot_com.rb +253 -0
  35. data/lib/active_merchant/billing/gateways/pin.rb +11 -0
  36. data/lib/active_merchant/billing/gateways/qvalent.rb +23 -9
  37. data/lib/active_merchant/billing/gateways/redsys.rb +101 -5
  38. data/lib/active_merchant/billing/gateways/safe_charge.rb +39 -6
  39. data/lib/active_merchant/billing/gateways/stripe.rb +9 -9
  40. data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +82 -25
  41. data/lib/active_merchant/billing/gateways/vpos.rb +177 -0
  42. data/lib/active_merchant/billing/gateways/worldpay.rb +31 -14
  43. data/lib/active_merchant/billing/response.rb +2 -1
  44. data/lib/active_merchant/version.rb +1 -1
  45. data/lib/certs/cacert.pem +1582 -2431
  46. metadata +5 -3
@@ -5,7 +5,10 @@ module ActiveMerchant #:nodoc:
5
5
  class LitleGateway < Gateway
6
6
  SCHEMA_VERSION = '9.14'
7
7
 
8
+ class_attribute :postlive_url
9
+
8
10
  self.test_url = 'https://www.testvantivcnp.com/sandbox/communicator/online'
11
+ self.postlive_url = 'https://payments.vantivpostlive.com/vap/communicator/online'
9
12
  self.live_url = 'https://payments.vantivcnp.com/vap/communicator/online'
10
13
 
11
14
  self.supported_countries = ['US']
@@ -84,7 +87,7 @@ module ActiveMerchant #:nodoc:
84
87
  elsif check?(payment)
85
88
  add_echeck_purchase_params(doc, money, payment, options)
86
89
  else
87
- add_auth_purchase_params(doc, money, payment, options)
90
+ add_credit_params(doc, money, payment, options)
88
91
  end
89
92
  end
90
93
  end
@@ -227,6 +230,17 @@ module ActiveMerchant #:nodoc:
227
230
  add_stored_credential_params(doc, options)
228
231
  end
229
232
 
233
+ def add_credit_params(doc, money, payment_method, options)
234
+ doc.orderId(truncate(options[:order_id], 24))
235
+ doc.amount(money)
236
+ add_order_source(doc, payment_method, options)
237
+ add_billing_address(doc, payment_method, options)
238
+ add_payment_method(doc, payment_method, options)
239
+ add_pos(doc, payment_method)
240
+ add_descriptor(doc, options)
241
+ add_merchant_data(doc, options)
242
+ end
243
+
230
244
  def add_merchant_data(doc, options = {})
231
245
  if options[:affiliate] || options[:campaign] || options[:merchant_grouping_id]
232
246
  doc.merchantData do
@@ -357,9 +371,9 @@ module ActiveMerchant #:nodoc:
357
371
  return unless address
358
372
 
359
373
  doc.companyName(address[:company]) unless address[:company].blank?
360
- doc.addressLine1(address[:address1]) unless address[:address1].blank?
361
- doc.addressLine2(address[:address2]) unless address[:address2].blank?
362
- doc.city(address[:city]) unless address[:city].blank?
374
+ doc.addressLine1(truncate(address[:address1], 35)) unless address[:address1].blank?
375
+ doc.addressLine2(truncate(address[:address2], 35)) unless address[:address2].blank?
376
+ doc.city(truncate(address[:city], 35)) unless address[:city].blank?
363
377
  doc.state(address[:state]) unless address[:state].blank?
364
378
  doc.zip(address[:zip]) unless address[:zip].blank?
365
379
  doc.country(address[:country]) unless address[:country].blank?
@@ -480,7 +494,7 @@ module ActiveMerchant #:nodoc:
480
494
  attributes = {}
481
495
  attributes[:id] = truncate(options[:id] || options[:order_id], 24)
482
496
  attributes[:reportGroup] = options[:merchant] || 'Default Report Group'
483
- attributes[:customerId] = options[:customer]
497
+ attributes[:customerId] = options[:customer_id]
484
498
  attributes.delete_if { |_key, value| value == nil }
485
499
  attributes
486
500
  end
@@ -502,6 +516,8 @@ module ActiveMerchant #:nodoc:
502
516
  end
503
517
 
504
518
  def url
519
+ return postlive_url if @options[:url_override].to_s == 'postlive'
520
+
505
521
  test? ? test_url : live_url
506
522
  end
507
523
 
@@ -4,7 +4,7 @@ module ActiveMerchant #:nodoc:
4
4
  self.live_url = self.test_url = 'https://api.mercadopago.com/v1'
5
5
 
6
6
  self.supported_countries = %w[AR BR CL CO MX PE UY]
7
- self.supported_cardtypes = %i[visa master american_express elo cabal naranja]
7
+ self.supported_cardtypes = %i[visa master american_express elo cabal naranja creditel]
8
8
 
9
9
  self.homepage_url = 'https://www.mercadopago.com/'
10
10
  self.display_name = 'Mercado Pago'
@@ -105,7 +105,7 @@ module ActiveMerchant #:nodoc:
105
105
 
106
106
  def authorize_request(money, payment, options = {})
107
107
  post = purchase_request(money, payment, options)
108
- post[:capture] = false
108
+ post[:capture] = options[:capture] || false
109
109
  post
110
110
  end
111
111
 
@@ -22,6 +22,22 @@ module ActiveMerchant #:nodoc:
22
22
  self.homepage_url = 'https://processing.paysafe.com/'
23
23
  self.display_name = 'Netbanx by PaySafe'
24
24
 
25
+ AVS_CODE_CONVERTER = {
26
+ 'MATCH' => 'X',
27
+ 'MATCH_ADDRESS_ONLY' => 'A',
28
+ 'MATCH_ZIP_ONLY' => 'Z',
29
+ 'NO_MATCH' => 'N',
30
+ 'NOT_PROCESSED' => 'U',
31
+ 'UNKNOWN' => 'Q'
32
+ }
33
+
34
+ CVV_CODE_CONVERTER = {
35
+ 'MATCH' => 'M',
36
+ 'NO_MATCH' => 'N',
37
+ 'NOT_PROCESSED' => 'P',
38
+ 'UNKNOWN' => 'U'
39
+ }
40
+
25
41
  def initialize(options = {})
26
42
  requires!(options, :account_number, :api_key)
27
43
  super
@@ -36,6 +52,7 @@ module ActiveMerchant #:nodoc:
36
52
  add_invoice(post, money, options)
37
53
  add_settle_with_auth(post)
38
54
  add_payment(post, payment, options)
55
+ add_customer_detail_data(post, options)
39
56
 
40
57
  commit(:post, 'auths', post)
41
58
  end
@@ -48,6 +65,7 @@ module ActiveMerchant #:nodoc:
48
65
  post = {}
49
66
  add_invoice(post, money, options)
50
67
  add_payment(post, payment, options)
68
+ add_customer_detail_data(post, options)
51
69
 
52
70
  commit(:post, 'auths', post)
53
71
  end
@@ -147,6 +165,15 @@ module ActiveMerchant #:nodoc:
147
165
  post[:locale] = options[:locale]
148
166
  end
149
167
 
168
+ def add_customer_detail_data(post, options)
169
+ post[:profile] ||= {}
170
+ post[:profile][:email] = options[:email] if options[:email]
171
+ post[:customerIp] = options[:ip] if options[:ip]
172
+ if (billing_address = options[:billing_address])
173
+ post[:profile][:firstName], post[:profile][:lastName] = split_names(billing_address[:name])
174
+ end
175
+ end
176
+
150
177
  def add_credit_card(post, credit_card, options = {})
151
178
  post[:card] ||= {}
152
179
  post[:card][:cardNum] = credit_card.number
@@ -245,11 +272,19 @@ module ActiveMerchant #:nodoc:
245
272
  test: test?,
246
273
  error_code: error_code_from(response),
247
274
  authorization: authorization_from(success, get_url(uri), method, response),
248
- avs_result: AVSResult.new(code: response['avsResponse']),
249
- cvv_result: CVVResult.new(response['cvvVerification'])
275
+ avs_result: avs_result(response),
276
+ cvv_result: cvv_result(response)
250
277
  )
251
278
  end
252
279
 
280
+ def avs_result(response)
281
+ AVSResult.new(code: AVS_CODE_CONVERTER[response['avsResponse']])
282
+ end
283
+
284
+ def cvv_result(response)
285
+ CVVResult.new(CVV_CODE_CONVERTER[response['cvvVerification']])
286
+ end
287
+
253
288
  def get_url(uri)
254
289
  url = (test? ? test_url : live_url)
255
290
  if /^customervault/.match?(uri)
@@ -30,7 +30,7 @@ module ActiveMerchant #:nodoc:
30
30
  class OrbitalGateway < Gateway
31
31
  include Empty
32
32
 
33
- API_VERSION = '7.7'
33
+ API_VERSION = '8.1'
34
34
 
35
35
  POST_HEADERS = {
36
36
  'MIME-Version' => '1.1',
@@ -60,7 +60,8 @@ module ActiveMerchant #:nodoc:
60
60
  '93', # Approved high fraud
61
61
  '94', # Approved fraud service unavailable
62
62
  'E7', # Stored
63
- 'PA' # Partial approval
63
+ 'PA', # Partial approval
64
+ 'P1' # ECP - AVS - Account Status Verification and/or AOA data is in a positive status.
64
65
  ]
65
66
 
66
67
  class_attribute :secondary_test_url, :secondary_live_url
@@ -183,6 +184,12 @@ module ActiveMerchant #:nodoc:
183
184
 
184
185
  SENSITIVE_FIELDS = %i[account_num cc_account_num]
185
186
 
187
+ # Bank account types to be used for check processing
188
+ ACCOUNT_TYPE = {
189
+ 'savings' => 'S',
190
+ 'checking' => 'C'
191
+ }
192
+
186
193
  def initialize(options = {})
187
194
  requires!(options, :merchant_id)
188
195
  requires!(options, :login, :password) unless options[:ip_authentication]
@@ -191,16 +198,24 @@ module ActiveMerchant #:nodoc:
191
198
  end
192
199
 
193
200
  # A – Authorization request
194
- def authorize(money, creditcard, options = {})
195
- order = build_new_order_xml(AUTH_ONLY, money, creditcard, options) do |xml|
196
- add_creditcard(xml, creditcard, options[:currency])
197
- add_address(xml, creditcard, options)
201
+ def authorize(money, payment_source, options = {})
202
+ # ECP for Orbital requires $0 prenotes so ensure
203
+ # if we are doing a force capture with a check, that
204
+ # we do a purchase here
205
+ if options[:force_capture] && payment_source.is_a?(Check) &&
206
+ (options[:action_code].include?('W8') || options[:action_code].include?('W9') || options[:action_code].include?('ND'))
207
+ return purchase(money, payment_source, options)
208
+ end
209
+
210
+ order = build_new_order_xml(AUTH_ONLY, money, payment_source, options) do |xml|
211
+ add_payment_source(xml, payment_source, options)
212
+ add_address(xml, payment_source, options)
198
213
  if @options[:customer_profiles]
199
- add_customer_data(xml, creditcard, options)
214
+ add_customer_data(xml, payment_source, options)
200
215
  add_managed_billing(xml, options)
201
216
  end
202
217
  end
203
- commit(order, :authorize, options[:trace_number])
218
+ commit(order, :authorize, options[:retry_logic], options[:trace_number])
204
219
  end
205
220
 
206
221
  def verify(creditcard, options = {})
@@ -211,35 +226,43 @@ module ActiveMerchant #:nodoc:
211
226
  end
212
227
 
213
228
  # AC – Authorization and Capture
214
- def purchase(money, creditcard, options = {})
215
- order = build_new_order_xml(AUTH_AND_CAPTURE, money, creditcard, options) do |xml|
216
- add_creditcard(xml, creditcard, options[:currency])
217
- add_address(xml, creditcard, options)
229
+ def purchase(money, payment_source, options = {})
230
+ order = build_new_order_xml(options[:force_capture] ? FORCE_AUTH_AND_CAPTURE : AUTH_AND_CAPTURE, money, payment_source, options) do |xml|
231
+ add_payment_source(xml, payment_source, options)
232
+ add_address(xml, payment_source, options)
218
233
  if @options[:customer_profiles]
219
- add_customer_data(xml, creditcard, options)
234
+ add_customer_data(xml, payment_source, options)
220
235
  add_managed_billing(xml, options)
221
236
  end
222
237
  end
223
- commit(order, :purchase, options[:trace_number])
238
+
239
+ commit(order, :purchase, options[:retry_logic], options[:trace_number])
224
240
  end
225
241
 
226
242
  # MFC - Mark For Capture
227
243
  def capture(money, authorization, options = {})
228
- commit(build_mark_for_capture_xml(money, authorization, options), :capture)
244
+ commit(build_mark_for_capture_xml(money, authorization, options), :capture, options[:retry_logic], options[:trace_number])
229
245
  end
230
246
 
231
247
  # R – Refund request
232
248
  def refund(money, authorization, options = {})
233
- order = build_new_order_xml(REFUND, money, nil, options.merge(authorization: authorization)) do |xml|
234
- add_refund(xml, options[:currency])
249
+ payment_method = options[:payment_method]
250
+ order = build_new_order_xml(REFUND, money, payment_method, options.merge(authorization: authorization)) do |xml|
251
+ if payment_method.is_a?(Check)
252
+ add_echeck(xml, payment_method, options)
253
+ else
254
+ add_refund(xml, options[:currency])
255
+ end
235
256
  xml.tag! :CustomerRefNum, options[:customer_ref_num] if @options[:customer_profiles] && options[:profile_txn]
236
257
  end
237
- commit(order, :refund, options[:trace_number])
258
+ commit(order, :refund, options[:retry_logic], options[:trace_number])
238
259
  end
239
260
 
240
- def credit(money, authorization, options = {})
241
- ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
242
- refund(money, authorization, options)
261
+ def credit(money, payment_method, options = {})
262
+ order = build_new_order_xml(REFUND, money, payment_method, options) do |xml|
263
+ add_payment_source(xml, payment_method, options)
264
+ end
265
+ commit(order, :refund, options[:retry_logic], options[:trace_number])
243
266
  end
244
267
 
245
268
  def void(authorization, options = {}, deprecated = {})
@@ -249,7 +272,7 @@ module ActiveMerchant #:nodoc:
249
272
  end
250
273
 
251
274
  order = build_void_request_xml(authorization, options)
252
- commit(order, :void, options[:trace_number])
275
+ commit(order, :void, options[:retry_logic], options[:trace_number])
253
276
  end
254
277
 
255
278
  # ==== Customer Profiles
@@ -310,7 +333,8 @@ module ActiveMerchant #:nodoc:
310
333
  gsub(%r((<CCAccountNum>).+(</CC)), '\1[FILTERED]\2').
311
334
  gsub(%r((<CardSecVal>).+(</CardSecVal>)), '\1[FILTERED]\2').
312
335
  gsub(%r((<MerchantID>).+(</MerchantID>)), '\1[FILTERED]\2').
313
- gsub(%r((<CustomerMerchantID>).+(</CustomerMerchantID>)), '\1[FILTERED]\2')
336
+ gsub(%r((<CustomerMerchantID>).+(</CustomerMerchantID>)), '\1[FILTERED]\2').
337
+ gsub(%r((<CustomerProfileMessage>).+(</CustomerProfileMessage>)), '\1[FILTERED]\2')
314
338
  end
315
339
 
316
340
  private
@@ -365,9 +389,9 @@ module ActiveMerchant #:nodoc:
365
389
  def add_level3_tax(xml, options = {})
366
390
  if (level3 = options[:level_3_data])
367
391
  xml.tag! :PC3VATtaxAmt, byte_limit(level3[:vat_tax], 12) if level3[:vat_tax]
368
- xml.tag! :PC3AltTaxAmt, byte_limit(level3[:alt_tax], 9) if level3[:alt_tax]
369
392
  xml.tag! :PC3VATtaxRate, byte_limit(level3[:vat_rate], 4) if level3[:vat_rate]
370
393
  xml.tag! :PC3AltTaxInd, byte_limit(level3[:alt_ind], 15) if level3[:alt_ind]
394
+ xml.tag! :PC3AltTaxAmt, byte_limit(level3[:alt_tax], 9) if level3[:alt_tax]
371
395
  end
372
396
  end
373
397
 
@@ -425,20 +449,22 @@ module ActiveMerchant #:nodoc:
425
449
  xml.tag! :CardIndicators, options[:card_indicators] if options[:card_indicators]
426
450
  end
427
451
 
428
- def add_address(xml, creditcard, options)
429
- if (address = (options[:billing_address] || options[:address]))
452
+ def add_address(xml, payment_source, options)
453
+ address = get_address(options)
454
+
455
+ unless address.blank?
430
456
  avs_supported = AVS_SUPPORTED_COUNTRIES.include?(address[:country].to_s) || empty?(address[:country])
431
457
 
432
458
  if avs_supported
433
- xml.tag! :AVSzip, byte_limit(format_address_field(address[:zip]), 10)
459
+ xml.tag! :AVSzip, byte_limit(format_address_field(address[:zip]), 10)
434
460
  xml.tag! :AVSaddress1, byte_limit(format_address_field(address[:address1]), 30)
435
461
  xml.tag! :AVSaddress2, byte_limit(format_address_field(address[:address2]), 30)
436
- xml.tag! :AVScity, byte_limit(format_address_field(address[:city]), 20)
437
- xml.tag! :AVSstate, byte_limit(format_address_field(address[:state]), 2)
462
+ xml.tag! :AVScity, byte_limit(format_address_field(address[:city]), 20)
463
+ xml.tag! :AVSstate, byte_limit(format_address_field(address[:state]), 2)
438
464
  xml.tag! :AVSphoneNum, (address[:phone] ? address[:phone].scan(/\d/).join.to_s[0..13] : nil)
439
465
  end
440
466
 
441
- xml.tag! :AVSname, (creditcard&.name ? creditcard.name[0..29] : nil)
467
+ xml.tag! :AVSname, billing_name(payment_source, options)
442
468
  xml.tag! :AVScountryCode, (avs_supported ? byte_limit(format_address_field(address[:country]), 2) : '')
443
469
 
444
470
  # Needs to come after AVScountryCode
@@ -446,6 +472,14 @@ module ActiveMerchant #:nodoc:
446
472
  end
447
473
  end
448
474
 
475
+ def billing_name(payment_source, options)
476
+ if payment_source&.name.present?
477
+ payment_source.name[0..29]
478
+ elsif options[:billing_address][:name].present?
479
+ options[:billing_address][:name][0..29]
480
+ end
481
+ end
482
+
449
483
  def add_destination_address(xml, address)
450
484
  if address[:dest_zip]
451
485
  avs_supported = AVS_SUPPORTED_COUNTRIES.include?(address[:dest_country].to_s)
@@ -464,7 +498,9 @@ module ActiveMerchant #:nodoc:
464
498
 
465
499
  # For Profile requests
466
500
  def add_customer_address(xml, options)
467
- if (address = (options[:billing_address] || options[:address]))
501
+ address = get_address(options)
502
+
503
+ unless address.blank?
468
504
  avs_supported = AVS_SUPPORTED_COUNTRIES.include?(address[:country].to_s)
469
505
 
470
506
  xml.tag! :CustomerAddress1, byte_limit(format_address_field(address[:address1]), 30)
@@ -478,6 +514,38 @@ module ActiveMerchant #:nodoc:
478
514
  end
479
515
  end
480
516
 
517
+ # Payment can be done through either Credit Card or Electronic Check
518
+ def add_payment_source(xml, payment_source, options = {})
519
+ if payment_source.is_a?(Check)
520
+ add_echeck(xml, payment_source, options)
521
+ else
522
+ add_creditcard(xml, payment_source, options[:currency])
523
+ end
524
+ end
525
+
526
+ # Adds Electronic Check attributes
527
+ def add_echeck(xml, check, options = {})
528
+ xml.tag! :CardBrand, 'EC'
529
+ xml.tag! :CurrencyCode, currency_code(options[:currency])
530
+ xml.tag! :CurrencyExponent, currency_exponents(options[:currency])
531
+ unless check.nil?
532
+
533
+ xml.tag! :BCRtNum, check.routing_number
534
+ xml.tag! :CheckDDA, check.account_number if check.account_number
535
+ xml.tag! :BankAccountType, ACCOUNT_TYPE[check.account_type] if ACCOUNT_TYPE[check.account_type]
536
+ xml.tag! :ECPAuthMethod, options[:auth_method] if options[:auth_method]
537
+
538
+ if options[:payment_delivery]
539
+ xml.tag! :BankPmtDelv, options[:payment_delivery]
540
+ else
541
+ xml.tag! :BankPmtDelv, 'B'
542
+ end
543
+
544
+ xml.tag! :AVSname, (check&.name ? check.name[0..29] : nil) if get_address(options).blank?
545
+ end
546
+ end
547
+
548
+ # Adds Credit Card attributes
481
549
  def add_creditcard(xml, creditcard, currency = nil)
482
550
  unless creditcard.nil?
483
551
  xml.tag! :AccountNum, creditcard.number
@@ -532,6 +600,24 @@ module ActiveMerchant #:nodoc:
532
600
  xml.tag!(:AAV, three_d_secure[:cavv])
533
601
  end
534
602
 
603
+ def add_mc_program_protocol(xml, creditcard, three_d_secure)
604
+ return unless three_d_secure && creditcard.brand == 'master'
605
+
606
+ xml.tag!(:MCProgramProtocol, three_d_secure[:version]) if three_d_secure[:version]
607
+ end
608
+
609
+ def add_mc_directory_trans_id(xml, creditcard, three_d_secure)
610
+ return unless three_d_secure && creditcard.brand == 'master'
611
+
612
+ xml.tag!(:MCDirectoryTransID, three_d_secure[:ds_transaction_id]) if three_d_secure[:ds_transaction_id]
613
+ end
614
+
615
+ def add_ucafind(xml, creditcard, three_d_secure)
616
+ return unless three_d_secure && creditcard.brand == 'master'
617
+
618
+ xml.tag! :UCAFInd, '4'
619
+ end
620
+
535
621
  def add_dpanind(xml, creditcard)
536
622
  return unless creditcard.is_a?(NetworkTokenizationCreditCard)
537
623
 
@@ -587,6 +673,42 @@ module ActiveMerchant #:nodoc:
587
673
  end
588
674
  end
589
675
 
676
+ def add_ews_details(xml, payment_source, parameters = {})
677
+ split_name = payment_source.first_name.split if payment_source.first_name
678
+ xml.tag! :EWSFirstName, split_name[0]
679
+ xml.tag! :EWSMiddleName, split_name[1..-1].join(' ')
680
+ xml.tag! :EWSLastName, payment_source.last_name
681
+ xml.tag! :EWSBusinessName, parameters[:company] if payment_source.first_name.empty? && payment_source.last_name.empty?
682
+
683
+ if (address = (parameters[:billing_address] || parameters[:address]))
684
+ xml.tag! :EWSAddressLine1, byte_limit(format_address_field(address[:address1]), 30)
685
+ xml.tag! :EWSAddressLine2, byte_limit(format_address_field(address[:address2]), 30)
686
+ xml.tag! :EWSCity, byte_limit(format_address_field(address[:city]), 20)
687
+ xml.tag! :EWSState, byte_limit(format_address_field(address[:state]), 2)
688
+ xml.tag! :EWSZip, byte_limit(format_address_field(address[:zip]), 10)
689
+ end
690
+
691
+ xml.tag! :EWSPhoneType, parameters[:phone_type]
692
+ xml.tag! :EWSPhoneNumber, parameters[:phone_number]
693
+ xml.tag! :EWSCheckSerialNumber, payment_source.account_number unless parameters[:auth_method].eql?('I')
694
+ end
695
+
696
+ # Adds ECP conditional attributes depending on other attribute values
697
+ def add_ecp_details(xml, payment_source, parameters = {})
698
+ requires!(payment_source.account_number) if parameters[:auth_method]&.eql?('A') || parameters[:auth_method]&.eql?('P')
699
+ xml.tag! :ECPActionCode, parameters[:action_code] if parameters[:action_code]
700
+ xml.tag! :ECPCheckSerialNumber, payment_source.account_number if parameters[:auth_method]&.eql?('A') || parameters[:auth_method]&.eql?('P')
701
+ if parameters[:auth_method]&.eql?('P')
702
+ xml.tag! :ECPTerminalCity, parameters[:terminal_city] if parameters[:terminal_city]
703
+ xml.tag! :ECPTerminalState, parameters[:terminal_state] if parameters[:terminal_state]
704
+ xml.tag! :ECPImageReferenceNumber, parameters[:image_reference_number] if parameters[:image_reference_number]
705
+ end
706
+ if parameters[:action_code]&.eql?('W3') || parameters[:action_code]&.eql?('W5') ||
707
+ parameters[:action_code]&.eql?('W7') || parameters[:action_code]&.eql?('W9')
708
+ add_ews_details(xml, payment_source, parameters)
709
+ end
710
+ end
711
+
590
712
  def add_stored_credentials(xml, parameters)
591
713
  return unless parameters[:mit_stored_credential_ind] == 'Y' || parameters[:stored_credential] && !parameters[:stored_credential].values.all?(&:nil?)
592
714
 
@@ -643,9 +765,9 @@ module ActiveMerchant #:nodoc:
643
765
  end
644
766
  end
645
767
 
646
- def commit(order, message_type, trace_number = nil)
768
+ def commit(order, message_type, retry_logic = nil, trace_number = nil)
647
769
  headers = POST_HEADERS.merge('Content-length' => order.size.to_s)
648
- if @options[:retry_logic] && trace_number
770
+ if (@options[:retry_logic] || retry_logic) && trace_number
649
771
  headers['Trace-number'] = trace_number.to_s
650
772
  headers['Merchant-Id'] = @options[:merchant_id]
651
773
  end
@@ -695,7 +817,7 @@ module ActiveMerchant #:nodoc:
695
817
  @options[:ip_authentication] == true
696
818
  end
697
819
 
698
- def build_new_order_xml(action, money, creditcard, parameters = {})
820
+ def build_new_order_xml(action, money, payment_source, parameters = {})
699
821
  requires!(parameters, :order_id)
700
822
  xml = xml_envelope
701
823
  xml.tag! :Request do
@@ -720,9 +842,9 @@ module ActiveMerchant #:nodoc:
720
842
 
721
843
  three_d_secure = parameters[:three_d_secure]
722
844
 
723
- add_eci(xml, creditcard, three_d_secure)
724
- add_cavv(xml, creditcard, three_d_secure)
725
- add_xid(xml, creditcard, three_d_secure)
845
+ add_eci(xml, payment_source, three_d_secure)
846
+ add_cavv(xml, payment_source, three_d_secure)
847
+ add_xid(xml, payment_source, three_d_secure)
726
848
 
727
849
  xml.tag! :OrderID, format_order_id(parameters[:order_id])
728
850
  xml.tag! :Amount, amount(money)
@@ -731,7 +853,7 @@ module ActiveMerchant #:nodoc:
731
853
  add_level2_tax(xml, parameters)
732
854
  add_level2_advice_addendum(xml, parameters)
733
855
 
734
- add_aav(xml, creditcard, three_d_secure)
856
+ add_aav(xml, payment_source, three_d_secure)
735
857
  # CustomerAni, AVSPhoneType and AVSDestPhoneType could be added here.
736
858
 
737
859
  if parameters[:soft_descriptors].is_a?(OrbitalSoftDescriptors)
@@ -740,14 +862,16 @@ module ActiveMerchant #:nodoc:
740
862
  add_soft_descriptors_from_hash(xml, parameters[:soft_descriptors])
741
863
  end
742
864
 
743
- add_dpanind(xml, creditcard)
744
- add_aevv(xml, creditcard, three_d_secure)
745
- add_digital_token_cryptogram(xml, creditcard)
865
+ add_dpanind(xml, payment_source)
866
+ add_aevv(xml, payment_source, three_d_secure)
867
+ add_digital_token_cryptogram(xml, payment_source)
868
+
869
+ xml.tag! :ECPSameDayInd, parameters[:same_day] if parameters[:same_day] && payment_source.is_a?(Check)
746
870
 
747
871
  set_recurring_ind(xml, parameters)
748
872
 
749
873
  # Append Transaction Reference Number at the end for Refund transactions
750
- if action == REFUND
874
+ if action == REFUND && parameters[:authorization]
751
875
  tx_ref_num, = split_authorization(parameters[:authorization])
752
876
  xml.tag! :TxRefNum, tx_ref_num
753
877
  end
@@ -756,9 +880,13 @@ module ActiveMerchant #:nodoc:
756
880
  add_level3_purchase(xml, parameters)
757
881
  add_level3_tax(xml, parameters)
758
882
  add_line_items(xml, parameters) if parameters[:line_items]
883
+ add_ecp_details(xml, payment_source, parameters) if payment_source.is_a?(Check)
759
884
  add_card_indicators(xml, parameters)
760
885
  add_stored_credentials(xml, parameters)
761
- add_pymt_brand_program_code(xml, creditcard, three_d_secure)
886
+ add_pymt_brand_program_code(xml, payment_source, three_d_secure)
887
+ add_mc_program_protocol(xml, payment_source, three_d_secure)
888
+ add_mc_directory_trans_id(xml, payment_source, three_d_secure)
889
+ add_ucafind(xml, payment_source, three_d_secure)
762
890
  end
763
891
  end
764
892
  xml.target!
@@ -790,6 +918,7 @@ module ActiveMerchant #:nodoc:
790
918
  add_level2_advice_addendum(xml, parameters)
791
919
  add_level3_purchase(xml, parameters)
792
920
  add_level3_tax(xml, parameters)
921
+ add_line_items(xml, parameters) if parameters[:line_items]
793
922
  end
794
923
  end
795
924
  xml.target!
@@ -852,6 +981,10 @@ module ActiveMerchant #:nodoc:
852
981
  @options[:merchant_id].length == 6
853
982
  end
854
983
 
984
+ def get_address(options)
985
+ options[:billing_address] || options[:address]
986
+ end
987
+
855
988
  # The valid characters include:
856
989
  #
857
990
  # 1. all letters and digits
@@ -989,7 +1122,7 @@ module ActiveMerchant #:nodoc:
989
1122
  'Y' => %w(9 A B C H JA JD M2 M3 M5 N5 N8 N9 X Z),
990
1123
  'N' => %w(D E F G M8),
991
1124
  'X' => %w(4 J R),
992
- nil => %w(1 2 3 5 6 7 8 JB JC M1 M4 M6 M7 N3 N4 N6 N7 UK)
1125
+ nil => %w(1 2 3 5 6 7 8 JB JC M1 M4 M6 M7 N3 N4 N6 N7 UK)
993
1126
  }.inject({}) do |map, (type, codes)|
994
1127
  codes.each { |code| map[code] = type }
995
1128
  map
@@ -1000,7 +1133,7 @@ module ActiveMerchant #:nodoc:
1000
1133
  'Y' => %w(9 B D F H JA JB M2 M4 M5 M6 M7 N3 N5 N7 N8 N9 X),
1001
1134
  'N' => %w(A C E G M8 Z),
1002
1135
  'X' => %w(4 J R),
1003
- nil => %w(1 2 3 5 6 7 8 JC JD M1 M3 N4 N6 UK)
1136
+ nil => %w(1 2 3 5 6 7 8 JC JD M1 M3 N4 N6 UK)
1004
1137
  }.inject({}) do |map, (type, codes)|
1005
1138
  codes.each { |code| map[code] = type }
1006
1139
  map