activemerchant 1.116.0 → 1.117.0

Sign up to get free protection for your applications and to get access to all the features.
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