activemerchant 1.97.0 → 1.98.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 +4 -4
- data/CHANGELOG +30 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +18 -0
- data/lib/active_merchant/billing/gateways/adyen.rb +39 -0
- data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +22 -18
- data/lib/active_merchant/billing/gateways/blue_snap.rb +18 -1
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +23 -7
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +13 -3
- data/lib/active_merchant/billing/gateways/d_local.rb +1 -1
- data/lib/active_merchant/billing/gateways/decidir.rb +3 -2
- data/lib/active_merchant/billing/gateways/epay.rb +13 -2
- data/lib/active_merchant/billing/gateways/eway_rapid.rb +42 -12
- data/lib/active_merchant/billing/gateways/fat_zebra.rb +6 -0
- data/lib/active_merchant/billing/gateways/global_collect.rb +1 -1
- data/lib/active_merchant/billing/gateways/payu_latam.rb +5 -2
- data/lib/active_merchant/billing/gateways/stripe.rb +37 -8
- data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +267 -0
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +22 -2
- data/lib/active_merchant/billing/gateways/worldpay.rb +7 -1
- data/lib/active_merchant/version.rb +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: acfbb780d39dd416b823a9abef4cdcf4de902ec75210ed78e6771314d00b069b
|
|
4
|
+
data.tar.gz: 95e9bf94b3610b33d843fd82af8e4f204380e7c53557d24141b654c553160d9f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6222cdad43482972e2a799981936dc1d8114ccbede88604880d350650f7b81422b6551a07375dd1a7e06ef562d4f128c332dabc2fc16ebb7b635f774de18a54e
|
|
7
|
+
data.tar.gz: 2f9fe3fe9dfe17fc045f0a3e97940ae4b38a461c48f0416a26ed4b5a4e2bb549464911fbe7527392c8dfbcbbee16bfa82266e3ad644060199ee9552b5b82659b
|
data/CHANGELOG
CHANGED
|
@@ -1,6 +1,35 @@
|
|
|
1
1
|
= ActiveMerchant CHANGELOG
|
|
2
2
|
|
|
3
3
|
== HEAD
|
|
4
|
+
== Version 1.98.0 (Sep 9, 2019)
|
|
5
|
+
* Stripe Payment Intents: Add new gateway [britth] #3290
|
|
6
|
+
* Stripe: Send cardholder name and address when creating sources for 3DS 1.0 [jknipp] #3300
|
|
7
|
+
* Checkout_v2: Support for native 3DS2.0 [nfarve] #3303
|
|
8
|
+
* Adds new Maestro BINs [tanyajajodia] #3305
|
|
9
|
+
* eWAY Rapid: If no address is available, default to the name associated with the payment method when setting the Customer fields [jasonxp] #3306
|
|
10
|
+
* eWAY Rapid: Fix a bug in which the email was not set in Customer fields if no address was provided [jasonxp] #3306
|
|
11
|
+
* eWAY Rapid: Support both `phone` and `phone_number` fields under the `shipping_address` option [jasonxp] #3306
|
|
12
|
+
* PayU Latam: Add support for the `merchant_buyer_id` field in the `options` and `buyer` hashes [jasonxp] #3308
|
|
13
|
+
* Update Braintree Gem [curiousepic] #3311
|
|
14
|
+
* Fat Zebra: Send metadata for purchase and authorize [montdidier] #3101
|
|
15
|
+
* TrustCommerce: Add support for custom fields [jasonxp] #3313
|
|
16
|
+
* Stripe Payment Intents: Support option fields `transfer_destination` and `transfer_amount` and remove `transfer_data` hash [britth] #3317
|
|
17
|
+
* Barclaycard Smartpay: Add support for `shopperStatement` gateway-specific field [jasonxp] #3319
|
|
18
|
+
* Stripe Payment Intents: Add support for billing_details on payment methods [britth] #3320
|
|
19
|
+
* BlueSnap: add standardized 3DS 2 auth fields [bayprogrammer] #3318
|
|
20
|
+
* Barclaycard Smartpay: Add app based 3DS requests for auth and purchase [britth] #3327
|
|
21
|
+
* Stripe Payment Intents, Checkout V2: Add support for `MOTO` flagging [britth] #3323
|
|
22
|
+
* Braintree Blue: Adding 3DS2 passthru support [molbrown] #3328
|
|
23
|
+
* Global Collect: Add Cabal card [leila-alderman] #3310
|
|
24
|
+
* WorldPay: Add Cabal card [leila-alderman] #3316
|
|
25
|
+
* Decidir: Add Cabal card [leila-alderman] #3322
|
|
26
|
+
* PayU Latam: Add Cabal card [leila-alderman] #3324
|
|
27
|
+
* dLocal: Add Cabal card [leila-alderman] #3325
|
|
28
|
+
* BlueSnap: Add Cabal card [leila-alderman] #3326
|
|
29
|
+
* Adyen: added 3DS support through external [rikterbeek] #3294
|
|
30
|
+
* Worldpay: Add support for MOTO flagging [britth] #3329
|
|
31
|
+
* ePay: 3DS support [AllaWLie] #3321
|
|
32
|
+
* Checkout.com: added options[:metadata][:manual_entry] support for MOTO transactions [filipebarcos] #3330
|
|
4
33
|
|
|
5
34
|
== Version 1.97.0 (Aug 15, 2019)
|
|
6
35
|
* CyberSource: Add issuer `additionalData` gateway-specific field [jasonxp] #3296
|
|
@@ -206,6 +235,7 @@
|
|
|
206
235
|
* Forte: Allow void on capture [nfarve] #3059
|
|
207
236
|
|
|
208
237
|
== Version 1.86.0 (October 26, 2018)
|
|
238
|
+
* UsaEpayTransaction: Support UMcheckformat option for echecks [dtykocki] #3002
|
|
209
239
|
* Global Collect: handle internal server errors [molbrown] #3005
|
|
210
240
|
* Barclaycard Smartpay: allow third-party payouts for credits [bpollack] #3009
|
|
211
241
|
* RuboCop: AlignHash [nfarve] #3004
|
|
@@ -66,6 +66,24 @@ module ActiveMerchant #:nodoc:
|
|
|
66
66
|
|
|
67
67
|
# https://www.mastercard.us/content/dam/mccom/global/documents/mastercard-rules.pdf, page 73
|
|
68
68
|
MAESTRO_RANGES = [
|
|
69
|
+
(561200..561269),
|
|
70
|
+
(561271..561299),
|
|
71
|
+
(561320..561356),
|
|
72
|
+
(581700..581751),
|
|
73
|
+
(581753..581800),
|
|
74
|
+
(589998..591259),
|
|
75
|
+
(591261..596770),
|
|
76
|
+
(596772..598744),
|
|
77
|
+
(598746..599999),
|
|
78
|
+
(600297..600314),
|
|
79
|
+
(600316..600335),
|
|
80
|
+
(600337..600362),
|
|
81
|
+
(600364..600382),
|
|
82
|
+
(601232..601254),
|
|
83
|
+
(601256..601276),
|
|
84
|
+
(601640..601652),
|
|
85
|
+
(601689..601700),
|
|
86
|
+
(602011..602050),
|
|
69
87
|
(639000..639099),
|
|
70
88
|
(670000..679999),
|
|
71
89
|
]
|
|
@@ -56,6 +56,7 @@ module ActiveMerchant #:nodoc:
|
|
|
56
56
|
add_address(post, options)
|
|
57
57
|
add_installments(post, options) if options[:installments]
|
|
58
58
|
add_3ds(post, options)
|
|
59
|
+
add_3ds_authenticated_data(post, options)
|
|
59
60
|
commit('authorise', post, options)
|
|
60
61
|
end
|
|
61
62
|
|
|
@@ -342,6 +343,44 @@ module ActiveMerchant #:nodoc:
|
|
|
342
343
|
end
|
|
343
344
|
end
|
|
344
345
|
|
|
346
|
+
def add_3ds_authenticated_data(post, options)
|
|
347
|
+
if options[:three_d_secure] && options[:three_d_secure][:eci] && options[:three_d_secure][:xid]
|
|
348
|
+
add_3ds1_authenticated_data(post, options)
|
|
349
|
+
elsif options[:three_d_secure]
|
|
350
|
+
add_3ds2_authenticated_data(post, options)
|
|
351
|
+
end
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
def add_3ds1_authenticated_data(post, options)
|
|
355
|
+
three_d_secure_options = options[:three_d_secure]
|
|
356
|
+
post[:mpiData] = {
|
|
357
|
+
cavv: three_d_secure_options[:cavv],
|
|
358
|
+
cavvAlgorithm: three_d_secure_options[:cavv_algorithm],
|
|
359
|
+
eci: three_d_secure_options[:eci],
|
|
360
|
+
xid: three_d_secure_options[:xid],
|
|
361
|
+
directoryResponse: three_d_secure_options[:directory_response_status],
|
|
362
|
+
authenticationResponse: three_d_secure_options[:authentication_response_status]
|
|
363
|
+
}
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
def add_3ds2_authenticated_data(post, options)
|
|
367
|
+
three_d_secure_options = options[:three_d_secure]
|
|
368
|
+
# If the transaction was authenticated in a frictionless flow, send the transStatus from the ARes.
|
|
369
|
+
if(three_d_secure_options[:authentication_response_status].nil?)
|
|
370
|
+
authentication_response = three_d_secure_options[:directory_response_status]
|
|
371
|
+
else
|
|
372
|
+
authentication_response = three_d_secure_options[:authentication_response_status]
|
|
373
|
+
end
|
|
374
|
+
post[:mpiData] = {
|
|
375
|
+
threeDSVersion: three_d_secure_options[:version],
|
|
376
|
+
eci: three_d_secure_options[:eci],
|
|
377
|
+
cavv: three_d_secure_options[:cavv],
|
|
378
|
+
dsTransID: three_d_secure_options[:ds_transaction_id],
|
|
379
|
+
directoryResponse: three_d_secure_options[:directory_response_status],
|
|
380
|
+
authenticationResponse: authentication_response
|
|
381
|
+
}
|
|
382
|
+
end
|
|
383
|
+
|
|
345
384
|
def parse(body)
|
|
346
385
|
return {} if body.blank?
|
|
347
386
|
JSON.parse(body)
|
|
@@ -37,6 +37,8 @@ module ActiveMerchant #:nodoc:
|
|
|
37
37
|
post[:card] = credit_card_hash(creditcard)
|
|
38
38
|
post[:billingAddress] = billing_address_hash(options) if options[:billing_address]
|
|
39
39
|
post[:deliveryAddress] = shipping_address_hash(options) if options[:shipping_address]
|
|
40
|
+
post[:shopperStatement] = options[:shopper_statement] if options[:shopper_statement]
|
|
41
|
+
|
|
40
42
|
add_3ds(post, options)
|
|
41
43
|
commit('authorise', post)
|
|
42
44
|
end
|
|
@@ -350,24 +352,12 @@ module ActiveMerchant #:nodoc:
|
|
|
350
352
|
|
|
351
353
|
def add_3ds(post, options)
|
|
352
354
|
if three_ds_2_options = options[:three_ds_2]
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
screenHeight: browser_info[:height],
|
|
360
|
-
screenWidth: browser_info[:width],
|
|
361
|
-
timeZoneOffset: browser_info[:timezone],
|
|
362
|
-
userAgent: browser_info[:user_agent]
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
if device_channel = three_ds_2_options[:channel]
|
|
366
|
-
post[:threeDS2RequestData] = {
|
|
367
|
-
deviceChannel: device_channel,
|
|
368
|
-
notificationURL: three_ds_2_options[:notification_url]
|
|
369
|
-
}
|
|
370
|
-
end
|
|
355
|
+
device_channel = three_ds_2_options[:channel]
|
|
356
|
+
if device_channel == 'app'
|
|
357
|
+
post[:threeDS2RequestData] = { deviceChannel: device_channel }
|
|
358
|
+
else
|
|
359
|
+
add_browser_info(three_ds_2_options[:browser_info], post)
|
|
360
|
+
post[:threeDS2RequestData] = { deviceChannel: device_channel, notificationURL: three_ds_2_options[:notification_url] }
|
|
371
361
|
end
|
|
372
362
|
else
|
|
373
363
|
return unless options[:execute_threed] || options[:threed_dynamic]
|
|
@@ -375,6 +365,20 @@ module ActiveMerchant #:nodoc:
|
|
|
375
365
|
post[:additionalData] = { executeThreeD: 'true' } if options[:execute_threed]
|
|
376
366
|
end
|
|
377
367
|
end
|
|
368
|
+
|
|
369
|
+
def add_browser_info(browser_info, post)
|
|
370
|
+
return unless browser_info
|
|
371
|
+
post[:browserInfo] = {
|
|
372
|
+
acceptHeader: browser_info[:accept_header],
|
|
373
|
+
colorDepth: browser_info[:depth],
|
|
374
|
+
javaEnabled: browser_info[:java],
|
|
375
|
+
language: browser_info[:language],
|
|
376
|
+
screenHeight: browser_info[:height],
|
|
377
|
+
screenWidth: browser_info[:width],
|
|
378
|
+
timeZoneOffset: browser_info[:timezone],
|
|
379
|
+
userAgent: browser_info[:user_agent]
|
|
380
|
+
}
|
|
381
|
+
end
|
|
378
382
|
end
|
|
379
383
|
end
|
|
380
384
|
end
|
|
@@ -8,7 +8,7 @@ module ActiveMerchant
|
|
|
8
8
|
self.supported_countries = %w(US CA GB AT BE BG HR CY CZ DK EE FI FR DE GR HU IE IT LV LT LU MT NL PL PT RO SK SI ES SE AR BO BR BZ CL CO CR DO EC GF GP GT HN HT MF MQ MX NI PA PE PR PY SV UY VE)
|
|
9
9
|
|
|
10
10
|
self.default_currency = 'USD'
|
|
11
|
-
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club, :maestro, :naranja]
|
|
11
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club, :maestro, :naranja, :cabal]
|
|
12
12
|
|
|
13
13
|
self.homepage_url = 'https://home.bluesnap.com/'
|
|
14
14
|
self.display_name = 'BlueSnap'
|
|
@@ -223,6 +223,7 @@ module ActiveMerchant
|
|
|
223
223
|
doc.send('merchant-transaction-id', truncate(options[:order_id], 50)) if options[:order_id]
|
|
224
224
|
doc.send('soft-descriptor', options[:soft_descriptor]) if options[:soft_descriptor]
|
|
225
225
|
add_description(doc, options[:description]) if options[:description]
|
|
226
|
+
add_3ds(doc, options[:three_d_secure]) if options[:three_d_secure]
|
|
226
227
|
add_level_3_data(doc, options)
|
|
227
228
|
end
|
|
228
229
|
|
|
@@ -237,6 +238,22 @@ module ActiveMerchant
|
|
|
237
238
|
doc.zip(address[:zip]) if address[:zip]
|
|
238
239
|
end
|
|
239
240
|
|
|
241
|
+
def add_3ds(doc, three_d_secure_options)
|
|
242
|
+
eci = three_d_secure_options[:eci]
|
|
243
|
+
cavv = three_d_secure_options[:cavv]
|
|
244
|
+
xid = three_d_secure_options[:xid]
|
|
245
|
+
ds_transaction_id = three_d_secure_options[:ds_transaction_id]
|
|
246
|
+
version = three_d_secure_options[:version]
|
|
247
|
+
|
|
248
|
+
doc.send('three-d-secure') do
|
|
249
|
+
doc.eci(eci) if eci
|
|
250
|
+
doc.cavv(cavv) if cavv
|
|
251
|
+
doc.xid(xid) if xid
|
|
252
|
+
doc.send('three-d-secure-version', version) if version
|
|
253
|
+
doc.send('ds-transaction-id', ds_transaction_id) if ds_transaction_id
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
240
257
|
def add_level_3_data(doc, options)
|
|
241
258
|
return unless options[:customer_reference_number]
|
|
242
259
|
doc.send('level-3-data') do
|
|
@@ -630,13 +630,7 @@ module ActiveMerchant #:nodoc:
|
|
|
630
630
|
}
|
|
631
631
|
end
|
|
632
632
|
|
|
633
|
-
|
|
634
|
-
parameters[:three_d_secure_pass_thru] = {
|
|
635
|
-
cavv: options[:three_d_secure][:cavv],
|
|
636
|
-
eci_flag: options[:three_d_secure][:eci],
|
|
637
|
-
xid: options[:three_d_secure][:xid],
|
|
638
|
-
}
|
|
639
|
-
end
|
|
633
|
+
add_3ds_info(parameters, options[:three_d_secure])
|
|
640
634
|
|
|
641
635
|
parameters[:tax_amount] = options[:tax_amount] if options[:tax_amount]
|
|
642
636
|
parameters[:tax_exempt] = options[:tax_exempt] if options[:tax_exempt]
|
|
@@ -651,6 +645,28 @@ module ActiveMerchant #:nodoc:
|
|
|
651
645
|
parameters
|
|
652
646
|
end
|
|
653
647
|
|
|
648
|
+
def add_3ds_info(parameters, three_d_secure_opts)
|
|
649
|
+
return if empty?(three_d_secure_opts)
|
|
650
|
+
pass_thru = {}
|
|
651
|
+
|
|
652
|
+
pass_thru[:three_d_secure_version] = three_d_secure_opts[:version] if three_d_secure_opts[:version]
|
|
653
|
+
pass_thru[:eci_flag] = three_d_secure_opts[:eci] if three_d_secure_opts[:eci]
|
|
654
|
+
pass_thru[:cavv_algorithm] = three_d_secure_opts[:cavv_algorithm] if three_d_secure_opts[:cavv_algorithm]
|
|
655
|
+
pass_thru[:cavv] = three_d_secure_opts[:cavv] if three_d_secure_opts[:cavv]
|
|
656
|
+
pass_thru[:directory_response] = three_d_secure_opts[:directory_response_status] if three_d_secure_opts[:directory_response_status]
|
|
657
|
+
pass_thru[:authentication_response] = three_d_secure_opts[:authentication_response_status] if three_d_secure_opts[:authentication_response_status]
|
|
658
|
+
|
|
659
|
+
parameters[:three_d_secure_pass_thru] = pass_thru.merge(xid_or_ds_trans_id(three_d_secure_opts))
|
|
660
|
+
end
|
|
661
|
+
|
|
662
|
+
def xid_or_ds_trans_id(three_d_secure_opts)
|
|
663
|
+
if three_d_secure_opts[:version].to_f >= 2
|
|
664
|
+
{ ds_transaction_id: three_d_secure_opts[:ds_transaction_id] }
|
|
665
|
+
else
|
|
666
|
+
{ xid: three_d_secure_opts[:xid] }
|
|
667
|
+
end
|
|
668
|
+
end
|
|
669
|
+
|
|
654
670
|
def add_stored_credential_data(parameters, credit_card_or_vault_id, options)
|
|
655
671
|
return unless (stored_credential = options[:stored_credential])
|
|
656
672
|
parameters[:external_vault] = {}
|
|
@@ -68,6 +68,10 @@ module ActiveMerchant #:nodoc:
|
|
|
68
68
|
end
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
+
def verify_payment(authorization, option={})
|
|
72
|
+
commit(:verify_payment, authorization)
|
|
73
|
+
end
|
|
74
|
+
|
|
71
75
|
def supports_scrubbing?
|
|
72
76
|
true
|
|
73
77
|
end
|
|
@@ -124,13 +128,19 @@ module ActiveMerchant #:nodoc:
|
|
|
124
128
|
def add_transaction_data(post, options = {})
|
|
125
129
|
post[:payment_type] = 'Regular' if options[:transaction_indicator] == 1
|
|
126
130
|
post[:payment_type] = 'Recurring' if options[:transaction_indicator] == 2
|
|
131
|
+
post[:payment_type] = 'MOTO' if options[:transaction_indicator] == 3 || options.dig(:metadata, :manual_entry)
|
|
127
132
|
post[:previous_payment_id] = options[:previous_charge_id] if options[:previous_charge_id]
|
|
128
133
|
end
|
|
129
134
|
|
|
130
135
|
def add_3ds(post, options)
|
|
131
|
-
if options[:three_d_secure]
|
|
136
|
+
if options[:three_d_secure] || options[:execute_threed]
|
|
132
137
|
post[:'3ds'] = {}
|
|
133
138
|
post[:'3ds'][:enabled] = true
|
|
139
|
+
post[:success_url] = options[:callback_url] if options[:callback_url]
|
|
140
|
+
post[:failure_url] = options[:callback_url] if options[:callback_url]
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
if options[:three_d_secure]
|
|
134
144
|
post[:'3ds'][:eci] = options[:three_d_secure][:eci] if options[:three_d_secure][:eci]
|
|
135
145
|
post[:'3ds'][:cryptogram] = options[:three_d_secure][:cavv] if options[:three_d_secure][:cavv]
|
|
136
146
|
post[:'3ds'][:version] = options[:three_d_secure][:version] if options[:three_d_secure][:version]
|
|
@@ -140,7 +150,7 @@ module ActiveMerchant #:nodoc:
|
|
|
140
150
|
|
|
141
151
|
def commit(action, post, authorization = nil)
|
|
142
152
|
begin
|
|
143
|
-
raw_response = ssl_post(url(post, action, authorization), post.to_json, headers)
|
|
153
|
+
raw_response = (action == :verify_payment ? ssl_get("#{base_url}/payments/#{post}", headers) : ssl_post(url(post, action, authorization), post.to_json, headers))
|
|
144
154
|
response = parse(raw_response)
|
|
145
155
|
if action == :capture && response.key?('_links')
|
|
146
156
|
response['id'] = response['_links']['payment']['href'].split('/')[-1]
|
|
@@ -215,7 +225,7 @@ module ActiveMerchant #:nodoc:
|
|
|
215
225
|
end
|
|
216
226
|
|
|
217
227
|
def success_from(response)
|
|
218
|
-
response['response_summary'] == 'Approved' || !response.key?('response_summary') && response.key?('action_id')
|
|
228
|
+
response['response_summary'] == 'Approved' || response['approved'] == true || !response.key?('response_summary') && response.key?('action_id')
|
|
219
229
|
end
|
|
220
230
|
|
|
221
231
|
def message_from(succeeded, response)
|
|
@@ -6,7 +6,7 @@ module ActiveMerchant #:nodoc:
|
|
|
6
6
|
|
|
7
7
|
self.supported_countries = ['AR', 'BR', 'CL', 'CO', 'MX', 'PE', 'UY', 'TR']
|
|
8
8
|
self.default_currency = 'USD'
|
|
9
|
-
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club, :maestro, :naranja]
|
|
9
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club, :maestro, :naranja, :cabal]
|
|
10
10
|
|
|
11
11
|
self.homepage_url = 'https://dlocal.com/'
|
|
12
12
|
self.display_name = 'dLocal'
|
|
@@ -7,7 +7,7 @@ module ActiveMerchant #:nodoc:
|
|
|
7
7
|
self.supported_countries = ['AR']
|
|
8
8
|
self.money_format = :cents
|
|
9
9
|
self.default_currency = 'ARS'
|
|
10
|
-
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club]
|
|
10
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :naranja, :cabal]
|
|
11
11
|
|
|
12
12
|
self.homepage_url = 'http://www.decidir.com'
|
|
13
13
|
self.display_name = 'Decidir'
|
|
@@ -99,7 +99,8 @@ module ActiveMerchant #:nodoc:
|
|
|
99
99
|
transcript.
|
|
100
100
|
gsub(%r((apikey: )\w+)i, '\1[FILTERED]').
|
|
101
101
|
gsub(%r((\"card_number\\\":\\\")\d+), '\1[FILTERED]').
|
|
102
|
-
gsub(%r((\"security_code\\\":\\\")\d+), '\1[FILTERED]')
|
|
102
|
+
gsub(%r((\"security_code\\\":\\\")\d+), '\1[FILTERED]').
|
|
103
|
+
gsub(%r((\"emv_issuer_data\\\":\\\")\d+), '\1[FILTERED]')
|
|
103
104
|
end
|
|
104
105
|
|
|
105
106
|
private
|
|
@@ -63,6 +63,7 @@ module ActiveMerchant #:nodoc:
|
|
|
63
63
|
add_invoice(post, options)
|
|
64
64
|
add_creditcard_or_reference(post, credit_card_or_reference)
|
|
65
65
|
add_instant_capture(post, false)
|
|
66
|
+
add_3ds_auth(post, options)
|
|
66
67
|
|
|
67
68
|
commit(:authorize, post)
|
|
68
69
|
end
|
|
@@ -74,6 +75,7 @@ module ActiveMerchant #:nodoc:
|
|
|
74
75
|
add_creditcard_or_reference(post, credit_card_or_reference)
|
|
75
76
|
add_invoice(post, options)
|
|
76
77
|
add_instant_capture(post, true)
|
|
78
|
+
add_3ds_auth(post, options)
|
|
77
79
|
|
|
78
80
|
commit(:authorize, post)
|
|
79
81
|
end
|
|
@@ -158,6 +160,16 @@ module ActiveMerchant #:nodoc:
|
|
|
158
160
|
post[:instantcapture] = option ? 1 : 0
|
|
159
161
|
end
|
|
160
162
|
|
|
163
|
+
def add_3ds_auth(post, options)
|
|
164
|
+
if options[:three_d_secure]
|
|
165
|
+
post[:eci] = options.dig(:three_d_secure, :eci)
|
|
166
|
+
post[:xid] = options.dig(:three_d_secure, :xid)
|
|
167
|
+
post[:cavv] = options.dig(:three_d_secure, :cavv)
|
|
168
|
+
post[:threeds_version] = options.dig(:three_d_secure, :version)
|
|
169
|
+
post[:ds_transaction_id] = options.dig(:three_d_secure, :ds_transaction_id)
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
161
173
|
def commit(action, params)
|
|
162
174
|
response = send("do_#{action}", params)
|
|
163
175
|
|
|
@@ -193,7 +205,6 @@ module ActiveMerchant #:nodoc:
|
|
|
193
205
|
headers['Referer'] = (options[:password] || 'activemerchant.org')
|
|
194
206
|
|
|
195
207
|
response = raw_ssl_request(:post, live_url + 'auth/default.aspx', authorize_post_data(params), headers)
|
|
196
|
-
|
|
197
208
|
# Authorize gives the response back by redirecting with the values in
|
|
198
209
|
# the URL query
|
|
199
210
|
if location = response['Location']
|
|
@@ -268,7 +279,7 @@ module ActiveMerchant #:nodoc:
|
|
|
268
279
|
|
|
269
280
|
def authorize_post_data(params = {})
|
|
270
281
|
params[:language] = '2'
|
|
271
|
-
params[:cms] = '
|
|
282
|
+
params[:cms] = 'activemerchant_3ds'
|
|
272
283
|
params[:accepturl] = live_url + 'auth/default.aspx?accept=1'
|
|
273
284
|
params[:declineurl] = live_url + 'auth/default.aspx?decline=1'
|
|
274
285
|
params[:merchantnumber] = @options[:login]
|
|
@@ -51,7 +51,7 @@ module ActiveMerchant #:nodoc:
|
|
|
51
51
|
params = {}
|
|
52
52
|
add_metadata(params, options)
|
|
53
53
|
add_invoice(params, amount, options)
|
|
54
|
-
add_customer_data(params, options)
|
|
54
|
+
add_customer_data(params, options, payment_method)
|
|
55
55
|
add_credit_card(params, payment_method, options)
|
|
56
56
|
params['Method'] = payment_method.respond_to?(:number) ? 'ProcessPayment' : 'TokenPayment'
|
|
57
57
|
commit(url_for('Transaction'), params)
|
|
@@ -61,7 +61,7 @@ module ActiveMerchant #:nodoc:
|
|
|
61
61
|
params = {}
|
|
62
62
|
add_metadata(params, options)
|
|
63
63
|
add_invoice(params, amount, options)
|
|
64
|
-
add_customer_data(params, options)
|
|
64
|
+
add_customer_data(params, options, payment_method)
|
|
65
65
|
add_credit_card(params, payment_method, options)
|
|
66
66
|
params['Method'] = 'Authorise'
|
|
67
67
|
commit(url_for('Authorisation'), params)
|
|
@@ -137,7 +137,7 @@ module ActiveMerchant #:nodoc:
|
|
|
137
137
|
params = {}
|
|
138
138
|
add_metadata(params, options)
|
|
139
139
|
add_invoice(params, 0, options)
|
|
140
|
-
add_customer_data(params, options)
|
|
140
|
+
add_customer_data(params, options, payment_method)
|
|
141
141
|
add_credit_card(params, payment_method, options)
|
|
142
142
|
params['Method'] = 'CreateTokenCustomer'
|
|
143
143
|
commit(url_for('Transaction'), params)
|
|
@@ -166,7 +166,7 @@ module ActiveMerchant #:nodoc:
|
|
|
166
166
|
params = {}
|
|
167
167
|
add_metadata(params, options)
|
|
168
168
|
add_invoice(params, 0, options)
|
|
169
|
-
add_customer_data(params, options)
|
|
169
|
+
add_customer_data(params, options, payment_method)
|
|
170
170
|
add_credit_card(params, payment_method, options)
|
|
171
171
|
add_customer_token(params, customer_token)
|
|
172
172
|
params['Method'] = 'UpdateTokenCustomer'
|
|
@@ -212,17 +212,48 @@ module ActiveMerchant #:nodoc:
|
|
|
212
212
|
params['TransactionID'] = reference
|
|
213
213
|
end
|
|
214
214
|
|
|
215
|
-
def add_customer_data(params, options)
|
|
216
|
-
params
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
215
|
+
def add_customer_data(params, options, payment_method = nil)
|
|
216
|
+
add_customer_fields(params, options, payment_method)
|
|
217
|
+
add_shipping_fields(params, options)
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def add_customer_fields(params, options, payment_method)
|
|
221
|
+
key = 'Customer'
|
|
222
|
+
params[key] ||= {}
|
|
223
|
+
|
|
224
|
+
customer_address = options[:billing_address] || options[:address]
|
|
225
|
+
|
|
226
|
+
add_name_and_email(params[key], customer_address, options[:email], payment_method)
|
|
227
|
+
add_address(params[key], customer_address)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def add_shipping_fields(params, options)
|
|
231
|
+
key = 'ShippingAddress'
|
|
232
|
+
params[key] = {}
|
|
233
|
+
|
|
234
|
+
add_name_and_email(params[key], options[:shipping_address], options[:email])
|
|
235
|
+
add_address(params[key], options[:shipping_address], {:skip_company => true})
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def add_name_and_email(params, address, email, payment_method = nil)
|
|
239
|
+
if address.present?
|
|
240
|
+
params['FirstName'], params['LastName'] = split_names(address[:name])
|
|
241
|
+
elsif payment_method_name_available?(payment_method)
|
|
242
|
+
params['FirstName'] = payment_method.first_name
|
|
243
|
+
params['LastName'] = payment_method.last_name
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
params['Email'] = email
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
def payment_method_name_available?(payment_method)
|
|
250
|
+
payment_method.respond_to?(:first_name) && payment_method.respond_to?(:last_name) &&
|
|
251
|
+
payment_method.first_name.present? && payment_method.last_name.present?
|
|
220
252
|
end
|
|
221
253
|
|
|
222
254
|
def add_address(params, address, options={})
|
|
223
255
|
return unless address
|
|
224
256
|
|
|
225
|
-
params['FirstName'], params['LastName'] = split_names(address[:name])
|
|
226
257
|
params['Title'] = address[:title]
|
|
227
258
|
params['CompanyName'] = address[:company] unless options[:skip_company]
|
|
228
259
|
params['Street1'] = truncate(address[:address1], 50)
|
|
@@ -231,9 +262,8 @@ module ActiveMerchant #:nodoc:
|
|
|
231
262
|
params['State'] = address[:state]
|
|
232
263
|
params['PostalCode'] = address[:zip]
|
|
233
264
|
params['Country'] = address[:country].to_s.downcase
|
|
234
|
-
params['Phone'] = address[:phone]
|
|
265
|
+
params['Phone'] = address[:phone] || address[:phone_number]
|
|
235
266
|
params['Fax'] = address[:fax]
|
|
236
|
-
params['Email'] = options[:email]
|
|
237
267
|
end
|
|
238
268
|
|
|
239
269
|
def add_credit_card(params, credit_card, options)
|
|
@@ -27,6 +27,7 @@ module ActiveMerchant #:nodoc:
|
|
|
27
27
|
add_extra_options(post, options)
|
|
28
28
|
add_order_id(post, options)
|
|
29
29
|
add_ip(post, options)
|
|
30
|
+
add_metadata(post, options)
|
|
30
31
|
|
|
31
32
|
commit(:post, 'purchases', post)
|
|
32
33
|
end
|
|
@@ -39,6 +40,7 @@ module ActiveMerchant #:nodoc:
|
|
|
39
40
|
add_extra_options(post, options)
|
|
40
41
|
add_order_id(post, options)
|
|
41
42
|
add_ip(post, options)
|
|
43
|
+
add_metadata(post, options)
|
|
42
44
|
|
|
43
45
|
post[:capture] = false
|
|
44
46
|
|
|
@@ -138,6 +140,10 @@ module ActiveMerchant #:nodoc:
|
|
|
138
140
|
post[:customer_ip] = options[:ip] || '127.0.0.1'
|
|
139
141
|
end
|
|
140
142
|
|
|
143
|
+
def add_metadata(post, options)
|
|
144
|
+
post[:metadata] = options.fetch(:metadata, {})
|
|
145
|
+
end
|
|
146
|
+
|
|
141
147
|
def commit(method, uri, parameters=nil)
|
|
142
148
|
response = begin
|
|
143
149
|
parse(ssl_request(method, get_url(uri), parameters.to_json, headers))
|
|
@@ -10,7 +10,7 @@ module ActiveMerchant #:nodoc:
|
|
|
10
10
|
self.supported_countries = ['AD', 'AE', 'AG', 'AI', 'AL', 'AM', 'AO', 'AR', 'AS', 'AT', 'AU', 'AW', 'AX', 'AZ', 'BA', 'BB', 'BD', 'BE', 'BF', 'BG', 'BH', 'BI', 'BJ', 'BL', 'BM', 'BN', 'BO', 'BQ', 'BR', 'BS', 'BT', 'BW', 'BY', 'BZ', 'CA', 'CC', 'CD', 'CF', 'CH', 'CI', 'CK', 'CL', 'CM', 'CN', 'CO', 'CR', 'CU', 'CV', 'CW', 'CX', 'CY', 'CZ', 'DE', 'DJ', 'DK', 'DM', 'DO', 'DZ', 'EC', 'EE', 'EG', 'ER', 'ES', 'ET', 'FI', 'FJ', 'FK', 'FM', 'FO', 'FR', 'GA', 'GB', 'GD', 'GE', 'GF', 'GH', 'GI', 'GL', 'GM', 'GN', 'GP', 'GQ', 'GR', 'GS', 'GT', 'GU', 'GW', 'GY', 'HK', 'HN', 'HR', 'HT', 'HU', 'ID', 'IE', 'IL', 'IM', 'IN', 'IS', 'IT', 'JM', 'JO', 'JP', 'KE', 'KG', 'KH', 'KI', 'KM', 'KN', 'KR', 'KW', 'KY', 'KZ', 'LA', 'LB', 'LC', 'LI', 'LK', 'LR', 'LS', 'LT', 'LU', 'LV', 'MA', 'MC', 'MD', 'ME', 'MF', 'MG', 'MH', 'MK', 'MM', 'MN', 'MO', 'MP', 'MQ', 'MR', 'MS', 'MT', 'MU', 'MV', 'MW', 'MX', 'MY', 'MZ', 'NA', 'NC', 'NE', 'NG', 'NI', 'NL', 'NO', 'NP', 'NR', 'NU', 'NZ', 'OM', 'PA', 'PE', 'PF', 'PG', 'PH', 'PL', 'PN', 'PS', 'PT', 'PW', 'QA', 'RE', 'RO', 'RS', 'RU', 'RW', 'SA', 'SB', 'SC', 'SE', 'SG', 'SH', 'SI', 'SJ', 'SK', 'SL', 'SM', 'SN', 'SR', 'ST', 'SV', 'SZ', 'TC', 'TD', 'TG', 'TH', 'TJ', 'TL', 'TM', 'TN', 'TO', 'TR', 'TT', 'TV', 'TW', 'TZ', 'UA', 'UG', 'US', 'UY', 'UZ', 'VC', 'VE', 'VG', 'VI', 'VN', 'WF', 'WS', 'ZA', 'ZM', 'ZW']
|
|
11
11
|
self.default_currency = 'USD'
|
|
12
12
|
self.money_format = :cents
|
|
13
|
-
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :naranja]
|
|
13
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :naranja, :cabal]
|
|
14
14
|
|
|
15
15
|
def initialize(options={})
|
|
16
16
|
requires!(options, :merchant_id, :api_key_id, :secret_api_key)
|
|
@@ -12,14 +12,15 @@ module ActiveMerchant #:nodoc:
|
|
|
12
12
|
self.supported_countries = ['AR', 'BR', 'CL', 'CO', 'MX', 'PA', 'PE']
|
|
13
13
|
self.default_currency = 'USD'
|
|
14
14
|
self.money_format = :dollars
|
|
15
|
-
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :naranja]
|
|
15
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :naranja, :cabal]
|
|
16
16
|
|
|
17
17
|
BRAND_MAP = {
|
|
18
18
|
'visa' => 'VISA',
|
|
19
19
|
'master' => 'MASTERCARD',
|
|
20
20
|
'american_express' => 'AMEX',
|
|
21
21
|
'diners_club' => 'DINERS',
|
|
22
|
-
'naranja' => 'NARANJA'
|
|
22
|
+
'naranja' => 'NARANJA',
|
|
23
|
+
'cabal' => 'CABAL'
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
MINIMUMS = {
|
|
@@ -196,6 +197,7 @@ module ActiveMerchant #:nodoc:
|
|
|
196
197
|
buyer[:fullName] = buyer_hash[:name]
|
|
197
198
|
buyer[:dniNumber] = buyer_hash[:dni_number]
|
|
198
199
|
buyer[:dniType] = buyer_hash[:dni_type]
|
|
200
|
+
buyer[:merchantBuyerId] = buyer_hash[:merchant_buyer_id]
|
|
199
201
|
buyer[:cnpj] = buyer_hash[:cnpj] if @options[:payment_country] == 'BR'
|
|
200
202
|
buyer[:emailAddress] = buyer_hash[:email]
|
|
201
203
|
buyer[:contactPhone] = (options[:billing_address][:phone] if options[:billing_address]) || (options[:shipping_address][:phone] if options[:shipping_address]) || ''
|
|
@@ -204,6 +206,7 @@ module ActiveMerchant #:nodoc:
|
|
|
204
206
|
buyer[:fullName] = payment_method.name.strip
|
|
205
207
|
buyer[:dniNumber] = options[:dni_number]
|
|
206
208
|
buyer[:dniType] = options[:dni_type]
|
|
209
|
+
buyer[:merchantBuyerId] = options[:merchant_buyer_id]
|
|
207
210
|
buyer[:cnpj] = options[:cnpj] if @options[:payment_country] == 'BR'
|
|
208
211
|
buyer[:emailAddress] = options[:email]
|
|
209
212
|
buyer[:contactPhone] = (options[:billing_address][:phone] if options[:billing_address]) || (options[:shipping_address][:phone] if options[:shipping_address]) || ''
|
|
@@ -2,6 +2,8 @@ require 'active_support/core_ext/hash/slice'
|
|
|
2
2
|
|
|
3
3
|
module ActiveMerchant #:nodoc:
|
|
4
4
|
module Billing #:nodoc:
|
|
5
|
+
# This gateway uses an older version of the Stripe API.
|
|
6
|
+
# To utilize the updated {Payment Intents API}[https://stripe.com/docs/api/payment_intents], integrate with the StripePaymentIntents gateway
|
|
5
7
|
class StripeGateway < Gateway
|
|
6
8
|
self.live_url = 'https://api.stripe.com/v1/'
|
|
7
9
|
|
|
@@ -21,6 +23,8 @@ module ActiveMerchant #:nodoc:
|
|
|
21
23
|
'unchecked' => 'P'
|
|
22
24
|
}
|
|
23
25
|
|
|
26
|
+
DEFAULT_API_VERSION = '2015-04-07'
|
|
27
|
+
|
|
24
28
|
self.supported_countries = %w(AT AU BE BR CA CH DE DK ES FI FR GB HK IE IT JP LU MX NL NO NZ PT SE SG US)
|
|
25
29
|
self.default_currency = 'USD'
|
|
26
30
|
self.money_format = :cents
|
|
@@ -300,8 +304,8 @@ module ActiveMerchant #:nodoc:
|
|
|
300
304
|
add_amount(post, money, options, true)
|
|
301
305
|
post[:type] = type
|
|
302
306
|
if type == 'card'
|
|
303
|
-
add_creditcard(post, payment, options)
|
|
304
|
-
post
|
|
307
|
+
add_creditcard(post, payment, options, true)
|
|
308
|
+
add_source_owner(post, payment, options)
|
|
305
309
|
elsif type == 'three_d_secure'
|
|
306
310
|
post[:three_d_secure] = {card: payment}
|
|
307
311
|
post[:redirect] = {return_url: options[:redirect_url]}
|
|
@@ -347,6 +351,12 @@ module ActiveMerchant #:nodoc:
|
|
|
347
351
|
add_creditcard(post, payment, options)
|
|
348
352
|
end
|
|
349
353
|
|
|
354
|
+
add_charge_details(post, money, payment, options)
|
|
355
|
+
post
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
# Used internally by Spreedly to populate the charge object for 3DS 1.0 transactions
|
|
359
|
+
def add_charge_details(post, money, payment, options)
|
|
350
360
|
if emv_payment?(payment)
|
|
351
361
|
add_statement_address(post, options)
|
|
352
362
|
add_emv_metadata(post, payment)
|
|
@@ -449,7 +459,7 @@ module ActiveMerchant #:nodoc:
|
|
|
449
459
|
post[:statement_address][:state] = statement_address[:state]
|
|
450
460
|
end
|
|
451
461
|
|
|
452
|
-
def add_creditcard(post, creditcard, options)
|
|
462
|
+
def add_creditcard(post, creditcard, options, use_sources = false)
|
|
453
463
|
card = {}
|
|
454
464
|
if emv_payment?(creditcard)
|
|
455
465
|
add_emv_creditcard(post, creditcard.icc_data)
|
|
@@ -472,7 +482,7 @@ module ActiveMerchant #:nodoc:
|
|
|
472
482
|
card[:exp_month] = creditcard.month
|
|
473
483
|
card[:exp_year] = creditcard.year
|
|
474
484
|
card[:cvc] = creditcard.verification_value if creditcard.verification_value?
|
|
475
|
-
card[:name] = creditcard.name if creditcard.name
|
|
485
|
+
card[:name] = creditcard.name if creditcard.name && !use_sources
|
|
476
486
|
end
|
|
477
487
|
|
|
478
488
|
if creditcard.is_a?(NetworkTokenizationCreditCard)
|
|
@@ -482,7 +492,7 @@ module ActiveMerchant #:nodoc:
|
|
|
482
492
|
end
|
|
483
493
|
post[:card] = card
|
|
484
494
|
|
|
485
|
-
add_address(post, options)
|
|
495
|
+
add_address(post, options) unless use_sources
|
|
486
496
|
elsif creditcard.kind_of?(String)
|
|
487
497
|
if options[:track_data]
|
|
488
498
|
card[:swipe_data] = options[:track_data]
|
|
@@ -530,6 +540,25 @@ module ActiveMerchant #:nodoc:
|
|
|
530
540
|
post[:metadata][:card_read_method] = creditcard.read_method if creditcard.respond_to?(:read_method)
|
|
531
541
|
end
|
|
532
542
|
|
|
543
|
+
def add_source_owner(post, creditcard, options)
|
|
544
|
+
post[:owner] = {}
|
|
545
|
+
post[:owner][:name] = creditcard.name if creditcard.name
|
|
546
|
+
post[:owner][:email] = options[:email] if options[:email]
|
|
547
|
+
|
|
548
|
+
if address = options[:billing_address] || options[:address]
|
|
549
|
+
owner_address = {}
|
|
550
|
+
owner_address[:line1] = address[:address1] if address[:address1]
|
|
551
|
+
owner_address[:line2] = address[:address2] if address[:address2]
|
|
552
|
+
owner_address[:country] = address[:country] if address[:country]
|
|
553
|
+
owner_address[:postal_code] = address[:zip] if address[:zip]
|
|
554
|
+
owner_address[:state] = address[:state] if address[:state]
|
|
555
|
+
owner_address[:city] = address[:city] if address[:city]
|
|
556
|
+
|
|
557
|
+
post[:owner][:phone] = address[:phone] if address[:phone]
|
|
558
|
+
post[:owner][:address] = owner_address
|
|
559
|
+
end
|
|
560
|
+
end
|
|
561
|
+
|
|
533
562
|
def parse(body)
|
|
534
563
|
JSON.parse(body)
|
|
535
564
|
end
|
|
@@ -589,7 +618,7 @@ module ActiveMerchant #:nodoc:
|
|
|
589
618
|
end
|
|
590
619
|
|
|
591
620
|
def api_version(options)
|
|
592
|
-
options[:version] || @options[:version] ||
|
|
621
|
+
options[:version] || @options[:version] || self.class::DEFAULT_API_VERSION
|
|
593
622
|
end
|
|
594
623
|
|
|
595
624
|
def api_request(method, endpoint, parameters = nil, options = {})
|
|
@@ -632,8 +661,8 @@ module ActiveMerchant #:nodoc:
|
|
|
632
661
|
return response.fetch('error', {})['charge'] unless success
|
|
633
662
|
|
|
634
663
|
if url == 'customers'
|
|
635
|
-
[response['id'], response
|
|
636
|
-
elsif method == :post && url.match(/customers\/.*\/cards/)
|
|
664
|
+
[response['id'], response.dig('sources', 'data').first&.dig('id')].join('|')
|
|
665
|
+
elsif method == :post && (url.match(/customers\/.*\/cards/) || url.match(/payment_methods\/.*\/attach/))
|
|
637
666
|
[response['customer'], response['id']].join('|')
|
|
638
667
|
else
|
|
639
668
|
response['id']
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
require 'active_support/core_ext/hash/slice'
|
|
2
|
+
|
|
3
|
+
module ActiveMerchant #:nodoc:
|
|
4
|
+
module Billing #:nodoc:
|
|
5
|
+
# This gateway uses the current Stripe {Payment Intents API}[https://stripe.com/docs/api/payment_intents].
|
|
6
|
+
# For the legacy API, see the Stripe gateway
|
|
7
|
+
class StripePaymentIntentsGateway < StripeGateway
|
|
8
|
+
|
|
9
|
+
self.supported_countries = %w(AT AU BE BR CA CH DE DK ES FI FR GB HK IE IT JP LU MX NL NO NZ PT SE SG US)
|
|
10
|
+
|
|
11
|
+
ALLOWED_METHOD_STATES = %w[automatic manual].freeze
|
|
12
|
+
ALLOWED_CANCELLATION_REASONS = %w[duplicate fraudulent requested_by_customer abandoned].freeze
|
|
13
|
+
CREATE_INTENT_ATTRIBUTES = %i[description statement_descriptor receipt_email save_payment_method]
|
|
14
|
+
CONFIRM_INTENT_ATTRIBUTES = %i[receipt_email return_url save_payment_method setup_future_usage off_session]
|
|
15
|
+
UPDATE_INTENT_ATTRIBUTES = %i[description statement_descriptor receipt_email setup_future_usage]
|
|
16
|
+
DEFAULT_API_VERSION = '2019-05-16'
|
|
17
|
+
|
|
18
|
+
def create_intent(money, payment_method, options = {})
|
|
19
|
+
post = {}
|
|
20
|
+
add_amount(post, money, options, true)
|
|
21
|
+
add_capture_method(post, options)
|
|
22
|
+
add_confirmation_method(post, options)
|
|
23
|
+
add_customer(post, options)
|
|
24
|
+
add_payment_method_token(post, payment_method, options)
|
|
25
|
+
add_metadata(post, options)
|
|
26
|
+
add_return_url(post, options)
|
|
27
|
+
add_connected_account(post, options)
|
|
28
|
+
add_shipping_address(post, options)
|
|
29
|
+
setup_future_usage(post, options)
|
|
30
|
+
add_exemption(post, options)
|
|
31
|
+
|
|
32
|
+
CREATE_INTENT_ATTRIBUTES.each do |attribute|
|
|
33
|
+
add_whitelisted_attribute(post, options, attribute)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
commit(:post, 'payment_intents', post, options)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def show_intent(intent_id, options)
|
|
40
|
+
commit(:get, "payment_intents/#{intent_id}", nil, options)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def confirm_intent(intent_id, payment_method, options = {})
|
|
44
|
+
post = {}
|
|
45
|
+
add_payment_method_token(post, payment_method, options)
|
|
46
|
+
CONFIRM_INTENT_ATTRIBUTES.each do |attribute|
|
|
47
|
+
add_whitelisted_attribute(post, options, attribute)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
commit(:post, "payment_intents/#{intent_id}/confirm", post, options)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def create_payment_method(payment_method, options = {})
|
|
54
|
+
post = {}
|
|
55
|
+
post[:type] = 'card'
|
|
56
|
+
post[:card] = {}
|
|
57
|
+
post[:card][:number] = payment_method.number
|
|
58
|
+
post[:card][:exp_month] = payment_method.month
|
|
59
|
+
post[:card][:exp_year] = payment_method.year
|
|
60
|
+
post[:card][:cvc] = payment_method.verification_value if payment_method.verification_value
|
|
61
|
+
add_billing_address(post, options)
|
|
62
|
+
|
|
63
|
+
commit(:post, 'payment_methods', post, options)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def update_intent(money, intent_id, payment_method, options = {})
|
|
67
|
+
post = {}
|
|
68
|
+
post[:amount] = money if money
|
|
69
|
+
|
|
70
|
+
add_payment_method_token(post, payment_method, options)
|
|
71
|
+
add_payment_method_types(post, options)
|
|
72
|
+
add_customer(post, options)
|
|
73
|
+
add_metadata(post, options)
|
|
74
|
+
add_shipping_address(post, options)
|
|
75
|
+
add_connected_account(post, options)
|
|
76
|
+
|
|
77
|
+
UPDATE_INTENT_ATTRIBUTES.each do |attribute|
|
|
78
|
+
add_whitelisted_attribute(post, options, attribute)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
commit(:post, "payment_intents/#{intent_id}", post, options)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def authorize(money, payment_method, options = {})
|
|
85
|
+
create_intent(money, payment_method, options.merge!(confirm: true, capture_method: 'manual'))
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def purchase(money, payment_method, options = {})
|
|
89
|
+
create_intent(money, payment_method, options.merge!(confirm: true, capture_method: 'automatic'))
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def capture(money, intent_id, options = {})
|
|
93
|
+
post = {}
|
|
94
|
+
post[:amount_to_capture] = money
|
|
95
|
+
add_connected_account(post, options)
|
|
96
|
+
commit(:post, "payment_intents/#{intent_id}/capture", post, options)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def void(intent_id, options = {})
|
|
100
|
+
post = {}
|
|
101
|
+
post[:cancellation_reason] = options[:cancellation_reason] if ALLOWED_CANCELLATION_REASONS.include?(options[:cancellation_reason])
|
|
102
|
+
commit(:post, "payment_intents/#{intent_id}/cancel", post, options)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def refund(money, intent_id, options = {})
|
|
106
|
+
intent = commit(:get, "payment_intents/#{intent_id}", nil, options)
|
|
107
|
+
charge_id = intent.params.dig('charges', 'data')[0].dig('id')
|
|
108
|
+
super(money, charge_id, options)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Note: Not all payment methods are currently supported by the {Payment Methods API}[https://stripe.com/docs/payments/payment-methods]
|
|
112
|
+
# Current implementation will create a PaymentMethod object if the method is a token or credit card
|
|
113
|
+
# All other types will default to legacy Stripe store
|
|
114
|
+
def store(payment_method, options = {})
|
|
115
|
+
params = {}
|
|
116
|
+
post = {}
|
|
117
|
+
|
|
118
|
+
# If customer option is provided, create a payment method and attach to customer id
|
|
119
|
+
# Otherwise, create a customer, then attach
|
|
120
|
+
if payment_method.is_a?(StripePaymentToken) || payment_method.is_a?(ActiveMerchant::Billing::CreditCard)
|
|
121
|
+
add_payment_method_token(params, payment_method, options)
|
|
122
|
+
if options[:customer]
|
|
123
|
+
customer_id = options[:customer]
|
|
124
|
+
else
|
|
125
|
+
post[:validate] = options[:validate] unless options[:validate].nil?
|
|
126
|
+
post[:description] = options[:description] if options[:description]
|
|
127
|
+
post[:email] = options[:email] if options[:email]
|
|
128
|
+
customer = commit(:post, 'customers', post, options)
|
|
129
|
+
customer_id = customer.params['id']
|
|
130
|
+
end
|
|
131
|
+
commit(:post, "payment_methods/#{params[:payment_method]}/attach", { customer: customer_id }, options)
|
|
132
|
+
else
|
|
133
|
+
super(payment, options)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def unstore(identification, options = {}, deprecated_options = {})
|
|
138
|
+
if identification.include?('pm_')
|
|
139
|
+
_, payment_method = identification.split('|')
|
|
140
|
+
commit(:post, "payment_methods/#{payment_method}/detach", nil, options)
|
|
141
|
+
else
|
|
142
|
+
super(identification, options, deprecated_options)
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
private
|
|
147
|
+
|
|
148
|
+
def add_whitelisted_attribute(post, options, attribute)
|
|
149
|
+
post[attribute] = options[attribute] if options[attribute]
|
|
150
|
+
post
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def add_capture_method(post, options)
|
|
154
|
+
capture_method = options[:capture_method].to_s
|
|
155
|
+
post[:capture_method] = capture_method if ALLOWED_METHOD_STATES.include?(capture_method)
|
|
156
|
+
post
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def add_confirmation_method(post, options)
|
|
160
|
+
confirmation_method = options[:confirmation_method].to_s
|
|
161
|
+
post[:confirmation_method] = confirmation_method if ALLOWED_METHOD_STATES.include?(confirmation_method)
|
|
162
|
+
post
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def add_customer(post, options)
|
|
166
|
+
customer = options[:customer].to_s
|
|
167
|
+
post[:customer] = customer if customer.start_with?('cus_')
|
|
168
|
+
post
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def add_return_url(post, options)
|
|
172
|
+
return unless options[:confirm]
|
|
173
|
+
post[:confirm] = options[:confirm]
|
|
174
|
+
post[:return_url] = options[:return_url] if options[:return_url]
|
|
175
|
+
post
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def add_payment_method_token(post, payment_method, options)
|
|
179
|
+
return if payment_method.nil?
|
|
180
|
+
|
|
181
|
+
if payment_method.is_a?(ActiveMerchant::Billing::CreditCard)
|
|
182
|
+
p = create_payment_method(payment_method, options)
|
|
183
|
+
payment_method = p.params['id']
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
if payment_method.is_a?(StripePaymentToken)
|
|
187
|
+
post[:payment_method] = payment_method.payment_data['id']
|
|
188
|
+
elsif payment_method.is_a?(String)
|
|
189
|
+
if payment_method.include?('|')
|
|
190
|
+
customer_id, payment_method_id = payment_method.split('|')
|
|
191
|
+
token = payment_method_id
|
|
192
|
+
post[:customer] = customer_id
|
|
193
|
+
else
|
|
194
|
+
token = payment_method
|
|
195
|
+
end
|
|
196
|
+
post[:payment_method] = token
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def add_payment_method_types(post, options)
|
|
201
|
+
payment_method_types = options[:payment_method_types] if options[:payment_method_types]
|
|
202
|
+
return if payment_method_types.nil?
|
|
203
|
+
|
|
204
|
+
post[:payment_method_types] = Array(payment_method_types)
|
|
205
|
+
post
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def add_exemption(post, options = {})
|
|
209
|
+
return unless options[:confirm]
|
|
210
|
+
post[:payment_method_options] ||= {}
|
|
211
|
+
post[:payment_method_options][:card] ||= {}
|
|
212
|
+
post[:payment_method_options][:card][:moto] = true if options[:moto]
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def setup_future_usage(post, options = {})
|
|
216
|
+
post[:setup_future_usage] = options[:setup_future_usage] if %w( on_session off_session ).include?(options[:setup_future_usage])
|
|
217
|
+
post[:off_session] = options[:off_session] if options[:off_session] && options[:confirm] == true
|
|
218
|
+
post
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def add_connected_account(post, options = {})
|
|
222
|
+
return unless options[:transfer_destination]
|
|
223
|
+
post[:transfer_data] = {}
|
|
224
|
+
post[:transfer_data][:destination] = options[:transfer_destination]
|
|
225
|
+
post[:transfer_data][:amount] = options[:transfer_amount] if options[:transfer_amount]
|
|
226
|
+
post[:on_behalf_of] = options[:on_behalf_of] if options[:on_behalf_of]
|
|
227
|
+
post[:transfer_group] = options[:transfer_group] if options[:transfer_group]
|
|
228
|
+
post[:application_fee_amount] = options[:application_fee] if options[:application_fee]
|
|
229
|
+
post
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def add_billing_address(post, options = {})
|
|
233
|
+
return unless billing = options[:billing_address] || options[:address]
|
|
234
|
+
post[:billing_details] = {}
|
|
235
|
+
post[:billing_details][:address] = {}
|
|
236
|
+
post[:billing_details][:address][:city] = billing[:city] if billing[:city]
|
|
237
|
+
post[:billing_details][:address][:country] = billing[:country] if billing[:country]
|
|
238
|
+
post[:billing_details][:address][:line1] = billing[:address1] if billing[:address1]
|
|
239
|
+
post[:billing_details][:address][:line2] = billing[:address2] if billing[:address2]
|
|
240
|
+
post[:billing_details][:address][:postal_code] = billing[:zip] if billing[:zip]
|
|
241
|
+
post[:billing_details][:address][:state] = billing[:state] if billing[:state]
|
|
242
|
+
post[:billing_details][:email] = billing[:email] if billing[:email]
|
|
243
|
+
post[:billing_details][:name] = billing[:name] if billing[:name]
|
|
244
|
+
post[:billing_details][:phone] = billing[:phone] if billing[:phone]
|
|
245
|
+
post
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def add_shipping_address(post, options = {})
|
|
249
|
+
return unless shipping = options[:shipping]
|
|
250
|
+
post[:shipping] = {}
|
|
251
|
+
post[:shipping][:address] = {}
|
|
252
|
+
post[:shipping][:address][:line1] = shipping[:address][:line1]
|
|
253
|
+
post[:shipping][:address][:city] = shipping[:address][:city] if shipping[:address][:city]
|
|
254
|
+
post[:shipping][:address][:country] = shipping[:address][:country] if shipping[:address][:country]
|
|
255
|
+
post[:shipping][:address][:line2] = shipping[:address][:line2] if shipping[:address][:line2]
|
|
256
|
+
post[:shipping][:address][:postal_code] = shipping[:address][:postal_code] if shipping[:address][:postal_code]
|
|
257
|
+
post[:shipping][:address][:state] = shipping[:address][:state] if shipping[:address][:state]
|
|
258
|
+
|
|
259
|
+
post[:shipping][:name] = shipping[:name]
|
|
260
|
+
post[:shipping][:carrier] = shipping[:carrier] if shipping[:carrier]
|
|
261
|
+
post[:shipping][:phone] = shipping[:phone] if shipping[:phone]
|
|
262
|
+
post[:shipping][:tracking_number] = shipping[:tracking_number] if shipping[:tracking_number]
|
|
263
|
+
post
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
end
|
|
@@ -159,6 +159,8 @@ module ActiveMerchant #:nodoc:
|
|
|
159
159
|
add_customer_data(parameters, options)
|
|
160
160
|
add_payment_source(parameters, creditcard_or_billing_id)
|
|
161
161
|
add_addresses(parameters, options)
|
|
162
|
+
add_custom_fields(parameters, options)
|
|
163
|
+
|
|
162
164
|
commit('preauth', parameters)
|
|
163
165
|
end
|
|
164
166
|
|
|
@@ -174,6 +176,8 @@ module ActiveMerchant #:nodoc:
|
|
|
174
176
|
add_customer_data(parameters, options)
|
|
175
177
|
add_payment_source(parameters, creditcard_or_billing_id)
|
|
176
178
|
add_addresses(parameters, options)
|
|
179
|
+
add_custom_fields(parameters, options)
|
|
180
|
+
|
|
177
181
|
commit('sale', parameters)
|
|
178
182
|
end
|
|
179
183
|
|
|
@@ -187,6 +191,7 @@ module ActiveMerchant #:nodoc:
|
|
|
187
191
|
:transid => transaction_id,
|
|
188
192
|
}
|
|
189
193
|
add_aggregator(parameters, options)
|
|
194
|
+
add_custom_fields(parameters, options)
|
|
190
195
|
|
|
191
196
|
commit('postauth', parameters)
|
|
192
197
|
end
|
|
@@ -195,11 +200,14 @@ module ActiveMerchant #:nodoc:
|
|
|
195
200
|
# that you want to refund, and a TC transid for the transaction that you are refunding.
|
|
196
201
|
def refund(money, identification, options = {})
|
|
197
202
|
transaction_id, _ = split_authorization(identification)
|
|
203
|
+
|
|
198
204
|
parameters = {
|
|
199
205
|
:amount => amount(money),
|
|
200
206
|
:transid => transaction_id
|
|
201
207
|
}
|
|
208
|
+
|
|
202
209
|
add_aggregator(parameters, options)
|
|
210
|
+
add_custom_fields(parameters, options)
|
|
203
211
|
|
|
204
212
|
commit('credit', parameters)
|
|
205
213
|
end
|
|
@@ -233,7 +241,9 @@ module ActiveMerchant #:nodoc:
|
|
|
233
241
|
parameters = {
|
|
234
242
|
:transid => transaction_id,
|
|
235
243
|
}
|
|
244
|
+
|
|
236
245
|
add_aggregator(parameters, options)
|
|
246
|
+
add_custom_fields(parameters, options)
|
|
237
247
|
|
|
238
248
|
commit(action, parameters)
|
|
239
249
|
end
|
|
@@ -294,6 +304,8 @@ module ActiveMerchant #:nodoc:
|
|
|
294
304
|
|
|
295
305
|
add_creditcard(parameters, creditcard)
|
|
296
306
|
add_addresses(parameters, options)
|
|
307
|
+
add_custom_fields(parameters, options)
|
|
308
|
+
|
|
297
309
|
commit('store', parameters)
|
|
298
310
|
end
|
|
299
311
|
|
|
@@ -304,6 +316,8 @@ module ActiveMerchant #:nodoc:
|
|
|
304
316
|
:billingid => identification,
|
|
305
317
|
}
|
|
306
318
|
|
|
319
|
+
add_custom_fields(parameters, options)
|
|
320
|
+
|
|
307
321
|
commit('unstore', parameters)
|
|
308
322
|
end
|
|
309
323
|
|
|
@@ -321,6 +335,12 @@ module ActiveMerchant #:nodoc:
|
|
|
321
335
|
|
|
322
336
|
private
|
|
323
337
|
|
|
338
|
+
def add_custom_fields(params, options)
|
|
339
|
+
options[:custom_fields]&.each do |key, value|
|
|
340
|
+
params[key.to_sym] = value
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
|
|
324
344
|
def add_aggregator(params, options)
|
|
325
345
|
if @options[:aggregator_id] || application_id != Gateway.application_id
|
|
326
346
|
params[:aggregators] = 1
|
|
@@ -419,7 +439,7 @@ module ActiveMerchant #:nodoc:
|
|
|
419
439
|
TCLink.send(parameters)
|
|
420
440
|
else
|
|
421
441
|
parse(ssl_post(self.live_url, post_data(parameters)))
|
|
422
|
-
|
|
442
|
+
end
|
|
423
443
|
|
|
424
444
|
# to be considered successful, transaction status must be either "approved" or "accepted"
|
|
425
445
|
success = SUCCESS_TYPES.include?(data['status'])
|
|
@@ -463,7 +483,7 @@ module ActiveMerchant #:nodoc:
|
|
|
463
483
|
end
|
|
464
484
|
|
|
465
485
|
def split_authorization(authorization)
|
|
466
|
-
authorization
|
|
486
|
+
authorization&.split('|')
|
|
467
487
|
end
|
|
468
488
|
end
|
|
469
489
|
end
|
|
@@ -7,7 +7,7 @@ module ActiveMerchant #:nodoc:
|
|
|
7
7
|
self.default_currency = 'GBP'
|
|
8
8
|
self.money_format = :cents
|
|
9
9
|
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)
|
|
10
|
-
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :maestro, :elo, :naranja]
|
|
10
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :maestro, :elo, :naranja, :cabal]
|
|
11
11
|
self.currencies_without_fractions = %w(HUF IDR ISK JPY KRW)
|
|
12
12
|
self.currencies_with_three_decimal_places = %w(BHD KWD OMR RSD TND)
|
|
13
13
|
self.homepage_url = 'http://www.worldpay.com/'
|
|
@@ -23,6 +23,7 @@ module ActiveMerchant #:nodoc:
|
|
|
23
23
|
'diners_club' => 'DINERS-SSL',
|
|
24
24
|
'elo' => 'ELO-SSL',
|
|
25
25
|
'naranja' => 'NARANJA-SSL',
|
|
26
|
+
'cabal' => 'CABAL-SSL',
|
|
26
27
|
'unknown' => 'CARD-SSL'
|
|
27
28
|
}
|
|
28
29
|
|
|
@@ -206,6 +207,7 @@ module ActiveMerchant #:nodoc:
|
|
|
206
207
|
if options[:instalments]
|
|
207
208
|
add_instalments_data(xml, options)
|
|
208
209
|
end
|
|
210
|
+
add_moto_flag(xml, options) if options.dig(:metadata, :manual_entry)
|
|
209
211
|
end
|
|
210
212
|
end
|
|
211
213
|
end
|
|
@@ -422,6 +424,10 @@ module ActiveMerchant #:nodoc:
|
|
|
422
424
|
end
|
|
423
425
|
end
|
|
424
426
|
|
|
427
|
+
def add_moto_flag(xml, options)
|
|
428
|
+
xml.tag! 'dynamicInteractionType', 'type' => 'MOTO'
|
|
429
|
+
end
|
|
430
|
+
|
|
425
431
|
def address_with_defaults(address)
|
|
426
432
|
address ||= {}
|
|
427
433
|
address.delete_if { |_, v| v.blank? }
|
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.
|
|
4
|
+
version: 1.98.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: 2019-
|
|
11
|
+
date: 2019-09-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -128,6 +128,20 @@ dependencies:
|
|
|
128
128
|
- - ">="
|
|
129
129
|
- !ruby/object:Gem::Version
|
|
130
130
|
version: '0'
|
|
131
|
+
- !ruby/object:Gem::Dependency
|
|
132
|
+
name: pry
|
|
133
|
+
requirement: !ruby/object:Gem::Requirement
|
|
134
|
+
requirements:
|
|
135
|
+
- - ">="
|
|
136
|
+
- !ruby/object:Gem::Version
|
|
137
|
+
version: '0'
|
|
138
|
+
type: :development
|
|
139
|
+
prerelease: false
|
|
140
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
141
|
+
requirements:
|
|
142
|
+
- - ">="
|
|
143
|
+
- !ruby/object:Gem::Version
|
|
144
|
+
version: '0'
|
|
131
145
|
description: Active Merchant is a simple payment abstraction library used in and sponsored
|
|
132
146
|
by Shopify. It is written by Tobias Luetke, Cody Fauser, and contributors. The aim
|
|
133
147
|
of the project is to feel natural to Ruby users and to abstract as many parts as
|
|
@@ -350,6 +364,7 @@ files:
|
|
|
350
364
|
- lib/active_merchant/billing/gateways/so_easy_pay.rb
|
|
351
365
|
- lib/active_merchant/billing/gateways/spreedly_core.rb
|
|
352
366
|
- lib/active_merchant/billing/gateways/stripe.rb
|
|
367
|
+
- lib/active_merchant/billing/gateways/stripe_payment_intents.rb
|
|
353
368
|
- lib/active_merchant/billing/gateways/swipe_checkout.rb
|
|
354
369
|
- lib/active_merchant/billing/gateways/telr.rb
|
|
355
370
|
- lib/active_merchant/billing/gateways/tns.rb
|