activemerchant 1.94.0 → 1.99.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 +120 -1
- data/README.md +3 -0
- data/lib/active_merchant/billing/avs_result.rb +4 -5
- data/lib/active_merchant/billing/credit_card.rb +6 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +65 -2
- data/lib/active_merchant/billing/gateway.rb +10 -0
- data/lib/active_merchant/billing/gateways/adyen.rb +119 -34
- data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +43 -10
- data/lib/active_merchant/billing/gateways/beanstream.rb +11 -6
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +3 -0
- data/lib/active_merchant/billing/gateways/blue_snap.rb +22 -2
- data/lib/active_merchant/billing/gateways/bpoint.rb +4 -4
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +56 -9
- data/lib/active_merchant/billing/gateways/card_connect.rb +2 -1
- data/lib/active_merchant/billing/gateways/cecabank.rb +7 -7
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +37 -27
- data/lib/active_merchant/billing/gateways/credorax.rb +69 -4
- data/lib/active_merchant/billing/gateways/cyber_source.rb +51 -11
- data/lib/active_merchant/billing/gateways/d_local.rb +1 -1
- data/lib/active_merchant/billing/gateways/decidir.rb +245 -0
- data/lib/active_merchant/billing/gateways/epay.rb +13 -2
- data/lib/active_merchant/billing/gateways/eway_rapid.rb +42 -12
- data/lib/active_merchant/billing/gateways/fat_zebra.rb +6 -0
- data/lib/active_merchant/billing/gateways/global_collect.rb +3 -7
- data/lib/active_merchant/billing/gateways/hps.rb +46 -1
- data/lib/active_merchant/billing/gateways/kushki.rb +1 -1
- data/lib/active_merchant/billing/gateways/mastercard.rb +30 -5
- data/lib/active_merchant/billing/gateways/mercado_pago.rb +1 -1
- data/lib/active_merchant/billing/gateways/migs.rb +8 -0
- data/lib/active_merchant/billing/gateways/monei.rb +31 -0
- data/lib/active_merchant/billing/gateways/mundipagg.rb +33 -6
- data/lib/active_merchant/billing/gateways/nab_transact.rb +1 -1
- data/lib/active_merchant/billing/gateways/nmi.rb +39 -1
- data/lib/active_merchant/billing/gateways/opp.rb +20 -1
- data/lib/active_merchant/billing/gateways/orbital.rb +60 -10
- data/lib/active_merchant/billing/gateways/payflow.rb +64 -14
- data/lib/active_merchant/billing/gateways/paymill.rb +5 -0
- data/lib/active_merchant/billing/gateways/paypal.rb +14 -1
- data/lib/active_merchant/billing/gateways/payu_latam.rb +6 -2
- data/lib/active_merchant/billing/gateways/qvalent.rb +43 -1
- data/lib/active_merchant/billing/gateways/realex.rb +32 -9
- data/lib/active_merchant/billing/gateways/redsys.rb +113 -30
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +43 -29
- data/lib/active_merchant/billing/gateways/stripe.rb +38 -9
- data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +271 -0
- data/lib/active_merchant/billing/gateways/tns.rb +10 -5
- data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +2 -2
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +45 -6
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +8 -5
- data/lib/active_merchant/billing/gateways/worldpay.rb +177 -39
- data/lib/active_merchant/country.rb +1 -0
- data/lib/active_merchant/version.rb +1 -1
- metadata +19 -4
@@ -13,7 +13,7 @@ module ActiveMerchant #:nodoc:
|
|
13
13
|
self.homepage_url = 'https://www.barclaycardsmartpay.com/'
|
14
14
|
self.display_name = 'Barclaycard Smartpay'
|
15
15
|
|
16
|
-
API_VERSION = '
|
16
|
+
API_VERSION = 'v40'
|
17
17
|
|
18
18
|
def initialize(options = {})
|
19
19
|
requires!(options, :company, :merchant, :password)
|
@@ -37,7 +37,9 @@ module ActiveMerchant #:nodoc:
|
|
37
37
|
post[:card] = credit_card_hash(creditcard)
|
38
38
|
post[:billingAddress] = billing_address_hash(options) if options[:billing_address]
|
39
39
|
post[:deliveryAddress] = shipping_address_hash(options) if options[:shipping_address]
|
40
|
-
|
40
|
+
post[:shopperStatement] = options[:shopper_statement] if options[:shopper_statement]
|
41
|
+
|
42
|
+
add_3ds(post, options)
|
41
43
|
commit('authorise', post)
|
42
44
|
end
|
43
45
|
|
@@ -186,7 +188,7 @@ module ActiveMerchant #:nodoc:
|
|
186
188
|
end
|
187
189
|
|
188
190
|
def parse_avs_code(response)
|
189
|
-
AVS_MAPPING[response['avsResult'][0..1].strip] if response
|
191
|
+
AVS_MAPPING[response['additionalData']['avsResult'][0..1].strip] if response.dig('additionalData', 'avsResult')
|
190
192
|
end
|
191
193
|
|
192
194
|
def flatten_hash(hash, prefix = nil)
|
@@ -210,12 +212,18 @@ module ActiveMerchant #:nodoc:
|
|
210
212
|
end
|
211
213
|
|
212
214
|
def parse(response)
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
215
|
+
parsed_response = {}
|
216
|
+
params = CGI.parse(response)
|
217
|
+
params.each do |key, value|
|
218
|
+
parsed_key = key.split('.', 2)
|
219
|
+
if parsed_key.size > 1
|
220
|
+
parsed_response[parsed_key[0]] ||= {}
|
221
|
+
parsed_response[parsed_key[0]][parsed_key[1]] = value[0]
|
222
|
+
else
|
223
|
+
parsed_response[parsed_key[0]] = value[0]
|
217
224
|
end
|
218
|
-
|
225
|
+
end
|
226
|
+
parsed_response
|
219
227
|
end
|
220
228
|
|
221
229
|
def post_data(data)
|
@@ -343,8 +351,33 @@ module ActiveMerchant #:nodoc:
|
|
343
351
|
end
|
344
352
|
|
345
353
|
def add_3ds(post, options)
|
346
|
-
|
347
|
-
|
354
|
+
if three_ds_2_options = options[:three_ds_2]
|
355
|
+
device_channel = three_ds_2_options[:channel]
|
356
|
+
if device_channel == 'app'
|
357
|
+
post[:threeDS2RequestData] = { deviceChannel: device_channel }
|
358
|
+
else
|
359
|
+
add_browser_info(three_ds_2_options[:browser_info], post)
|
360
|
+
post[:threeDS2RequestData] = { deviceChannel: device_channel, notificationURL: three_ds_2_options[:notification_url] }
|
361
|
+
end
|
362
|
+
else
|
363
|
+
return unless options[:execute_threed] || options[:threed_dynamic]
|
364
|
+
post[:browserInfo] = { userAgent: options[:user_agent], acceptHeader: options[:accept_header] }
|
365
|
+
post[:additionalData] = { executeThreeD: 'true' } if options[:execute_threed]
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
def add_browser_info(browser_info, post)
|
370
|
+
return unless browser_info
|
371
|
+
post[:browserInfo] = {
|
372
|
+
acceptHeader: browser_info[:accept_header],
|
373
|
+
colorDepth: browser_info[:depth],
|
374
|
+
javaEnabled: browser_info[:java],
|
375
|
+
language: browser_info[:language],
|
376
|
+
screenHeight: browser_info[:height],
|
377
|
+
screenWidth: browser_info[:width],
|
378
|
+
timeZoneOffset: browser_info[:timezone],
|
379
|
+
userAgent: browser_info[:user_agent]
|
380
|
+
}
|
348
381
|
end
|
349
382
|
end
|
350
383
|
end
|
@@ -93,12 +93,15 @@ module ActiveMerchant #:nodoc:
|
|
93
93
|
|
94
94
|
def void(authorization, options = {})
|
95
95
|
reference, amount, type = split_auth(authorization)
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
96
|
+
if type == TRANSACTIONS[:authorization]
|
97
|
+
capture(0, authorization, options)
|
98
|
+
else
|
99
|
+
post = {}
|
100
|
+
add_reference(post, reference)
|
101
|
+
add_original_amount(post, amount)
|
102
|
+
add_transaction_type(post, void_action(type))
|
103
|
+
commit(post)
|
104
|
+
end
|
102
105
|
end
|
103
106
|
|
104
107
|
def verify(source, options={})
|
@@ -153,6 +156,8 @@ module ActiveMerchant #:nodoc:
|
|
153
156
|
|
154
157
|
# To match the other stored-value gateways, like TrustCommerce,
|
155
158
|
# store and unstore need to be defined
|
159
|
+
#
|
160
|
+
# When passing a single-use token the :name option is required
|
156
161
|
def store(payment_method, options = {})
|
157
162
|
post = {}
|
158
163
|
add_address(post, options)
|
@@ -315,6 +315,9 @@ module ActiveMerchant #:nodoc:
|
|
315
315
|
post[:operationType] = options[:operationType] || options[:operation] || secure_profile_action(:new)
|
316
316
|
post[:customerCode] = options[:billing_id] || options[:vault_id] || false
|
317
317
|
post[:status] = options[:status]
|
318
|
+
|
319
|
+
billing_address = options[:billing_address] || options[:address]
|
320
|
+
post[:trnCardOwner] = billing_address ? billing_address[:name] : nil
|
318
321
|
end
|
319
322
|
|
320
323
|
def add_recurring_amount(post, money)
|
@@ -8,7 +8,7 @@ module ActiveMerchant
|
|
8
8
|
self.supported_countries = %w(US CA GB AT BE BG HR CY CZ DK EE FI FR DE GR HU IE IT LV LT LU MT NL PL PT RO SK SI ES SE AR BO BR BZ CL CO CR DO EC GF GP GT HN HT MF MQ MX NI PA PE PR PY SV UY VE)
|
9
9
|
|
10
10
|
self.default_currency = 'USD'
|
11
|
-
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club, :maestro]
|
11
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club, :maestro, :naranja, :cabal]
|
12
12
|
|
13
13
|
self.homepage_url = 'https://home.bluesnap.com/'
|
14
14
|
self.display_name = 'BlueSnap'
|
@@ -66,6 +66,8 @@ module ActiveMerchant
|
|
66
66
|
'business_savings' => 'CORPORATE_SAVINGS'
|
67
67
|
}
|
68
68
|
|
69
|
+
STATE_CODE_COUNTRIES = %w(US CA)
|
70
|
+
|
69
71
|
def initialize(options={})
|
70
72
|
requires!(options, :api_username, :api_password)
|
71
73
|
super
|
@@ -93,6 +95,7 @@ module ActiveMerchant
|
|
93
95
|
commit(:capture, :put) do |doc|
|
94
96
|
add_authorization(doc, authorization)
|
95
97
|
add_order(doc, options)
|
98
|
+
add_amount(doc, money, options) if options[:include_capture_amount] == true
|
96
99
|
end
|
97
100
|
end
|
98
101
|
|
@@ -220,6 +223,7 @@ module ActiveMerchant
|
|
220
223
|
doc.send('merchant-transaction-id', truncate(options[:order_id], 50)) if options[:order_id]
|
221
224
|
doc.send('soft-descriptor', options[:soft_descriptor]) if options[:soft_descriptor]
|
222
225
|
add_description(doc, options[:description]) if options[:description]
|
226
|
+
add_3ds(doc, options[:three_d_secure]) if options[:three_d_secure]
|
223
227
|
add_level_3_data(doc, options)
|
224
228
|
end
|
225
229
|
|
@@ -228,12 +232,28 @@ module ActiveMerchant
|
|
228
232
|
return unless address
|
229
233
|
|
230
234
|
doc.country(address[:country]) if address[:country]
|
231
|
-
doc.state(address[:state]) if address[:state]
|
235
|
+
doc.state(address[:state]) if address[:state] && STATE_CODE_COUNTRIES.include?(address[:country])
|
232
236
|
doc.address(address[:address]) if address[:address]
|
233
237
|
doc.city(address[:city]) if address[:city]
|
234
238
|
doc.zip(address[:zip]) if address[:zip]
|
235
239
|
end
|
236
240
|
|
241
|
+
def add_3ds(doc, three_d_secure_options)
|
242
|
+
eci = three_d_secure_options[:eci]
|
243
|
+
cavv = three_d_secure_options[:cavv]
|
244
|
+
xid = three_d_secure_options[:xid]
|
245
|
+
ds_transaction_id = three_d_secure_options[:ds_transaction_id]
|
246
|
+
version = three_d_secure_options[:version]
|
247
|
+
|
248
|
+
doc.send('three-d-secure') do
|
249
|
+
doc.eci(eci) if eci
|
250
|
+
doc.cavv(cavv) if cavv
|
251
|
+
doc.xid(xid) if xid
|
252
|
+
doc.send('three-d-secure-version', version) if version
|
253
|
+
doc.send('ds-transaction-id', ds_transaction_id) if ds_transaction_id
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
237
257
|
def add_level_3_data(doc, options)
|
238
258
|
return unless options[:customer_reference_number]
|
239
259
|
doc.send('level-3-data') do
|
@@ -163,10 +163,10 @@ module ActiveMerchant #:nodoc:
|
|
163
163
|
xml.send('PaymentType', payment_type)
|
164
164
|
xml.send('TxnType', 'WEB_SHOP')
|
165
165
|
xml.send('BillerCode', options.fetch(:biller_code, ''))
|
166
|
-
xml.send('MerchantReference',
|
167
|
-
xml.send('CRN1',
|
168
|
-
xml.send('CRN2',
|
169
|
-
xml.send('CRN3',
|
166
|
+
xml.send('MerchantReference', options[:order_id]) if options[:order_id]
|
167
|
+
xml.send('CRN1', options[:crn1]) if options[:crn1]
|
168
|
+
xml.send('CRN2', options[:crn2]) if options[:crn2]
|
169
|
+
xml.send('CRN3', options[:crn3]) if options[:crn3]
|
170
170
|
xml.send('Amount', amount)
|
171
171
|
end
|
172
172
|
|
@@ -419,7 +419,9 @@ module ActiveMerchant #:nodoc:
|
|
419
419
|
'street: A, zip: N' => 'C',
|
420
420
|
'street: A, zip: U' => 'I',
|
421
421
|
'street: A, zip: I' => 'I',
|
422
|
-
'street: A, zip: A' => 'I'
|
422
|
+
'street: A, zip: A' => 'I',
|
423
|
+
|
424
|
+
'street: B, zip: B' => 'B'
|
423
425
|
}
|
424
426
|
end
|
425
427
|
|
@@ -445,7 +447,6 @@ module ActiveMerchant #:nodoc:
|
|
445
447
|
|
446
448
|
def create_transaction(transaction_type, money, credit_card_or_vault_id, options)
|
447
449
|
transaction_params = create_transaction_parameters(money, credit_card_or_vault_id, options)
|
448
|
-
|
449
450
|
commit do
|
450
451
|
result = @braintree_gateway.transaction.send(transaction_type, transaction_params)
|
451
452
|
response = Response.new(result.success?, message_from_transaction_result(result), response_params(result), response_options(result))
|
@@ -565,6 +566,7 @@ module ActiveMerchant #:nodoc:
|
|
565
566
|
'vault_customer' => vault_customer,
|
566
567
|
'merchant_account_id' => transaction.merchant_account_id,
|
567
568
|
'risk_data' => risk_data,
|
569
|
+
'network_transaction_id' => transaction.network_transaction_id || nil,
|
568
570
|
'processor_response_code' => response_code_from_result(result)
|
569
571
|
}
|
570
572
|
end
|
@@ -590,6 +592,14 @@ module ActiveMerchant #:nodoc:
|
|
590
592
|
parameters[:options][:skip_advanced_fraud_checking] = options[:skip_advanced_fraud_checking]
|
591
593
|
end
|
592
594
|
|
595
|
+
if options[:skip_avs]
|
596
|
+
parameters[:options][:skip_avs] = options[:skip_avs]
|
597
|
+
end
|
598
|
+
|
599
|
+
if options[:skip_cvv]
|
600
|
+
parameters[:options][:skip_cvv] = options[:skip_cvv]
|
601
|
+
end
|
602
|
+
|
593
603
|
parameters[:custom_fields] = options[:custom_fields]
|
594
604
|
parameters[:device_data] = options[:device_data] if options[:device_data]
|
595
605
|
parameters[:service_fee_amount] = options[:service_fee_amount] if options[:service_fee_amount]
|
@@ -604,6 +614,7 @@ module ActiveMerchant #:nodoc:
|
|
604
614
|
end
|
605
615
|
|
606
616
|
add_payment_method(parameters, credit_card_or_vault_id, options)
|
617
|
+
add_stored_credential_data(parameters, credit_card_or_vault_id, options)
|
607
618
|
|
608
619
|
parameters[:billing] = map_address(options[:billing_address]) if options[:billing_address]
|
609
620
|
parameters[:shipping] = map_address(options[:shipping_address]) if options[:shipping_address]
|
@@ -619,13 +630,7 @@ module ActiveMerchant #:nodoc:
|
|
619
630
|
}
|
620
631
|
end
|
621
632
|
|
622
|
-
|
623
|
-
parameters[:three_d_secure_pass_thru] = {
|
624
|
-
cavv: options[:three_d_secure][:cavv],
|
625
|
-
eci_flag: options[:three_d_secure][:eci],
|
626
|
-
xid: options[:three_d_secure][:xid],
|
627
|
-
}
|
628
|
-
end
|
633
|
+
add_3ds_info(parameters, options[:three_d_secure])
|
629
634
|
|
630
635
|
parameters[:tax_amount] = options[:tax_amount] if options[:tax_amount]
|
631
636
|
parameters[:tax_exempt] = options[:tax_exempt] if options[:tax_exempt]
|
@@ -640,6 +645,48 @@ module ActiveMerchant #:nodoc:
|
|
640
645
|
parameters
|
641
646
|
end
|
642
647
|
|
648
|
+
def add_3ds_info(parameters, three_d_secure_opts)
|
649
|
+
return if empty?(three_d_secure_opts)
|
650
|
+
pass_thru = {}
|
651
|
+
|
652
|
+
pass_thru[:three_d_secure_version] = three_d_secure_opts[:version] if three_d_secure_opts[:version]
|
653
|
+
pass_thru[:eci_flag] = three_d_secure_opts[:eci] if three_d_secure_opts[:eci]
|
654
|
+
pass_thru[:cavv_algorithm] = three_d_secure_opts[:cavv_algorithm] if three_d_secure_opts[:cavv_algorithm]
|
655
|
+
pass_thru[:cavv] = three_d_secure_opts[:cavv] if three_d_secure_opts[:cavv]
|
656
|
+
pass_thru[:directory_response] = three_d_secure_opts[:directory_response_status] if three_d_secure_opts[:directory_response_status]
|
657
|
+
pass_thru[:authentication_response] = three_d_secure_opts[:authentication_response_status] if three_d_secure_opts[:authentication_response_status]
|
658
|
+
|
659
|
+
parameters[:three_d_secure_pass_thru] = pass_thru.merge(xid_or_ds_trans_id(three_d_secure_opts))
|
660
|
+
end
|
661
|
+
|
662
|
+
def xid_or_ds_trans_id(three_d_secure_opts)
|
663
|
+
if three_d_secure_opts[:version].to_f >= 2
|
664
|
+
{ ds_transaction_id: three_d_secure_opts[:ds_transaction_id] }
|
665
|
+
else
|
666
|
+
{ xid: three_d_secure_opts[:xid] }
|
667
|
+
end
|
668
|
+
end
|
669
|
+
|
670
|
+
def add_stored_credential_data(parameters, credit_card_or_vault_id, options)
|
671
|
+
return unless (stored_credential = options[:stored_credential])
|
672
|
+
parameters[:external_vault] = {}
|
673
|
+
if stored_credential[:initial_transaction]
|
674
|
+
parameters[:external_vault][:status] = 'will_vault'
|
675
|
+
else
|
676
|
+
parameters[:external_vault][:status] = 'vaulted'
|
677
|
+
parameters[:external_vault][:previous_network_transaction_id] = stored_credential[:network_transaction_id]
|
678
|
+
end
|
679
|
+
if stored_credential[:initiator] == 'merchant'
|
680
|
+
if stored_credential[:reason_type] == 'installment'
|
681
|
+
parameters[:transaction_source] = 'recurring'
|
682
|
+
else
|
683
|
+
parameters[:transaction_source] = stored_credential[:reason_type]
|
684
|
+
end
|
685
|
+
else
|
686
|
+
parameters[:transaction_source] = ''
|
687
|
+
end
|
688
|
+
end
|
689
|
+
|
643
690
|
def add_payment_method(parameters, credit_card_or_vault_id, options)
|
644
691
|
if credit_card_or_vault_id.is_a?(String) || credit_card_or_vault_id.is_a?(Integer)
|
645
692
|
if options[:payment_method_token]
|
@@ -68,7 +68,7 @@ module ActiveMerchant #:nodoc:
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def require_valid_domain!(options, param)
|
71
|
-
if options
|
71
|
+
if options[param]
|
72
72
|
raise ArgumentError.new('not a valid cardconnect domain') unless /\Dcardconnect.com:\d{1,}\D/ =~ options[param]
|
73
73
|
end
|
74
74
|
end
|
@@ -233,6 +233,7 @@ module ActiveMerchant #:nodoc:
|
|
233
233
|
item.each_pair do |k, v|
|
234
234
|
updated.merge!(k.to_s.gsub(/_/, '') => v)
|
235
235
|
end
|
236
|
+
updated
|
236
237
|
end
|
237
238
|
end
|
238
239
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module ActiveMerchant #:nodoc:
|
2
2
|
module Billing #:nodoc:
|
3
3
|
class CecabankGateway < Gateway
|
4
|
-
self.test_url = '
|
4
|
+
self.test_url = 'https://tpv.ceca.es'
|
5
5
|
self.live_url = 'https://pgw.ceca.es'
|
6
6
|
|
7
7
|
self.supported_countries = ['ES']
|
@@ -13,14 +13,14 @@ module ActiveMerchant #:nodoc:
|
|
13
13
|
|
14
14
|
#### CECA's MAGIC NUMBERS
|
15
15
|
CECA_NOTIFICATIONS_URL = 'NONE'
|
16
|
-
CECA_ENCRIPTION = '
|
16
|
+
CECA_ENCRIPTION = 'SHA2'
|
17
17
|
CECA_DECIMALS = '2'
|
18
18
|
CECA_MODE = 'SSL'
|
19
19
|
CECA_UI_LESS_LANGUAGE = 'XML'
|
20
20
|
CECA_UI_LESS_LANGUAGE_REFUND = '1'
|
21
21
|
CECA_UI_LESS_REFUND_PAGE = 'anulacion_xml'
|
22
|
-
CECA_ACTION_REFUND = '
|
23
|
-
CECA_ACTION_PURCHASE = 'tpv'
|
22
|
+
CECA_ACTION_REFUND = 'anulaciones/anularParcial' # use partial refund's URL to avoid time frame limitations and decision logic on client side
|
23
|
+
CECA_ACTION_PURCHASE = 'tpv/compra'
|
24
24
|
CECA_CURRENCIES_DICTIONARY = {'EUR' => 978, 'USD' => 840, 'GBP' => 826}
|
25
25
|
|
26
26
|
# Creates a new CecabankGateway
|
@@ -168,8 +168,8 @@ module ActiveMerchant #:nodoc:
|
|
168
168
|
'AcquirerBIN' => options[:acquirer_bin],
|
169
169
|
'TerminalID' => options[:terminal_id]
|
170
170
|
)
|
171
|
-
url = (test? ? self.test_url : self.live_url) + "/
|
172
|
-
xml = ssl_post(url, post_data(parameters))
|
171
|
+
url = (test? ? self.test_url : self.live_url) + "/tpvweb/#{action}.action"
|
172
|
+
xml = ssl_post("#{url}?", post_data(parameters))
|
173
173
|
response = parse(xml)
|
174
174
|
Response.new(
|
175
175
|
response[:success],
|
@@ -242,7 +242,7 @@ module ActiveMerchant #:nodoc:
|
|
242
242
|
CECA_NOTIFICATIONS_URL +
|
243
243
|
CECA_NOTIFICATIONS_URL
|
244
244
|
end
|
245
|
-
Digest::
|
245
|
+
Digest::SHA2.hexdigest(signature_fields)
|
246
246
|
end
|
247
247
|
end
|
248
248
|
end
|
@@ -9,14 +9,14 @@ module ActiveMerchant #:nodoc:
|
|
9
9
|
self.supported_countries = ['AD', 'AE', 'AT', 'BE', 'BG', 'CH', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FO', 'FI', 'FR', 'GB', 'GI', 'GL', 'GR', 'HR', 'HU', 'IE', 'IS', 'IL', 'IT', 'LI', 'LT', 'LU', 'LV', 'MC', 'MT', 'NL', 'NO', 'PL', 'PT', 'RO', 'SE', 'SI', 'SM', 'SK', 'SJ', 'TR', 'VA']
|
10
10
|
self.default_currency = 'USD'
|
11
11
|
self.money_format = :cents
|
12
|
-
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :maestro,
|
12
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :maestro, :discover]
|
13
13
|
|
14
|
-
def initialize(options={})
|
14
|
+
def initialize(options = {})
|
15
15
|
requires!(options, :secret_key)
|
16
16
|
super
|
17
17
|
end
|
18
18
|
|
19
|
-
def purchase(amount, payment_method, options={})
|
19
|
+
def purchase(amount, payment_method, options = {})
|
20
20
|
multi = MultiResponse.run do |r|
|
21
21
|
r.process { authorize(amount, payment_method, options) }
|
22
22
|
r.process { capture(amount, r.authorization, options) }
|
@@ -28,11 +28,11 @@ module ActiveMerchant #:nodoc:
|
|
28
28
|
response(:purchase, succeeded, merged_params)
|
29
29
|
end
|
30
30
|
|
31
|
-
def authorize(amount, payment_method, options={})
|
31
|
+
def authorize(amount, payment_method, options = {})
|
32
32
|
post = {}
|
33
33
|
post[:capture] = false
|
34
34
|
add_invoice(post, amount, options)
|
35
|
-
add_payment_method(post, payment_method)
|
35
|
+
add_payment_method(post, payment_method, options)
|
36
36
|
add_customer_data(post, options)
|
37
37
|
add_transaction_data(post, options)
|
38
38
|
add_3ds(post, options)
|
@@ -40,7 +40,7 @@ module ActiveMerchant #:nodoc:
|
|
40
40
|
commit(:authorize, post)
|
41
41
|
end
|
42
42
|
|
43
|
-
def capture(amount, authorization, options={})
|
43
|
+
def capture(amount, authorization, options = {})
|
44
44
|
post = {}
|
45
45
|
add_invoice(post, amount, options)
|
46
46
|
add_customer_data(post, options)
|
@@ -48,12 +48,12 @@ module ActiveMerchant #:nodoc:
|
|
48
48
|
commit(:capture, post, authorization)
|
49
49
|
end
|
50
50
|
|
51
|
-
def void(authorization,
|
51
|
+
def void(authorization, _options = {})
|
52
52
|
post = {}
|
53
53
|
commit(:void, post, authorization)
|
54
54
|
end
|
55
55
|
|
56
|
-
def refund(amount, authorization, options={})
|
56
|
+
def refund(amount, authorization, options = {})
|
57
57
|
post = {}
|
58
58
|
add_invoice(post, amount, options)
|
59
59
|
add_customer_data(post, options)
|
@@ -61,22 +61,26 @@ module ActiveMerchant #:nodoc:
|
|
61
61
|
commit(:refund, post, authorization)
|
62
62
|
end
|
63
63
|
|
64
|
-
def verify(credit_card, options={})
|
64
|
+
def verify(credit_card, options = {})
|
65
65
|
MultiResponse.run(:use_first_response) do |r|
|
66
66
|
r.process { authorize(100, credit_card, options) }
|
67
67
|
r.process(:ignore_result) { void(r.authorization, options) }
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
+
def verify_payment(authorization, option={})
|
72
|
+
commit(:verify_payment, authorization)
|
73
|
+
end
|
74
|
+
|
71
75
|
def supports_scrubbing?
|
72
76
|
true
|
73
77
|
end
|
74
78
|
|
75
79
|
def scrub(transcript)
|
76
80
|
transcript.
|
77
|
-
gsub(
|
78
|
-
gsub(
|
79
|
-
gsub(
|
81
|
+
gsub(/(Authorization: )[^\\]*/i, '\1[FILTERED]').
|
82
|
+
gsub(/("number\\":\\")\d+/, '\1[FILTERED]').
|
83
|
+
gsub(/("cvv\\":\\")\d+/, '\1[FILTERED]')
|
80
84
|
end
|
81
85
|
|
82
86
|
private
|
@@ -94,7 +98,7 @@ module ActiveMerchant #:nodoc:
|
|
94
98
|
post[:metadata][:udf5] = application_id || 'ActiveMerchant'
|
95
99
|
end
|
96
100
|
|
97
|
-
def add_payment_method(post, payment_method)
|
101
|
+
def add_payment_method(post, payment_method, options)
|
98
102
|
post[:source] = {}
|
99
103
|
post[:source][:type] = 'card'
|
100
104
|
post[:source][:name] = payment_method.name
|
@@ -102,6 +106,7 @@ module ActiveMerchant #:nodoc:
|
|
102
106
|
post[:source][:cvv] = payment_method.verification_value
|
103
107
|
post[:source][:expiry_year] = format(payment_method.year, :four_digits)
|
104
108
|
post[:source][:expiry_month] = format(payment_method.month, :two_digits)
|
109
|
+
post[:source][:stored] = 'true' if options[:card_on_file] == true
|
105
110
|
end
|
106
111
|
|
107
112
|
def add_customer_data(post, options)
|
@@ -109,7 +114,7 @@ module ActiveMerchant #:nodoc:
|
|
109
114
|
post[:customer][:email] = options[:email] || nil
|
110
115
|
post[:payment_ip] = options[:ip] if options[:ip]
|
111
116
|
address = options[:billing_address]
|
112
|
-
if
|
117
|
+
if address && post[:source]
|
113
118
|
post[:source][:billing_address] = {}
|
114
119
|
post[:source][:billing_address][:address_line1] = address[:address1] unless address[:address1].blank?
|
115
120
|
post[:source][:billing_address][:address_line2] = address[:address2] unless address[:address2].blank?
|
@@ -117,36 +122,41 @@ module ActiveMerchant #:nodoc:
|
|
117
122
|
post[:source][:billing_address][:state] = address[:state] unless address[:state].blank?
|
118
123
|
post[:source][:billing_address][:country] = address[:country] unless address[:country].blank?
|
119
124
|
post[:source][:billing_address][:zip] = address[:zip] unless address[:zip].blank?
|
120
|
-
post[:source][:phone] = { number: address[:phone] } unless address[:phone].blank?
|
121
125
|
end
|
122
126
|
end
|
123
127
|
|
124
|
-
def add_transaction_data(post, options={})
|
125
|
-
post[:card_on_file] = true if options[:card_on_file] == true
|
128
|
+
def add_transaction_data(post, options = {})
|
126
129
|
post[:payment_type] = 'Regular' if options[:transaction_indicator] == 1
|
127
130
|
post[:payment_type] = 'Recurring' if options[:transaction_indicator] == 2
|
131
|
+
post[:payment_type] = 'MOTO' if options[:transaction_indicator] == 3 || options.dig(:metadata, :manual_entry)
|
128
132
|
post[:previous_payment_id] = options[:previous_charge_id] if options[:previous_charge_id]
|
129
133
|
end
|
130
134
|
|
131
135
|
def add_3ds(post, options)
|
132
|
-
if options[:three_d_secure]
|
136
|
+
if options[:three_d_secure] || options[:execute_threed]
|
133
137
|
post[:'3ds'] = {}
|
134
138
|
post[:'3ds'][:enabled] = true
|
135
|
-
post[:
|
136
|
-
post[:
|
137
|
-
|
139
|
+
post[:success_url] = options[:callback_url] if options[:callback_url]
|
140
|
+
post[:failure_url] = options[:callback_url] if options[:callback_url]
|
141
|
+
end
|
142
|
+
|
143
|
+
if options[:three_d_secure]
|
144
|
+
post[:'3ds'][:eci] = options[:three_d_secure][:eci] if options[:three_d_secure][:eci]
|
145
|
+
post[:'3ds'][:cryptogram] = options[:three_d_secure][:cavv] if options[:three_d_secure][:cavv]
|
146
|
+
post[:'3ds'][:version] = options[:three_d_secure][:version] if options[:three_d_secure][:version]
|
147
|
+
post[:'3ds'][:xid] = options[:three_d_secure][:ds_transaction_id] || options[:three_d_secure][:xid]
|
138
148
|
end
|
139
149
|
end
|
140
150
|
|
141
151
|
def commit(action, post, authorization = nil)
|
142
152
|
begin
|
143
|
-
raw_response = ssl_post(url(post, action, authorization), post.to_json, headers)
|
153
|
+
raw_response = (action == :verify_payment ? ssl_get("#{base_url}/payments/#{post}", headers) : ssl_post(url(post, action, authorization), post.to_json, headers))
|
144
154
|
response = parse(raw_response)
|
145
155
|
if action == :capture && response.key?('_links')
|
146
156
|
response['id'] = response['_links']['payment']['href'].split('/')[-1]
|
147
157
|
end
|
148
158
|
rescue ResponseError => e
|
149
|
-
raise unless
|
159
|
+
raise unless e.response.code.to_s =~ /4\d\d/
|
150
160
|
response = parse(e.response.body)
|
151
161
|
end
|
152
162
|
|
@@ -175,11 +185,11 @@ module ActiveMerchant #:nodoc:
|
|
175
185
|
def headers
|
176
186
|
{
|
177
187
|
'Authorization' => @options[:secret_key],
|
178
|
-
'Content-Type'
|
188
|
+
'Content-Type' => 'application/json;charset=UTF-8',
|
179
189
|
}
|
180
190
|
end
|
181
191
|
|
182
|
-
def url(
|
192
|
+
def url(_post, action, authorization)
|
183
193
|
if action == :authorize
|
184
194
|
"#{base_url}/payments"
|
185
195
|
elsif action == :capture
|
@@ -215,7 +225,7 @@ module ActiveMerchant #:nodoc:
|
|
215
225
|
end
|
216
226
|
|
217
227
|
def success_from(response)
|
218
|
-
response['response_summary'] == 'Approved' || !response.key?('response_summary') && response.key?('action_id')
|
228
|
+
response['response_summary'] == 'Approved' || response['approved'] == true || !response.key?('response_summary') && response.key?('action_id')
|
219
229
|
end
|
220
230
|
|
221
231
|
def message_from(succeeded, response)
|
@@ -248,7 +258,7 @@ module ActiveMerchant #:nodoc:
|
|
248
258
|
def error_code_from(succeeded, response)
|
249
259
|
return if succeeded
|
250
260
|
if response['error_type'] && response['error_codes']
|
251
|
-
"#{response[
|
261
|
+
"#{response['error_type']}: #{response['error_codes'].join(', ')}"
|
252
262
|
elsif response['error_type']
|
253
263
|
response['error_type']
|
254
264
|
else
|