activemerchant 1.116.0 → 1.117.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c32d76816ad9cdc73be63181629990b876d69e62e84c324b0cf0b240bb4fab42
4
- data.tar.gz: 8c4263133c364d786f480ac146e174765ac1a5b5c462680c17f4f104af9f0d49
3
+ metadata.gz: 40c5c0774f8eb95c3aff1873f2067aea19df812d49af757df53e8f448b8ad9d1
4
+ data.tar.gz: d30077388953e6945c9353f829e8ea38503828e39555594bb76c46c30c0b7f45
5
5
  SHA512:
6
- metadata.gz: 167eff38aa013365fab6ff2ba49cee58b15b8b5aa7f604f2c58d0040fac2fe931a4550c3fe594df618326630138ef63265767f2270f3ae6838642a26694fb921
7
- data.tar.gz: 23a60e19999c1ce903bfc35503eac491d5cff0de0b59ab8dfe99e67f2f0d4b31380ef3826926c70cc60303c348bfa9377e642ed420f58d519a1ec779521516db
6
+ metadata.gz: 8ae4e27c577076982790c058395b863f659e9a07e71a5dd904bb755ce7a2f086c60112f25d91f054087a4c62740adf0f8b1cece5968bc8e0ee247b0f3e0ee06d
7
+ data.tar.gz: 896c982831e68d0b70813c80c8dfc086302389f8aa13dc8b64fdc0582ef42baab1c75d50f502f681f2abc085f2c74992e0b1f85919d84012af5ba024bab11602
data/CHANGELOG CHANGED
@@ -2,8 +2,24 @@
2
2
 
3
3
  == HEAD
4
4
 
5
+ == Version 1.117.0 (November 13th)
6
+ * Checkout V2: Pass attempt_n3d along with 3ds enabled [naashton] #3805
7
+ * GlobalCollect: Add support for Third-party 3DS2 data [molbrown] #3801
8
+ * Authorize.net: Pass stored credentials [therufs] #3804
9
+ * Authorize.net: Don't pass isFirstRecurringPayment [therufs] #3805
10
+ * Litle: Add support for general credit transactions [naashton] #3807
11
+ * Redsys: Add 3DS2 Integration Support [esmitperez] #3794
12
+ * Cybersource: Use firstname/lastname from address instead of the payment method [pi3r] #3798
13
+ * Add MPI functionality for SafeCharge gateway [daniel] #3809
14
+ * SafeCharge: Standardize MPI fields [curiousepic] #3809
15
+ * Credorax: Adds AMEX to supported cards and adds 1A error code [LinTrieu] #3792
16
+ * Stripe PI: Pass external 3DS auth data [curiousepic] #3811
17
+ * Credorax: Allow 3DS1 normalized pass-through, ease version matching [britth] #3812
18
+ * Redsys: Redsys: Harden 3DS v1/v2 check for External MPI [esmitperez] #3814
19
+ * Add card types for Stripe, Worldpay, Checkout.com [LinTrieu] #3810
20
+
5
21
  == Version 1.116.0 (October 28th)
6
- * Remove Braintree specific version dependency [pi3r] #38000
22
+ * Remove Braintree specific version dependency [pi3r] #3800
7
23
 
8
24
  == Version 1.115.0 (October 27th)
9
25
  * Checkout v2: $0 Auth on gateway [jessiagee] #3762
@@ -257,6 +257,8 @@ module ActiveMerchant
257
257
  add_settings(xml, payment, options)
258
258
  add_user_fields(xml, amount, options)
259
259
  add_ship_from_address(xml, options)
260
+ add_processing_options(xml, options)
261
+ add_subsequent_auth_information(xml, options)
260
262
  end
261
263
  end
262
264
 
@@ -408,7 +410,7 @@ module ActiveMerchant
408
410
 
409
411
  def add_settings(xml, source, options)
410
412
  xml.transactionSettings do
411
- if options[:recurring]
413
+ if options[:recurring] || subsequent_recurring_transaction?(options)
412
414
  xml.setting do
413
415
  xml.settingName('recurringBilling')
414
416
  xml.settingValue('true')
@@ -702,6 +704,30 @@ module ActiveMerchant
702
704
  xml.extraOptions("x_delim_char=#{options[:delimiter]}") if options[:delimiter]
