activemerchant 1.119.0 → 1.124.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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +216 -1
  3. data/README.md +4 -2
  4. data/lib/active_merchant/billing/check.rb +19 -12
  5. data/lib/active_merchant/billing/credit_card.rb +3 -0
  6. data/lib/active_merchant/billing/credit_card_formatting.rb +1 -0
  7. data/lib/active_merchant/billing/credit_card_methods.rb +32 -14
  8. data/lib/active_merchant/billing/gateways/adyen.rb +94 -25
  9. data/lib/active_merchant/billing/gateways/authorize_net.rb +19 -11
  10. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +3 -0
  11. data/lib/active_merchant/billing/gateways/blue_pay.rb +29 -0
  12. data/lib/active_merchant/billing/gateways/blue_snap.rb +2 -2
  13. data/lib/active_merchant/billing/gateways/braintree_blue.rb +52 -8
  14. data/lib/active_merchant/billing/gateways/card_stream.rb +17 -13
  15. data/lib/active_merchant/billing/gateways/cashnet.rb +7 -2
  16. data/lib/active_merchant/billing/gateways/checkout_v2.rb +31 -0
  17. data/lib/active_merchant/billing/gateways/credorax.rb +15 -9
  18. data/lib/active_merchant/billing/gateways/cyber_source.rb +53 -6
  19. data/lib/active_merchant/billing/gateways/d_local.rb +9 -2
  20. data/lib/active_merchant/billing/gateways/decidir.rb +7 -1
  21. data/lib/active_merchant/billing/gateways/elavon.rb +70 -28
  22. data/lib/active_merchant/billing/gateways/element.rb +2 -0
  23. data/lib/active_merchant/billing/gateways/forte.rb +12 -0
  24. data/lib/active_merchant/billing/gateways/global_collect.rb +24 -10
  25. data/lib/active_merchant/billing/gateways/hps.rb +55 -1
  26. data/lib/active_merchant/billing/gateways/kushki.rb +23 -0
  27. data/lib/active_merchant/billing/gateways/litle.rb +1 -1
  28. data/lib/active_merchant/billing/gateways/mercado_pago.rb +5 -4
  29. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +2 -0
  30. data/lib/active_merchant/billing/gateways/mit.rb +260 -0
  31. data/lib/active_merchant/billing/gateways/moka.rb +290 -0
  32. data/lib/active_merchant/billing/gateways/monei.rb +228 -144
  33. data/lib/active_merchant/billing/gateways/mundipagg.rb +14 -5
  34. data/lib/active_merchant/billing/gateways/netbanx.rb +26 -2
  35. data/lib/active_merchant/billing/gateways/nmi.rb +27 -9
  36. data/lib/active_merchant/billing/gateways/orbital.rb +99 -59
  37. data/lib/active_merchant/billing/gateways/pay_arc.rb +392 -0
  38. data/lib/active_merchant/billing/gateways/pay_conex.rb +3 -1
  39. data/lib/active_merchant/billing/gateways/pay_trace.rb +404 -0
  40. data/lib/active_merchant/billing/gateways/payeezy.rb +34 -6
  41. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +1 -0
  42. data/lib/active_merchant/billing/gateways/payflow.rb +21 -4
  43. data/lib/active_merchant/billing/gateways/payment_express.rb +5 -5
  44. data/lib/active_merchant/billing/gateways/paymentez.rb +5 -0
  45. data/lib/active_merchant/billing/gateways/paypal_express.rb +1 -0
  46. data/lib/active_merchant/billing/gateways/paysafe.rb +376 -0
  47. data/lib/active_merchant/billing/gateways/payu_latam.rb +3 -3
  48. data/lib/active_merchant/billing/gateways/payway_dot_com.rb +253 -0
  49. data/lib/active_merchant/billing/gateways/qvalent.rb +23 -9
  50. data/lib/active_merchant/billing/gateways/realex.rb +18 -0
  51. data/lib/active_merchant/billing/gateways/redsys.rb +42 -24
  52. data/lib/active_merchant/billing/gateways/safe_charge.rb +25 -13
  53. data/lib/active_merchant/billing/gateways/spreedly_core.rb +13 -4
  54. data/lib/active_merchant/billing/gateways/stripe.rb +18 -8
  55. data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +126 -48
  56. data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +2 -1
  57. data/lib/active_merchant/billing/gateways/trust_commerce.rb +2 -1
  58. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +1 -1
  59. data/lib/active_merchant/billing/gateways/vpos.rb +220 -0
  60. data/lib/active_merchant/billing/gateways/worldpay.rb +78 -18
  61. data/lib/active_merchant/billing/response.rb +4 -0
  62. data/lib/active_merchant/billing/three_d_secure_eci_mapper.rb +27 -0
  63. data/lib/active_merchant/billing.rb +1 -0
  64. data/lib/active_merchant/version.rb +1 -1
  65. data/lib/certs/cacert.pem +1582 -2431
  66. metadata +11 -3
