activemerchant 1.125.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 +316 -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 +91 -23
- data/lib/active_merchant/billing/gateway.rb +2 -1
- data/lib/active_merchant/billing/gateways/adyen.rb +74 -12
- data/lib/active_merchant/billing/gateways/airwallex.rb +370 -0
- 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/barclaycard_smartpay.rb +2 -1
- data/lib/active_merchant/billing/gateways/beanstream.rb +18 -0
- data/lib/active_merchant/billing/gateways/blue_pay.rb +1 -1
- data/lib/active_merchant/billing/gateways/blue_snap.rb +53 -22
- 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/braintree_common.rb +6 -1
- data/lib/active_merchant/billing/gateways/braintree/token_nonce.rb +113 -0
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +151 -32
- data/lib/active_merchant/billing/gateways/card_connect.rb +28 -10
- 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 +56 -26
- data/lib/active_merchant/billing/gateways/cyber_source/cyber_source_common.rb +36 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +112 -58
- data/lib/active_merchant/billing/gateways/cyber_source_rest.rb +456 -0
- data/lib/active_merchant/billing/gateways/d_local.rb +93 -5
- data/lib/active_merchant/billing/gateways/decidir.rb +32 -5
- data/lib/active_merchant/billing/gateways/decidir_plus.rb +185 -14
- data/lib/active_merchant/billing/gateways/ebanx.rb +39 -26
- data/lib/active_merchant/billing/gateways/element.rb +21 -1
- data/lib/active_merchant/billing/gateways/global_collect.rb +98 -37
- data/lib/active_merchant/billing/gateways/ipg.rb +14 -10
- 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 +118 -6
- 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 +55 -13
- data/lib/active_merchant/billing/gateways/mundipagg.rb +3 -0
- data/lib/active_merchant/billing/gateways/nmi.rb +12 -7
- 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 +378 -335
- 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/payflow.rb +62 -0
- data/lib/active_merchant/billing/gateways/paymentez.rb +44 -13
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +4 -0
- data/lib/active_merchant/billing/gateways/paysafe.rb +37 -29
- data/lib/active_merchant/billing/gateways/payu_latam.rb +28 -15
- data/lib/active_merchant/billing/gateways/plexo.rb +308 -0
- data/lib/active_merchant/billing/gateways/priority.rb +185 -140
- data/lib/active_merchant/billing/gateways/rapyd.rb +319 -0
- 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/safe_charge.rb +1 -4
- 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 +368 -0
- data/lib/active_merchant/billing/gateways/stripe.rb +25 -3
- data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +155 -70
- 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 +6 -2
- 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 +28 -3
@@ -218,14 +218,7 @@ module ActiveMerchant
|
|
218
218
|
|
219
219
|
def base_url
|
220
220
|
if test?
|
221
|
-
|
222
|
-
when 'asia_pacific'
|
223
|
-
test_ap_url
|
224
|
-
when 'europe'
|
225
|
-
test_eu_url
|
226
|
-
when 'north_america', nil
|
227
|
-
test_na_url
|
228
|
-
end
|
221
|
+
test_url
|
229
222
|
else
|
230
223
|
case @options[:region]
|
231
224
|
when 'asia_pacific'
|
@@ -61,6 +61,10 @@ module ActiveMerchant #:nodoc:
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
+
def inquire(authorization, options = {})
|
65
|
+
commit('inquire', inquire_path(authorization, options), {})
|
66
|
+
end
|
67
|
+
|
64
68
|
def supports_scrubbing?
|
65
69
|
true
|
66
70
|
end
|
@@ -261,6 +265,10 @@ module ActiveMerchant #:nodoc:
|
|
261
265
|
def commit(action, path, parameters)
|
262
266
|
if %w[capture void].include?(action)
|
263
267
|
response = parse(ssl_request(:put, url(path), post_data(parameters), headers))
|
268
|
+
elsif action == 'inquire'
|
269
|
+
response = parse(ssl_get(url(path), headers))
|
270
|
+
|
271
|
+
response = response[0]['results'][0] if response.is_a?(Array)
|
264
272
|
else
|
265
273
|
response = parse(ssl_post(url(path), post_data(parameters), headers(parameters)))
|
266
274
|
end
|
@@ -295,6 +303,15 @@ module ActiveMerchant #:nodoc:
|
|
295
303
|
parameters.clone.tap { |p| p.delete(:device_id) }.to_json
|
296
304
|
end
|
297
305
|
|
306
|
+
def inquire_path(authorization, options)
|
307
|
+
if authorization
|
308
|
+
authorization, = authorization.split('|')
|
309
|
+
"payments/#{authorization}"
|
310
|
+
else
|
311
|
+
"payments/search?external_reference=#{options[:order_id] || options[:external_reference]}"
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
298
315
|
def error_code_from(action, response)
|
299
316
|
unless success_from(action, response)
|
300
317
|
if cause = response['cause']
|
@@ -18,6 +18,8 @@ module ActiveMerchant #:nodoc:
|
|
18
18
|
# The name of the gateway
|
19
19
|
self.display_name = 'Merchant e-Solutions'
|
20
20
|
|
21
|
+
SUCCESS_RESPONSE_CODES = %w(000 085)
|
22
|
+
|
21
23
|
def initialize(options = {})
|
22
24
|
requires!(options, :login, :password)
|
23
25
|
super
|
@@ -25,23 +27,21 @@ module ActiveMerchant #:nodoc:
|
|
25
27
|
|
26
28
|
def authorize(money, creditcard_or_card_id, options = {})
|
27
29
|
post = {}
|
28
|
-
post[:client_reference_number] = options[:customer] if options.has_key?(:customer)
|
29
|
-
post[:moto_ecommerce_ind] = options[:moto_ecommerce_ind] if options.has_key?(:moto_ecommerce_ind)
|
30
30
|
add_invoice(post, options)
|
31
31
|
add_payment_source(post, creditcard_or_card_id, options)
|
32
32
|
add_address(post, options)
|
33
33
|
add_3dsecure_params(post, options)
|
34
|
+
add_stored_credentials(post, options)
|
34
35
|
commit('P', money, post)
|
35
36
|
end
|
36
37
|
|
37
38
|
def purchase(money, creditcard_or_card_id, options = {})
|
38
39
|
post = {}
|
39
|
-
post[:client_reference_number] = options[:customer] if options.has_key?(:customer)
|
40
|
-
post[:moto_ecommerce_ind] = options[:moto_ecommerce_ind] if options.has_key?(:moto_ecommerce_ind)
|
41
40
|
add_invoice(post, options)
|
42
41
|
add_payment_source(post, creditcard_or_card_id, options)
|
43
42
|
add_address(post, options)
|
44
43
|
add_3dsecure_params(post, options)
|
44
|
+
add_stored_credentials(post, options)
|
45
45
|
commit('D', money, post)
|
46
46
|
end
|
47
47
|
|
@@ -55,10 +55,10 @@ module ActiveMerchant #:nodoc:
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def store(creditcard, options = {})
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
58
|
+
MultiResponse.run do |r|
|
59
|
+
r.process { temporary_store(creditcard, options) }
|
60
|
+
r.process { verify(r.authorization, { store_card: 'y' }) }
|
61
|
+
end
|
62
62
|
end
|
63
63
|
|
64
64
|
def unstore(card_id, options = {})
|
@@ -94,6 +94,13 @@ module ActiveMerchant #:nodoc:
|
|
94
94
|
commit('V', nil, options.merge(post))
|
95
95
|
end
|
96
96
|
|
97
|
+
def verify(credit_card, options = {})
|
98
|
+
post = {}
|
99
|
+
post[:store_card] = options[:store_card] if options[:store_card]
|
100
|
+
add_payment_source(post, credit_card, options)
|
101
|
+
commit('A', 0, post)
|
102
|
+
end
|
103
|
+
|
97
104
|
def supports_scrubbing?
|
98
105
|
true
|
99
106
|
end
|
@@ -107,6 +114,13 @@ module ActiveMerchant #:nodoc:
|
|
107
114
|
|
108
115
|
private
|
109
116
|
|
117
|
+
def temporary_store(creditcard, options = {})
|
118
|
+
post = {}
|
119
|
+
post[:client_reference_number] = options[:customer] if options.has_key?(:customer)
|
120
|
+
add_creditcard(post, creditcard, options)
|
121
|
+
commit('T', nil, post)
|
122
|
+
end
|
123
|
+
|
110
124
|
def add_address(post, options)
|
111
125
|
if address = options[:billing_address] || options[:address]
|
112
126
|
post[:cardholder_street_address] = address[:address1].to_s.gsub(/[^\w.]/, '+')
|
@@ -145,6 +159,16 @@ module ActiveMerchant #:nodoc:
|
|
145
159
|
post[:ucaf_auth_data] = options[:ucaf_auth_data] unless empty?(options[:ucaf_auth_data])
|
146
160
|
end
|
147
161
|
|
162
|
+
def add_stored_credentials(post, options)
|
163
|
+
post[:client_reference_number] = options[:client_reference_number] if options[:client_reference_number]
|
164
|
+
post[:moto_ecommerce_ind] = options[:moto_ecommerce_ind] if options[:moto_ecommerce_ind]
|
165
|
+
post[:recurring_pmt_num] = options[:recurring_pmt_num] if options[:recurring_pmt_num]
|
166
|
+
post[:recurring_pmt_count] = options[:recurring_pmt_count] if options[:recurring_pmt_count]
|
167
|
+
post[:card_on_file] = options[:card_on_file] if options[:card_on_file]
|
168
|
+
post[:cit_mit_indicator] = options[:cit_mit_indicator] if options[:cit_mit_indicator]
|
169
|
+
post[:account_data_source] = options[:account_data_source] if options[:account_data_source]
|
170
|
+
end
|
171
|
+
|
148
172
|
def parse(body)
|
149
173
|
results = {}
|
150
174
|
body.split(/&/).each do |pair|
|
@@ -165,13 +189,23 @@ module ActiveMerchant #:nodoc:
|
|
165
189
|
{ 'error_code' => '404', 'auth_response_text' => e.to_s }
|
166
190
|
end
|
167
191
|
|
168
|
-
Response.new(response
|
169
|
-
authorization: response
|
192
|
+
Response.new(success_from(response), message_from(response), response,
|
193
|
+
authorization: authorization_from(response),
|
170
194
|
test: test?,
|
171
195
|
cvv_result: response['cvv2_result'],
|
172
196
|
avs_result: { code: response['avs_result'] })
|
173
197
|
end
|
174
198
|
|
199
|
+
def authorization_from(response)
|
200
|
+
return response['card_id'] if response['card_id']
|
201
|
+
|
202
|
+
response['transaction_id']
|
203
|
+
end
|
204
|
+
|
205
|
+
def success_from(response)
|
206
|
+
SUCCESS_RESPONSE_CODES.include?(response['error_code'])
|
207
|
+
end
|
208
|
+
|
175
209
|
def message_from(response)
|
176
210
|
if response['error_code'] == '000'
|
177
211
|
'This transaction has been approved'
|
@@ -201,6 +201,7 @@ module ActiveMerchant #:nodoc:
|
|
201
201
|
request[:paymentMethod][:card][:expMonth] = format(payment_method.month, :two_digits)
|
202
202
|
request[:paymentMethod][:card][:expYear] = format(payment_method.year, :two_digits)
|
203
203
|
request[:paymentMethod][:card][:cvc] = payment_method.verification_value.to_s
|
204
|
+
request[:paymentMethod][:card][:cardholderName] = payment_method.name
|
204
205
|
end
|
205
206
|
end
|
206
207
|
|
@@ -293,6 +294,7 @@ module ActiveMerchant #:nodoc:
|
|
293
294
|
def add_browser_info(request, options)
|
294
295
|
request[:sessionDetails][:ip] = options[:ip] if options[:ip]
|
295
296
|
request[:sessionDetails][:userAgent] = options[:user_agent] if options[:user_agent]
|
297
|
+
request[:sessionDetails][:lang] = options[:lang] if options[:lang]
|
296
298
|
end
|
297
299
|
|
298
300
|
# Private: Parse JSON response from Monei servers
|
@@ -9,6 +9,8 @@ module ActiveMerchant #:nodoc:
|
|
9
9
|
# Response Values", available at Moneris' {eSelect Plus Documentation
|
10
10
|
# Centre}[https://www3.moneris.com/connect/en/documents/index.html].
|
11
11
|
class MonerisGateway < Gateway
|
12
|
+
WALLETS = %w(APP GPP)
|
13
|
+
|
12
14
|
self.test_url = 'https://esqa.moneris.com/gateway2/servlet/MpgRequest'
|
13
15
|
self.live_url = 'https://www3.moneris.com/gateway2/servlet/MpgRequest'
|
14
16
|
|
@@ -47,18 +49,19 @@ module ActiveMerchant #:nodoc:
|
|
47
49
|
post = {}
|
48
50
|
add_payment_source(post, creditcard_or_datakey, options)
|
49
51
|
post[:amount] = amount(money)
|
50
|
-
post[:order_id] = options[:order_id]
|
52
|
+
post[:order_id] = format_order_id(post[:wallet_indicator], options[:order_id])
|
51
53
|
post[:address] = options[:billing_address] || options[:address]
|
52
54
|
post[:crypt_type] = options[:crypt_type] || @options[:crypt_type]
|
55
|
+
add_external_mpi_fields(post, options)
|
53
56
|
add_stored_credential(post, options)
|
54
|
-
action = if post[:cavv]
|
57
|
+
action = if post[:cavv] || options[:three_d_secure]
|
55
58
|
'cavv_preauth'
|
56
59
|
elsif post[:data_key].blank?
|
57
60
|
'preauth'
|
58
61
|
else
|
59
62
|
'res_preauth_cc'
|
60
63
|
end
|
61
|
-
commit(action, post)
|
64
|
+
commit(action, post, options)
|
62
65
|
end
|
63
66
|
|
64
67
|
# This action verifies funding on a customer's card and readies them for
|
@@ -70,18 +73,19 @@ module ActiveMerchant #:nodoc:
|
|
70
73
|
post = {}
|
71
74
|
add_payment_source(post, creditcard_or_datakey, options)
|
72
75
|
post[:amount] = amount(money)
|
73
|
-
post[:order_id] = options[:order_id]
|
76
|
+
post[:order_id] = format_order_id(post[:wallet_indicator], options[:order_id])
|
74
77
|
post[:address] = options[:billing_address] || options[:address]
|
75
78
|
post[:crypt_type] = options[:crypt_type] || @options[:crypt_type]
|
79
|
+
add_external_mpi_fields(post, options)
|
76
80
|
add_stored_credential(post, options)
|
77
|
-
action = if post[:cavv]
|
81
|
+
action = if post[:cavv] || options[:three_d_secure]
|
78
82
|
'cavv_purchase'
|
79
83
|
elsif post[:data_key].blank?
|
80
84
|
'purchase'
|
81
85
|
else
|
82
86
|
'res_purchase_cc'
|
83
87
|
end
|
84
|
-
commit(action, post)
|
88
|
+
commit(action, post, options)
|
85
89
|
end
|
86
90
|
|
87
91
|
# This method retrieves locked funds from a customer's account (from a
|
@@ -203,6 +207,21 @@ module ActiveMerchant #:nodoc:
|
|
203
207
|
sprintf('%.4i', creditcard.year)[-2..-1] + sprintf('%.2i', creditcard.month)
|
204
208
|
end
|
205
209
|
|
210
|
+
def add_external_mpi_fields(post, options)
|
211
|
+
# See these pages:
|
212
|
+
# https://developer.moneris.com/livedemo/3ds2/cavv_purchase/tool/php
|
213
|
+
# https://developer.moneris.com/livedemo/3ds2/cavv_preauth/guide/php
|
214
|
+
return unless options[:three_d_secure]
|
215
|
+
|
216
|
+
three_d_secure_options = options[:three_d_secure]
|
217
|
+
|
218
|
+
post[:threeds_version] = three_d_secure_options[:version]
|
219
|
+
post[:crypt_type] = three_d_secure_options[:eci]
|
220
|
+
post[:cavv] = three_d_secure_options[:cavv]
|
221
|
+
post[:threeds_server_trans_id] = three_d_secure_options[:three_ds_server_trans_id]
|
222
|
+
post[:ds_trans_id] = three_d_secure_options[:ds_transaction_id]
|
223
|
+
end
|
224
|
+
|
206
225
|
def add_payment_source(post, payment_method, options)
|
207
226
|
if payment_method.is_a?(String)
|
208
227
|
post[:data_key] = payment_method
|
@@ -291,14 +310,16 @@ module ActiveMerchant #:nodoc:
|
|
291
310
|
end
|
292
311
|
end
|
293
312
|
|
294
|
-
def commit(action, parameters = {})
|
313
|
+
def commit(action, parameters = {}, options = {})
|
314
|
+
threed_ds_transaction = options[:three_d_secure].present?
|
315
|
+
|
295
316
|
data = post_data(action, parameters)
|
296
317
|
url = test? ? self.test_url : self.live_url
|
297
318
|
raw = ssl_post(url, data)
|
298
319
|
response = parse(raw)
|
299
320
|
|
300
321
|
Response.new(
|
301
|
-
successful?(response),
|
322
|
+
successful?(action, response, threed_ds_transaction),
|
302
323
|
message_from(response[:message]),
|
303
324
|
response,
|
304
325
|
test: test?,
|
@@ -314,8 +335,16 @@ module ActiveMerchant #:nodoc:
|
|
314
335
|
end
|
315
336
|
|
316
337
|
# Tests for a successful response from Moneris' servers
|
317
|
-
def successful?(response)
|
318
|
-
|
338
|
+
def successful?(action, response, threed_ds_transaction = false)
|
339
|
+
# See 9.4 CAVV Result Codes in https://developer.moneris.com/livedemo/3ds2/reference/guide/php
|
340
|
+
cavv_accepted = if threed_ds_transaction
|
341
|
+
response[:cavv_result_code] && response[:cavv_result_code] == '2'
|
342
|
+
else
|
343
|
+
true
|
344
|
+
end
|
345
|
+
|
346
|
+
cavv_accepted &&
|
347
|
+
response[:response_code] &&
|
319
348
|
response[:complete] &&
|
320
349
|
(0..49).cover?(response[:response_code].to_i)
|
321
350
|
end
|
@@ -404,10 +433,23 @@ module ActiveMerchant #:nodoc:
|
|
404
433
|
end
|
405
434
|
|
406
435
|
def wallet_indicator(token_source)
|
407
|
-
return
|
408
|
-
|
436
|
+
return {
|
437
|
+
'apple_pay' => 'APP',
|
438
|
+
'google_pay' => 'GPP',
|
439
|
+
'android_pay' => 'ANP'
|
440
|
+
}[token_source]
|
441
|
+
end
|
442
|
+
|
443
|
+
def format_order_id(wallet_indicator_code, order_id = nil)
|
444
|
+
# Truncate (max 100 characters) order id for
|
445
|
+
# google pay and apple pay (specific wallets / token sources)
|
446
|
+
return truncate_order_id(order_id) if WALLETS.include?(wallet_indicator_code)
|
447
|
+
|
448
|
+
order_id
|
449
|
+
end
|
409
450
|
|
410
|
-
|
451
|
+
def truncate_order_id(order_id = nil)
|
452
|
+
order_id.present? ? order_id[0, 100] : SecureRandom.alphanumeric(100)
|
411
453
|
end
|
412
454
|
|
413
455
|
def message_from(message)
|
@@ -60,11 +60,13 @@ module ActiveMerchant #:nodoc:
|
|
60
60
|
post = {}
|
61
61
|
post[:code] = authorization
|
62
62
|
add_invoice(post, money, options)
|
63
|
+
add_auth_key(post, options)
|
63
64
|
commit('capture', post, authorization)
|
64
65
|
end
|
65
66
|
|
66
67
|
def refund(money, authorization, options = {})
|
67
68
|
add_invoice(post = {}, money, options)
|
69
|
+
add_auth_key(post, options)
|
68
70
|
commit('refund', post, authorization)
|
69
71
|
end
|
70
72
|
|
@@ -77,6 +79,7 @@ module ActiveMerchant #:nodoc:
|
|
77
79
|
options.update(name: payment.name)
|
78
80
|
options = add_customer(options) unless options[:customer_id]
|
79
81
|
add_payment(post, payment, options)
|
82
|
+
add_auth_key(post, options)
|
80
83
|
commit('store', post, options[:customer_id])
|
81
84
|
end
|
82
85
|
|
@@ -5,7 +5,7 @@ module ActiveMerchant #:nodoc:
|
|
5
5
|
|
6
6
|
DUP_WINDOW_DEPRECATION_MESSAGE = 'The class-level duplicate_window variable is deprecated. Please use the :dup_seconds transaction option instead.'
|
7
7
|
|
8
|
-
self.test_url = self.live_url = 'https://secure.
|
8
|
+
self.test_url = self.live_url = 'https://secure.networkmerchants.com/api/transact.php'
|
9
9
|
self.default_currency = 'USD'
|
10
10
|
self.money_format = :dollars
|
11
11
|
self.supported_countries = ['US']
|
@@ -23,7 +23,11 @@ module ActiveMerchant #:nodoc:
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def initialize(options = {})
|
26
|
-
|
26
|
+
if options.has_key?(:security_key)
|
27
|
+
requires!(options, :security_key)
|
28
|
+
else
|
29
|
+
requires!(options, :login, :password)
|
30
|
+
end
|
27
31
|
super
|
28
32
|
end
|
29
33
|
|
@@ -51,7 +55,6 @@ module ActiveMerchant #:nodoc:
|
|
51
55
|
add_merchant_defined_fields(post, options)
|
52
56
|
add_level3_fields(post, options)
|
53
57
|
add_three_d_secure(post, options)
|
54
|
-
|
55
58
|
commit('auth', post)
|
56
59
|
end
|
57
60
|
|
@@ -126,6 +129,7 @@ module ActiveMerchant #:nodoc:
|
|
126
129
|
def scrub(transcript)
|
127
130
|
transcript.
|
128
131
|
gsub(%r((password=)[^&\n]*), '\1[FILTERED]').
|
132
|
+
gsub(%r((security_key=)[^&\n]*), '\1[FILTERED]').
|
129
133
|
gsub(%r((ccnumber=)\d+), '\1[FILTERED]').
|
130
134
|
gsub(%r((cvv=)\d+), '\1[FILTERED]').
|
131
135
|
gsub(%r((checkaba=)\d+), '\1[FILTERED]').
|
@@ -297,9 +301,9 @@ module ActiveMerchant #:nodoc:
|
|
297
301
|
|
298
302
|
def commit(action, params)
|
299
303
|
params[action == 'add_customer' ? :customer_vault : :type] = action
|
300
|
-
params[:username] = @options[:login]
|
301
|
-
params[:password] = @options[:password]
|
302
|
-
|
304
|
+
params[:username] = @options[:login] unless @options[:login].nil?
|
305
|
+
params[:password] = @options[:password] unless @options[:password].nil?
|
306
|
+
params[:security_key] = @options[:security_key] unless @options[:security_key].nil?
|
303
307
|
raw_response = ssl_post(url, post_data(action, params), headers)
|
304
308
|
response = parse(raw_response)
|
305
309
|
succeeded = success_from(response)
|
@@ -325,7 +329,8 @@ module ActiveMerchant #:nodoc:
|
|
325
329
|
end
|
326
330
|
|
327
331
|
def headers
|
328
|
-
{ 'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8' }
|
332
|
+
headers = { 'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8' }
|
333
|
+
headers
|
329
334
|
end
|
330
335
|
|
331
336
|
def post_data(action, params)
|
@@ -136,7 +136,7 @@ module ActiveMerchant #:nodoc:
|
|
136
136
|
self.supported_countries = %w[BE DE FR NL AT CH]
|
137
137
|
# also supports Airplus and UATP
|
138
138
|
self.supported_cardtypes = %i[visa master american_express diners_club discover jcb maestro]
|
139
|
-
self.homepage_url = '
|
139
|
+
self.homepage_url = 'https://www.ingenico.com/login/ogone/'
|
140
140
|
self.display_name = 'Ogone'
|
141
141
|
self.default_currency = 'EUR'
|
142
142
|
self.money_format = :cents
|
@@ -264,7 +264,6 @@ module ActiveMerchant #:nodoc:
|
|
264
264
|
|
265
265
|
def add_payment_source(post, payment_source, options)
|
266
266
|
add_d3d(post, options) if options[:d3d]
|
267
|
-
|
268
267
|
if payment_source.is_a?(String)
|
269
268
|
add_alias(post, payment_source, options[:alias_operation])
|
270
269
|
add_eci(post, options[:eci] || '9')
|
@@ -285,8 +284,6 @@ module ActiveMerchant #:nodoc:
|
|
285
284
|
THREE_D_SECURE_DISPLAY_WAYS[options[:win_3ds]] :
|
286
285
|
THREE_D_SECURE_DISPLAY_WAYS[:main_window]
|
287
286
|
add_pair post, 'WIN3DS', win_3ds
|
288
|
-
|
289
|
-
add_pair post, 'HTTP_ACCEPT', options[:http_accept] || '*/*'
|
290
287
|
add_pair post, 'HTTP_USER_AGENT', options[:http_user_agent] if options[:http_user_agent]
|
291
288
|
add_pair post, 'ACCEPTURL', options[:accept_url] if options[:accept_url]
|
292
289
|
add_pair post, 'DECLINEURL', options[:decline_url] if options[:decline_url]
|
@@ -296,6 +293,37 @@ module ActiveMerchant #:nodoc:
|
|
296
293
|
add_pair post, 'PARAMPLUS', options[:paramplus] if options[:paramplus]
|
297
294
|
add_pair post, 'COMPLUS', options[:complus] if options[:complus]
|
298
295
|
add_pair post, 'LANGUAGE', options[:language] if options[:language]
|
296
|
+
if options[:three_ds_2]
|
297
|
+
browser_info = options[:three_ds_2][:browser_info]
|
298
|
+
ecom_postal = options[:billing_address]
|
299
|
+
if browser_info
|
300
|
+
add_pair post, 'BROWSERACCEPTHEADER', browser_info[:accept_header]
|
301
|
+
add_pair post, 'BROWSERCOLORDEPTH', browser_info[:depth]
|
302
|
+
|
303
|
+
# for 3ds v2.1 to v2.2 add BROWSERJAVASCRIPTENABLED: This boolean indicates whether your customers have enabled JavaScript in their browsers when making a purchase.
|
304
|
+
# the following BROWSER<tag> parameters will remain mandatory unless browser_info[:javascript] = false
|
305
|
+
# her documentation https://epayments-support.ingenico.com/en/integration-solutions/integrations/directlink#directlink_integration_guides_secure_payment_with_3_d_secure
|
306
|
+
add_pair post, 'BROWSERJAVASCRIPTENABLED', browser_info[:javascript]
|
307
|
+
add_pair post, 'BROWSERJAVAENABLED', browser_info[:java]
|
308
|
+
add_pair post, 'BROWSERLANGUAGE', browser_info[:language]
|
309
|
+
add_pair post, 'BROWSERSCREENHEIGHT', browser_info[:height]
|
310
|
+
add_pair post, 'BROWSERSCREENWIDTH', browser_info[:width]
|
311
|
+
add_pair post, 'BROWSERTIMEZONE', browser_info[:timezone]
|
312
|
+
add_pair post, 'BROWSERUSERAGENT', browser_info[:user_agent]
|
313
|
+
end
|
314
|
+
# recommended
|
315
|
+
if ecom_postal
|
316
|
+
add_pair post, 'ECOM_BILLTO_POSTAL_CITY', ecom_postal[:city]
|
317
|
+
add_pair post, 'ECOM_BILLTO_POSTAL_COUNTRYCODE', ecom_postal[:country]
|
318
|
+
add_pair post, 'ECOM_BILLTO_POSTAL_STREET_LINE1', ecom_postal[:address1]
|
319
|
+
add_pair post, 'ECOM_BILLTO_POSTAL_STREET_LINE2', ecom_postal[:address2]
|
320
|
+
add_pair post, 'ECOM_BILLTO_POSTAL_POSTALCODE', ecom_postal[:zip]
|
321
|
+
end
|
322
|
+
# optional
|
323
|
+
add_pair post, 'Mpi.threeDSRequestorChallengeIndicator', options[:three_ds_reqchallengeind]
|
324
|
+
else
|
325
|
+
add_pair post, 'HTTP_ACCEPT', options[:http_accept] || '*/*'
|
326
|
+
end
|
299
327
|
end
|
300
328
|
|
301
329
|
def add_eci(post, eci)
|
@@ -414,7 +442,7 @@ module ActiveMerchant #:nodoc:
|
|
414
442
|
return
|
415
443
|
end
|
416
444
|
|
417
|
-
add_pair parameters, '
|
445
|
+
add_pair parameters, 'SHASIGN', calculate_signature(parameters, @options[:signature_encryptor], @options[:signature])
|
418
446
|
end
|
419
447
|
|
420
448
|
def calculate_signature(signed_parameters, algorithm, secret)
|
@@ -432,7 +460,7 @@ module ActiveMerchant #:nodoc:
|
|
432
460
|
raise "Unknown signature algorithm #{algorithm}"
|
433
461
|
end
|
434
462
|
|
435
|
-
filtered_params = signed_parameters.
|
463
|
+
filtered_params = signed_parameters.compact
|
436
464
|
sha_encryptor.hexdigest(
|
437
465
|
filtered_params.sort_by { |k, _v| k.upcase }.map { |k, v| "#{k.upcase}=#{v}#{secret}" }.join('')
|
438
466
|
).upcase
|
@@ -456,7 +484,7 @@ module ActiveMerchant #:nodoc:
|
|
456
484
|
end
|
457
485
|
|
458
486
|
def add_pair(post, key, value)
|
459
|
-
post[key] = value
|
487
|
+
post[key] = value unless value.nil?
|
460
488
|
end
|
461
489
|
|
462
490
|
def convert_attributes_to_hash(rexml_attributes)
|
@@ -1,8 +1,15 @@
|
|
1
1
|
module ActiveMerchant #:nodoc:
|
2
2
|
module Billing #:nodoc:
|
3
3
|
class OpenpayGateway < Gateway
|
4
|
-
|
5
|
-
|
4
|
+
class_attribute :mx_live_url, :mx_test_url
|
5
|
+
class_attribute :co_live_url, :co_test_url
|
6
|
+
|
7
|
+
self.co_live_url = 'https://api.openpay.co/v1/'
|
8
|
+
self.co_test_url = 'https://sandbox-api.openpay.co/v1/'
|
9
|
+
self.mx_live_url = 'https://api.openpay.mx/v1/'
|
10
|
+
self.mx_test_url = 'https://sandbox-api.openpay.mx/v1/'
|
11
|
+
self.live_url = self.co_live_url
|
12
|
+
self.test_url = self.co_test_url
|
6
13
|
|
7
14
|
self.supported_countries = %w(CO MX)
|
8
15
|
self.supported_cardtypes = %i[visa master american_express carnet]
|
@@ -24,6 +31,16 @@ module ActiveMerchant #:nodoc:
|
|
24
31
|
super
|
25
32
|
end
|
26
33
|
|
34
|
+
def gateway_url(options = {})
|
35
|
+
country = options[:merchant_country] || @options[:merchant_country]
|
36
|
+
|
37
|
+
if country == 'MX'
|
38
|
+
test? ? mx_test_url : mx_live_url
|
39
|
+
else
|
40
|
+
test? ? co_test_url : co_live_url
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
27
44
|
def purchase(money, creditcard, options = {})
|
28
45
|
post = create_post_for_auth_or_purchase(money, creditcard, options)
|
29
46
|
commit(:post, 'charges', post, options)
|
@@ -192,7 +209,7 @@ module ActiveMerchant #:nodoc:
|
|
192
209
|
end
|
193
210
|
|
194
211
|
def http_request(method, resource, parameters = {}, options = {})
|
195
|
-
url = (
|
212
|
+
url = gateway_url(options) + @merchant_id + '/' + resource
|
196
213
|
raw_response = nil
|
197
214
|
begin
|
198
215
|
raw_response = ssl_request(method, url, (parameters ? parameters.to_json : nil), headers(options))
|