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
@@ -5,9 +5,10 @@ module ActiveMerchant #:nodoc:
|
|
5
5
|
class LitleGateway < Gateway
|
6
6
|
SCHEMA_VERSION = '9.14'
|
7
7
|
|
8
|
-
class_attribute :postlive_url
|
8
|
+
class_attribute :postlive_url, :prelive_url
|
9
9
|
|
10
10
|
self.test_url = 'https://www.testvantivcnp.com/sandbox/communicator/online'
|
11
|
+
self.prelive_url = 'https://payments.vantivprelive.com/vap/communicator/online'
|
11
12
|
self.postlive_url = 'https://payments.vantivpostlive.com/vap/communicator/online'
|
12
13
|
self.live_url = 'https://payments.vantivcnp.com/vap/communicator/online'
|
13
14
|
|
@@ -15,7 +16,7 @@ module ActiveMerchant #:nodoc:
|
|
15
16
|
self.default_currency = 'USD'
|
16
17
|
self.supported_cardtypes = %i[visa master american_express discover diners_club jcb]
|
17
18
|
|
18
|
-
self.homepage_url = '
|
19
|
+
self.homepage_url = 'https://www.fisglobal.com/'
|
19
20
|
self.display_name = 'Vantiv eCommerce'
|
20
21
|
|
21
22
|
def initialize(options = {})
|
@@ -320,6 +321,7 @@ module ActiveMerchant #:nodoc:
|
|
320
321
|
add_merchant_data(doc, options)
|
321
322
|
add_debt_repayment(doc, options)
|
322
323
|
add_stored_credential_params(doc, options)
|
324
|
+
add_fraud_filter_override(doc, options)
|
323
325
|
end
|
324
326
|
|
325
327
|
def add_credit_params(doc, money, payment_method, options)
|
@@ -365,6 +367,10 @@ module ActiveMerchant #:nodoc:
|
|
365
367
|
doc.debtRepayment(true) if options[:debt_repayment] == true
|
366
368
|
end
|
367
369
|
|
370
|
+
def add_fraud_filter_override(doc, options)
|
371
|
+
doc.fraudFilterOverride(options[:fraud_filter_override]) if options[:fraud_filter_override]
|
372
|
+
end
|
373
|
+
|
368
374
|
def add_payment_method(doc, payment_method, options)
|
369
375
|
if payment_method.is_a?(String)
|
370
376
|
doc.token do
|
@@ -532,8 +538,10 @@ module ActiveMerchant #:nodoc:
|
|
532
538
|
|
533
539
|
def parse(kind, xml)
|
534
540
|
parsed = {}
|
535
|
-
|
536
541
|
doc = Nokogiri::XML(xml).remove_namespaces!
|
542
|
+
|
543
|
+
parsed['duplicate'] = doc.at_xpath('//saleResponse').try(:[], 'duplicate') == 'true' if kind == :sale
|
544
|
+
|
537
545
|
doc.xpath("//litleOnlineResponse/#{kind}Response/*").each do |node|
|
538
546
|
if node.elements.empty?
|
539
547
|
parsed[node.name.to_sym] = node.text
|
@@ -564,15 +572,26 @@ module ActiveMerchant #:nodoc:
|
|
564
572
|
cvv_result: parsed[:fraudResult_cardValidationResult]
|
565
573
|
}
|
566
574
|
|
567
|
-
Response.new(success_from(kind, parsed), parsed
|
575
|
+
Response.new(success_from(kind, parsed), message_from(parsed), parsed, options)
|
568
576
|
end
|
569
577
|
|
570
578
|
def success_from(kind, parsed)
|
571
|
-
return (parsed[:response]
|
579
|
+
return %w(000 001 010).any?(parsed[:response]) unless kind == :registerToken
|
572
580
|
|
573
581
|
%w(000 801 802).include?(parsed[:response])
|
574
582
|
end
|
575
583
|
|
584
|
+
def message_from(parsed)
|
585
|
+
case parsed[:response]
|
586
|
+
when '010'
|
587
|
+
return "#{parsed[:message]}: The authorized amount is less than the requested amount."
|
588
|
+
when '001'
|
589
|
+
return "#{parsed[:message]}: This is sent to acknowledge that the submitted transaction has been received."
|
590
|
+
else
|
591
|
+
parsed[:message]
|
592
|
+
end
|
593
|
+
end
|
594
|
+
|
576
595
|
def authorization_from(kind, parsed, money)
|
577
596
|
kind == :registerToken ? parsed[:litleToken] : "#{parsed[:litleTxnId]};#{kind};#{money}"
|
578
597
|
end
|
@@ -609,6 +628,7 @@ module ActiveMerchant #:nodoc:
|
|
609
628
|
|
610
629
|
def url
|
611
630
|
return postlive_url if @options[:url_override].to_s == 'postlive'
|
631
|
+
return prelive_url if @options[:url_override].to_s == 'prelive'
|
612
632
|
|
613
633
|
test? ? test_url : live_url
|
614
634
|
end
|
@@ -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,7 +49,7 @@ 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]
|
53
55
|
add_external_mpi_fields(post, options)
|
@@ -71,7 +73,7 @@ module ActiveMerchant #:nodoc:
|
|
71
73
|
post = {}
|
72
74
|
add_payment_source(post, creditcard_or_datakey, options)
|
73
75
|
post[:amount] = amount(money)
|
74
|
-
post[:order_id] = options[:order_id]
|
76
|
+
post[:order_id] = format_order_id(post[:wallet_indicator], options[:order_id])
|
75
77
|
post[:address] = options[:billing_address] || options[:address]
|
76
78
|
post[:crypt_type] = options[:crypt_type] || @options[:crypt_type]
|
77
79
|
add_external_mpi_fields(post, options)
|
@@ -431,10 +433,23 @@ module ActiveMerchant #:nodoc:
|
|
431
433
|
end
|
432
434
|
|
433
435
|
def wallet_indicator(token_source)
|
434
|
-
return
|
435
|
-
|
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
|
436
450
|
|
437
|
-
|
451
|
+
def truncate_order_id(order_id = nil)
|
452
|
+
order_id.present? ? order_id[0, 100] : SecureRandom.alphanumeric(100)
|
438
453
|
end
|
439
454
|
|
440
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
|
|
@@ -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))
|
@@ -30,7 +30,7 @@ module ActiveMerchant #:nodoc:
|
|
30
30
|
class OrbitalGateway < Gateway
|
31
31
|
include Empty
|
32
32
|
|
33
|
-
API_VERSION = '
|
33
|
+
API_VERSION = '9.0'
|
34
34
|
|
35
35
|
POST_HEADERS = {
|
36
36
|
'MIME-Version' => '1.1',
|
@@ -98,6 +98,7 @@ module ActiveMerchant #:nodoc:
|
|
98
98
|
'NZD' => '554',
|
99
99
|
'NOK' => '578',
|
100
100
|
'SGD' => '702',
|
101
|
+
'ZAR' => '710',
|
101
102
|
'SEK' => '752',
|
102
103
|
'CHF' => '756',
|
103
104
|
'GBP' => '826',
|
@@ -119,6 +120,7 @@ module ActiveMerchant #:nodoc:
|
|
119
120
|
'NZD' => '2',
|
120
121
|
'NOK' => '2',
|
121
122
|
'SGD' => '2',
|
123
|
+
'ZAR' => '2',
|
122
124
|
'SEK' => '2',
|
123
125
|
'CHF' => '2',
|
124
126
|
'GBP' => '2',
|
@@ -196,6 +198,7 @@ module ActiveMerchant #:nodoc:
|
|
196
198
|
requires!(options, :login, :password) unless options[:ip_authentication]
|
197
199
|
super
|
198
200
|
@options[:merchant_id] = @options[:merchant_id].to_s
|
201
|
+
@use_secondary_url = false
|
199
202
|
end
|
200
203
|
|
201
204
|
# A – Authorization request
|
@@ -235,11 +238,7 @@ module ActiveMerchant #:nodoc:
|
|
235
238
|
def refund(money, authorization, options = {})
|
236
239
|
payment_method = options[:payment_method]
|
237
240
|
order = build_new_order_xml(REFUND, money, payment_method, options.merge(authorization: authorization)) do |xml|
|
238
|
-
|
239
|
-
add_echeck(xml, payment_method, options)
|
240
|
-
else
|
241
|
-
add_refund_payment_source(xml, options[:currency])
|
242
|
-
end
|
241
|
+
add_payment_source(xml, payment_method, options)
|
243
242
|
xml.tag! :CustomerRefNum, options[:customer_ref_num] if @options[:customer_profiles] && options[:profile_txn]
|
244
243
|
end
|
245
244
|
|
@@ -398,6 +397,12 @@ module ActiveMerchant #:nodoc:
|
|
398
397
|
add_soft_descriptors_from_hash(xml, descriptors) if descriptors.is_a?(Hash)
|
399
398
|
end
|
400
399
|
|
400
|
+
def add_payment_action_ind(xml, payment_action_ind)
|
401
|
+
return unless payment_action_ind
|
402
|
+
|
403
|
+
xml.tag! :PaymentActionInd, payment_action_ind
|
404
|
+
end
|
405
|
+
|
401
406
|
def add_soft_descriptors_from_specialized_class(xml, soft_desc)
|
402
407
|
xml.tag! :SDMerchantName, soft_desc.merchant_name if soft_desc.merchant_name
|
403
408
|
xml.tag! :SDProductDescription, soft_desc.product_description if soft_desc.product_description
|
@@ -564,7 +569,7 @@ module ActiveMerchant #:nodoc:
|
|
564
569
|
add_currency_fields(xml, options[:currency])
|
565
570
|
xml.tag! :BCRtNum, check.routing_number
|
566
571
|
xml.tag! :CheckDDA, check.account_number if check.account_number
|
567
|
-
xml
|
572
|
+
add_bank_account_type(xml, check)
|
568
573
|
xml.tag! :ECPAuthMethod, options[:auth_method] if options[:auth_method]
|
569
574
|
xml.tag! :BankPmtDelv, options[:payment_delivery] || 'B'
|
570
575
|
xml.tag! :AVSname, (check&.name ? check.name[0..29] : nil) if get_address(options).blank?
|
@@ -577,12 +582,6 @@ module ActiveMerchant #:nodoc:
|
|
577
582
|
add_verification_value(xml, credit_card) if credit_card
|
578
583
|
end
|
579
584
|
|
580
|
-
def add_refund_payment_source(xml, currency = nil)
|
581
|
-
xml.tag! :AccountNum, nil
|
582
|
-
|
583
|
-
add_currency_fields(xml, currency)
|
584
|
-
end
|
585
|
-
|
586
585
|
def add_verification_value(xml, credit_card)
|
587
586
|
return unless credit_card&.verification_value?
|
588
587
|
|
@@ -595,7 +594,7 @@ module ActiveMerchant #:nodoc:
|
|
595
594
|
# Null-fill this attribute OR
|
596
595
|
# Do not submit the attribute at all.
|
597
596
|
# - http://download.chasepaymentech.com/docs/orbital/orbital_gateway_xml_specification.pdf
|
598
|
-
xml.tag! :CardSecValInd, '1' if %w(visa
|
597
|
+
xml.tag! :CardSecValInd, '1' if %w(visa discover diners_club).include?(credit_card.brand)
|
599
598
|
xml.tag! :CardSecVal, credit_card.verification_value
|
600
599
|
end
|
601
600
|
|
@@ -604,6 +603,17 @@ module ActiveMerchant #:nodoc:
|
|
604
603
|
xml.tag! :CurrencyExponent, currency_exponents(currency)
|
605
604
|
end
|
606
605
|
|
606
|
+
def add_bank_account_type(xml, check)
|
607
|
+
bank_account_type =
|
608
|
+
if check.account_holder_type == 'business'
|
609
|
+
'X'
|
610
|
+
else
|
611
|
+
ACCOUNT_TYPE[check.account_type]
|
612
|
+
end
|
613
|
+
|
614
|
+
xml.tag! :BankAccountType, bank_account_type if bank_account_type
|
615
|
+
end
|
616
|
+
|
607
617
|
def add_card_indicators(xml, options)
|
608
618
|
xml.tag! :CardIndicators, options[:card_indicators] if options[:card_indicators]
|
609
619
|
end
|
@@ -752,16 +762,23 @@ module ActiveMerchant #:nodoc:
|
|
752
762
|
xml.tag!(:AuthenticationECIInd, eci) if eci
|
753
763
|
end
|
754
764
|
|
755
|
-
def add_dpanind(xml, credit_card)
|
765
|
+
def add_dpanind(xml, credit_card, industry_type = nil)
|
756
766
|
return unless credit_card.is_a?(NetworkTokenizationCreditCard)
|
757
767
|
|
758
|
-
xml.tag! :DPANInd, 'Y'
|
768
|
+
xml.tag! :DPANInd, 'Y' unless industry_type == 'RC'
|
759
769
|
end
|
760
770
|
|
761
|
-
def add_digital_token_cryptogram(xml, credit_card)
|
762
|
-
return unless credit_card.is_a?(NetworkTokenizationCreditCard)
|
771
|
+
def add_digital_token_cryptogram(xml, credit_card, three_d_secure)
|
772
|
+
return unless credit_card.is_a?(NetworkTokenizationCreditCard) || three_d_secure && credit_card.brand == 'discover'
|
763
773
|
|
764
|
-
|
774
|
+
cryptogram =
|
775
|
+
if three_d_secure && credit_card.brand == 'discover'
|
776
|
+
three_d_secure[:cavv]
|
777
|
+
else
|
778
|
+
credit_card.payment_cryptogram
|
779
|
+
end
|
780
|
+
|
781
|
+
xml.tag!(:DigitalTokenCryptogram, cryptogram)
|
765
782
|
end
|
766
783
|
|
767
784
|
#=====OTHER FIELDS=====
|
@@ -862,6 +879,8 @@ module ActiveMerchant #:nodoc:
|
|
862
879
|
# Failover URL will be attempted in the event of a connection error
|
863
880
|
response =
|
864
881
|
begin
|
882
|
+
raise ConnectionError.new 'Should use secondary url', 500 if @use_secondary_url
|
883
|
+
|
865
884
|
request.call(remote_url)
|
866
885
|
rescue ConnectionError
|
867
886
|
request.call(remote_url(:secondary))
|
@@ -942,6 +961,7 @@ module ActiveMerchant #:nodoc:
|
|
942
961
|
|
943
962
|
def build_new_order_xml(action, money, payment_source, parameters = {})
|
944
963
|
requires!(parameters, :order_id)
|
964
|
+
@use_secondary_url = parameters[:use_secondary_url] if parameters[:use_secondary_url]
|
945
965
|
xml = xml_envelope
|
946
966
|
xml.tag! :Request do
|
947
967
|
xml.tag! :NewOrder do
|
@@ -969,16 +989,17 @@ module ActiveMerchant #:nodoc:
|
|
969
989
|
# CustomerAni, AVSPhoneType and AVSDestPhoneType could be added here.
|
970
990
|
|
971
991
|
add_soft_descriptors(xml, parameters[:soft_descriptors])
|
972
|
-
|
992
|
+
add_payment_action_ind(xml, parameters[:payment_action_ind])
|
993
|
+
add_dpanind(xml, payment_source, parameters[:industry_type])
|
973
994
|
add_aevv(xml, payment_source, three_d_secure)
|
974
|
-
add_digital_token_cryptogram(xml, payment_source)
|
995
|
+
add_digital_token_cryptogram(xml, payment_source, three_d_secure)
|
975
996
|
|
976
997
|
xml.tag! :ECPSameDayInd, parameters[:same_day] if parameters[:same_day] && payment_source.is_a?(Check)
|
977
998
|
|
978
999
|
set_recurring_ind(xml, parameters)
|
979
1000
|
|
980
1001
|
# Append Transaction Reference Number at the end for Refund transactions
|
981
|
-
add_tx_ref_num(xml, parameters[:authorization]) if action == REFUND
|
1002
|
+
add_tx_ref_num(xml, parameters[:authorization]) if action == REFUND && payment_source.nil?
|
982
1003
|
|
983
1004
|
add_level2_purchase(xml, parameters)
|
984
1005
|
add_level3_purchase(xml, parameters)
|