@@ -42,6 +42,7 @@ module ActiveMerchant #:nodoc:
42
42
  }
43
43
 
44
44
  SUCCESS = '0'
45
+ APPROVAL_SUCCESS = '1'
45
46
 
46
47
  APPROVED = [
47
48
  '00', # Approved
@@ -190,31 +191,6 @@ module ActiveMerchant #:nodoc:
190
191
  'checking' => 'C'
191
192
  }
192
193
 
193
- # Fixed possible values for orbital ECP attributes
194
- # Auth methods for electronic checks can be:
195
- # Written, Internet, Telephonic, Account Receivable, Point of Purchase.
196
- # Default auth method for ECP is Internet (I).
197
- # Bank payment delivery can be either ACH (Automated Clearing House) or Best Possible.
198
- # Default Bank Payment Delivery is Best Possible (B).
199
- # Action codes to be used for Early Warning System and additional validations.
200
- # Valid combinations of Message Type and Action Code to be used are:
201
- # A W1
202
- # AC W1
203
- # FC W4
204
- # R W6
205
- # FC W8
206
- # A W3
207
- # AC W3
208
- # FC W5
209
- # R W7
210
- # Default Action code for ECP is nil.
211
- # Electronic check to be processed on same day (Y) or next day (N).
212
- # Default ECP Same Day Index is Yes (Y).
213
- ECP_AUTH_METHODS = %w[W I T A P]
214
- ECP_BANK_PAYMENT = %w[A B]
215
- ECP_ACTION_CODES = %w[LO ND NC W1 W3 W4 W5 W6 W7 W8 W9]
216
- ECP_SAME_DAY = %w[Y N]
217
-
218
194
  def initialize(options = {})
219
195
  requires!(options, :merchant_id)
220
196
  requires!(options, :login, :password) unless options[:ip_authentication]
@@ -224,6 +200,14 @@ module ActiveMerchant #:nodoc:
224
200
 
225
201
  # A – Authorization request
226
202
  def authorize(money, payment_source, options = {})
203
+ # ECP for Orbital requires $0 prenotes so ensure
204
+ # if we are doing a force capture with a check, that
205
+ # 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
210
+
227
211
  order = build_new_order_xml(AUTH_ONLY, money, payment_source, options) do |xml|
228
212
  add_payment_source(xml, payment_source, options)
229
213
  add_address(xml, payment_source, options)
@@ -232,7 +216,7 @@ module ActiveMerchant #:nodoc:
232
216
  add_managed_billing(xml, options)
233
217
  end
234
218
  end
235
- commit(order, :authorize, options[:trace_number])
219
+ commit(order, :authorize, options[:retry_logic], options[:trace_number])
236
220
  end
237
221
 
238
222
  def verify(creditcard, options = {})
@@ -252,26 +236,34 @@ module ActiveMerchant #:nodoc:
252
236
  add_managed_billing(xml, options)
253
237
  end
254
238
  end
255
- commit(order, :purchase, options[:trace_number])
239
+
240
+ commit(order, :purchase, options[:retry_logic], options[:trace_number])
256
241
  end
257
242
 
258
243
  # MFC - Mark For Capture
259
244
  def capture(money, authorization, options = {})
260
- commit(build_mark_for_capture_xml(money, authorization, options), :capture)
245
+ commit(build_mark_for_capture_xml(money, authorization, options), :capture, options[:retry_logic], options[:trace_number])
261
246
  end
262
247
 
263
248
  # R – Refund request
264
249
  def refund(money, authorization, options = {})