703
705
  end
704
706
 
707
+ def add_processing_options(xml, options)
708
+ return unless options[:stored_credential]
709
+
710
+ xml.processingOptions do
711
+ if options[:stored_credential][:initial_transaction]
712
+ xml.isFirstSubsequentAuth 'true'
713
+ # xml.isFirstRecurringPayment 'true' if options[:stored_credential][:reason_type] == 'recurring'
714
+ elsif options[:stored_credential][:initiator] == 'cardholder'
715
+ xml.isStoredCredentials 'true'
716
+ else
717
+ xml.isSubsequentAuth 'true'
718
+ end
719
+ end
720
+ end
721
+
722
+ def add_subsequent_auth_information(xml, options)
723
+ return unless options.dig(:stored_credential, :reason_type) == 'unscheduled'
724
+
725
+ xml.subsequentAuthInformation do
726
+ xml.reason options[:stored_credential_reason_type_override] if options[:stored_credential_reason_type_override]
727
+ xml.originalNetworkTransId options[:stored_credential][:network_transaction_id] if options[:stored_credential][:network_transaction_id]
728
+ end
729
+ end
730
+
705
731
  def create_customer_payment_profile(credit_card, options)
706
732
  commit(:cim_store_update, options) do |xml|
707
733
  xml.customerProfileId options[:customer_profile_id]
@@ -764,6 +790,10 @@ module ActiveMerchant
764
790
  end
765
791
  end
766
792
 
793
+ def subsequent_recurring_transaction?(options)
794
+ options.dig(:stored_credential, :reason_type) == 'recurring' && !options.dig(:stored_credential, :initial_transaction)
795
+ end
796
+
767
797
  def headers
768
798
  { 'Content-Type' => 'text/xml' }
769
799
  end
@@ -9,7 +9,7 @@ module ActiveMerchant #:nodoc:
9
9
  self.supported_countries = %w[AD AE AR AT AU BE BG BH BR CH CL CN CO CY CZ DE DK EE EG ES FI FR GB GR HK HR HU IE IS IT JO JP KW LI LT LU LV MC MT MX MY NL NO NZ OM PE PL PT QA RO SA SE SG SI SK SM TR US]
10
10
  self.default_currency = 'USD'
11
11
  self.money_format = :cents
12
- self.supported_cardtypes = %i[visa master american_express diners_club maestro discover]
12
+ self.supported_cardtypes = %i[visa master american_express diners_club maestro discover jcb]
13
13
  self.currencies_without_fractions = %w(BIF DJF GNF ISK KMF XAF CLF XPF JPY PYG RWF KRW VUV VND XOF)
14
14
  self.currencies_with_three_decimal_places = %w(BHD LYD JOD KWD OMR TND)
15
15
 
@@ -144,6 +144,7 @@ module ActiveMerchant #:nodoc:
144
144
  post[:'3ds'][:enabled] = true
145
145
  post[:success_url] = options[:callback_url] if options[:callback_url]
146
146
  post[:failure_url] = options[:callback_url] if options[:callback_url]
147
+ post[:'3ds'][:attempt_n3d] = options[:attempt_n3d] if options[:attempt_n3d]
147
148
  end
148
149
 
149
150
  if options[:three_d_secure]
@@ -151,7 +152,6 @@ module ActiveMerchant #:nodoc:
151
152
  post[:'3ds'][:cryptogram] = options[:three_d_secure][:cavv] if options[:three_d_secure][:cavv]
152
153
  post[:'3ds'][:version] = options[:three_d_secure][:version] if options[:three_d_secure][:version]
153
154
  post[:'3ds'][:xid] = options[:three_d_secure][:ds_transaction_id] || options[:three_d_secure][:xid]
154
- post[:'3ds'][:attempt_n3d] = options[:attempt_n3d] if options[:attempt_n3d]
155
155
  end
156
156
  end
157
157
 
@@ -25,7 +25,7 @@ module ActiveMerchant #:nodoc:
25
25
  self.currencies_with_three_decimal_places = %w(BHD IQD JOD KWD LYD OMR TND)
26
26
 
27
27
  self.money_format = :cents
28
- self.supported_cardtypes = %i[visa master maestro]
28
+ self.supported_cardtypes = %i[visa master maestro american_express]
29
29
 
