activemerchant 1.117.0 → 1.118.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 +32 -0
- data/README.md +1 -1
- data/lib/active_merchant/billing/credit_card.rb +2 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +57 -10
- data/lib/active_merchant/billing/gateways/adyen.rb +2 -2
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +1 -0
- data/lib/active_merchant/billing/gateways/blue_snap.rb +3 -1
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +6 -0
- data/lib/active_merchant/billing/gateways/credorax.rb +1 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +14 -3
- data/lib/active_merchant/billing/gateways/decidir.rb +14 -0
- data/lib/active_merchant/billing/gateways/elavon.rb +35 -2
- data/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb +17 -6
- data/lib/active_merchant/billing/gateways/hps.rb +1 -1
- data/lib/active_merchant/billing/gateways/litle.rb +5 -0
- data/lib/active_merchant/billing/gateways/orbital.rb +112 -20
- data/lib/active_merchant/billing/gateways/payeezy.rb +23 -5
- data/lib/active_merchant/billing/gateways/paymentez.rb +21 -1
- data/lib/active_merchant/billing/gateways/paypal.rb +10 -2
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +1 -0
- data/lib/active_merchant/billing/gateways/pin.rb +11 -0
- data/lib/active_merchant/billing/gateways/redsys.rb +34 -5
- data/lib/active_merchant/billing/gateways/safe_charge.rb +5 -3
- data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +7 -0
- data/lib/active_merchant/billing/gateways/worldpay.rb +4 -1
- data/lib/active_merchant/billing/response.rb +2 -1
- data/lib/active_merchant/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 506cd11074e8ee661844d74fb2a114665b025952d47517a423f27bd2ca566c49
|
|
4
|
+
data.tar.gz: 35cfe858b3bd6c492558dcd47cf17518edc6dbd96176dbb72abe6df2ff607724
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8955f8c555ec9049fa06e76176a2a819e2e1bbe54868eab1c88023ece7dcd722201009b39d238acfedc79a5ac50363c73dbfa776b95f61d3db308f0b7dd897e6
|
|
7
|
+
data.tar.gz: 77736f76e9483256f71abb8799d8bf4804ba0f56992e226f9f185ecb0fed1cb87dc8956e886473a17c4643d3f799e6b9898565c4ec0420b1b3fcefa7471e1d16
|
data/CHANGELOG
CHANGED
|
@@ -2,6 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
== HEAD
|
|
4
4
|
|
|
5
|
+
== Version 1.118.0 (January 22nd, 2021)
|
|
6
|
+
* Worldpay: Add support for challengeWindowSize [carrigan] #3823
|
|
7
|
+
* Adyen: Update capitalization on subMerchantId field [cdmackeyfree] #3824
|
|
8
|
+
* Maestro and Elo: Update BIN ranges [meagabeth] #3822
|
|
9
|
+
* HPS: Truncate invoice numbers that are too long [curiousepic] #3825
|
|
10
|
+
* Pass network_transaction_id attribute in Response [therufs] #3815
|
|
11
|
+
* Elavon: support standardized stored credentials [therufs] #3816
|
|
12
|
+
* Decidir: update fraud_detection field [cdmackeyfree] #3829
|
|
13
|
+
* Paymentez: Add Olimpica cardtype [meagabeth] #3831
|
|
14
|
+
* SafeCharge: 3DS external MPI data refinements [curiousepic] #3821
|
|
15
|
+
* Credorax: Add support for 3DS Adviser [meagabeth] #3834
|
|
16
|
+
* Adyen: Support subMerchant data [mymir][therufs] #3835
|
|
17
|
+
* Decidir: add device_unique_identifier to card data [cdmackeyfree] #3839
|
|
18
|
+
* BraintreeBlue: add support for account_type field [jimilpatel24] #3840
|
|
19
|
+
* Redsys: Add support for stored_credential [meagabeth] #3844
|
|
20
|
+
* Redsys: add_payment method solution [meagabeth] #3845
|
|
21
|
+
* Stripe Payment Intents: Add support for error_on_requires_action option [tatsianaclifton] #3846
|
|
22
|
+
* Add 3DS 2.0 values to paypal [nebdil] #3285
|
|
23
|
+
* Redsys: Update Mpi Fields [tatsianaclifton] #3855
|
|
24
|
+
* Paypal: Update AuthStatus3ds MPI field [curiousepic] #3857
|
|
25
|
+
* Orbital: Update 3DS support for Mastercard [meagabeth] #3850
|
|
26
|
+
* Payeezy: Support standardized stored credentials [therufs] #3861
|
|
27
|
+
* CyberSource: Update `billing_address` override [meagabeth] #3862
|
|
28
|
+
* Paymentez: Add 3DS MPI field support [carrigan] #3856
|
|
29
|
+
* BlueSnap: Add support `fraud-session-id` field [meagabeth] #3863
|
|
30
|
+
* BlueSnap: Update handling of `transaction-fraud-info` fields [meagabeth] #3866
|
|
31
|
+
* Payeezy: Allow no stored credential transaction id [therufs] #3868
|
|
32
|
+
* Orbital: eCheck processing added [ajawadmirza] #3870
|
|
33
|
+
* FirsdataE4V27: Fixes some apple pay transaction issues [pi3r] #3872
|
|
34
|
+
|
|
5
35
|
== Version 1.117.0 (November 13th)
|
|
6
36
|
* Checkout V2: Pass attempt_n3d along with 3ds enabled [naashton] #3805
|
|
7
37
|
* GlobalCollect: Add support for Third-party 3DS2 data [molbrown] #3801
|
|
@@ -17,6 +47,7 @@
|
|
|
17
47
|
* Credorax: Allow 3DS1 normalized pass-through, ease version matching [britth] #3812
|
|
18
48
|
* Redsys: Redsys: Harden 3DS v1/v2 check for External MPI [esmitperez] #3814
|
|
19
49
|
* Add card types for Stripe, Worldpay, Checkout.com [LinTrieu] #3810
|
|
50
|
+
* ActiveMerchant::Billing::Response: Include `network_transaction_id` attribute [therufs] #3815
|
|
20
51
|
|
|
21
52
|
== Version 1.116.0 (October 28th)
|
|
22
53
|
* Remove Braintree specific version dependency [pi3r] #3800
|
|
@@ -62,6 +93,7 @@
|
|
|
62
93
|
* Checkout V2: Support for attempt_n3d 3DS field [naashton] #3790
|
|
63
94
|
* Elavon: Strip ampersands [therufs] #3795
|
|
64
95
|
* Paybox: Add support for 3DS 1.0 values [jcpaybox] #3335
|
|
96
|
+
* Decidir: Add additional fraud_detection options [cdmackeyfree] #3812
|
|
65
97
|
|
|
66
98
|
== Version 1.114.0
|
|
67
99
|
* BlueSnap: Add address1,address2,phone,shipping_* support #3749
|
data/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Active Merchant
|
|
2
|
-
[](https://github.com/activemerchant/active_merchant/actions?query=workflow%3ACI)
|
|
3
3
|
[](https://codeclimate.com/github/activemerchant/active_merchant)
|
|
4
4
|
|
|
5
5
|
Active Merchant is an extraction from the ecommerce system [Shopify](http://www.shopify.com).
|
|
@@ -24,6 +24,7 @@ module ActiveMerchant #:nodoc:
|
|
|
24
24
|
# * Naranja
|
|
25
25
|
# * UnionPay
|
|
26
26
|
# * Alia
|
|
27
|
+
# * Olimpica
|
|
27
28
|
#
|
|
28
29
|
# For testing purposes, use the 'bogus' credit card brand. This skips the vast majority of
|
|
29
30
|
# validations, allowing you to focus on your core concerns until you're ready to be more concerned
|
|
@@ -100,6 +101,7 @@ module ActiveMerchant #:nodoc:
|
|
|
100
101
|
# * +'naranja'+
|
|
101
102
|
# * +'union_pay'+
|
|
102
103
|
# * +'alia'+
|
|
104
|
+
# * +'olimpica'+
|
|
103
105
|
#
|
|
104
106
|
# Or, if you wish to test your implementation, +'bogus'+.
|
|
105
107
|
#
|
|
@@ -30,7 +30,8 @@ module ActiveMerchant #:nodoc:
|
|
|
30
30
|
in_bin_range?(num.slice(0, 6), CARNET_RANGES) ||
|
|
31
31
|
CARNET_BINS.any? { |bin| num.slice(0, bin.size) == bin }
|
|
32
32
|
)
|
|
33
|
-
}
|
|
33
|
+
},
|
|
34
|
+
'olimpica' => ->(num) { num =~ /^636853\d{10}$/ }
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
# http://www.barclaycard.co.uk/business/files/bin_rules.pdf
|
|
@@ -72,11 +73,57 @@ module ActiveMerchant #:nodoc:
|
|
|
72
73
|
]
|
|
73
74
|
|
|
74
75
|
MAESTRO_BINS = Set.new(
|
|
75
|
-
%w[
|
|
76
|
+
%w[ 500057
|
|
77
|
+
501018 501043 501045 501047 501049 501051 501072 501075 501087 501089 501095
|
|
78
|
+
501500
|
|
79
|
+
501879 502113 502301 503175
|
|
80
|
+
503645 503670
|
|
81
|
+
504310 504338 504363 504533 504587 504620 504639 504656 504738 504781 504910
|
|
82
|
+
507001 507002 507004 507082 507090
|
|
83
|
+
560014 560565 561033
|
|
84
|
+
572402 572610 572626
|
|
85
|
+
576904
|
|
86
|
+
578614
|
|
87
|
+
581149
|
|
88
|
+
585274 585697
|
|
89
|
+
586509
|
|
90
|
+
588729 588792
|
|
91
|
+
589244 589407 589471 589605 589633 589647 589671
|
|
92
|
+
590043 590206 590263 590265 590278 590361 590362 590379 590393 590590
|
|
93
|
+
591235 591420 591481 591620 591770 591948 591994
|
|
94
|
+
592024 592161 592184 592186 592201 592384 592393 592528 592566 592704 592735 592879 592884
|
|
95
|
+
593074 593264 593272 593355 593496 593556 593589 593666 593709 593825 593963 593994
|
|
96
|
+
594184 594409 594468 594475 594581 594665 594691 594710 594874 594968
|
|
97
|
+
595355 595364 595532 595547 595561 595568 595743 595929
|
|
98
|
+
596245 596289 596399 596405 596590 596608 596645 596646 596791 596808 596815 596846
|
|
99
|
+
597077 597094 597143 597370 597410 597765 597855 597862
|
|
100
|
+
598053 598054 598395 598585 598793 598794 598815 598835 598838 598880 598889
|
|
101
|
+
599000 599069 599089 599148 599191 599310 599741 599742 599867
|
|
102
|
+
601070
|
|
103
|
+
604983
|
|
104
|
+
606126
|
|
105
|
+
636380 636422 636502 636639
|
|
106
|
+
637046 637756
|
|
107
|
+
639130
|
|
108
|
+
690032]
|
|
76
109
|
)
|
|
77
110
|
|
|
78
111
|
# https://www.mastercard.us/content/dam/mccom/global/documents/mastercard-rules.pdf, page 73
|
|
79
112
|
MAESTRO_RANGES = [
|
|
113
|
+
(500032..500033),
|
|
114
|
+
(501015..501016),
|
|
115
|
+
(501020..501021),
|
|
116
|
+
(501023..501029),
|
|
117
|
+
(501038..501041),
|
|
118
|
+
(501053..501058),
|
|
119
|
+
(501060..501063),
|
|
120
|
+
(501066..501067),
|
|
121
|
+
(501080..501083),
|
|
122
|
+
(501091..501092),
|
|
123
|
+
(501104..501105),
|
|
124
|
+
(501107..501108),
|
|
125
|
+
(501104..501105),
|
|
126
|
+
(501107..501108),
|
|
80
127
|
(561200..561269),
|
|
81
128
|
(561271..561299),
|
|
82
129
|
(561320..561356),
|
|
@@ -101,14 +148,14 @@ module ActiveMerchant #:nodoc:
|
|
|
101
148
|
|
|
102
149
|
# https://dev.elo.com.br/apis/tabela-de-bins, download csv from left sidebar
|
|
103
150
|
ELO_RANGES = [
|
|
104
|
-
506707..506708, 506715..506715,
|
|
105
|
-
506745..506747, 506753..506753, 506774..
|
|
106
|
-
509020..
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
650901..650922, 650928..650928, 650938..650939, 650946..
|
|
111
|
-
|
|
151
|
+
506707..506708, 506715..506715, 506717..506722, 506724..506736, 506739..506743,
|
|
152
|
+
506745..506747, 506753..506753, 506774..506778, 509000..509007, 509009..509014,
|
|
153
|
+
509020..509030, 509035..509042, 509044..509089, 509091..509101, 509104..509807,
|
|
154
|
+
509831..509877, 509897..509900, 509918..509964, 509971..509986, 509995..509999,
|
|
155
|
+
627780..627780, 636368..636368, 650031..650033, 650035..650051, 650057..650081,
|
|
156
|
+
650406..650439, 650485..650504, 650506..650538, 650552..650598, 650720..650727,
|
|
157
|
+
650901..650922, 650928..650928, 650938..650939, 650946..650978, 651652..651704,
|
|
158
|
+
655000..655019, 655021..655057
|
|
112
159
|
]
|
|
113
160
|
|
|
114
161
|
# Alelo provides BIN ranges by e-mailing them out periodically.
|
|
@@ -227,7 +227,7 @@ module ActiveMerchant #:nodoc:
|
|
|
227
227
|
end
|
|
228
228
|
|
|
229
229
|
def add_merchant_data(post, options)
|
|
230
|
-
post[:additionalData][:
|
|
230
|
+
post[:additionalData][:subMerchantID] = options[:sub_merchant_id] if options[:sub_merchant_id]
|
|
231
231
|
post[:additionalData][:subMerchantName] = options[:sub_merchant_name] if options[:sub_merchant_name]
|
|
232
232
|
post[:additionalData][:subMerchantStreet] = options[:sub_merchant_street] if options[:sub_merchant_street]
|
|
233
233
|
post[:additionalData][:subMerchantCity] = options[:sub_merchant_city] if options[:sub_merchant_city]
|
|
@@ -235,8 +235,8 @@ module ActiveMerchant #:nodoc:
|
|
|
235
235
|
post[:additionalData][:subMerchantPostalCode] = options[:sub_merchant_postal_code] if options[:sub_merchant_postal_code]
|
|
236
236
|
post[:additionalData][:subMerchantCountry] = options[:sub_merchant_country] if options[:sub_merchant_country]
|
|
237
237
|
post[:additionalData][:subMerchantTaxId] = options[:sub_merchant_tax_id] if options[:sub_merchant_tax_id]
|
|
238
|
-
post[:additionalData][:subMerchantId] = options[:sub_merchant_id] if options[:sub_merchant_id]
|
|
239
238
|
post[:additionalData][:subMerchantMCC] = options[:sub_merchant_mcc] if options[:sub_merchant_mcc]
|
|
239
|
+
post[:additionalData] = post[:additionalData].merge(options[:sub_merchant_data]) if options[:sub_merchant_data]
|
|
240
240
|
end
|
|
241
241
|
|
|
242
242
|
def add_risk_data(post, options)
|
|
@@ -319,7 +319,9 @@ module ActiveMerchant
|
|
|
319
319
|
def add_fraud_info(doc, payment_method, options)
|
|
320
320
|
doc.send('transaction-fraud-info') do
|
|
321
321
|
doc.send('shopper-ip-address', options[:ip]) if options[:ip]
|
|
322
|
-
|
|
322
|
+
if fraud_info = options[:transaction_fraud_info]
|
|
323
|
+
doc.send('fraud-session-id', fraud_info[:fraud_session_id]) if fraud_info[:fraud_session_id]
|
|
324
|
+
end
|
|
323
325
|
unless payment_method.is_a? String
|
|
324
326
|
doc.send('shipping-contact-info') do
|
|
325
327
|
add_shipping_contact_info(doc, payment_method, options)
|
|
@@ -583,6 +583,7 @@ module ActiveMerchant #:nodoc:
|
|
|
583
583
|
parameters[:device_data] = options[:device_data] if options[:device_data]
|
|
584
584
|
parameters[:service_fee_amount] = options[:service_fee_amount] if options[:service_fee_amount]
|
|
585
585
|
|
|
586
|
+
add_account_type(parameters, options) if options[:account_type]
|
|
586
587
|
add_skip_options(parameters, options)
|
|
587
588
|
add_merchant_account_id(parameters, options)
|
|
588
589
|
|
|
@@ -609,6 +610,11 @@ module ActiveMerchant #:nodoc:
|
|
|
609
610
|
parameters
|
|
610
611
|
end
|
|
611
612
|
|
|
613
|
+
def add_account_type(parameters, options)
|
|
614
|
+
parameters[:options][:credit_card] = {}
|
|
615
|
+
parameters[:options][:credit_card][:account_type] = options[:account_type]
|
|
616
|
+
end
|
|
617
|
+
|
|
612
618
|
def add_skip_options(parameters, options)
|
|
613
619
|
parameters[:options][:skip_advanced_fraud_checking] = options[:skip_advanced_fraud_checking] if options[:skip_advanced_fraud_checking]
|
|
614
620
|
parameters[:options][:skip_avs] = options[:skip_avs] if options[:skip_avs]
|
|
@@ -331,6 +331,7 @@ module ActiveMerchant #:nodoc:
|
|
|
331
331
|
three_ds_2_options = options[:three_ds_2]
|
|
332
332
|
browser_info = three_ds_2_options[:browser_info]
|
|
333
333
|
post[:'3ds_initiate'] = options[:three_ds_initiate] || '01'
|
|
334
|
+
post[:f23] = options[:f23] if options[:f23]
|
|
334
335
|
post[:'3ds_purchasedate'] = Time.now.utc.strftime('%Y%m%d%I%M%S')
|
|
335
336
|
options.dig(:stored_credential, :initiator) == 'merchant' ? post[:'3ds_channel'] = '03' : post[:'3ds_channel'] = '02'
|
|
336
337
|
post[:'3ds_redirect_url'] = three_ds_2_options[:notification_url]
|
|
@@ -256,8 +256,9 @@ module ActiveMerchant #:nodoc:
|
|
|
256
256
|
|
|
257
257
|
private
|
|
258
258
|
|
|
259
|
-
# Create all address hash key value pairs
|
|
260
|
-
#
|
|
259
|
+
# Create all required address hash key value pairs
|
|
260
|
+
# If a value of nil is received, that value will be passed on to the gateway and will not be replaced with a default value
|
|
261
|
+
# Billing address fields received without an override value or with an empty string value will be replaced with the default_address values
|
|
261
262
|
def setup_address_hash(options)
|
|
262
263
|
default_address = {
|
|
263
264
|
address1: 'Unspecified',
|
|
@@ -268,10 +269,20 @@ module ActiveMerchant #:nodoc:
|
|
|
268
269
|
}
|
|
269
270
|
|
|
270
271
|
submitted_address = options[:billing_address] || options[:address] || default_address
|
|
271
|
-
options[:billing_address] = default_address.merge(submitted_address.symbolize_keys) { |_k, default, submitted|
|
|
272
|
+
options[:billing_address] = default_address.merge(submitted_address.symbolize_keys) { |_k, default, submitted| check_billing_field_value(default, submitted) }
|
|
272
273
|
options[:shipping_address] = options[:shipping_address] || {}
|
|
273
274
|
end
|
|
274
275
|
|
|
276
|
+
def check_billing_field_value(default, submitted)
|
|
277
|
+
if submitted.nil?
|
|
278
|
+
nil
|
|
279
|
+
elsif submitted.blank?
|
|
280
|
+
default
|
|
281
|
+
else
|
|
282
|
+
submitted
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
|
|
275
286
|
def build_auth_request(money, creditcard_or_reference, options)
|
|
276
287
|
xml = Builder::XmlMarkup.new indent: 2
|
|
277
288
|
add_payment_method_or_subscription(xml, money, creditcard_or_reference, options)
|
|
@@ -170,6 +170,12 @@ module ActiveMerchant #:nodoc:
|
|
|
170
170
|
card_data[:security_code] = credit_card.verification_value if credit_card.verification_value?
|
|
171
171
|
card_data[:card_holder_name] = credit_card.name if credit_card.name
|
|
172
172
|
|
|
173
|
+
# the device_unique_id has to be sent in via the card data (as device_unique_identifier) no other fraud detection fields require this
|
|
174
|
+
if options[:fraud_detection].present?
|
|
175
|
+
card_data[:fraud_detection] = {} if (options[:fraud_detection][:device_unique_id]).present?
|
|
176
|
+
card_data[:fraud_detection][:device_unique_identifier] = (options[:fraud_detection][:device_unique_id]) if (options[:fraud_detection][:device_unique_id]).present?
|
|
177
|
+
end
|
|
178
|
+
|
|
173
179
|
# additional data used for Visa transactions
|
|
174
180
|
card_data[:card_holder_door_number] = options[:card_holder_door_number].to_i if options[:card_holder_door_number]
|
|
175
181
|
card_data[:card_holder_birthday] = options[:card_holder_birthday] if options[:card_holder_birthday]
|
|
@@ -210,6 +216,14 @@ module ActiveMerchant #:nodoc:
|
|
|
210
216
|
hsh[:channel] = options[:channel] if valid_fraud_detection_option?(options[:channel])
|
|
211
217
|
hsh[:dispatch_method] = options[:dispatch_method] if valid_fraud_detection_option?(options[:dispatch_method])
|
|
212
218
|
hsh[:csmdds] = options[:csmdds] if valid_fraud_detection_option?(options[:csmdds])
|
|
219
|
+
hsh[:device_unique_id] = options[:device_unique_id] if valid_fraud_detection_option?(options[:device_unique_id])
|
|
220
|
+
hsh[:bill_to] = options[:bill_to] if valid_fraud_detection_option?(options[:bill_to])
|
|
221
|
+
hsh[:purchase_totals] = options[:purchase_totals] if valid_fraud_detection_option?(options[:purchase_totals])
|
|
222
|
+
hsh[:customer_in_site] = options[:customer_in_site] if valid_fraud_detection_option?(options[:customer_in_site])
|
|
223
|
+
hsh[:retail_transaction_data] = options[:retail_transaction_data] if valid_fraud_detection_option?(options[:retail_transaction_data])
|
|
224
|
+
hsh[:ship_to] = options[:ship_to] if valid_fraud_detection_option?(options[:ship_to])
|
|
225
|
+
hsh[:tax_voucher_required] = options[:tax_voucher_required] if valid_fraud_detection_option?(options[:tax_voucher_required])
|
|
226
|
+
hsh[:copy_paste_card_data] = options[:copy_paste_card_data] if valid_fraud_detection_option?(options[:copy_paste_card_data])
|
|
213
227
|
end
|
|
214
228
|
end
|
|
215
229
|
|
|
@@ -285,10 +285,12 @@ module ActiveMerchant #:nodoc:
|
|
|
285
285
|
|
|
286
286
|
def add_auth_purchase_params(xml, options)
|
|
287
287
|
xml.ssl_dynamic_dba options[:dba] if options.has_key?(:dba)
|
|
288
|
-
xml.ssl_merchant_initiated_unscheduled options
|
|
288
|
+
xml.ssl_merchant_initiated_unscheduled merchant_initiated_unscheduled(options) if merchant_initiated_unscheduled(options)
|
|
289
289
|
xml.ssl_customer_code options[:customer] if options.has_key?(:customer)
|
|
290
290
|
xml.ssl_customer_number options[:customer_number] if options.has_key?(:customer_number)
|
|
291
|
+
xml.ssl_entry_mode entry_mode(options) if entry_mode(options)
|
|
291
292
|
add_custom_fields(xml, options) if options[:custom_fields]
|
|
293
|
+
add_stored_credential(xml, options) if options[:stored_credential]
|
|
292
294
|
end
|
|
293
295
|
|
|
294
296
|
def add_custom_fields(xml, options)
|
|
@@ -337,6 +339,32 @@ module ActiveMerchant #:nodoc:
|
|
|
337
339
|
}
|
|
338
340
|
end
|
|
339
341
|
|
|
342
|
+
def add_stored_credential(xml, options)
|
|
343
|
+
network_transaction_id = options.dig(:stored_credential, :network_transaction_id)
|
|
344
|
+
case
|
|
345
|
+
when network_transaction_id.nil?
|
|
346
|
+
return
|
|
347
|
+
when network_transaction_id.to_s.include?('|')
|
|
348
|
+
oar_data, ps2000_data = options[:stored_credential][:network_transaction_id].split('|')
|
|
349
|
+
xml.ssl_oar_data oar_data unless oar_data.nil? || oar_data.empty?
|
|
350
|
+
xml.ssl_ps2000_data ps2000_data unless ps2000_data.nil? || ps2000_data.empty?
|
|
351
|
+
when network_transaction_id.to_s.length > 22
|
|
352
|
+
xml.ssl_oar_data options.dig(:stored_credential, :network_transaction_id)
|
|
353
|
+
else
|
|
354
|
+
xml.ssl_ps2000_data options.dig(:stored_credential, :network_transaction_id)
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
def merchant_initiated_unscheduled(options)
|
|
359
|
+
return options[:merchant_initiated_unscheduled] if options[:merchant_initiated_unscheduled]
|
|
360
|
+
return 'Y' if options.dig(:stored_credential, :initiator) == 'merchant' && options.dig(:stored_credential, :reason_type) == 'unscheduled'
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
def entry_mode(options)
|
|
364
|
+
return options[:entry_mode] if options[:entry_mode]
|
|
365
|
+
return 12 if options[:stored_credential]
|
|
366
|
+
end
|
|
367
|
+
|
|
340
368
|
def build_xml_request
|
|
341
369
|
builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
|
|
342
370
|
xml.txn do
|
|
@@ -362,10 +390,15 @@ module ActiveMerchant #:nodoc:
|
|
|
362
390
|
authorization: authorization_from(response),
|
|
363
391
|
error_code: response[:errorCode],
|
|
364
392
|
avs_result: { code: response[:avs_response] },
|
|
365
|
-
cvv_result: response[:cvv2_response]
|
|
393
|
+
cvv_result: response[:cvv2_response],
|
|
394
|
+
network_transaction_id: build_network_transaction_id(response)
|
|
366
395
|
)
|
|
367
396
|
end
|
|
368
397
|
|
|
398
|
+
def build_network_transaction_id(response)
|
|
399
|
+
"#{response[:oar_data]}|#{response[:ps2000_data]}"
|
|
400
|
+
end
|
|
401
|
+
|
|
369
402
|
def headers
|
|
370
403
|
{
|
|
371
404
|
'Accept' => 'application/xml',
|
|
@@ -212,8 +212,8 @@ module ActiveMerchant #:nodoc:
|
|
|
212
212
|
xml.tag! 'Expiry_Date', expdate(credit_card)
|
|
213
213
|
xml.tag! 'CardHoldersName', credit_card.name
|
|
214
214
|
xml.tag! 'CardType', card_type(credit_card.brand)
|
|
215
|
-
xml.tag! 'WalletProviderID', options[:wallet_provider_id] if options[:wallet_provider_id]
|
|
216
215
|
|
|
216
|
+
add_wallet_provider_id(xml, credit_card, options)
|
|
217
217
|
add_credit_card_eci(xml, credit_card, options)
|
|
218
218
|
add_credit_card_verification_strings(xml, credit_card, options)
|
|
219
219
|
end
|
|
@@ -221,10 +221,9 @@ module ActiveMerchant #:nodoc:
|
|
|
221
221
|
|
|
222
222
|
def add_credit_card_eci(xml, credit_card, options)
|
|
223
223
|
eci = if credit_card.is_a?(NetworkTokenizationCreditCard) && credit_card.source == :apple_pay && card_brand(credit_card) == 'discover'
|
|
224
|
-
#
|
|
225
|
-
#
|
|
226
|
-
|
|
227
|
-
'04'
|
|
224
|
+
# Payeezy requires an ECI of 5 for apple pay transactions
|
|
225
|
+
# See: https://support.payeezy.com/hc/en-us/articles/203730589-Ecommerce-Flag-Values
|
|
226
|
+
'05'
|
|
228
227
|
else
|
|
229
228
|
(credit_card.respond_to?(:eci) ? credit_card.eci : nil) || options[:eci] || DEFAULT_ECI
|
|
230
229
|
end
|
|
@@ -276,10 +275,22 @@ module ActiveMerchant #:nodoc:
|
|
|
276
275
|
xml.tag! 'Expiry_Date', expdate(credit_card)
|
|
277
276
|
xml.tag! 'CardHoldersName', credit_card.name
|
|
278
277
|
xml.tag! 'CardType', card_type(credit_card.brand)
|
|
279
|
-
|
|
278
|
+
|
|
279
|
+
add_wallet_provider_id(xml, credit_card, options)
|
|
280
280
|
add_card_authentication_data(xml, options)
|
|
281
281
|
end
|
|
282
282
|
|
|
283
|
+
def add_wallet_provider_id(xml, credit_card, options)
|
|
284
|
+
provider_id = if options[:wallet_provider_id]
|
|
285
|
+
options[:wallet_provider_id]
|
|
286
|
+
elsif credit_card.is_a?(NetworkTokenizationCreditCard) && credit_card.source == :apple_pay
|
|
287
|
+
# See: https://support.payeezy.com/hc/en-us/articles/206601408-First-Data-Payeezy-Gateway-Web-Service-API-Reference-Guide#3.9
|
|
288
|
+
4
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
xml.tag! 'WalletProviderID', provider_id if provider_id
|
|
292
|
+
end
|
|
293
|
+
|
|
283
294
|
def add_customer_data(xml, options)
|
|
284
295
|
xml.tag! 'Customer_Ref', options[:customer] if options[:customer]
|
|
285
296
|
xml.tag! 'Client_IP', options[:ip] if options[:ip]
|
|
@@ -210,7 +210,7 @@ module ActiveMerchant #:nodoc:
|
|
|
210
210
|
def add_details(xml, options)
|
|
211
211
|
xml.hps :AdditionalTxnFields do
|
|
212
212
|
xml.hps :Description, options[:description] if options[:description]
|
|
213
|
-
xml.hps :InvoiceNbr, options[:order_id] if options[:order_id]
|
|
213
|
+
xml.hps :InvoiceNbr, options[:order_id][0..59] if options[:order_id]
|
|
214
214
|
xml.hps :CustomerID, options[:customer_id] if options[:customer_id]
|
|
215
215
|
end
|
|
216
216
|
end
|
|
@@ -5,7 +5,10 @@ module ActiveMerchant #:nodoc:
|
|
|
5
5
|
class LitleGateway < Gateway
|
|
6
6
|
SCHEMA_VERSION = '9.14'
|
|
7
7
|
|
|
8
|
+
class_attribute :postlive_url
|
|
9
|
+
|
|
8
10
|
self.test_url = 'https://www.testvantivcnp.com/sandbox/communicator/online'
|
|
11
|
+
self.postlive_url = 'https://payments.vantivpostlive.com/vap/communicator/online'
|
|
9
12
|
self.live_url = 'https://payments.vantivcnp.com/vap/communicator/online'
|
|
10
13
|
|
|
11
14
|
self.supported_countries = ['US']
|
|
@@ -513,6 +516,8 @@ module ActiveMerchant #:nodoc:
|
|
|
513
516
|
end
|
|
514
517
|
|
|
515
518
|
def url
|
|
519
|
+
return postlive_url if @options[:url_override].to_s == 'postlive'
|
|
520
|
+
|
|
516
521
|
test? ? test_url : live_url
|
|
517
522
|
end
|
|
518
523
|
|
|
@@ -30,7 +30,7 @@ module ActiveMerchant #:nodoc:
|
|
|
30
30
|
class OrbitalGateway < Gateway
|
|
31
31
|
include Empty
|
|
32
32
|
|
|
33
|
-
API_VERSION = '
|
|
33
|
+
API_VERSION = '8.1'
|
|
34
34
|
|
|
35
35
|
POST_HEADERS = {
|
|
36
36
|
'MIME-Version' => '1.1',
|
|
@@ -183,6 +183,37 @@ module ActiveMerchant #:nodoc:
|
|
|
183
183
|
|
|
184
184
|
SENSITIVE_FIELDS = %i[account_num cc_account_num]
|
|
185
185
|
|
|
186
|
+
# Bank account types to be used for check processing
|
|
187
|
+
ACCOUNT_TYPE = {
|
|
188
|
+
'savings' => 'S',
|
|
189
|
+
'checking' => 'C'
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
# Fixed possible values for orbital ECP attributes
|
|
193
|
+
# Auth methods for electronic checks can be:
|
|
194
|
+
# Written, Internet, Telephonic, Account Receivable, Point of Purchase.
|
|
195
|
+
# Default auth method for ECP is Internet (I).
|
|
196
|
+
# Bank payment delivery can be either ACH (Automated Clearing House) or Best Possible.
|
|
197
|
+
# Default Bank Payment Delivery is Best Possible (B).
|
|
198
|
+
# Action codes to be used for Early Warning System and additional validations.
|
|
199
|
+
# Valid combinations of Message Type and Action Code to be used are:
|
|
200
|
+
# A W1
|
|
201
|
+
# AC W1
|
|
202
|
+
# FC W4
|
|
203
|
+
# R W6
|
|
204
|
+
# FC W8
|
|
205
|
+
# A W3
|
|
206
|
+
# AC W3
|
|
207
|
+
# FC W5
|
|
208
|
+
# R W7
|
|
209
|
+
# Default Action code for ECP is nil.
|
|
210
|
+
# Electronic check to be processed on same day (Y) or next day (N).
|
|
211
|
+
# Default ECP Same Day Index is Yes (Y).
|
|
212
|
+
ECP_AUTH_METHODS = %w[W I T A P]
|
|
213
|
+
ECP_BANK_PAYMENT = %w[A B]
|
|
214
|
+
ECP_ACTION_CODES = %w[LO ND NC W1 W3 W4 W5 W6 W7 W8 W9]
|
|
215
|
+
ECP_SAME_DAY = %w[Y N]
|
|
216
|
+
|
|
186
217
|
def initialize(options = {})
|
|
187
218
|
requires!(options, :merchant_id)
|
|
188
219
|
requires!(options, :login, :password) unless options[:ip_authentication]
|
|
@@ -191,12 +222,12 @@ module ActiveMerchant #:nodoc:
|
|
|
191
222
|
end
|
|
192
223
|
|
|
193
224
|
# A – Authorization request
|
|
194
|
-
def authorize(money,
|
|
195
|
-
order = build_new_order_xml(AUTH_ONLY, money,
|
|
196
|
-
|
|
197
|
-
add_address(xml,
|
|
225
|
+
def authorize(money, payment_source, options = {})
|
|
226
|
+
order = build_new_order_xml(AUTH_ONLY, money, payment_source, options) do |xml|
|
|
227
|
+
add_payment_source(xml, payment_source, options)
|
|
228
|
+
add_address(xml, payment_source, options)
|
|
198
229
|
if @options[:customer_profiles]
|
|
199
|
-
add_customer_data(xml,
|
|
230
|
+
add_customer_data(xml, payment_source, options)
|
|
200
231
|
add_managed_billing(xml, options)
|
|
201
232
|
end
|
|
202
233
|
end
|
|
@@ -211,12 +242,12 @@ module ActiveMerchant #:nodoc:
|
|
|
211
242
|
end
|
|
212
243
|
|
|
213
244
|
# AC – Authorization and Capture
|
|
214
|
-
def purchase(money,
|
|
215
|
-
order = build_new_order_xml(AUTH_AND_CAPTURE, money,
|
|
216
|
-
|
|
217
|
-
add_address(xml,
|
|
245
|
+
def purchase(money, payment_source, options = {})
|
|
246
|
+
order = build_new_order_xml(options[:force_capture] ? FORCE_AUTH_AND_CAPTURE : AUTH_AND_CAPTURE, money, payment_source, options) do |xml|
|
|
247
|
+
add_payment_source(xml, payment_source, options)
|
|
248
|
+
add_address(xml, payment_source, options)
|
|
218
249
|
if @options[:customer_profiles]
|
|
219
|
-
add_customer_data(xml,
|
|
250
|
+
add_customer_data(xml, payment_source, options)
|
|
220
251
|
add_managed_billing(xml, options)
|
|
221
252
|
end
|
|
222
253
|
end
|
|
@@ -478,6 +509,31 @@ module ActiveMerchant #:nodoc:
|
|
|
478
509
|
end
|
|
479
510
|
end
|
|
480
511
|
|
|
512
|
+
# Payment can be done through either Credit Card or Electronic Check
|
|
513
|
+
def add_payment_source(xml, payment_source, options = {})
|
|
514
|
+
if payment_source.instance_of?(ActiveMerchant::Billing::Check)
|
|
515
|
+
add_echeck(xml, payment_source, options)
|
|
516
|
+
else
|
|
517
|
+
add_creditcard(xml, payment_source, options[:currency])
|
|
518
|
+
end
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
# Adds Electronic Check attributes
|
|
522
|
+
def add_echeck(xml, check, options = {})
|
|
523
|
+
xml.tag! :CardBrand, 'EC'
|
|
524
|
+
xml.tag! :CurrencyCode, currency_code(options[:currency])
|
|
525
|
+
xml.tag! :CurrencyExponent, currency_exponents(options[:currency])
|
|
526
|
+
unless check.nil?
|
|
527
|
+
|
|
528
|
+
xml.tag! :BCRtNum, check.routing_number
|
|
529
|
+
xml.tag! :CheckDDA, check.account_number if check.account_number
|
|
530
|
+
xml.tag! :BankAccountType, ACCOUNT_TYPE[check.account_type] if ACCOUNT_TYPE[check.account_type]
|
|
531
|
+
xml.tag! :ECPAuthMethod, options[:auth_method] if options[:auth_method] && ECP_AUTH_METHODS.include?(options[:auth_method])
|
|
532
|
+
xml.tag! :BankPmtDelv, options[:payment_delivery] if options[:payment_delivery] && ECP_BANK_PAYMENT.include?(options[:payment_delivery])
|
|
533
|
+
end
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
# Adds Credit Card attributes
|
|
481
537
|
def add_creditcard(xml, creditcard, currency = nil)
|
|
482
538
|
unless creditcard.nil?
|
|
483
539
|
xml.tag! :AccountNum, creditcard.number
|
|
@@ -532,6 +588,24 @@ module ActiveMerchant #:nodoc:
|
|
|
532
588
|
xml.tag!(:AAV, three_d_secure[:cavv])
|
|
533
589
|
end
|
|
534
590
|
|
|
591
|
+
def add_mc_program_protocol(xml, creditcard, three_d_secure)
|
|
592
|
+
return unless three_d_secure && creditcard.brand == 'master'
|
|
593
|
+
|
|
594
|
+
xml.tag!(:MCProgramProtocol, three_d_secure[:version]) if three_d_secure[:version]
|
|
595
|
+
end
|
|
596
|
+
|
|
597
|
+
def add_mc_directory_trans_id(xml, creditcard, three_d_secure)
|
|
598
|
+
return unless three_d_secure && creditcard.brand == 'master'
|
|
599
|
+
|
|
600
|
+
xml.tag!(:MCDirectoryTransID, three_d_secure[:ds_transaction_id]) if three_d_secure[:ds_transaction_id]
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
def add_ucafind(xml, creditcard, three_d_secure)
|
|
604
|
+
return unless three_d_secure && creditcard.brand == 'master'
|
|
605
|
+
|
|
606
|
+
xml.tag! :UCAFInd, '4'
|
|
607
|
+
end
|
|
608
|
+
|
|
535
609
|
def add_dpanind(xml, creditcard)
|
|
536
610
|
return unless creditcard.is_a?(NetworkTokenizationCreditCard)
|
|
537
611
|
|
|
@@ -587,6 +661,18 @@ module ActiveMerchant #:nodoc:
|
|
|
587
661
|
end
|
|
588
662
|
end
|
|
589
663
|
|
|
664
|
+
# Adds ECP conditional attributes depending on other attribute values
|
|
665
|
+
def add_ecp_details(xml, parameters = {})
|
|
666
|
+
requires!(parameters, :check_serial_number) if parameters[:auth_method]&.eql?('A') || parameters[:auth_method]&.eql?('P')
|
|
667
|
+
xml.tag! :ECPActionCode, parameters[:action_code] if parameters[:action_code] && ECP_ACTION_CODES.include?(parameters[:action_code])
|
|
668
|
+
xml.tag! :ECPCheckSerialNumber, parameters[:check_serial_number] if parameters[:auth_method]&.eql?('A') || parameters[:auth_method]&.eql?('P')
|
|
669
|
+
if parameters[:auth_method]&.eql?('P')
|
|
670
|
+
xml.tag! :ECPTerminalCity, parameters[:terminal_city] if parameters[:terminal_city]
|
|
671
|
+
xml.tag! :ECPTerminalState, parameters[:terminal_state] if parameters[:terminal_state]
|
|
672
|
+
xml.tag! :ECPImageReferenceNumber, parameters[:image_reference_number] if parameters[:image_reference_number]
|
|
673
|
+
end
|
|
674
|
+
end
|
|
675
|
+
|
|
590
676
|
def add_stored_credentials(xml, parameters)
|
|
591
677
|
return unless parameters[:mit_stored_credential_ind] == 'Y' || parameters[:stored_credential] && !parameters[:stored_credential].values.all?(&:nil?)
|
|
592
678
|
|
|
@@ -695,7 +781,7 @@ module ActiveMerchant #:nodoc:
|
|
|
695
781
|
@options[:ip_authentication] == true
|
|
696
782
|
end
|
|
697
783
|
|
|
698
|
-
def build_new_order_xml(action, money,
|
|
784
|
+
def build_new_order_xml(action, money, payment_source, parameters = {})
|
|
699
785
|
requires!(parameters, :order_id)
|
|
700
786
|
xml = xml_envelope
|
|
701
787
|
xml.tag! :Request do
|
|
@@ -720,9 +806,9 @@ module ActiveMerchant #:nodoc:
|
|
|
720
806
|
|
|
721
807
|
three_d_secure = parameters[:three_d_secure]
|
|
722
808
|
|
|
723
|
-
add_eci(xml,
|
|
724
|
-
add_cavv(xml,
|
|
725
|
-
add_xid(xml,
|
|
809
|
+
add_eci(xml, payment_source, three_d_secure)
|
|
810
|
+
add_cavv(xml, payment_source, three_d_secure)
|
|
811
|
+
add_xid(xml, payment_source, three_d_secure)
|
|
726
812
|
|
|
727
813
|
xml.tag! :OrderID, format_order_id(parameters[:order_id])
|
|
728
814
|
xml.tag! :Amount, amount(money)
|
|
@@ -731,7 +817,7 @@ module ActiveMerchant #:nodoc:
|
|
|
731
817
|
add_level2_tax(xml, parameters)
|
|
732
818
|
add_level2_advice_addendum(xml, parameters)
|
|
733
819
|
|
|
734
|
-
add_aav(xml,
|
|
820
|
+
add_aav(xml, payment_source, three_d_secure)
|
|
735
821
|
# CustomerAni, AVSPhoneType and AVSDestPhoneType could be added here.
|
|
736
822
|
|
|
737
823
|
if parameters[:soft_descriptors].is_a?(OrbitalSoftDescriptors)
|
|
@@ -740,9 +826,11 @@ module ActiveMerchant #:nodoc:
|
|
|
740
826
|
add_soft_descriptors_from_hash(xml, parameters[:soft_descriptors])
|
|
741
827
|
end
|
|
742
828
|
|
|
743
|
-
add_dpanind(xml,
|
|
744
|
-
add_aevv(xml,
|
|
745
|
-
add_digital_token_cryptogram(xml,
|
|
829
|
+
add_dpanind(xml, payment_source)
|
|
830
|
+
add_aevv(xml, payment_source, three_d_secure)
|
|
831
|
+
add_digital_token_cryptogram(xml, payment_source)
|
|
832
|
+
|
|
833
|
+
xml.tag! :ECPSameDayInd, parameters[:same_day] if parameters[:same_day] && ECP_SAME_DAY.include?(parameters[:same_day]) && payment_source.instance_of?(ActiveMerchant::Billing::Check)
|
|
746
834
|
|
|
747
835
|
set_recurring_ind(xml, parameters)
|
|
748
836
|
|
|
@@ -756,9 +844,13 @@ module ActiveMerchant #:nodoc:
|
|
|
756
844
|
add_level3_purchase(xml, parameters)
|
|
757
845
|
add_level3_tax(xml, parameters)
|
|
758
846
|
add_line_items(xml, parameters) if parameters[:line_items]
|
|
847
|
+
add_ecp_details(xml, parameters) if payment_source.instance_of?(ActiveMerchant::Billing::Check)
|
|
759
848
|
add_card_indicators(xml, parameters)
|
|
760
849
|
add_stored_credentials(xml, parameters)
|
|
761
|
-
add_pymt_brand_program_code(xml,
|
|
850
|
+
add_pymt_brand_program_code(xml, payment_source, three_d_secure)
|
|
851
|
+
add_mc_program_protocol(xml, payment_source, three_d_secure)
|
|
852
|
+
add_mc_directory_trans_id(xml, payment_source, three_d_secure)
|
|
853
|
+
add_ucafind(xml, payment_source, three_d_secure)
|
|
762
854
|
end
|
|
763
855
|
end
|
|
764
856
|
xml.target!
|
|
@@ -247,16 +247,34 @@ module ActiveMerchant
|
|
|
247
247
|
end
|
|
248
248
|
|
|
249
249
|
def add_stored_credentials(params, options)
|
|
250
|
-
if options[:sequence]
|
|
250
|
+
if options[:sequence] || options[:stored_credential]
|
|
251
251
|
params[:stored_credentials] = {}
|
|
252
|
-
params[:stored_credentials][:cardbrand_original_transaction_id] = options
|
|
253
|
-
params[:stored_credentials][:
|
|
254
|
-
params[:stored_credentials][:
|
|
255
|
-
params[:stored_credentials][:is_scheduled] = options[:is_scheduled]
|
|
252
|
+
params[:stored_credentials][:cardbrand_original_transaction_id] = original_transaction_id(options) if original_transaction_id(options)
|
|
253
|
+
params[:stored_credentials][:initiator] = initiator(options) if initiator(options)
|
|
254
|
+
params[:stored_credentials][:sequence] = options[:sequence] || sequence(options[:stored_credential][:initial_transaction])
|
|
255
|
+
params[:stored_credentials][:is_scheduled] = options[:is_scheduled] || is_scheduled(options[:stored_credential][:reason_type])
|
|
256
256
|
params[:stored_credentials][:auth_type_override] = options[:auth_type_override] if options[:auth_type_override]
|
|
257
257
|
end
|
|
258
258
|
end
|
|
259
259
|
|
|
260
|
+
def original_transaction_id(options)
|
|
261
|
+
return options[:cardbrand_original_transaction_id] if options[:cardbrand_original_transaction_id]
|
|
262
|
+
return options[:stored_credential][:network_transaction_id] if options.dig(:stored_credential, :network_transaction_id)
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
def initiator(options)
|
|
266
|
+
return options[:initiator] if options[:initiator]
|
|
267
|
+
return options[:stored_credential][:initiator].upcase if options.dig(:stored_credential, :initiator)
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def sequence(initial_transaction)
|
|
271
|
+
initial_transaction ? 'FIRST' : 'SUBSEQUENT'
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def is_scheduled(reason_type)
|
|
275
|
+
reason_type == 'recurring' ? 'true' : 'false'
|
|
276
|
+
end
|
|
277
|
+
|
|
260
278
|
def commit(params, options)
|
|
261
279
|
url = base_url(options) + endpoint(params)
|
|
262
280
|
|
|
@@ -9,7 +9,7 @@ module ActiveMerchant #:nodoc:
|
|
|
9
9
|
|
|
10
10
|
self.supported_countries = %w[MX EC CO BR CL PE]
|
|
11
11
|
self.default_currency = 'USD'
|
|
12
|
-
self.supported_cardtypes = %i[visa master american_express diners_club elo alia]
|
|
12
|
+
self.supported_cardtypes = %i[visa master american_express diners_club elo alia olimpica]
|
|
13
13
|
|
|
14
14
|
self.homepage_url = 'https://secure.paymentez.com/'
|
|
15
15
|
self.display_name = 'Paymentez'
|
|
@@ -175,9 +175,29 @@ module ActiveMerchant #:nodoc:
|
|
|
175
175
|
extra_params = {}
|
|
176
176
|
extra_params.merge!(options[:extra_params]) if options[:extra_params]
|
|
177
177
|
|
|
178
|
+
add_external_mpi_fields(extra_params, options)
|
|
179
|
+
|
|
178
180
|
post['extra_params'] = extra_params unless extra_params.empty?
|
|
179
181
|
end
|
|
180
182
|
|
|
183
|
+
def add_external_mpi_fields(extra_params, options)
|
|
184
|
+
three_d_secure_options = options[:three_d_secure]
|
|
185
|
+
return unless three_d_secure_options
|
|
186
|
+
|
|
187
|
+
auth_data = {
|
|
188
|
+
cavv: three_d_secure_options[:cavv],
|
|
189
|
+
xid: three_d_secure_options[:xid],
|
|
190
|
+
eci: three_d_secure_options[:eci],
|
|
191
|
+
version: three_d_secure_options[:version],
|
|
192
|
+
reference_id: three_d_secure_options[:three_ds_server_trans_id],
|
|
193
|
+
status: three_d_secure_options[:authentication_response_status] || three_d_secure_options[:directory_response_status]
|
|
194
|
+
}.compact
|
|
195
|
+
|
|
196
|
+
return if auth_data.empty?
|
|
197
|
+
|
|
198
|
+
extra_params[:auth_data] = auth_data
|
|
199
|
+
end
|
|
200
|
+
|
|
181
201
|
def parse(body)
|
|
182
202
|
JSON.parse(body)
|
|
183
203
|
end
|
|
@@ -58,7 +58,7 @@ module ActiveMerchant #:nodoc:
|
|
|
58
58
|
xml = Builder::XmlMarkup.new indent: 2
|
|
59
59
|
xml.tag! transaction_type + 'Req', 'xmlns' => PAYPAL_NAMESPACE do
|
|
60
60
|
xml.tag! transaction_type + 'Request', 'xmlns:n2' => EBAY_NAMESPACE do
|
|
61
|
-
xml.tag! 'n2:Version',
|
|
61
|
+
xml.tag! 'n2:Version', api_version(options)
|
|
62
62
|
xml.tag! 'n2:' + transaction_type + 'RequestDetails' do
|
|
63
63
|
xml.tag! 'n2:ReferenceID', reference_id if transaction_type == 'DoReferenceTransaction'
|
|
64
64
|
xml.tag! 'n2:PaymentAction', action
|
|
@@ -73,6 +73,12 @@ module ActiveMerchant #:nodoc:
|
|
|
73
73
|
xml.target!
|
|
74
74
|
end
|
|
75
75
|
|
|
76
|
+
def api_version(options)
|
|
77
|
+
return API_VERSION_3DS2 if options.dig(:three_d_secure, :version) =~ /^2/
|
|
78
|
+
|
|
79
|
+
API_VERSION
|
|
80
|
+
end
|
|
81
|
+
|
|
76
82
|
def add_credit_card(xml, credit_card, address, options)
|
|
77
83
|
xml.tag! 'n2:CreditCard' do
|
|
78
84
|
xml.tag! 'n2:CreditCardType', credit_card_type(card_brand(credit_card))
|
|
@@ -104,10 +110,12 @@ module ActiveMerchant #:nodoc:
|
|
|
104
110
|
three_d_secure = options[:three_d_secure]
|
|
105
111
|
xml.tag! 'ThreeDSecureRequest' do
|
|
106
112
|
xml.tag! 'MpiVendor3ds', 'Y'
|
|
107
|
-
xml.tag! 'AuthStatus3ds', three_d_secure[:trans_status]
|
|
113
|
+
xml.tag! 'AuthStatus3ds', three_d_secure[:authentication_response_status] || three_d_secure[:trans_status] if three_d_secure[:authentication_response_status] || three_d_secure[:trans_status]
|
|
108
114
|
xml.tag! 'Cavv', three_d_secure[:cavv] unless three_d_secure[:cavv].blank?
|
|
109
115
|
xml.tag! 'Eci3ds', three_d_secure[:eci] unless three_d_secure[:eci].blank?
|
|
110
116
|
xml.tag! 'Xid', three_d_secure[:xid] unless three_d_secure[:xid].blank?
|
|
117
|
+
xml.tag! 'ThreeDSVersion', three_d_secure[:version] unless three_d_secure[:version].blank?
|
|
118
|
+
xml.tag! 'DSTransactionId', three_d_secure[:ds_transaction_id] unless three_d_secure[:ds_transaction_id].blank?
|
|
111
119
|
end
|
|
112
120
|
end
|
|
113
121
|
|
|
@@ -30,6 +30,7 @@ module ActiveMerchant #:nodoc:
|
|
|
30
30
|
add_address(post, creditcard, options)
|
|
31
31
|
add_capture(post, options)
|
|
32
32
|
add_metadata(post, options)
|
|
33
|
+
add_3ds(post, options)
|
|
33
34
|
|
|
34
35
|
commit(:post, 'charges', post, options)
|
|
35
36
|
end
|
|
@@ -158,6 +159,16 @@ module ActiveMerchant #:nodoc:
|
|
|
158
159
|
post[:metadata] = options[:metadata] if options[:metadata]
|
|
159
160
|
end
|
|
160
161
|
|
|
162
|
+
def add_3ds(post, options)
|
|
163
|
+
if options[:three_d_secure]
|
|
164
|
+
post[:three_d_secure] = {}
|
|
165
|
+
post[:three_d_secure][:version] = options[:three_d_secure][:version] if options[:three_d_secure][:version]
|
|
166
|
+
post[:three_d_secure][:eci] = options[:three_d_secure][:eci] if options[:three_d_secure][:eci]
|
|
167
|
+
post[:three_d_secure][:cavv] = options[:three_d_secure][:cavv] if options[:three_d_secure][:cavv]
|
|
168
|
+
post[:three_d_secure][:transaction_id] = options[:three_d_secure][:ds_transaction_id] || options[:three_d_secure][:xid]
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
161
172
|
def headers(params = {})
|
|
162
173
|
result = {
|
|
163
174
|
'Content-Type' => 'application/json',
|
|
@@ -203,6 +203,7 @@ module ActiveMerchant #:nodoc:
|
|
|
203
203
|
add_payment(data, payment)
|
|
204
204
|
add_external_mpi_fields(data, options)
|
|
205
205
|
add_threeds(data, options) if options[:execute_threed]
|
|
206
|
+
add_stored_credential_options(data, options)
|
|
206
207
|
data[:description] = options[:description]
|
|
207
208
|
data[:store_in_vault] = options[:store]
|
|
208
209
|
data[:sca_exemption] = options[:sca_exemption]
|
|
@@ -220,6 +221,7 @@ module ActiveMerchant #:nodoc:
|
|
|
220
221
|
add_payment(data, payment)
|
|
221
222
|
add_external_mpi_fields(data, options)
|
|
222
223
|
add_threeds(data, options) if options[:execute_threed]
|
|
224
|
+
add_stored_credential_options(data, options)
|
|
223
225
|
data[:description] = options[:description]
|
|
224
226
|
data[:store_in_vault] = options[:store]
|
|
225
227
|
data[:sca_exemption] = options[:sca_exemption]
|
|
@@ -331,18 +333,39 @@ module ActiveMerchant #:nodoc:
|
|
|
331
333
|
return unless options[:three_d_secure]
|
|
332
334
|
|
|
333
335
|
if options[:three_d_secure][:version] == THREE_DS_V2
|
|
334
|
-
data[:threeDSServerTransID] = options[:three_d_secure][:
|
|
336
|
+
data[:threeDSServerTransID] = options[:three_d_secure][:three_ds_server_trans_id] if options[:three_d_secure][:three_ds_server_trans_id]
|
|
335
337
|
data[:dsTransID] = options[:three_d_secure][:ds_transaction_id] if options[:three_d_secure][:ds_transaction_id]
|
|
336
338
|
data[:authenticacionValue] = options[:three_d_secure][:cavv] if options[:three_d_secure][:cavv]
|
|
337
339
|
data[:protocolVersion] = options[:three_d_secure][:version] if options[:three_d_secure][:version]
|
|
338
|
-
|
|
339
340
|
data[:authenticacionMethod] = options[:authentication_method] if options[:authentication_method]
|
|
340
341
|
data[:authenticacionType] = options[:authentication_type] if options[:authentication_type]
|
|
341
342
|
data[:authenticacionFlow] = options[:authentication_flow] if options[:authentication_flow]
|
|
343
|
+
data[:eci_v2] = options[:three_d_secure][:eci] if options[:three_d_secure][:eci]
|
|
342
344
|
elsif options[:three_d_secure][:version] == THREE_DS_V1
|
|
343
345
|
data[:txid] = options[:three_d_secure][:xid] if options[:three_d_secure][:xid]
|
|
344
346
|
data[:cavv] = options[:three_d_secure][:cavv] if options[:three_d_secure][:cavv]
|
|
345
|
-
data[:
|
|
347
|
+
data[:eci_v1] = options[:three_d_secure][:eci] if options[:three_d_secure][:eci]
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
def add_stored_credential_options(data, options)
|
|
352
|
+
return unless options[:stored_credential]
|
|
353
|
+
|
|
354
|
+
case options[:stored_credential][:initial_transaction]
|
|
355
|
+
when true
|
|
356
|
+
data[:DS_MERCHANT_COF_INI] = 'S'
|
|
357
|
+
when false
|
|
358
|
+
data[:DS_MERCHANT_COF_INI] = 'N'
|
|
359
|
+
data[:DS_MERCHANT_COF_TXNID] = options[:stored_credential][:network_transaction_id] if options[:stored_credential][:network_transaction_id]
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
case options[:stored_credential][:reason_type]
|
|
363
|
+
when 'recurring'
|
|
364
|
+
data[:DS_MERCHANT_COF_TYPE] = 'R'
|
|
365
|
+
when 'installment'
|
|
366
|
+
data[:DS_MERCHANT_COF_TYPE] = 'I'
|
|
367
|
+
when 'unscheduled'
|
|
368
|
+
return
|
|
346
369
|
end
|
|
347
370
|
end
|
|
348
371
|
|
|
@@ -487,6 +510,12 @@ module ActiveMerchant #:nodoc:
|
|
|
487
510
|
xml.DS_MERCHANT_DIRECTPAYMENT 'moto' if options.dig(:moto) && options.dig(:metadata, :manual_entry)
|
|
488
511
|
|
|
489
512
|
xml.DS_MERCHANT_EMV3DS data[:threeds].to_json if data[:threeds]
|
|
513
|
+
|
|
514
|
+
if options[:stored_credential]
|
|
515
|
+
xml.DS_MERCHANT_COF_INI data[:DS_MERCHANT_COF_INI]
|
|
516
|
+
xml.DS_MERCHANT_COF_TYPE data[:DS_MERCHANT_COF_TYPE]
|
|
517
|
+
xml.DS_MERCHANT_COF_TXNID data[:DS_MERCHANT_COF_TXNID] if data[:DS_MERCHANT_COF_TXNID]
|
|
518
|
+
end
|
|
490
519
|
end
|
|
491
520
|
end
|
|
492
521
|
|
|
@@ -496,13 +525,13 @@ module ActiveMerchant #:nodoc:
|
|
|
496
525
|
ds_merchant_mpi_external = {}
|
|
497
526
|
ds_merchant_mpi_external[:TXID] = data[:txid] if data[:txid]
|
|
498
527
|
ds_merchant_mpi_external[:CAVV] = data[:cavv] if data[:cavv]
|
|
499
|
-
ds_merchant_mpi_external[:ECI] = data[:
|
|
528
|
+
ds_merchant_mpi_external[:ECI] = data[:eci_v1] if data[:eci_v1]
|
|
500
529
|
|
|
501
530
|
ds_merchant_mpi_external[:threeDSServerTransID] = data[:threeDSServerTransID] if data[:threeDSServerTransID]
|
|
502
531
|
ds_merchant_mpi_external[:dsTransID] = data[:dsTransID] if data[:dsTransID]
|
|
503
532
|
ds_merchant_mpi_external[:authenticacionValue] = data[:authenticacionValue] if data[:authenticacionValue]
|
|
504
533
|
ds_merchant_mpi_external[:protocolVersion] = data[:protocolVersion] if data[:protocolVersion]
|
|
505
|
-
|
|
534
|
+
ds_merchant_mpi_external[:Eci] = data[:eci_v2] if data[:eci_v2]
|
|
506
535
|
ds_merchant_mpi_external[:authenticacionMethod] = data[:authenticacionMethod] if data[:authenticacionMethod]
|
|
507
536
|
ds_merchant_mpi_external[:authenticacionType] = data[:authenticacionType] if data[:authenticacionType]
|
|
508
537
|
ds_merchant_mpi_external[:authenticacionFlow] = data[:authenticacionFlow] if data[:authenticacionFlow]
|
|
@@ -170,11 +170,13 @@ module ActiveMerchant #:nodoc:
|
|
|
170
170
|
end
|
|
171
171
|
|
|
172
172
|
def add_external_mpi_data(post, options)
|
|
173
|
+
version = options[:three_d_secure][:ds_transaction_id] ? '2' : '1'
|
|
174
|
+
|
|
173
175
|
post[:sg_eci] = options[:three_d_secure][:eci] if options[:three_d_secure][:eci]
|
|
174
176
|
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
|
|
176
|
-
post[:sg_threeDSProtocolVersion] =
|
|
177
|
-
post[:sg_xid] = options[:three_d_secure][:xid]
|
|
177
|
+
post[:sg_dsTransID] = options[:three_d_secure][:ds_transaction_id] if version == '2'
|
|
178
|
+
post[:sg_threeDSProtocolVersion] = version
|
|
179
|
+
post[:sg_xid] = options[:three_d_secure][:xid] if version == '1'
|
|
178
180
|
post[:sg_IsExternalMPI] = 1
|
|
179
181
|
end
|
|
180
182
|
|
|
@@ -30,6 +30,7 @@ module ActiveMerchant #:nodoc:
|
|
|
30
30
|
add_shipping_address(post, options)
|
|
31
31
|
setup_future_usage(post, options)
|
|
32
32
|
add_exemption(post, options)
|
|
33
|
+
add_error_on_requires_action(post, options)
|
|
33
34
|
request_three_d_secure(post, options)
|
|
34
35
|
|
|
35
36
|
CREATE_INTENT_ATTRIBUTES.each do |attribute|
|
|
@@ -269,6 +270,12 @@ module ActiveMerchant #:nodoc:
|
|
|
269
270
|
post[:payment_method_options][:card][:moto] = true if options[:moto]
|
|
270
271
|
end
|
|
271
272
|
|
|
273
|
+
def add_error_on_requires_action(post, options = {})
|
|
274
|
+
return unless options[:confirm]
|
|
275
|
+
|
|
276
|
+
post[:error_on_requires_action] = true if options[:error_on_requires_action]
|
|
277
|
+
end
|
|
278
|
+
|
|
272
279
|
def request_three_d_secure(post, options = {})
|
|
273
280
|
return unless options[:request_three_d_secure] && %w(any automatic).include?(options[:request_three_d_secure])
|
|
274
281
|
|
|
@@ -260,7 +260,10 @@ module ActiveMerchant #:nodoc:
|
|
|
260
260
|
end
|
|
261
261
|
|
|
262
262
|
def add_additional_3ds_data(xml, options)
|
|
263
|
-
|
|
263
|
+
additional_data = { 'dfReferenceId' => options[:session_id] }
|
|
264
|
+
additional_data['challengeWindowSize'] = options[:browser_size] if options[:browser_size]
|
|
265
|
+
|
|
266
|
+
xml.additional3DSData additional_data
|
|
264
267
|
end
|
|
265
268
|
|
|
266
269
|
def add_3ds_exemption(xml, options)
|
|
@@ -4,7 +4,7 @@ module ActiveMerchant #:nodoc:
|
|
|
4
4
|
end
|
|
5
5
|
|
|
6
6
|
class Response
|
|
7
|
-
attr_reader :params, :message, :test, :authorization, :avs_result, :cvv_result, :error_code, :emv_authorization
|
|
7
|
+
attr_reader :params, :message, :test, :authorization, :avs_result, :cvv_result, :error_code, :emv_authorization, :network_transaction_id
|
|
8
8
|
|
|
9
9
|
def success?
|
|
10
10
|
@success
|
|
@@ -25,6 +25,7 @@ module ActiveMerchant #:nodoc:
|
|
|
25
25
|
@fraud_review = options[:fraud_review]
|
|
26
26
|
@error_code = options[:error_code]
|
|
27
27
|
@emv_authorization = options[:emv_authorization]
|
|
28
|
+
@network_transaction_id = options[:network_transaction_id]
|
|
28
29
|
|
|
29
30
|
@avs_result = if options[:avs_result].kind_of?(AVSResult)
|
|
30
31
|
options[:avs_result].to_hash
|
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.118.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:
|
|
11
|
+
date: 2021-01-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|