265
- order = build_new_order_xml(REFUND, money, nil, options.merge(authorization: authorization)) do |xml|
266
- add_refund(xml, options[:currency])
250
+ payment_method = options[:payment_method]
251
+ order = build_new_order_xml(REFUND, money, payment_method, options.merge(authorization: authorization)) do |xml|
252
+ if payment_method.is_a?(Check)
253
+ add_echeck(xml, payment_method, options)
254
+ else
255
+ add_refund(xml, options[:currency])
256
+ end
267
257
  xml.tag! :CustomerRefNum, options[:customer_ref_num] if @options[:customer_profiles] && options[:profile_txn]
268
258
  end
269
- commit(order, :refund, options[:trace_number])
259
+ commit(order, :refund, options[:retry_logic], options[:trace_number])
270
260
  end
271
261
 
272
- def credit(money, authorization, options = {})
273
- ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
274
- refund(money, authorization, options)
262
+ def credit(money, payment_method, options = {})
263
+ order = build_new_order_xml(REFUND, money, payment_method, options) do |xml|
264
+ add_payment_source(xml, payment_method, options)
265
+ end
266
+ commit(order, :refund, options[:retry_logic], options[:trace_number])
275
267
  end
276
268
 
277
269
  def void(authorization, options = {}, deprecated = {})
@@ -281,7 +273,7 @@ module ActiveMerchant #:nodoc:
281
273
  end
282
274
 
283
275
  order = build_void_request_xml(authorization, options)
284
- commit(order, :void, options[:trace_number])
276
+ commit(order, :void, options[:retry_logic], options[:trace_number])
285
277
  end
286
278
 
287
279
  # ==== Customer Profiles
@@ -343,7 +335,10 @@ module ActiveMerchant #:nodoc:
343
335
  gsub(%r((<CardSecVal>).+(</CardSecVal>)), '\1[FILTERED]\2').
344
336
  gsub(%r((<MerchantID>).+(</MerchantID>)), '\1[FILTERED]\2').
345
337
  gsub(%r((<CustomerMerchantID>).+(</CustomerMerchantID>)), '\1[FILTERED]\2').
346
- gsub(%r((<CustomerProfileMessage>).+(</CustomerProfileMessage>)), '\1[FILTERED]\2')
338
+ gsub(%r((<CustomerProfileMessage>).+(</CustomerProfileMessage>)), '\1[FILTERED]\2').
339
+ gsub(%r((<CheckDDA>).+(</CheckDDA>)), '\1[FILTERED]\2').
340
+ gsub(%r((<BCRtNum>).+(</BCRtNum>)), '\1[FILTERED]\2').
341
+ gsub(%r((<DigitalTokenCryptogram>).+(</DigitalTokenCryptogram>)), '\1[FILTERED]\2')
347
342
  end
348
343
 
349
344
  private
@@ -398,9 +393,9 @@ module ActiveMerchant #:nodoc:
398
393
  def add_level3_tax(xml, options = {})
399
394
  if (level3 = options[:level_3_data])
400
395
  xml.tag! :PC3VATtaxAmt, byte_limit(level3[:vat_tax], 12) if level3[:vat_tax]
401
- xml.tag! :PC3AltTaxAmt, byte_limit(level3[:alt_tax], 9) if level3[:alt_tax]
402
396
  xml.tag! :PC3VATtaxRate, byte_limit(level3[:vat_rate], 4) if level3[:vat_rate]
403
397
  xml.tag! :PC3AltTaxInd, byte_limit(level3[:alt_ind], 15) if level3[:alt_ind]
398
+ xml.tag! :PC3AltTaxAmt, byte_limit(level3[:alt_tax], 9) if level3[:alt_tax]
404
399
  end
405
400
  end
406
401
 
@@ -458,20 +453,22 @@ module ActiveMerchant #:nodoc:
458
453
  xml.tag! :CardIndicators, options[:card_indicators] if options[:card_indicators]
459
454
  end
460
455
 
461
- def add_address(xml, creditcard, options)
462
- if (address = (options[:billing_address] || options[:address]))
456
+ def add_address(xml, payment_source, options)
457
+ address = get_address(options)
458
+
459
+ unless address.blank?
463
460
  avs_supported = AVS_SUPPORTED_COUNTRIES.include?(address[:country].to_s) || empty?(address[:country])
464
461
 
465
462
  if avs_supported
466
- xml.tag! :AVSzip, byte_limit(format_address_field(address[:zip]), 10)
463
+ xml.tag! :AVSzip, byte_limit(format_address_field(address[:zip]), 10)
467
464
  xml.tag! :AVSaddress1, byte_limit(format_address_field(address[:address1]), 30)