30
30
  RESPONSE_MESSAGES = {
31
31
  '00' => 'Approved or completed successfully',
@@ -117,7 +117,8 @@ module ActiveMerchant #:nodoc:
117
117
  '96' => 'System malfunction',
118
118
  'R0' => 'Stop Payment Order',
119
119
  'R1' => 'Revocation of Authorisation Order',
120
- 'R3' => 'Revocation of all Authorisations Order'
120
+ 'R3' => 'Revocation of all Authorisations Order',
121
+ '1A' => 'Strong Customer Authentication required'
121
122
  }
122
123
 
123
124
  def initialize(options = {})
@@ -324,7 +325,7 @@ module ActiveMerchant #:nodoc:
324
325
  end
325
326
 
326
327
  def add_3d_secure(post, options)
327
- if options[:eci] && options[:xid]
328
+ if (options[:eci] && options[:xid]) || (options[:three_d_secure] && options[:three_d_secure][:version]&.start_with?('1'))
328
329
  add_3d_secure_1_data(post, options)
329
330
  elsif options[:execute_threed] && options[:three_ds_2]
330
331
  three_ds_2_options = options[:three_ds_2]
@@ -357,8 +358,17 @@ module ActiveMerchant #:nodoc:
357
358
  end
358
359
 
359
360
  def add_3d_secure_1_data(post, options)
360
- post[:i8] = build_i8(options[:eci], options[:cavv], options[:xid])
361
- post[:'3ds_version'] = options[:three_ds_version].nil? || options[:three_ds_version] == '1' ? '1.0' : options[:three_ds_version]
361
+ if three_d_secure_options = options[:three_d_secure]
362
+ post[:i8] = build_i8(
363
+ three_d_secure_options[:eci],
364
+ three_d_secure_options[:cavv],
365
+ three_d_secure_options[:xid]
366
+ )
367
+ post[:'3ds_version'] = three_d_secure_options[:version]&.start_with?('1') ? '1.0' : three_d_secure_options[:version]
368
+ else
369
+ post[:i8] = build_i8(options[:eci], options[:cavv], options[:xid])
370
+ post[:'3ds_version'] = options[:three_ds_version].nil? || options[:three_ds_version]&.start_with?('1') ? '1.0' : options[:three_ds_version]
371
+ end
362
372
  end
363
373
 
364
374
  def add_normalized_3d_secure_2_data(post, options)
@@ -368,7 +378,7 @@ module ActiveMerchant #:nodoc:
368
378
  three_d_secure_options[:eci],
369
379
  three_d_secure_options[:cavv]
370
380
  )
371
- post[:'3ds_version'] = three_d_secure_options[:version] == '2' ? '2.0' : three_d_secure_options[:version]
381
+ post[:'3ds_version'] = three_d_secure_options[:version]&.start_with?('2') ? '2.0' : three_d_secure_options[:version]
372
382
  post[:'3ds_dstrxid'] = three_d_secure_options[:ds_transaction_id]
373
383
  end
374
384
 
@@ -520,9 +520,11 @@ module ActiveMerchant #:nodoc:
520
520
  end
521
521
 
522
522
  def add_address(xml, payment_method, address, options, shipTo = false)
523
+ first_name, last_name = address_names(address[:name], payment_method)
524
+
523
525
  xml.tag! shipTo ? 'shipTo' : 'billTo' do
524
- xml.tag! 'firstName', payment_method.first_name if payment_method
525
- xml.tag! 'lastName', payment_method.last_name if payment_method
526
+ xml.tag! 'firstName', first_name if first_name
527
+ xml.tag! 'lastName', last_name if last_name
526
528
  xml.tag! 'street1', address[:address1]
527
529
  xml.tag! 'street2', address[:address2] unless address[:address2].blank?
528
530
  xml.tag! 'city', address[:city]
@@ -539,6 +541,16 @@ module ActiveMerchant #:nodoc:
539
541
  end
540
542
  end
541
543
 
544
+ def address_names(address_name, payment_method)
545
+ names = split_names(address_name)
546
+ return names if names.any?(&:present?)
547
+
548
+ [
549
+ payment_method&.first_name,
550
+ payment_method&.last_name
551
+ ]
552
+ end
553
+
542
554
  def add_creditcard(xml, creditcard)
