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
@@ -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)
|