468
465
  xml.tag! :AVSaddress2, byte_limit(format_address_field(address[:address2]), 30)
469
- xml.tag! :AVScity, byte_limit(format_address_field(address[:city]), 20)
470
- xml.tag! :AVSstate, byte_limit(format_address_field(address[:state]), 2)
466
+ xml.tag! :AVScity, byte_limit(format_address_field(address[:city]), 20)
467
+ xml.tag! :AVSstate, byte_limit(format_address_field(address[:state]), 2)
471
468
  xml.tag! :AVSphoneNum, (address[:phone] ? address[:phone].scan(/\d/).join.to_s[0..13] : nil)
472
469
  end
473
470
 
474
- xml.tag! :AVSname, (creditcard&.name ? creditcard.name[0..29] : nil)
471
+ xml.tag! :AVSname, billing_name(payment_source, options)
475
472
  xml.tag! :AVScountryCode, (avs_supported ? byte_limit(format_address_field(address[:country]), 2) : '')
476
473
 
477
474
  # Needs to come after AVScountryCode
@@ -479,6 +476,14 @@ module ActiveMerchant #:nodoc:
479
476
  end
480
477
  end
481
478
 
479
+ def billing_name(payment_source, options)
480
+ if payment_source&.name.present?
481
+ payment_source.name[0..29]
482
+ elsif options[:billing_address][:name].present?
483
+ options[:billing_address][:name][0..29]
484
+ end
485
+ end
486
+
482
487
  def add_destination_address(xml, address)
483
488
  if address[:dest_zip]
484
489
  avs_supported = AVS_SUPPORTED_COUNTRIES.include?(address[:dest_country].to_s)
@@ -497,7 +502,9 @@ module ActiveMerchant #:nodoc:
497
502
 
498
503
  # For Profile requests
499
504
  def add_customer_address(xml, options)
500
- if (address = (options[:billing_address] || options[:address]))
505
+ address = get_address(options)
506
+
507
+ unless address.blank?
501
508
  avs_supported = AVS_SUPPORTED_COUNTRIES.include?(address[:country].to_s)
502
509
 
503
510
  xml.tag! :CustomerAddress1, byte_limit(format_address_field(address[:address1]), 30)
@@ -530,8 +537,15 @@ module ActiveMerchant #:nodoc:
530
537
  xml.tag! :BCRtNum, check.routing_number
531
538
  xml.tag! :CheckDDA, check.account_number if check.account_number
532
539
  xml.tag! :BankAccountType, ACCOUNT_TYPE[check.account_type] if ACCOUNT_TYPE[check.account_type]
533
- xml.tag! :ECPAuthMethod, options[:auth_method] if options[:auth_method] && ECP_AUTH_METHODS.include?(options[:auth_method])
534
- xml.tag! :BankPmtDelv, options[:payment_delivery] if options[:payment_delivery] && ECP_BANK_PAYMENT.include?(options[:payment_delivery])
540
+ xml.tag! :ECPAuthMethod, options[:auth_method] if options[:auth_method]
541
+
542
+ if options[:payment_delivery]
543
+ xml.tag! :BankPmtDelv, options[:payment_delivery]
544
+ else
545
+ xml.tag! :BankPmtDelv, 'B'
546
+ end
547
+
548
+ xml.tag! :AVSname, (check&.name ? check.name[0..29] : nil) if get_address(options).blank?
535
549
  end
536
550
  end
537
551
 
@@ -592,8 +606,10 @@ module ActiveMerchant #:nodoc:
592
606
 
593
607
  def add_mc_program_protocol(xml, creditcard, three_d_secure)
594
608
  return unless three_d_secure && creditcard.brand == 'master'
609
+ return unless three_d_secure[:version]
595
610
 
596
- xml.tag!(:MCProgramProtocol, three_d_secure[:version]) if three_d_secure[:version]
611
+ truncated_version = three_d_secure[:version].to_s[0]
612
+ xml.tag!(:MCProgramProtocol, truncated_version)
597
613
  end
598
614
 
599
615
  def add_mc_directory_trans_id(xml, creditcard, three_d_secure)