543
555
  xml.tag! 'card' do
544
556
  xml.tag! 'accountNumber', creditcard.number
@@ -32,6 +32,7 @@ module ActiveMerchant #:nodoc:
32
32
  add_address(post, payment, options)
33
33
  add_creator_info(post, options)
34
34
  add_fraud_fields(post, options)
35
+ add_external_cardholder_authentication_data(post, options)
35
36
  commit(:authorize, post)
36
37
  end
37
38
 
@@ -232,6 +233,24 @@ module ActiveMerchant #:nodoc:
232
233
  post['fraudFields'] = fraud_fields unless fraud_fields.empty?
233
234
  end
234
235
 
236
+ def add_external_cardholder_authentication_data(post, options)
237
+ return unless threeds_2_options = options[:three_d_secure]
238
+
239
+ authentication_data = {}
240
+ authentication_data[:acsTransactionId] = threeds_2_options[:acs_transaction_id] if threeds_2_options[:acs_transaction_id]
241
+ authentication_data[:cavv] = threeds_2_options[:cavv] if threeds_2_options[:cavv]
242
+ authentication_data[:cavvAlgorithm] = threeds_2_options[:cavv_algorithm] if threeds_2_options[:cavv_algorithm]
243
+ authentication_data[:directoryServerTransactionId] = threeds_2_options[:ds_transaction_id] if threeds_2_options[:ds_transaction_id]
244
+ authentication_data[:eci] = threeds_2_options[:eci] if threeds_2_options[:eci]
245
+ authentication_data[:threeDSecureVersion] = threeds_2_options[:version] if threeds_2_options[:version]
246
+ authentication_data[:validationResult] = threeds_2_options[:authentication_response_status] if threeds_2_options[:authentication_response_status]
247
+ authentication_data[:xid] = threeds_2_options[:xid] if threeds_2_options[:xid]
248
+
249
+ post['cardPaymentMethodSpecificInput'] ||= {}
250
+ post['cardPaymentMethodSpecificInput']['threeDSecure'] ||= {}
251
+ post['cardPaymentMethodSpecificInput']['threeDSecure']['externalCardholderAuthenticationData'] = authentication_data unless authentication_data.empty?
252
+ end
253
+
235
254
  def add_number_of_installments(post, options)
236
255
  post['order']['additionalInput']['numberOfInstallments'] = options[:number_of_installments] if options[:number_of_installments]
237
256
  end
@@ -84,7 +84,7 @@ module ActiveMerchant #:nodoc:
84
84
  elsif check?(payment)
85
85
  add_echeck_purchase_params(doc, money, payment, options)
86
86
  else
87
- add_auth_purchase_params(doc, money, payment, options)
87
+ add_credit_params(doc, money, payment, options)
88
88
  end
89
89
  end
90
90
  end
@@ -227,6 +227,17 @@ module ActiveMerchant #:nodoc:
227
227
  add_stored_credential_params(doc, options)
228
228
  end
229
229
 
230
+ def add_credit_params(doc, money, payment_method, options)
231
+ doc.orderId(truncate(options[:order_id], 24))
232
+ doc.amount(money)
233
+ add_order_source(doc, payment_method, options)
234
+ add_billing_address(doc, payment_method, options)
235
+ add_payment_method(doc, payment_method, options)
236
+ add_pos(doc, payment_method)
237
+ add_descriptor(doc, options)
238
+ add_merchant_data(doc, options)
239
+ end
240
+
230
241
  def add_merchant_data(doc, options = {})
231
242
  if options[:affiliate] || options[:campaign] || options[:merchant_grouping_id]
232
243
  doc.merchantData do
@@ -170,6 +170,10 @@ module ActiveMerchant #:nodoc:
170
170
  9914 => 'KO Confirmation'
171
171
  }
172
172
 
173
+ # Expected values as per documentation
174
+ THREE_DS_V1 = '1.0.2'
175
+ THREE_DS_V2 = '2.1.0'
176
+
173
177
  # Creates a new instance
174
178
  #
175
179
  # Redsys requires a login and secret_key, and optionally also accepts a
@@ -197,6 +201,7 @@ module ActiveMerchant #:nodoc:
197
201
  add_amount(data, money, options)
198
202
  add_order(data, options[:order_id])
