activemerchant 1.126.0 → 1.129.0
Sign up to get free protection for your applications and to get access to all the features.
- 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',
|