@@ -602,12 +618,20 @@ module ActiveMerchant #:nodoc:
602
618
  xml.tag!(:MCDirectoryTransID, three_d_secure[:ds_transaction_id]) if three_d_secure[:ds_transaction_id]
603
619
  end
604
620
 
605
- def add_ucafind(xml, creditcard, three_d_secure)
621
+ def add_mc_ucafind(xml, creditcard, three_d_secure)
606
622
  return unless three_d_secure && creditcard.brand == 'master'
607
623
 
608
624
  xml.tag! :UCAFInd, '4'
609
625
  end
610
626
 
627
+ def add_mc_scarecurring(xml, creditcard, parameters, three_d_secure)
628
+ return unless parameters && parameters[:sca_recurring] && creditcard.brand == 'master'
629
+
630
+ valid_eci = three_d_secure && three_d_secure[:eci] && three_d_secure[:eci] == '7'
631
+
632
+ xml.tag!(:SCARecurringPayment, parameters[:sca_recurring]) if valid_eci
633
+ end
634
+
611
635
  def add_dpanind(xml, creditcard)
612
636
  return unless creditcard.is_a?(NetworkTokenizationCreditCard)
613
637
 
@@ -664,7 +688,9 @@ module ActiveMerchant #:nodoc:
664
688
  end
665
689
 
666
690
  def add_ews_details(xml, payment_source, parameters = {})
667
- xml.tag! :EWSFirstName, payment_source.first_name
691
+ split_name = payment_source.first_name.split if payment_source.first_name
692
+ xml.tag! :EWSFirstName, split_name[0]
693
+ xml.tag! :EWSMiddleName, split_name[1..-1].join(' ')
668
694
  xml.tag! :EWSLastName, payment_source.last_name
669
695
  xml.tag! :EWSBusinessName, parameters[:company] if payment_source.first_name.empty? && payment_source.last_name.empty?
670
696
 
@@ -684,7 +710,7 @@ module ActiveMerchant #:nodoc:
684
710
  # Adds ECP conditional attributes depending on other attribute values
685
711
  def add_ecp_details(xml, payment_source, parameters = {})
686
712
  requires!(payment_source.account_number) if parameters[:auth_method]&.eql?('A') || parameters[:auth_method]&.eql?('P')
687
- xml.tag! :ECPActionCode, parameters[:action_code] if parameters[:action_code] && ECP_ACTION_CODES.include?(parameters[:action_code])
713
+ xml.tag! :ECPActionCode, parameters[:action_code] if parameters[:action_code]
688
714
  xml.tag! :ECPCheckSerialNumber, payment_source.account_number if parameters[:auth_method]&.eql?('A') || parameters[:auth_method]&.eql?('P')
689
715
  if parameters[:auth_method]&.eql?('P')
690
716
  xml.tag! :ECPTerminalCity, parameters[:terminal_city] if parameters[:terminal_city]
@@ -733,7 +759,7 @@ module ActiveMerchant #:nodoc:
733
759
 
734
760
  def parse(body)
735
761
  response = {}
736
- xml = REXML::Document.new(body)
762
+ xml = REXML::Document.new(strip_invalid_xml_chars(body))
737
763
  root = REXML::XPath.first(xml, '//Response') ||
738
764
  REXML::XPath.first(xml, '//ErrorResponse')
739
765
  if root
@@ -753,9 +779,9 @@ module ActiveMerchant #:nodoc:
753
779
  end
754
780
  end
755
781
 
756
- def commit(order, message_type, trace_number = nil)
782
+ def commit(order, message_type, retry_logic = nil, trace_number = nil)
757
783
  headers = POST_HEADERS.merge('Content-length' => order.size.to_s)
758
- if @options[:retry_logic] && trace_number
784
+ if (@options[:retry_logic] || retry_logic) && trace_number
759
785
  headers['Trace-number'] = trace_number.to_s
760
786
  headers['Merchant-Id'] = @options[:merchant_id]
761
787
  end
@@ -787,8 +813,10 @@ module ActiveMerchant #:nodoc:
787
813
  end
788
814
 
789
815
  def success?(response, message_type)
790
- if %i[refund void].include?(message_type)
816
+ if %i[void].include?(message_type)
791
817
  response[:proc_status] == SUCCESS
818
+ elsif %i[refund].include?(message_type)
819
+ response[:proc_status] == SUCCESS && response[:approval_status] == APPROVAL_SUCCESS
792
820
  elsif response[:customer_profile_action]
793
821
  response[:profile_proc_status] == SUCCESS
794
822
  else
@@ -854,12 +882,12 @@ module ActiveMerchant #:nodoc:
854
882
  add_aevv(xml, payment_source, three_d_secure)
855
883
  add_digital_token_cryptogram(xml, payment_source)
856
884
 
857
- xml.tag! :ECPSameDayInd, parameters[:same_day] if parameters[:same_day] && ECP_SAME_DAY.include?(parameters[:same_day]) && payment_source.is_a?(Check)
885
+ xml.tag! :ECPSameDayInd, parameters[:same_day] if parameters[:same_day] && payment_source.is_a?(Check)
858
886
 
859
887
  set_recurring_ind(xml, parameters)
860
888
 
861
889
  # Append Transaction Reference Number at the end for Refund transactions
862
- if action == REFUND
890
+ if action == REFUND && parameters[:authorization]
863
891
  tx_ref_num, = split_authorization(parameters[:authorization])
864
892
  xml.tag! :TxRefNum, tx_ref_num
865
893
  end
@@ -872,9 +900,10 @@ module ActiveMerchant #:nodoc:
872
900
  add_card_indicators(xml, parameters)
873
901
  add_stored_credentials(xml, parameters)
874
902
  add_pymt_brand_program_code(xml, payment_source, three_d_secure)
903
+ add_mc_scarecurring(xml, payment_source, parameters, three_d_secure)
875
904
  add_mc_program_protocol(xml, payment_source, three_d_secure)
876
905
  add_mc_directory_trans_id(xml, payment_source, three_d_secure)
877
- add_ucafind(xml, payment_source, three_d_secure)
906
+ add_mc_ucafind(xml, payment_source, three_d_secure)
878
907
  end
879
908
  end
880
909
  xml.target!
@@ -906,6 +935,7 @@ module ActiveMerchant #:nodoc:
906
935
  add_level2_advice_addendum(xml, parameters)
907
936
  add_level3_purchase(xml, parameters)
908
937
  add_level3_tax(xml, parameters)
938
+ add_line_items(xml, parameters) if parameters[:line_items]
909
939
  end
910
940
  end
911
941
  xml.target!
@@ -968,6 +998,16 @@ module ActiveMerchant #:nodoc:
968
998
  @options[:merchant_id].length == 6
969
999
  end
970
1000
 
1001
+ def get_address(options)
1002
+ options[:billing_address] || options[:address]
1003
+ end
1004
+
1005
+ # Null characters are possible in some responses (namely, the respMsg field), causing XML parsing errors
1006
+ # Prevent by substituting these with a valid placeholder string
1007
+ def strip_invalid_xml_chars(xml)
1008
+ xml.gsub(/\u0000/, '[null]')
1009
+ end
1010
+
971
1011
  # The valid characters include:
972
1012
  #
973
1013
  # 1. all letters and digits
@@ -1105,7 +1145,7 @@ module ActiveMerchant #:nodoc:
1105
1145
  'Y' => %w(9 A B C H JA JD M2 M3 M5 N5 N8 N9 X Z),
1106
1146
  'N' => %w(D E F G M8),
1107
1147
  'X' => %w(4 J R),
1108
- nil => %w(1 2 3 5 6 7 8 JB JC M1 M4 M6 M7 N3 N4 N6 N7 UK)
1148
+ nil => %w(1 2 3 5 6 7 8 JB JC M1 M4 M6 M7 N3 N4 N6 N7 UK)
1109
1149
  }.inject({}) do |map, (type, codes)|
1110
1150
  codes.each { |code| map[code] = type }
1111
1151
  map
@@ -1116,7 +1156,7 @@ module ActiveMerchant #:nodoc:
1116
1156
  'Y' => %w(9 B D F H JA JB M2 M4 M5 M6 M7 N3 N5 N7 N8 N9 X),
1117
1157
  'N' => %w(A C E G M8 Z),
1118
1158
  'X' => %w(4 J R),
1119
- nil => %w(1 2 3 5 6 7 8 JC JD M1 M3 N4 N6 UK)
1159
+ nil => %w(1 2 3 5 6 7 8 JC JD M1 M3 N4 N6 UK)
1120
1160
  }.inject({}) do |map, (type, codes)|
1121
1161
  codes.each { |code| map[code] = type }
1122
1162
  map