199
203
  add_payment(data, payment)
204
+ add_external_mpi_fields(data, options)
200
205
  add_threeds(data, options) if options[:execute_threed]
201
206
  data[:description] = options[:description]
202
207
  data[:store_in_vault] = options[:store]
@@ -213,6 +218,7 @@ module ActiveMerchant #:nodoc:
213
218
  add_amount(data, money, options)
214
219
  add_order(data, options[:order_id])
215
220
  add_payment(data, payment)
221
+ add_external_mpi_fields(data, options)
216
222
  add_threeds(data, options) if options[:execute_threed]
217
223
  data[:description] = options[:description]
218
224
  data[:store_in_vault] = options[:store]
@@ -321,6 +327,25 @@ module ActiveMerchant #:nodoc:
321
327
  end
322
328
  end
323
329
 
330
+ def add_external_mpi_fields(data, options)
331
+ return unless options[:three_d_secure]
332
+
333
+ if options[:three_d_secure][:version] == THREE_DS_V2
334
+ data[:threeDSServerTransID] = options[:three_d_secure][:xid] if options[:three_d_secure][:xid]
335
+ data[:dsTransID] = options[:three_d_secure][:ds_transaction_id] if options[:three_d_secure][:ds_transaction_id]
336
+ data[:authenticacionValue] = options[:three_d_secure][:cavv] if options[:three_d_secure][:cavv]
337
+ data[:protocolVersion] = options[:three_d_secure][:version] if options[:three_d_secure][:version]
338
+
339
+ data[:authenticacionMethod] = options[:authentication_method] if options[:authentication_method]
340
+ data[:authenticacionType] = options[:authentication_type] if options[:authentication_type]
341
+ data[:authenticacionFlow] = options[:authentication_flow] if options[:authentication_flow]
342
+ elsif options[:three_d_secure][:version] == THREE_DS_V1
343
+ data[:txid] = options[:three_d_secure][:xid] if options[:three_d_secure][:xid]
344
+ data[:cavv] = options[:three_d_secure][:cavv] if options[:three_d_secure][:cavv]
345
+ data[:eci] = options[:three_d_secure][:eci] if options[:three_d_secure][:eci]
346
+ end
347
+ end
348
+
324
349
  def add_threeds(data, options)
325
350
  data[:threeds] = { threeDSInfo: 'CardData' } if options[:execute_threed] == true
326
351
  end
@@ -419,6 +444,8 @@ module ActiveMerchant #:nodoc:
419
444
  end
420
445
 
421
446
  def build_merchant_data(xml, data, options = {})
447
+ # See https://sis-t.redsys.es:25443/sis/services/SerClsWSEntradaV2/wsdl/SerClsWSEntradaV2.wsdl
448
+ # (which results from calling #threeds_url + '?WSDL', https://sis-t.redsys.es:25443/sis/services/SerClsWSEntradaV2?WSDL)
422
449
  xml.DATOSENTRADA do
423
450
  # Basic elements
424
451
  xml.DS_Version 0.1
@@ -447,6 +474,9 @@ module ActiveMerchant #:nodoc:
447
474
  xml.DS_MERCHANT_EXPIRYDATE data[:card][:date]
448
475
  xml.DS_MERCHANT_CVV2 data[:card][:cvv]
449
476
  xml.DS_MERCHANT_IDENTIFIER 'REQUIRED' if data[:store_in_vault]
477
+
478
+ build_merchant_mpi_external(xml, data)
479
+
450
480
  elsif data[:credit_card_token]
451
481
  xml.DS_MERCHANT_IDENTIFIER data[:credit_card_token]
452
482
  xml.DS_MERCHANT_DIRECTPAYMENT 'true'
@@ -460,6 +490,27 @@ module ActiveMerchant #:nodoc:
460
490
  end
461
491
  end
462
492
 
