activemerchant 1.126.0 → 1.129.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 +241 -0
- data/lib/active_merchant/billing/check.rb +40 -8
- data/lib/active_merchant/billing/credit_card.rb +28 -1
- data/lib/active_merchant/billing/credit_card_methods.rb +79 -23
- data/lib/active_merchant/billing/gateways/adyen.rb +67 -8
- data/lib/active_merchant/billing/gateways/airwallex.rb +40 -11
- data/lib/active_merchant/billing/gateways/alelo.rb +256 -0
- data/lib/active_merchant/billing/gateways/authorize_net.rb +21 -4
- data/lib/active_merchant/billing/gateways/beanstream.rb +18 -0
- data/lib/active_merchant/billing/gateways/blue_snap.rb +22 -1
- data/lib/active_merchant/billing/gateways/bogus.rb +4 -0
- data/lib/active_merchant/billing/gateways/borgun.rb +56 -16
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +64 -17
- data/lib/active_merchant/billing/gateways/card_connect.rb +27 -9
- data/lib/active_merchant/billing/gateways/card_stream.rb +23 -0
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +228 -57
- data/lib/active_merchant/billing/gateways/commerce_hub.rb +361 -0
- data/lib/active_merchant/billing/gateways/credorax.rb +47 -27
- data/lib/active_merchant/billing/gateways/cyber_source/cyber_source_common.rb +36 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +100 -26
- data/lib/active_merchant/billing/gateways/cyber_source_rest.rb +456 -0
- data/lib/active_merchant/billing/gateways/d_local.rb +44 -5
- data/lib/active_merchant/billing/gateways/decidir.rb +15 -4
- data/lib/active_merchant/billing/gateways/ebanx.rb +36 -24
- data/lib/active_merchant/billing/gateways/element.rb +21 -1
- data/lib/active_merchant/billing/gateways/global_collect.rb +73 -22
- data/lib/active_merchant/billing/gateways/ipg.rb +13 -8
- data/lib/active_merchant/billing/gateways/iveri.rb +39 -3
- data/lib/active_merchant/billing/gateways/kushki.rb +21 -1
- data/lib/active_merchant/billing/gateways/litle.rb +25 -5
- data/lib/active_merchant/billing/gateways/mastercard.rb +1 -8
- data/lib/active_merchant/billing/gateways/mercado_pago.rb +17 -0
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +44 -10
- data/lib/active_merchant/billing/gateways/monei.rb +2 -0
- data/lib/active_merchant/billing/gateways/moneris.rb +20 -5
- data/lib/active_merchant/billing/gateways/mundipagg.rb +3 -0
- data/lib/active_merchant/billing/gateways/ogone.rb +35 -7
- data/lib/active_merchant/billing/gateways/openpay.rb +20 -3
- data/lib/active_merchant/billing/gateways/orbital.rb +43 -22
- data/lib/active_merchant/billing/gateways/pay_trace.rb +64 -18
- data/lib/active_merchant/billing/gateways/payeezy.rb +59 -4
- data/lib/active_merchant/billing/gateways/paymentez.rb +18 -6
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +4 -0
- data/lib/active_merchant/billing/gateways/paysafe.rb +22 -14
- data/lib/active_merchant/billing/gateways/payu_latam.rb +3 -0
- data/lib/active_merchant/billing/gateways/plexo.rb +308 -0
- data/lib/active_merchant/billing/gateways/priority.rb +29 -6
- data/lib/active_merchant/billing/gateways/rapyd.rb +110 -49
- data/lib/active_merchant/billing/gateways/reach.rb +277 -0
- data/lib/active_merchant/billing/gateways/redsys.rb +9 -5
- data/lib/active_merchant/billing/gateways/sage_pay.rb +1 -1
- data/lib/active_merchant/billing/gateways/securion_pay.rb +40 -0
- data/lib/active_merchant/billing/gateways/shift4.rb +342 -0
- data/lib/active_merchant/billing/gateways/simetrik.rb +28 -22
- data/lib/active_merchant/billing/gateways/stripe.rb +21 -1
- data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +62 -22
- data/lib/active_merchant/billing/gateways/tns.rb +2 -5
- data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +1 -1
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +14 -3
- data/lib/active_merchant/billing/gateways/vanco.rb +12 -3
- data/lib/active_merchant/billing/gateways/visanet_peru.rb +1 -1
- data/lib/active_merchant/billing/gateways/vpos.rb +7 -4
- data/lib/active_merchant/billing/gateways/wompi.rb +8 -4
- data/lib/active_merchant/billing/gateways/worldpay.rb +117 -9
- data/lib/active_merchant/billing/response.rb +15 -1
- data/lib/active_merchant/connection.rb +0 -2
- data/lib/active_merchant/country.rb +1 -0
- data/lib/active_merchant/errors.rb +4 -1
- data/lib/active_merchant/version.rb +1 -1
- metadata +24 -3
@@ -6,18 +6,12 @@ module ActiveMerchant #:nodoc:
|
|
6
6
|
|
7
7
|
self.supported_countries = %w(BR MX CO CL AR PE)
|
8
8
|
self.default_currency = 'USD'
|
9
|
-
self.supported_cardtypes = %i[visa master american_express discover diners_club]
|
9
|
+
self.supported_cardtypes = %i[visa master american_express discover diners_club elo hipercard]
|
10
10
|
|
11
11
|
self.homepage_url = 'http://www.ebanx.com/'
|
12
12
|
self.display_name = 'EBANX'
|
13
13
|
|
14
|
-
|
15
|
-
visa: 'visa',
|
16
|
-
master: 'master_card',
|
17
|
-
american_express: 'amex',
|
18
|
-
discover: 'discover',
|
19
|
-
diners_club: 'diners'
|
20
|
-
}
|
14
|
+
TAGS = ['Spreedly']
|
21
15
|
|
22
16
|
URL_MAP = {
|
23
17
|
purchase: 'direct',
|
@@ -25,7 +19,8 @@ module ActiveMerchant #:nodoc:
|
|
25
19
|
capture: 'capture',
|
26
20
|
refund: 'refund',
|
27
21
|
void: 'cancel',
|
28
|
-
store: 'token'
|
22
|
+
store: 'token',
|
23
|
+
inquire: 'query'
|
29
24
|
}
|
30
25
|
|
31
26
|
HTTP_METHOD = {
|
@@ -34,13 +29,14 @@ module ActiveMerchant #:nodoc:
|
|
34
29
|
capture: :get,
|
35
30
|
refund: :post,
|
36
31
|
void: :get,
|
37
|
-
store: :post
|
32
|
+
store: :post,
|
33
|
+
inquire: :get
|
38
34
|
}
|
39
35
|
|
40
36
|
VERIFY_AMOUNT_PER_COUNTRY = {
|
41
37
|
'br' => 100,
|
42
38
|
'ar' => 100,
|
43
|
-
'co' =>
|
39
|
+
'co' => 50000,
|
44
40
|
'pe' => 300,
|
45
41
|
'mx' => 2000,
|
46
42
|
'cl' => 80000
|
@@ -57,7 +53,7 @@ module ActiveMerchant #:nodoc:
|
|
57
53
|
add_operation(post)
|
58
54
|
add_invoice(post, money, options)
|
59
55
|
add_customer_data(post, payment, options)
|
60
|
-
add_card_or_token(post, payment)
|
56
|
+
add_card_or_token(post, payment, options)
|
61
57
|
add_address(post, options)
|
62
58
|
add_customer_responsible_person(post, payment, options)
|
63
59
|
add_additional_data(post, options)
|
@@ -71,7 +67,7 @@ module ActiveMerchant #:nodoc:
|
|
71
67
|
add_operation(post)
|
72
68
|
add_invoice(post, money, options)
|
73
69
|
add_customer_data(post, payment, options)
|
74
|
-
add_card_or_token(post, payment)
|
70
|
+
add_card_or_token(post, payment, options)
|
75
71
|
add_address(post, options)
|
76
72
|
add_customer_responsible_person(post, payment, options)
|
77
73
|
add_additional_data(post, options)
|
@@ -124,6 +120,14 @@ module ActiveMerchant #:nodoc:
|
|
124
120
|
end
|
125
121
|
end
|
126
122
|
|
123
|
+
def inquire(authorization, options = {})
|
124
|
+
post = {}
|
125
|
+
add_integration_key(post)
|
126
|
+
add_authorization(post, authorization)
|
127
|
+
|
128
|
+
commit(:inquire, post)
|
129
|
+
end
|
130
|
+
|
127
131
|
def supports_scrubbing?
|
128
132
|
true
|
129
133
|
end
|
@@ -151,7 +155,7 @@ module ActiveMerchant #:nodoc:
|
|
151
155
|
|
152
156
|
def add_customer_data(post, payment, options)
|
153
157
|
post[:payment][:name] = customer_name(payment, options)
|
154
|
-
post[:payment][:email] = options[:email]
|
158
|
+
post[:payment][:email] = options[:email]
|
155
159
|
post[:payment][:document] = options[:document]
|
156
160
|
post[:payment][:birth_date] = options[:birth_date] if options[:birth_date]
|
157
161
|
end
|
@@ -186,14 +190,15 @@ module ActiveMerchant #:nodoc:
|
|
186
190
|
post[:payment][:order_number] = options[:order_id][0..39] if options[:order_id]
|
187
191
|
end
|
188
192
|
|
189
|
-
def add_card_or_token(post, payment)
|
190
|
-
payment
|
191
|
-
post[:payment][:payment_type_code] =
|
193
|
+
def add_card_or_token(post, payment, options)
|
194
|
+
payment = payment.split('|')[0] if payment.is_a?(String)
|
195
|
+
post[:payment][:payment_type_code] = 'creditcard'
|
192
196
|
post[:payment][:creditcard] = payment_details(payment)
|
197
|
+
post[:payment][:creditcard][:soft_descriptor] = options[:soft_descriptor] if options[:soft_descriptor]
|
193
198
|
end
|
194
199
|
|
195
200
|
def add_payment_details(post, payment)
|
196
|
-
post[:payment_type_code] =
|
201
|
+
post[:payment_type_code] = 'creditcard'
|
197
202
|
post[:creditcard] = payment_details(payment)
|
198
203
|
end
|
199
204
|
|
@@ -216,6 +221,7 @@ module ActiveMerchant #:nodoc:
|
|
216
221
|
post[:metadata] = {} if post[:metadata].nil?
|
217
222
|
post[:metadata][:merchant_payment_code] = options[:order_id] if options[:order_id]
|
218
223
|
post[:processing_type] = options[:processing_type] if options[:processing_type]
|
224
|
+
post[:payment][:tags] = TAGS
|
219
225
|
end
|
220
226
|
|
221
227
|
def parse(body)
|
@@ -253,13 +259,15 @@ module ActiveMerchant #:nodoc:
|
|
253
259
|
end
|
254
260
|
|
255
261
|
def success_from(action, response)
|
262
|
+
payment_status = response.try(:[], 'payment').try(:[], 'status')
|
263
|
+
|
256
264
|
if %i[purchase capture refund].include?(action)
|
257
|
-
|
265
|
+
payment_status == 'CO'
|
258
266
|
elsif action == :authorize
|
259
|
-
|
267
|
+
payment_status == 'PE'
|
260
268
|
elsif action == :void
|
261
|
-
|
262
|
-
elsif action
|
269
|
+
payment_status == 'CA'
|
270
|
+
elsif %i[store inquire].include?(action)
|
263
271
|
response.try(:[], 'status') == 'SUCCESS'
|
264
272
|
else
|
265
273
|
false
|
@@ -274,7 +282,11 @@ module ActiveMerchant #:nodoc:
|
|
274
282
|
|
275
283
|
def authorization_from(action, parameters, response)
|
276
284
|
if action == :store
|
277
|
-
|
285
|
+
if success_from(action, response)
|
286
|
+
"#{response.try(:[], 'token')}|#{response['payment_type_code']}"
|
287
|
+
else
|
288
|
+
response.try(:[], 'token')
|
289
|
+
end
|
278
290
|
else
|
279
291
|
response.try(:[], 'payment').try(:[], 'hash')
|
280
292
|
end
|
@@ -294,7 +306,7 @@ module ActiveMerchant #:nodoc:
|
|
294
306
|
end
|
295
307
|
|
296
308
|
def requires_http_get(action)
|
297
|
-
return true if %i[capture void].include?(action)
|
309
|
+
return true if %i[capture void inquire].include?(action)
|
298
310
|
|
299
311
|
false
|
300
312
|
end
|
@@ -17,6 +17,11 @@ module ActiveMerchant #:nodoc:
|
|
17
17
|
SERVICE_TEST_URL = 'https://certservices.elementexpress.com/express.asmx'
|
18
18
|
SERVICE_LIVE_URL = 'https://services.elementexpress.com/express.asmx'
|
19
19
|
|
20
|
+
NETWORK_TOKEN_TYPE = {
|
21
|
+
apple_pay: '2',
|
22
|
+
google_pay: '1'
|
23
|
+
}
|
24
|
+
|
20
25
|
def initialize(options = {})
|
21
26
|
requires!(options, :account_id, :account_token, :application_id, :acceptor_id, :application_name, :application_version)
|
22
27
|
super
|
@@ -171,6 +176,8 @@ module ActiveMerchant #:nodoc:
|
|
171
176
|
add_payment_account_id(xml, payment)
|
172
177
|
elsif payment.is_a?(Check)
|
173
178
|
add_echeck(xml, payment)
|
179
|
+
elsif payment.is_a?(NetworkTokenizationCreditCard)
|
180
|
+
add_network_tokenization_card(xml, payment)
|
174
181
|
else
|
175
182
|
add_credit_card(xml, payment)
|
176
183
|
end
|
@@ -200,7 +207,7 @@ module ActiveMerchant #:nodoc:
|
|
200
207
|
xml.TransactionID options[:trans_id] if options[:trans_id]
|
201
208
|
xml.TransactionAmount amount(money.to_i) if money
|
202
209
|
xml.MarketCode market_code(money, options) if options[:market_code] || money
|
203
|
-
xml.ReferenceNumber options[:order_id]
|
210
|
+
xml.ReferenceNumber options[:order_id].present? ? options[:order_id][0, 50] : SecureRandom.hex(20)
|
204
211
|
xml.TicketNumber options[:ticket_number] if options[:ticket_number]
|
205
212
|
xml.MerchantSuppliedTransactionId options[:merchant_supplied_transaction_id] if options[:merchant_supplied_transaction_id]
|
206
213
|
xml.PaymentType options[:payment_type] if options[:payment_type]
|
@@ -246,8 +253,21 @@ module ActiveMerchant #:nodoc:
|
|
246
253
|
end
|
247
254
|
end
|
248
255
|
|
256
|
+
def add_network_tokenization_card(xml, payment)
|
257
|
+
xml.card do
|
258
|
+
xml.CardNumber payment.number
|
259
|
+
xml.ExpirationMonth format(payment.month, :two_digits)
|
260
|
+
xml.ExpirationYear format(payment.year, :two_digits)
|
261
|
+
xml.CardholderName "#{payment.first_name} #{payment.last_name}"
|
262
|
+
xml.Cryptogram payment.payment_cryptogram
|
263
|
+
xml.ElectronicCommerceIndicator payment.eci if payment.eci.present?
|
264
|
+
xml.WalletType NETWORK_TOKEN_TYPE.fetch(payment.source, '0')
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
249
268
|
def add_address(xml, options)
|
250
269
|
if address = options[:billing_address] || options[:address]
|
270
|
+
address[:email] ||= options[:email]
|
251
271
|
xml.address do
|
252
272
|
xml.BillingAddress1 address[:address1] if address[:address1]
|
253
273
|
xml.BillingAddress2 address[:address2] if address[:address2]
|
@@ -36,7 +36,7 @@ module ActiveMerchant #:nodoc:
|
|
36
36
|
add_creator_info(post, options)
|
37
37
|
add_fraud_fields(post, options)
|
38
38
|
add_external_cardholder_authentication_data(post, options)
|
39
|
-
commit(:authorize, post, options: options)
|
39
|
+
commit(:post, :authorize, post, options: options)
|
40
40
|
end
|
41
41
|
|
42
42
|
def capture(money, authorization, options = {})
|
@@ -44,7 +44,7 @@ module ActiveMerchant #:nodoc:
|
|
44
44
|
add_order(post, money, options, capture: true)
|
45
45
|
add_customer_data(post, options)
|
46
46
|
add_creator_info(post, options)
|
47
|
-
commit(:capture, post, authorization: authorization)
|
47
|
+
commit(:post, :capture, post, authorization: authorization)
|
48
48
|
end
|
49
49
|
|
50
50
|
def refund(money, authorization, options = {})
|
@@ -52,13 +52,13 @@ module ActiveMerchant #:nodoc:
|
|
52
52
|
add_amount(post, money, options)
|
53
53
|
add_refund_customer_data(post, options)
|
54
54
|
add_creator_info(post, options)
|
55
|
-
commit(:refund, post, authorization: authorization)
|
55
|
+
commit(:post, :refund, post, authorization: authorization)
|
56
56
|
end
|
57
57
|
|
58
58
|
def void(authorization, options = {})
|
59
59
|
post = nestable_hash
|
60
60
|
add_creator_info(post, options)
|
61
|
-
commit(:void, post, authorization: authorization)
|
61
|
+
commit(:post, :void, post, authorization: authorization)
|
62
62
|
end
|
63
63
|
|
64
64
|
def verify(payment, options = {})
|
@@ -68,6 +68,10 @@ module ActiveMerchant #:nodoc:
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
+
def inquire(authorization, options = {})
|
72
|
+
commit(:get, :inquire, nil, authorization: authorization)
|
73
|
+
end
|
74
|
+
|
71
75
|
def supports_scrubbing?
|
72
76
|
true
|
73
77
|
end
|
@@ -76,7 +80,10 @@ module ActiveMerchant #:nodoc:
|
|
76
80
|
transcript.
|
77
81
|
gsub(%r((Authorization: )[^\\]*)i, '\1[FILTERED]').
|
78
82
|
gsub(%r(("cardNumber\\+":\\+")\d+), '\1[FILTERED]').
|
79
|
-
gsub(%r(("cvv\\+":\\+")\d+), '\1[FILTERED]')
|
83
|
+
gsub(%r(("cvv\\+":\\+")\d+), '\1[FILTERED]').
|
84
|
+
gsub(%r(("dpan\\+":\\+")\d+), '\1[FILTERED]').
|
85
|
+
gsub(%r(("pan\\+":\\+")\d+), '\1[FILTERED]').
|
86
|
+
gsub(%r(("cryptogram\\+":\\+"|("cavv\\+" : \\+"))[^\\]*), '\1[FILTERED]')
|
80
87
|
end
|
81
88
|
|
82
89
|
private
|
@@ -89,7 +96,9 @@ module ActiveMerchant #:nodoc:
|
|
89
96
|
'jcb' => '125',
|
90
97
|
'diners_club' => '132',
|
91
98
|
'cabal' => '135',
|
92
|
-
'naranja' => '136'
|
99
|
+
'naranja' => '136',
|
100
|
+
'apple_pay': '302',
|
101
|
+
'google_pay': '320'
|
93
102
|
}
|
94
103
|
|
95
104
|
def add_order(post, money, options, capture: false)
|
@@ -250,20 +259,58 @@ module ActiveMerchant #:nodoc:
|
|
250
259
|
month = format(payment.month, :two_digits)
|
251
260
|
expirydate = "#{month}#{year}"
|
252
261
|
pre_authorization = options[:pre_authorization] ? 'PRE_AUTHORIZATION' : 'FINAL_AUTHORIZATION'
|
253
|
-
|
254
|
-
|
262
|
+
product_id = options[:payment_product_id] || BRAND_MAP[payment.brand]
|
263
|
+
specifics_inputs = {
|
264
|
+
'paymentProductId' => product_id,
|
255
265
|
'skipAuthentication' => 'true', # refers to 3DSecure
|
256
266
|
'skipFraudService' => 'true',
|
257
267
|
'authorizationMode' => pre_authorization
|
258
268
|
}
|
259
|
-
|
269
|
+
specifics_inputs['requiresApproval'] = options[:requires_approval] unless options[:requires_approval].nil?
|
270
|
+
if payment.is_a?(NetworkTokenizationCreditCard)
|
271
|
+
add_mobile_credit_card(post, payment, options, specifics_inputs, expirydate)
|
272
|
+
elsif payment.is_a?(CreditCard)
|
273
|
+
options[:google_pay_pan_only] ? add_mobile_credit_card(post, payment, options, specifics_inputs, expirydate) : add_credit_card(post, payment, specifics_inputs, expirydate)
|
274
|
+
end
|
275
|
+
end
|
260
276
|
|
261
|
-
|
262
|
-
|
263
|
-
'
|
264
|
-
|
265
|
-
|
266
|
-
|
277
|
+
def add_credit_card(post, payment, specifics_inputs, expirydate)
|
278
|
+
post['cardPaymentMethodSpecificInput'] = specifics_inputs.merge({
|
279
|
+
'card' => {
|
280
|
+
'cvv' => payment.verification_value,
|
281
|
+
'cardNumber' => payment.number,
|
282
|
+
'expiryDate' => expirydate,
|
283
|
+
'cardholderName' => payment.name
|
284
|
+
}
|
285
|
+
})
|
286
|
+
end
|
287
|
+
|
288
|
+
def add_mobile_credit_card(post, payment, options, specifics_inputs, expirydate)
|
289
|
+
specifics_inputs['paymentProductId'] = options[:google_pay_pan_only] ? BRAND_MAP[:google_pay] : BRAND_MAP[payment.source]
|
290
|
+
post['mobilePaymentMethodSpecificInput'] = specifics_inputs
|
291
|
+
add_decrypted_payment_data(post, payment, options, expirydate)
|
292
|
+
end
|
293
|
+
|
294
|
+
def add_decrypted_payment_data(post, payment, options, expirydate)
|
295
|
+
if payment.is_a?(NetworkTokenizationCreditCard) && payment.payment_cryptogram
|
296
|
+
data = {
|
297
|
+
'cardholderName' => payment.name,
|
298
|
+
'cryptogram' => payment.payment_cryptogram,
|
299
|
+
'eci' => payment.eci,
|
300
|
+
'expiryDate' => expirydate,
|
301
|
+
'dpan' => payment.number
|
302
|
+
}
|
303
|
+
data['paymentMethod'] = 'TOKENIZED_CARD' if payment.source == :google_pay
|
304
|
+
# else case when google payment is an ONLY_PAN, doesn't have cryptogram or eci.
|
305
|
+
elsif options[:google_pay_pan_only]
|
306
|
+
data = {
|
307
|
+
'cardholderName' => payment.name,
|
308
|
+
'expiryDate' => expirydate,
|
309
|
+
'pan' => payment.number,
|
310
|
+
'paymentMethod' => 'CARD'
|
311
|
+
}
|
312
|
+
end
|
313
|
+
post['mobilePaymentMethodSpecificInput']['decryptedPaymentData'] = data if data
|
267
314
|
end
|
268
315
|
|
269
316
|
def add_customer_data(post, options, payment = nil)
|
@@ -370,6 +417,8 @@ module ActiveMerchant #:nodoc:
|
|
370
417
|
uri + "payments/#{authorization}/refund"
|
371
418
|
when :void
|
372
419
|
uri + "payments/#{authorization}/cancel"
|
420
|
+
when :inquire
|
421
|
+
uri + "payments/#{authorization}"
|
373
422
|
end
|
374
423
|
end
|
375
424
|
|
@@ -377,9 +426,9 @@ module ActiveMerchant #:nodoc:
|
|
377
426
|
"x-gcs-idempotence-key:#{options[:idempotency_key]}" if options[:idempotency_key]
|
378
427
|
end
|
379
428
|
|
380
|
-
def commit(action, post, authorization: nil, options: {})
|
429
|
+
def commit(method, action, post, authorization: nil, options: {})
|
381
430
|
begin
|
382
|
-
raw_response =
|
431
|
+
raw_response = ssl_request(method, url(action, authorization), post&.to_json, headers(method, action, post, authorization, options))
|
383
432
|
response = parse(raw_response)
|
384
433
|
rescue ResponseError => e
|
385
434
|
response = parse(e.response.body) if e.response.code.to_i >= 400
|
@@ -405,10 +454,10 @@ module ActiveMerchant #:nodoc:
|
|
405
454
|
}
|
406
455
|
end
|
407
456
|
|
408
|
-
def headers(action, post, authorization = nil, options = {})
|
457
|
+
def headers(method, action, post, authorization = nil, options = {})
|
409
458
|
headers = {
|
410
459
|
'Content-Type' => content_type,
|
411
|
-
'Authorization' => auth_digest(action, post, authorization, options),
|
460
|
+
'Authorization' => auth_digest(method, action, post, authorization, options),
|
412
461
|
'Date' => date
|
413
462
|
}
|
414
463
|
|
@@ -416,9 +465,9 @@ module ActiveMerchant #:nodoc:
|
|
416
465
|
headers
|
417
466
|
end
|
418
467
|
|
419
|
-
def auth_digest(action, post, authorization = nil, options = {})
|
468
|
+
def auth_digest(method, action, post, authorization = nil, options = {})
|
420
469
|
data = <<~REQUEST
|
421
|
-
|
470
|
+
#{method.to_s.upcase}
|
422
471
|
#{content_type}
|
423
472
|
#{date}
|
424
473
|
#{idempotency_key_for_signature(options)}
|
@@ -431,7 +480,7 @@ module ActiveMerchant #:nodoc:
|
|
431
480
|
end
|
432
481
|
|
433
482
|
def date
|
434
|
-
@date ||= Time.now.strftime('%a, %d %b %Y %H:%M:%S %Z') # Must be same in digest and HTTP header
|
483
|
+
@date ||= Time.now.gmtime.strftime('%a, %d %b %Y %H:%M:%S %Z') # Must be same in digest and HTTP header
|
435
484
|
end
|
436
485
|
|
437
486
|
def content_type
|
@@ -441,6 +490,8 @@ module ActiveMerchant #:nodoc:
|
|
441
490
|
def success_from(action, response)
|
442
491
|
return false if response['errorId'] || response['error_message']
|
443
492
|
|
493
|
+
return %w(CAPTURED CAPTURE_REQUESTED).include?(response.dig('payment', 'status')) if response.dig('payment', 'paymentOutput', 'paymentMethod') == 'mobile'
|
494
|
+
|
444
495
|
case action
|
445
496
|
when :authorize
|
446
497
|
response.dig('payment', 'statusOutput', 'isAuthorized')
|
@@ -27,32 +27,32 @@ module ActiveMerchant #:nodoc:
|
|
27
27
|
def purchase(money, payment, options = {})
|
28
28
|
xml = build_purchase_and_authorize_request(money, payment, options)
|
29
29
|
|
30
|
-
commit('sale', xml)
|
30
|
+
commit('sale', xml, options)
|
31
31
|
end
|
32
32
|
|
33
33
|
def authorize(money, payment, options = {})
|
34
34
|
xml = build_purchase_and_authorize_request(money, payment, options)
|
35
35
|
|
36
|
-
commit('preAuth', xml)
|
36
|
+
commit('preAuth', xml, options)
|
37
37
|
end
|
38
38
|
|
39
39
|
def capture(money, authorization, options = {})
|
40
40
|
xml = build_capture_and_refund_request(money, authorization, options)
|
41
41
|
|
42
|
-
commit('postAuth', xml)
|
42
|
+
commit('postAuth', xml, options)
|
43
43
|
end
|
44
44
|
|
45
45
|
def refund(money, authorization, options = {})
|
46
46
|
xml = build_capture_and_refund_request(money, authorization, options)
|
47
47
|
|
48
|
-
commit('return', xml)
|
48
|
+
commit('return', xml, options)
|
49
49
|
end
|
50
50
|
|
51
51
|
def void(authorization, options = {})
|
52
52
|
xml = Builder::XmlMarkup.new(indent: 2)
|
53
53
|
add_transaction_details(xml, options.merge!({ order_id: authorization }))
|
54
54
|
|
55
|
-
commit('void', xml)
|
55
|
+
commit('void', xml, options)
|
56
56
|
end
|
57
57
|
|
58
58
|
def store(credit_card, options = {})
|
@@ -60,7 +60,7 @@ module ActiveMerchant #:nodoc:
|
|
60
60
|
xml = Builder::XmlMarkup.new(indent: 2)
|
61
61
|
add_storage_item(xml, credit_card, options)
|
62
62
|
|
63
|
-
commit('vault', xml)
|
63
|
+
commit('vault', xml, options)
|
64
64
|
end
|
65
65
|
|
66
66
|
def unstore(hosted_data_id)
|
@@ -343,7 +343,12 @@ module ActiveMerchant #:nodoc:
|
|
343
343
|
}
|
344
344
|
end
|
345
345
|
|
346
|
-
def
|
346
|
+
def override_store_id(options)
|
347
|
+
@credentials[:store_id] = options[:store_id] if options[:store_id].present?
|
348
|
+
end
|
349
|
+
|
350
|
+
def commit(action, request, options = {})
|
351
|
+
override_store_id(options)
|
347
352
|
url = (test? ? test_url : live_url)
|
348
353
|
soap_request = build_soap_request(action, request)
|
349
354
|
response = parse(ssl_post(url, soap_request, build_header))
|
@@ -391,7 +396,7 @@ module ActiveMerchant #:nodoc:
|
|
391
396
|
end
|
392
397
|
|
393
398
|
def message_from(response)
|
394
|
-
response[:TransactionResult]
|
399
|
+
[response[:TransactionResult], response[:ErrorMessage]&.split(':')&.last&.strip].compact.join(', ')
|
395
400
|
end
|
396
401
|
|
397
402
|
def authorization_from(action, response)
|
@@ -3,7 +3,10 @@ require 'nokogiri'
|
|
3
3
|
module ActiveMerchant #:nodoc:
|
4
4
|
module Billing #:nodoc:
|
5
5
|
class IveriGateway < Gateway
|
6
|
+
class_attribute :iveri_url
|
7
|
+
|
6
8
|
self.live_url = self.test_url = 'https://portal.nedsecure.co.za/iVeriWebService/Service.asmx'
|
9
|
+
self.iveri_url = 'https://portal.host.iveri.com/iVeriWebService/Service.asmx'
|
7
10
|
|
8
11
|
self.supported_countries = %w[US ZA GB]
|
9
12
|
self.default_currency = 'ZAR'
|
@@ -91,7 +94,7 @@ module ActiveMerchant #:nodoc:
|
|
91
94
|
xml[:soap].Envelope 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema', 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/' do
|
92
95
|
xml[:soap].Body do
|
93
96
|
xml.Execute 'xmlns' => 'http://iveri.com/' do
|
94
|
-
xml.validateRequest
|
97
|
+
xml.validateRequest('false')
|
95
98
|
xml.protocol 'V_XML'
|
96
99
|
xml.protocolVersion '2.0'
|
97
100
|
xml.request vxml
|
@@ -118,8 +121,9 @@ module ActiveMerchant #:nodoc:
|
|
118
121
|
def add_auth_purchase_params(post, money, payment_method, options)
|
119
122
|
add_card_holder_authentication(post, options)
|
120
123
|
add_amount(post, money, options)
|
121
|
-
add_electronic_commerce_indicator(post, options)
|
124
|
+
add_electronic_commerce_indicator(post, options) unless options[:three_d_secure]
|
122
125
|
add_payment_method(post, payment_method, options)
|
126
|
+
add_three_ds(post, options)
|
123
127
|
end
|
124
128
|
|
125
129
|
def add_amount(post, money, options)
|
@@ -156,7 +160,7 @@ module ActiveMerchant #:nodoc:
|
|
156
160
|
def commit(post)
|
157
161
|
raw_response =
|
158
162
|
begin
|
159
|
-
ssl_post(
|
163
|
+
ssl_post(url, build_xml_envelope(post), headers(post))
|
160
164
|
rescue ActiveMerchant::ResponseError => e
|
161
165
|
e.response.body
|
162
166
|
end
|
@@ -178,6 +182,10 @@ module ActiveMerchant #:nodoc:
|
|
178
182
|
test? ? 'Test' : 'Live'
|
179
183
|
end
|
180
184
|
|
185
|
+
def url
|
186
|
+
@options[:url_override].to_s == 'iveri' ? iveri_url : live_url
|
187
|
+
end
|
188
|
+
|
181
189
|
def headers(post)
|
182
190
|
{
|
183
191
|
'Content-Type' => 'text/xml; charset=utf-8',
|
@@ -249,6 +257,34 @@ module ActiveMerchant #:nodoc:
|
|
249
257
|
tr('-', '_').
|
250
258
|
downcase
|
251
259
|
end
|
260
|
+
|
261
|
+
def add_three_ds(post, options)
|
262
|
+
return unless three_d_secure = options[:three_d_secure]
|
263
|
+
|
264
|
+
post.ElectronicCommerceIndicator(formatted_three_ds_eci(three_d_secure[:eci])) if three_d_secure[:eci]
|
265
|
+
post.CardHolderAuthenticationID(three_d_secure[:xid]) if three_d_secure[:xid]
|
266
|
+
post.CardHolderAuthenticationData(three_d_secure[:cavv]) if three_d_secure[:cavv]
|
267
|
+
post.ThreeDSecure_ProtocolVersion(three_d_secure[:version]) if three_d_secure[:version]
|
268
|
+
post.ThreeDSecure_DSTransID(three_d_secure[:ds_transaction_id]) if three_d_secure[:ds_transaction_id]
|
269
|
+
post.ThreeDSecure_VEResEnrolled(formatted_enrollment(three_d_secure[:enrolled])) if three_d_secure[:enrolled]
|
270
|
+
end
|
271
|
+
|
272
|
+
def formatted_enrollment(val)
|
273
|
+
case val
|
274
|
+
when 'Y', 'N', 'U' then val
|
275
|
+
when true, 'true' then 'Y'
|
276
|
+
when false, 'false' then 'N'
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
def formatted_three_ds_eci(val)
|
281
|
+
case val
|
282
|
+
when '05', '02' then 'ThreeDSecure'
|
283
|
+
when '06', '01' then 'ThreeDSecureAttempted'
|
284
|
+
when '07' then 'SecureChannel'
|
285
|
+
else val
|
286
|
+
end
|
287
|
+
end
|
252
288
|
end
|
253
289
|
end
|
254
290
|
end
|
@@ -83,6 +83,8 @@ module ActiveMerchant #:nodoc:
|
|
83
83
|
add_payment_method(post, payment_method, options)
|
84
84
|
add_full_response(post, options)
|
85
85
|
add_metadata(post, options)
|
86
|
+
add_months(post, options)
|
87
|
+
add_deferred(post, options)
|
86
88
|
|
87
89
|
commit(action, post)
|
88
90
|
end
|
@@ -96,6 +98,8 @@ module ActiveMerchant #:nodoc:
|
|
96
98
|
add_contact_details(post, options[:contact_details]) if options[:contact_details]
|
97
99
|
add_full_response(post, options)
|
98
100
|
add_metadata(post, options)
|
101
|
+
add_months(post, options)
|
102
|
+
add_deferred(post, options)
|
99
103
|
|
100
104
|
commit(action, post)
|
101
105
|
end
|
@@ -108,6 +112,8 @@ module ActiveMerchant #:nodoc:
|
|
108
112
|
add_invoice(action, post, amount, options)
|
109
113
|
add_full_response(post, options)
|
110
114
|
add_metadata(post, options)
|
115
|
+
add_months(post, options)
|
116
|
+
add_deferred(post, options)
|
111
117
|
|
112
118
|
commit(action, post)
|
113
119
|
end
|
@@ -140,7 +146,7 @@ module ActiveMerchant #:nodoc:
|
|
140
146
|
sum[:iva] = amount[:iva].to_f if amount[:iva]
|
141
147
|
sum[:subtotalIva0] = amount[:subtotal_iva_0].to_f if amount[:subtotal_iva_0]
|
142
148
|
sum[:ice] = amount[:ice].to_f if amount[:ice]
|
143
|
-
if (extra_taxes = amount[:extra_taxes])
|
149
|
+
if (extra_taxes = amount[:extra_taxes])
|
144
150
|
sum[:extraTaxes] ||= Hash.new
|
145
151
|
sum[:extraTaxes][:propina] = extra_taxes[:propina].to_f if extra_taxes[:propina]
|
146
152
|
sum[:extraTaxes][:tasaAeroportuaria] = extra_taxes[:tasa_aeroportuaria].to_f if extra_taxes[:tasa_aeroportuaria]
|
@@ -184,6 +190,20 @@ module ActiveMerchant #:nodoc:
|
|
184
190
|
post[:metadata] = options[:metadata] if options[:metadata]
|
185
191
|
end
|
186
192
|
|
193
|
+
def add_months(post, options)
|
194
|
+
post[:months] = options[:months] if options[:months]
|
195
|
+
end
|
196
|
+
|
197
|
+
def add_deferred(post, options)
|
198
|
+
return unless options[:deferred_grace_months] && options[:deferred_credit_type] && options[:deferred_months]
|
199
|
+
|
200
|
+
post[:deferred] = {
|
201
|
+
graceMonths: options[:deferred_grace_months],
|
202
|
+
creditType: options[:deferred_credit_type],
|
203
|
+
months: options[:deferred_months]
|
204
|
+
}
|
205
|
+
end
|
206
|
+
|
187
207
|
ENDPOINT = {
|
188
208
|
'tokenize' => 'tokens',
|
189
209
|
'charge' => 'charges',
|