493
+ def build_merchant_mpi_external(xml, data)
494
+ return unless data[:txid] || data[:threeDSServerTransID]
495
+
496
+ ds_merchant_mpi_external = {}
497
+ ds_merchant_mpi_external[:TXID] = data[:txid] if data[:txid]
498
+ ds_merchant_mpi_external[:CAVV] = data[:cavv] if data[:cavv]
499
+ ds_merchant_mpi_external[:ECI] = data[:eci] if data[:eci]
500
+
501
+ ds_merchant_mpi_external[:threeDSServerTransID] = data[:threeDSServerTransID] if data[:threeDSServerTransID]
502
+ ds_merchant_mpi_external[:dsTransID] = data[:dsTransID] if data[:dsTransID]
503
+ ds_merchant_mpi_external[:authenticacionValue] = data[:authenticacionValue] if data[:authenticacionValue]
504
+ ds_merchant_mpi_external[:protocolVersion] = data[:protocolVersion] if data[:protocolVersion]
505
+
506
+ ds_merchant_mpi_external[:authenticacionMethod] = data[:authenticacionMethod] if data[:authenticacionMethod]
507
+ ds_merchant_mpi_external[:authenticacionType] = data[:authenticacionType] if data[:authenticacionType]
508
+ ds_merchant_mpi_external[:authenticacionFlow] = data[:authenticacionFlow] if data[:authenticacionFlow]
509
+
510
+ xml.DS_MERCHANT_MPIEXTERNAL ds_merchant_mpi_external.to_json unless ds_merchant_mpi_external.empty?
511
+ xml.target!
512
+ end
513
+
463
514
  def parse(data, action)
464
515
  params = {}
465
516
  success = false
@@ -22,8 +22,19 @@ module ActiveMerchant #:nodoc:
22
22
 
23
23
  def purchase(money, payment, options = {})
24
24
  post = {}
25
- post[:sg_APIType] = 1 if options[:three_d_secure]
26
- trans_type = options[:three_d_secure] ? 'Sale3D' : 'Sale'
25
+
26
+ # Determine if 3DS is requested, or there is standard external MPI data
27
+ if options[:three_d_secure]
28
+ if options[:three_d_secure].is_a?(Hash)
29
+ add_external_mpi_data(post, options)
30
+ else
31
+ post[:sg_APIType] = 1
32
+ trans_type = 'Sale3D'
33
+ end
34
+ end
35
+
36
+ trans_type ||= 'Sale'
37
+
27
38
  add_transaction_data(trans_type, post, money, options)
28
39
  add_payment(post, payment, options)
29
40
  add_customer_details(post, payment, options)
@@ -33,6 +44,8 @@ module ActiveMerchant #:nodoc:
33
44
 
34
45
  def authorize(money, payment, options = {})
35
46
  post = {}
47
+
48
+ add_external_mpi_data(post, options) if options[:three_d_secure]&.is_a?(Hash)
36
49
  add_transaction_data('Auth', post, money, options)
37
50
  add_payment(post, payment, options)
38
51
  add_customer_details(post, payment, options)
@@ -69,8 +82,10 @@ module ActiveMerchant #:nodoc:
69
82
 
70
83
  def credit(money, payment, options = {})
71
84
  post = {}
85
+
72
86
  add_payment(post, payment, options)
73
87
  add_transaction_data('Credit', post, money, options)
88
+
74
89
  post[:sg_CreditType] = 1
75
90
 
76
91
  commit(post)
@@ -154,6 +169,15 @@ module ActiveMerchant #:nodoc:
154
169
  post[:sg_Email] = options[:email]
155
170
  end
156
171
 
172
+ def add_external_mpi_data(post, options)
173
+ post[:sg_eci] = options[:three_d_secure][:eci] if options[:three_d_secure][:eci]
174
+ post[:sg_cavv] = options[:three_d_secure][:cavv] if options[:three_d_secure][:cavv]
175
+ post[:sg_dsTransID] = options[:three_d_secure][:ds_transaction_id] if options[:three_d_secure][:ds_transaction_id]
176
+ post[:sg_threeDSProtocolVersion] = options[:three_d_secure][:version] || (options[:three_d_secure][:ds_transaction_id] ? '2' : '1')
177
+ post[:sg_xid] = options[:three_d_secure][:xid]
178
+ post[:sg_IsExternalMPI] = 1
179
+ end
180
+
157
181
  def parse(xml)
158
182
  response = {}
159
183
 
@@ -28,7 +28,7 @@ module ActiveMerchant #:nodoc:
28
28
  self.supported_countries = %w(AT AU BE BG BR CA CH CY CZ DE DK EE ES FI FR GB GR HK IE IT JP LT LU LV MT MX NL NO NZ PL PT RO SE SG SI SK US)
29
29
  self.default_currency = 'USD'
30
30
  self.money_format = :cents
31
- self.supported_cardtypes = %i[visa master american_express discover jcb diners_club maestro]
31
+ self.supported_cardtypes = %i[visa master american_express discover jcb diners_club maestro unionpay]
32
32
  self.currencies_without_fractions = %w(BIF CLP DJF GNF JPY KMF KRW MGA PYG RWF VND VUV XAF XOF XPF UGX)
33
33
 
34
34
  self.homepage_url = 'https://stripe.com/'
@@ -23,6 +23,7 @@ module ActiveMerchant #:nodoc:
23
23
  payment_method = add_payment_method_token(post, payment_method, options)
24
24
  return payment_method if payment_method.is_a?(ActiveMerchant::Billing::Response)
25
25
 
26
+ add_external_three_d_secure_auth_data(post, options)
26
27
  add_metadata(post, options)
27
28
  add_return_url(post, options)
28
29
  add_connected_account(post, options)
@@ -276,6 +277,19 @@ module ActiveMerchant #:nodoc:
276
277
  post[:payment_method_options][:card][:request_three_d_secure] = options[:request_three_d_secure]
277
278
  end
278
279
 
280
+ def add_external_three_d_secure_auth_data(post, options = {})
281
+ return unless options[:three_d_secure]&.is_a?(Hash)
282
+
283
+ three_d_secure = options[:three_d_secure]
284
+ post[:payment_method_options] ||= {}
285
+ post[:payment_method_options][:card] ||= {}
286
+ post[:payment_method_options][:card][:three_d_secure] ||= {}
287
+ post[:payment_method_options][:card][:three_d_secure][:version] = three_d_secure[:version] || (three_d_secure[:ds_transaction_id] ? '2.2.0' : '1.0.2')
288
+ post[:payment_method_options][:card][:three_d_secure][:electronic_commerce_indicator] = three_d_secure[:eci] if three_d_secure[:eci]
289
+ post[:payment_method_options][:card][:three_d_secure][:cryptogram] = three_d_secure[:cavv] if three_d_secure[:cavv]
290
+ post[:payment_method_options][:card][:three_d_secure][:transaction_id] = three_d_secure[:ds_transaction_id] || three_d_secure[:xid]
291
+ end
292
+
279
293
  def setup_future_usage(post, options = {})
280
294
  post[:setup_future_usage] = options[:setup_future_usage] if %w(on_session off_session).include?(options[:setup_future_usage])
281
295
  post[:off_session] = options[:off_session] if options[:off_session] && options[:confirm] == true
@@ -9,7 +9,7 @@ module ActiveMerchant #:nodoc:
9
9
  self.default_currency = 'GBP'
10
10
  self.money_format = :cents
11
11
  self.supported_countries = %w(HK GB AU AD AR BE BR CA CH CN CO CR CY CZ DE DK ES FI FR GI GR HU IE IN IT JP LI LU MC MT MY MX NL NO NZ PA PE PL PT SE SG SI SM TR UM VA)
12
- self.supported_cardtypes = %i[visa master american_express discover jcb maestro elo naranja cabal]
12
+ self.supported_cardtypes = %i[visa master american_express discover jcb maestro elo naranja cabal unionpay]
13
13
  self.currencies_without_fractions = %w(HUF IDR ISK JPY KRW)
14
14
  self.currencies_with_three_decimal_places = %w(BHD KWD OMR RSD TND)
15
15
  self.homepage_url = 'http://www.worldpay.com/'
@@ -26,6 +26,7 @@ module ActiveMerchant #:nodoc:
26
26
  'elo' => 'ELO-SSL',
27
27
  'naranja' => 'NARANJA-SSL',
28
28
  'cabal' => 'CABAL-SSL',
29
+ 'unionpay' => 'CHINAUNIONPAY-SSL',
29
30
  'unknown' => 'CARD-SSL'
30
31
  }
31
32
 
@@ -1,3 +1,3 @@
1
1
  module ActiveMerchant
2
- VERSION = '1.116.0'
2
+ VERSION = '1.117.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activemerchant
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.116.0
4
+ version: 1.117.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Luetke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-29 00:00:00.000000000 Z
11
+ date: 2020-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport