activemerchant 1.96.0 → 1.97.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +14 -1
- data/lib/active_merchant/billing/credit_card.rb +4 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +33 -2
- data/lib/active_merchant/billing/gateways/adyen.rb +21 -19
- data/lib/active_merchant/billing/gateways/beanstream.rb +2 -0
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +3 -0
- data/lib/active_merchant/billing/gateways/blue_snap.rb +1 -1
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +22 -1
- data/lib/active_merchant/billing/gateways/card_connect.rb +1 -1
- data/lib/active_merchant/billing/gateways/cyber_source.rb +18 -2
- data/lib/active_merchant/billing/gateways/d_local.rb +1 -1
- data/lib/active_merchant/billing/gateways/global_collect.rb +1 -1
- data/lib/active_merchant/billing/gateways/mercado_pago.rb +1 -1
- data/lib/active_merchant/billing/gateways/monei.rb +31 -0
- data/lib/active_merchant/billing/gateways/orbital.rb +60 -10
- data/lib/active_merchant/billing/gateways/paymill.rb +5 -0
- data/lib/active_merchant/billing/gateways/payu_latam.rb +3 -2
- data/lib/active_merchant/billing/gateways/realex.rb +21 -4
- data/lib/active_merchant/billing/gateways/worldpay.rb +2 -1
- data/lib/active_merchant/version.rb +1 -1
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d0f7d776b87d565598558755d845eb264dbee972e2076cb73bca68c4ee33c78
|
4
|
+
data.tar.gz: d08dd14ebabb954845e8a8b951b1ebb66c6d92e1148f4b4187cbe5e47b8cbd36
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 879f72d1da257d47280e668b29238481031287c534868458029f31ffc8bf9498c3385cc90794e2f9391f3c74854b29a4a6d52ce43bb7b51e1d2b1d6f08379ccc
|
7
|
+
data.tar.gz: 70d1898a7869e96841d29d102a44e5b9b5da34c5685185f8a6e57901123af3e81a26f7889a75d942553b8dd8eb83b70c4ac4515e96ad6f7460ccb816d9801394
|
data/CHANGELOG
CHANGED
@@ -2,6 +2,20 @@
|
|
2
2
|
|
3
3
|
== HEAD
|
4
4
|
|
5
|
+
== Version 1.97.0 (Aug 15, 2019)
|
6
|
+
* CyberSource: Add issuer `additionalData` gateway-specific field [jasonxp] #3296
|
7
|
+
* PayU Latam: Add Naranja card type [hdeters] #3299
|
8
|
+
* Adyen: Add app based 3DS requests for auth and purchase [jeremywrowe] #3298
|
9
|
+
* MercadoPago: Add Cabal card type [leila-alderman] #3295
|
10
|
+
* MONEI: Add external MPI 3DS 1 support [jimmyn] #3292
|
11
|
+
* Bambora formerly Beanstream: Pass card owner when storing tokenized cards [alexdunae] #3006
|
12
|
+
* Realex: Prevent error calculating `refund_hash` or `credit_hash` when the secret is nil [jasonxp] #3291
|
13
|
+
* Orbital: Add external MPI support for 3DS1 [pi3r] #3261
|
14
|
+
* Paymill: Add currency and amount to store requests [jasonxp] #3289
|
15
|
+
* Realex: Re-implement credit as general credit [leila-alderman] #3280
|
16
|
+
* Braintree Blue: Support for stored credentials [hdeters] #3286
|
17
|
+
* CardConnect: Move domain from gateway specific to gateway field [hdeters] #3283
|
18
|
+
|
5
19
|
== Version 1.96.0 (Jul 26, 2019)
|
6
20
|
* Bluesnap: Omit state codes for unsupported countries [therufs] #3229
|
7
21
|
* Adyen: Pass updateShopperStatement, industryUsage [curiousepic] #3233
|
@@ -192,7 +206,6 @@
|
|
192
206
|
* Forte: Allow void on capture [nfarve] #3059
|
193
207
|
|
194
208
|
== Version 1.86.0 (October 26, 2018)
|
195
|
-
* UsaEpayTransaction: Support UMcheckformat option for echecks [dtykocki] #3002
|
196
209
|
* Global Collect: handle internal server errors [molbrown] #3005
|
197
210
|
* Barclaycard Smartpay: allow third-party payouts for credits [bpollack] #3009
|
198
211
|
* RuboCop: AlignHash [nfarve] #3004
|
@@ -20,6 +20,8 @@ module ActiveMerchant #:nodoc:
|
|
20
20
|
# * Forbrugsforeningen
|
21
21
|
# * Elo
|
22
22
|
# * Alelo
|
23
|
+
# * Cabal
|
24
|
+
# * Naranja
|
23
25
|
#
|
24
26
|
# For testing purposes, use the 'bogus' credit card brand. This skips the vast majority of
|
25
27
|
# validations, allowing you to focus on your core concerns until you're ready to be more concerned
|
@@ -92,6 +94,8 @@ module ActiveMerchant #:nodoc:
|
|
92
94
|
# * +'forbrugsforeningen'+
|
93
95
|
# * +'elo'+
|
94
96
|
# * +'alelo'+
|
97
|
+
# * +'cabal'+
|
98
|
+
# * +'naranja'+
|
95
99
|
#
|
96
100
|
# Or, if you wish to test your implementation, +'bogus'+.
|
97
101
|
#
|
@@ -9,6 +9,7 @@ module ActiveMerchant #:nodoc:
|
|
9
9
|
'alelo' => ->(num) { num&.size == 16 && in_bin_range?(num.slice(0, 6), ALELO_RANGES) },
|
10
10
|
'discover' => ->(num) { num =~ /^(6011|65\d{2}|64[4-9]\d)\d{12,15}|(62\d{14,17})$/ },
|
11
11
|
'american_express' => ->(num) { num =~ /^3[47]\d{13}$/ },
|
12
|
+
'naranja' => ->(num) { num&.size == 16 && in_bin_range?(num.slice(0, 6), NARANJA_RANGES) },
|
12
13
|
'diners_club' => ->(num) { num =~ /^3(0[0-5]|[68]\d)\d{11}$/ },
|
13
14
|
'jcb' => ->(num) { num =~ /^35(28|29|[3-8]\d)\d{12}$/ },
|
14
15
|
'dankort' => ->(num) { num =~ /^5019\d{12}$/ },
|
@@ -16,6 +17,7 @@ module ActiveMerchant #:nodoc:
|
|
16
17
|
'forbrugsforeningen' => ->(num) { num =~ /^600722\d{10}$/ },
|
17
18
|
'sodexo' => ->(num) { num =~ /^(606071|603389|606070|606069|606068|600818)\d{10}$/ },
|
18
19
|
'vr' => ->(num) { num =~ /^(627416|637036)\d{10}$/ },
|
20
|
+
'cabal' => ->(num) { num&.size == 16 && in_bin_range?(num.slice(0, 8), CABAL_RANGES) },
|
19
21
|
'carnet' => lambda { |num|
|
20
22
|
num&.size == 16 && (
|
21
23
|
in_bin_range?(num.slice(0, 6), CARNET_RANGES) ||
|
@@ -93,6 +95,16 @@ module ActiveMerchant #:nodoc:
|
|
93
95
|
506770..506771, 509015..509019, 509880..509882, 509884..509885, 509987..509988
|
94
96
|
]
|
95
97
|
|
98
|
+
CABAL_RANGES = [
|
99
|
+
60420100..60440099,
|
100
|
+
58965700..58965799,
|
101
|
+
60352200..60352299
|
102
|
+
]
|
103
|
+
|
104
|
+
NARANJA_RANGES = [
|
105
|
+
589562..589562
|
106
|
+
]
|
107
|
+
|
96
108
|
def self.included(base)
|
97
109
|
base.extend(ClassMethods)
|
98
110
|
end
|
@@ -168,7 +180,7 @@ module ActiveMerchant #:nodoc:
|
|
168
180
|
valid_test_mode_card_number?(number) ||
|
169
181
|
valid_card_number_length?(number) &&
|
170
182
|
valid_card_number_characters?(number) &&
|
171
|
-
|
183
|
+
valid_by_algorithm?(brand?(number), number)
|
172
184
|
end
|
173
185
|
|
174
186
|
def card_companies
|
@@ -242,6 +254,15 @@ module ActiveMerchant #:nodoc:
|
|
242
254
|
%w[1 2 3 success failure error].include?(number)
|
243
255
|
end
|
244
256
|
|
257
|
+
def valid_by_algorithm?(brand, numbers) #:nodoc:
|
258
|
+
case brand
|
259
|
+
when 'naranja'
|
260
|
+
valid_naranja_algo?(numbers)
|
261
|
+
else
|
262
|
+
valid_luhn?(numbers)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
245
266
|
ODD_LUHN_VALUE = {
|
246
267
|
48 => 0,
|
247
268
|
49 => 1,
|
@@ -272,7 +293,7 @@ module ActiveMerchant #:nodoc:
|
|
272
293
|
# Checks the validity of a card number by use of the Luhn Algorithm.
|
273
294
|
# Please see http://en.wikipedia.org/wiki/Luhn_algorithm for details.
|
274
295
|
# This implementation is from the luhn_checksum gem, https://github.com/zendesk/luhn_checksum.
|
275
|
-
def
|
296
|
+
def valid_luhn?(numbers) #:nodoc:
|
276
297
|
sum = 0
|
277
298
|
|
278
299
|
odd = true
|
@@ -288,6 +309,16 @@ module ActiveMerchant #:nodoc:
|
|
288
309
|
|
289
310
|
sum % 10 == 0
|
290
311
|
end
|
312
|
+
|
313
|
+
# Checks the validity of a card number by use of Naranja's specific algorithm.
|
314
|
+
def valid_naranja_algo?(numbers) #:nodoc:
|
315
|
+
num_array = numbers.to_s.chars.map(&:to_i)
|
316
|
+
multipliers = [4, 3, 2, 7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2]
|
317
|
+
num_sum = num_array[0..14].zip(multipliers).map { |a, b| a*b }.reduce(:+)
|
318
|
+
intermediate = 11 - (num_sum % 11)
|
319
|
+
final_num = intermediate > 9 ? 0 : intermediate
|
320
|
+
final_num == num_array[15]
|
321
|
+
end
|
291
322
|
end
|
292
323
|
end
|
293
324
|
end
|
@@ -10,7 +10,7 @@ module ActiveMerchant #:nodoc:
|
|
10
10
|
self.supported_countries = ['AT', 'AU', 'BE', 'BG', 'BR', 'CH', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GB', 'GI', 'GR', 'HK', 'HU', 'IE', 'IS', 'IT', 'LI', 'LT', 'LU', 'LV', 'MC', 'MT', 'MX', 'NL', 'NO', 'PL', 'PT', 'RO', 'SE', 'SG', 'SK', 'SI', 'US']
|
11
11
|
self.default_currency = 'USD'
|
12
12
|
self.currencies_without_fractions = %w(CVE DJF GNF IDR JPY KMF KRW PYG RWF UGX VND VUV XAF XOF XPF)
|
13
|
-
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :jcb, :dankort, :maestro, :discover, :elo]
|
13
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :jcb, :dankort, :maestro, :discover, :elo, :naranja]
|
14
14
|
|
15
15
|
self.money_format = :cents
|
16
16
|
|
@@ -328,24 +328,12 @@ module ActiveMerchant #:nodoc:
|
|
328
328
|
|
329
329
|
def add_3ds(post, options)
|
330
330
|
if three_ds_2_options = options[:three_ds_2]
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
screenHeight: browser_info[:height],
|
338
|
-
screenWidth: browser_info[:width],
|
339
|
-
timeZoneOffset: browser_info[:timezone],
|
340
|
-
userAgent: browser_info[:user_agent]
|
341
|
-
}
|
342
|
-
|
343
|
-
if device_channel = three_ds_2_options[:channel]
|
344
|
-
post[:threeDS2RequestData] = {
|
345
|
-
deviceChannel: device_channel,
|
346
|
-
notificationURL: three_ds_2_options[:notification_url] || 'https://example.com/notification'
|
347
|
-
}
|
348
|
-
end
|
331
|
+
device_channel = three_ds_2_options[:channel]
|
332
|
+
if device_channel == 'app'
|
333
|
+
post[:threeDS2RequestData] = { deviceChannel: device_channel }
|
334
|
+
else
|
335
|
+
add_browser_info(three_ds_2_options[:browser_info], post)
|
336
|
+
post[:threeDS2RequestData] = { deviceChannel: device_channel, notificationURL: three_ds_2_options[:notification_url] }
|
349
337
|
end
|
350
338
|
else
|
351
339
|
return unless options[:execute_threed] || options[:threed_dynamic]
|
@@ -457,6 +445,20 @@ module ActiveMerchant #:nodoc:
|
|
457
445
|
def error_code_from(response)
|
458
446
|
STANDARD_ERROR_CODE_MAPPING[response['errorCode']]
|
459
447
|
end
|
448
|
+
|
449
|
+
def add_browser_info(browser_info, post)
|
450
|
+
return unless browser_info
|
451
|
+
post[:browserInfo] = {
|
452
|
+
acceptHeader: browser_info[:accept_header],
|
453
|
+
colorDepth: browser_info[:depth],
|
454
|
+
javaEnabled: browser_info[:java],
|
455
|
+
language: browser_info[:language],
|
456
|
+
screenHeight: browser_info[:height],
|
457
|
+
screenWidth: browser_info[:width],
|
458
|
+
timeZoneOffset: browser_info[:timezone],
|
459
|
+
userAgent: browser_info[:user_agent]
|
460
|
+
}
|
461
|
+
end
|
460
462
|
end
|
461
463
|
end
|
462
464
|
end
|
@@ -153,6 +153,8 @@ module ActiveMerchant #:nodoc:
|
|
153
153
|
|
154
154
|
# To match the other stored-value gateways, like TrustCommerce,
|
155
155
|
# store and unstore need to be defined
|
156
|
+
#
|
157
|
+
# When passing a single-use token the :name option is required
|
156
158
|
def store(payment_method, options = {})
|
157
159
|
post = {}
|
158
160
|
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[:name]
|
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]
|
12
12
|
|
13
13
|
self.homepage_url = 'https://home.bluesnap.com/'
|
14
14
|
self.display_name = 'BlueSnap'
|
@@ -447,7 +447,6 @@ module ActiveMerchant #:nodoc:
|
|
447
447
|
|
448
448
|
def create_transaction(transaction_type, money, credit_card_or_vault_id, options)
|
449
449
|
transaction_params = create_transaction_parameters(money, credit_card_or_vault_id, options)
|
450
|
-
|
451
450
|
commit do
|
452
451
|
result = @braintree_gateway.transaction.send(transaction_type, transaction_params)
|
453
452
|
response = Response.new(result.success?, message_from_transaction_result(result), response_params(result), response_options(result))
|
@@ -567,6 +566,7 @@ module ActiveMerchant #:nodoc:
|
|
567
566
|
'vault_customer' => vault_customer,
|
568
567
|
'merchant_account_id' => transaction.merchant_account_id,
|
569
568
|
'risk_data' => risk_data,
|
569
|
+
'network_transaction_id' => transaction.network_transaction_id || nil,
|
570
570
|
'processor_response_code' => response_code_from_result(result)
|
571
571
|
}
|
572
572
|
end
|
@@ -614,6 +614,7 @@ module ActiveMerchant #:nodoc:
|
|
614
614
|
end
|
615
615
|
|
616
616
|
add_payment_method(parameters, credit_card_or_vault_id, options)
|
617
|
+
add_stored_credential_data(parameters, credit_card_or_vault_id, options)
|
617
618
|
|
618
619
|
parameters[:billing] = map_address(options[:billing_address]) if options[:billing_address]
|
619
620
|
parameters[:shipping] = map_address(options[:shipping_address]) if options[:shipping_address]
|
@@ -650,6 +651,26 @@ module ActiveMerchant #:nodoc:
|
|
650
651
|
parameters
|
651
652
|
end
|
652
653
|
|
654
|
+
def add_stored_credential_data(parameters, credit_card_or_vault_id, options)
|
655
|
+
return unless (stored_credential = options[:stored_credential])
|
656
|
+
parameters[:external_vault] = {}
|
657
|
+
if stored_credential[:initial_transaction]
|
658
|
+
parameters[:external_vault][:status] = 'will_vault'
|
659
|
+
else
|
660
|
+
parameters[:external_vault][:status] = 'vaulted'
|
661
|
+
parameters[:external_vault][:previous_network_transaction_id] = stored_credential[:network_transaction_id]
|
662
|
+
end
|
663
|
+
if stored_credential[:initiator] == 'merchant'
|
664
|
+
if stored_credential[:reason_type] == 'installment'
|
665
|
+
parameters[:transaction_source] = 'recurring'
|
666
|
+
else
|
667
|
+
parameters[:transaction_source] = stored_credential[:reason_type]
|
668
|
+
end
|
669
|
+
else
|
670
|
+
parameters[:transaction_source] = ''
|
671
|
+
end
|
672
|
+
end
|
673
|
+
|
653
674
|
def add_payment_method(parameters, credit_card_or_vault_id, options)
|
654
675
|
if credit_card_or_vault_id.is_a?(String) || credit_card_or_vault_id.is_a?(Integer)
|
655
676
|
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
|
@@ -24,7 +24,9 @@ module ActiveMerchant #:nodoc:
|
|
24
24
|
self.test_url = 'https://ics2wstesta.ic3.com/commerce/1.x/transactionProcessor'
|
25
25
|
self.live_url = 'https://ics2wsa.ic3.com/commerce/1.x/transactionProcessor'
|
26
26
|
|
27
|
-
|
27
|
+
# Schema files can be found here: https://ics2ws.ic3.com/commerce/1.x/transactionProcessor/
|
28
|
+
TEST_XSD_VERSION = '1.156'
|
29
|
+
PRODUCTION_XSD_VERSION = '1.155'
|
28
30
|
|
29
31
|
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb, :dankort, :maestro, :elo]
|
30
32
|
self.supported_countries = %w(US BR CA CN DK FI FR DE IN JP MX NO SE GB SG LB PK)
|
@@ -263,6 +265,8 @@ module ActiveMerchant #:nodoc:
|
|
263
265
|
add_payment_network_token(xml) if network_tokenization?(creditcard_or_reference)
|
264
266
|
add_business_rules_data(xml, creditcard_or_reference, options)
|
265
267
|
add_stored_credential_options(xml, options)
|
268
|
+
add_issuer_additional_data(xml, options)
|
269
|
+
|
266
270
|
xml.target!
|
267
271
|
end
|
268
272
|
|
@@ -301,6 +305,8 @@ module ActiveMerchant #:nodoc:
|
|
301
305
|
add_payment_network_token(xml) if network_tokenization?(payment_method_or_reference)
|
302
306
|
add_business_rules_data(xml, payment_method_or_reference, options) unless options[:pinless_debit_card]
|
303
307
|
end
|
308
|
+
add_issuer_additional_data(xml, options)
|
309
|
+
|
304
310
|
xml.target!
|
305
311
|
end
|
306
312
|
|
@@ -485,6 +491,14 @@ module ActiveMerchant #:nodoc:
|
|
485
491
|
end
|
486
492
|
end
|
487
493
|
|
494
|
+
def add_issuer_additional_data(xml, options)
|
495
|
+
return unless options[:issuer_additional_data]
|
496
|
+
|
497
|
+
xml.tag! 'issuer' do
|
498
|
+
xml.tag! 'additionalData', options[:issuer_additional_data]
|
499
|
+
end
|
500
|
+
end
|
501
|
+
|
488
502
|
def add_mdd_fields(xml, options)
|
489
503
|
return unless options.keys.any? { |key| key.to_s.start_with?('mdd_field') }
|
490
504
|
|
@@ -713,6 +727,8 @@ module ActiveMerchant #:nodoc:
|
|
713
727
|
|
714
728
|
# Where we actually build the full SOAP request using builder
|
715
729
|
def build_request(body, options)
|
730
|
+
xsd_version = test? ? TEST_XSD_VERSION : PRODUCTION_XSD_VERSION
|
731
|
+
|
716
732
|
xml = Builder::XmlMarkup.new :indent => 2
|
717
733
|
xml.instruct!
|
718
734
|
xml.tag! 's:Envelope', {'xmlns:s' => 'http://schemas.xmlsoap.org/soap/envelope/'} do
|
@@ -725,7 +741,7 @@ module ActiveMerchant #:nodoc:
|
|
725
741
|
end
|
726
742
|
end
|
727
743
|
xml.tag! 's:Body', {'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema'} do
|
728
|
-
xml.tag! 'requestMessage', {'xmlns' => "urn:schemas-cybersource-com:transaction-data-#{
|
744
|
+
xml.tag! 'requestMessage', {'xmlns' => "urn:schemas-cybersource-com:transaction-data-#{xsd_version}"} do
|
729
745
|
add_merchant_data(xml, options)
|
730
746
|
xml << body
|
731
747
|
end
|
@@ -6,7 +6,7 @@ module ActiveMerchant #:nodoc:
|
|
6
6
|
|
7
7
|
self.supported_countries = ['AR', 'BR', 'CL', 'CO', 'MX', 'PE', 'UY', 'TR']
|
8
8
|
self.default_currency = 'USD'
|
9
|
-
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club, :maestro]
|
9
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club, :maestro, :naranja]
|
10
10
|
|
11
11
|
self.homepage_url = 'https://dlocal.com/'
|
12
12
|
self.display_name = 'dLocal'
|
@@ -10,7 +10,7 @@ module ActiveMerchant #:nodoc:
|
|
10
10
|
self.supported_countries = ['AD', 'AE', 'AG', 'AI', 'AL', 'AM', 'AO', 'AR', 'AS', 'AT', 'AU', 'AW', 'AX', 'AZ', 'BA', 'BB', 'BD', 'BE', 'BF', 'BG', 'BH', 'BI', 'BJ', 'BL', 'BM', 'BN', 'BO', 'BQ', 'BR', 'BS', 'BT', 'BW', 'BY', 'BZ', 'CA', 'CC', 'CD', 'CF', 'CH', 'CI', 'CK', 'CL', 'CM', 'CN', 'CO', 'CR', 'CU', 'CV', 'CW', 'CX', 'CY', 'CZ', 'DE', 'DJ', 'DK', 'DM', 'DO', 'DZ', 'EC', 'EE', 'EG', 'ER', 'ES', 'ET', 'FI', 'FJ', 'FK', 'FM', 'FO', 'FR', 'GA', 'GB', 'GD', 'GE', 'GF', 'GH', 'GI', 'GL', 'GM', 'GN', 'GP', 'GQ', 'GR', 'GS', 'GT', 'GU', 'GW', 'GY', 'HK', 'HN', 'HR', 'HT', 'HU', 'ID', 'IE', 'IL', 'IM', 'IN', 'IS', 'IT', 'JM', 'JO', 'JP', 'KE', 'KG', 'KH', 'KI', 'KM', 'KN', 'KR', 'KW', 'KY', 'KZ', 'LA', 'LB', 'LC', 'LI', 'LK', 'LR', 'LS', 'LT', 'LU', 'LV', 'MA', 'MC', 'MD', 'ME', 'MF', 'MG', 'MH', 'MK', 'MM', 'MN', 'MO', 'MP', 'MQ', 'MR', 'MS', 'MT', 'MU', 'MV', 'MW', 'MX', 'MY', 'MZ', 'NA', 'NC', 'NE', 'NG', 'NI', 'NL', 'NO', 'NP', 'NR', 'NU', 'NZ', 'OM', 'PA', 'PE', 'PF', 'PG', 'PH', 'PL', 'PN', 'PS', 'PT', 'PW', 'QA', 'RE', 'RO', 'RS', 'RU', 'RW', 'SA', 'SB', 'SC', 'SE', 'SG', 'SH', 'SI', 'SJ', 'SK', 'SL', 'SM', 'SN', 'SR', 'ST', 'SV', 'SZ', 'TC', 'TD', 'TG', 'TH', 'TJ', 'TL', 'TM', 'TN', 'TO', 'TR', 'TT', 'TV', 'TW', 'TZ', 'UA', 'UG', 'US', 'UY', 'UZ', 'VC', 'VE', 'VG', 'VI', 'VN', 'WF', 'WS', 'ZA', 'ZM', 'ZW']
|
11
11
|
self.default_currency = 'USD'
|
12
12
|
self.money_format = :cents
|
13
|
-
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
13
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :naranja]
|
14
14
|
|
15
15
|
def initialize(options={})
|
16
16
|
requires!(options, :merchant_id, :api_key_id, :secret_api_key)
|
@@ -4,7 +4,7 @@ module ActiveMerchant #:nodoc:
|
|
4
4
|
self.live_url = self.test_url = 'https://api.mercadopago.com/v1'
|
5
5
|
|
6
6
|
self.supported_countries = ['AR', 'BR', 'CL', 'CO', 'MX', 'PE', 'UY']
|
7
|
-
self.supported_cardtypes = [:visa, :master, :american_express, :elo]
|
7
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :elo, :cabal, :naranja]
|
8
8
|
|
9
9
|
self.homepage_url = 'https://www.mercadopago.com/'
|
10
10
|
self.display_name = 'Mercado Pago'
|
@@ -133,6 +133,7 @@ module ActiveMerchant #:nodoc:
|
|
133
133
|
add_payment(xml, action, money, options)
|
134
134
|
add_account(xml, credit_card)
|
135
135
|
add_customer(xml, credit_card, options)
|
136
|
+
add_three_d_secure(xml, options)
|
136
137
|
end
|
137
138
|
|
138
139
|
commit(request)
|
@@ -225,6 +226,36 @@ module ActiveMerchant #:nodoc:
|
|
225
226
|
end
|
226
227
|
end
|
227
228
|
|
229
|
+
# Private : Convert ECI to ResultIndicator
|
230
|
+
# Possible ECI values:
|
231
|
+
# 02 or 05 - Fully Authenticated Transaction
|
232
|
+
# 00 or 07 - Non 3D Secure Transaction
|
233
|
+
# Possible ResultIndicator values:
|
234
|
+
# 01 = MASTER_3D_ATTEMPT
|
235
|
+
# 02 = MASTER_3D_SUCCESS
|
236
|
+
# 05 = VISA_3D_SUCCESS
|
237
|
+
# 06 = VISA_3D_ATTEMPT
|
238
|
+
# 07 = DEFAULT_E_COMMERCE
|
239
|
+
def eci_to_result_indicator(eci)
|
240
|
+
case eci
|
241
|
+
when '02', '05'
|
242
|
+
return eci
|
243
|
+
else
|
244
|
+
return '07'
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
# Private : Add the 3DSecure infos to XML
|
249
|
+
def add_three_d_secure(xml, options)
|
250
|
+
if options[:three_d_secure]
|
251
|
+
xml.Authentication(:type => '3DSecure') do
|
252
|
+
xml.ResultIndicator eci_to_result_indicator options[:three_d_secure][:eci]
|
253
|
+
xml.Parameter(:name => 'VERIFICATION_ID') { xml.text options[:three_d_secure][:cavv] }
|
254
|
+
xml.Parameter(:name => 'XID') { xml.text options[:three_d_secure][:xid] }
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
228
259
|
# Private: Parse XML response from Monei servers
|
229
260
|
def parse(body)
|
230
261
|
xml = Nokogiri::XML(body)
|
@@ -465,16 +465,62 @@ module ActiveMerchant #:nodoc:
|
|
465
465
|
end
|
466
466
|
end
|
467
467
|
|
468
|
-
def
|
469
|
-
|
470
|
-
|
468
|
+
def add_eci(xml, creditcard, three_d_secure)
|
469
|
+
eci = if three_d_secure
|
470
|
+
three_d_secure[:eci]
|
471
|
+
elsif creditcard.is_a?(NetworkTokenizationCreditCard)
|
472
|
+
creditcard.eci
|
473
|
+
end
|
474
|
+
|
475
|
+
xml.tag!(:AuthenticationECIInd, eci) if eci
|
476
|
+
end
|
477
|
+
|
478
|
+
def add_xid(xml, creditcard, three_d_secure)
|
479
|
+
xid = if three_d_secure && creditcard.brand == 'visa'
|
480
|
+
three_d_secure[:xid]
|
481
|
+
elsif creditcard.is_a?(NetworkTokenizationCreditCard)
|
482
|
+
creditcard.transaction_id
|
483
|
+
end
|
484
|
+
|
485
|
+
xml.tag!(:XID, xid) if xid
|
486
|
+
end
|
487
|
+
|
488
|
+
def add_cavv(xml, creditcard, three_d_secure)
|
489
|
+
return unless three_d_secure && creditcard.brand == 'visa'
|
490
|
+
|
491
|
+
xml.tag!(:CAVV, three_d_secure[:cavv])
|
492
|
+
end
|
493
|
+
|
494
|
+
def add_aav(xml, creditcard, three_d_secure)
|
495
|
+
return unless three_d_secure && creditcard.brand == 'master'
|
496
|
+
|
497
|
+
xml.tag!(:AAV, three_d_secure[:cavv])
|
471
498
|
end
|
472
499
|
|
473
|
-
def
|
500
|
+
def add_dpanind(xml, creditcard)
|
501
|
+
return unless creditcard.is_a?(NetworkTokenizationCreditCard)
|
502
|
+
|
474
503
|
xml.tag! :DPANInd, 'Y'
|
504
|
+
end
|
505
|
+
|
506
|
+
def add_digital_token_cryptogram(xml, creditcard)
|
507
|
+
return unless creditcard.is_a?(NetworkTokenizationCreditCard)
|
508
|
+
|
475
509
|
xml.tag! :DigitalTokenCryptogram, creditcard.payment_cryptogram
|
476
510
|
end
|
477
511
|
|
512
|
+
def add_aevv(xml, creditcard, three_d_secure)
|
513
|
+
return unless three_d_secure && creditcard.brand == 'american_express'
|
514
|
+
|
515
|
+
xml.tag!(:AEVV, three_d_secure[:cavv])
|
516
|
+
end
|
517
|
+
|
518
|
+
def add_pymt_brand_program_code(xml, creditcard, three_d_secure)
|
519
|
+
return unless three_d_secure && creditcard.brand == 'american_express'
|
520
|
+
|
521
|
+
xml.tag!(:PymtBrandProgramCode, 'ASK')
|
522
|
+
end
|
523
|
+
|
478
524
|
def add_refund(xml, currency=nil)
|
479
525
|
xml.tag! :AccountNum, nil
|
480
526
|
|
@@ -633,9 +679,11 @@ module ActiveMerchant #:nodoc:
|
|
633
679
|
|
634
680
|
yield xml if block_given?
|
635
681
|
|
636
|
-
|
637
|
-
|
638
|
-
|
682
|
+
three_d_secure = parameters[:three_d_secure]
|
683
|
+
|
684
|
+
add_eci(xml, creditcard, three_d_secure)
|
685
|
+
add_cavv(xml, creditcard, three_d_secure)
|
686
|
+
add_xid(xml, creditcard, three_d_secure)
|
639
687
|
|
640
688
|
xml.tag! :OrderID, format_order_id(parameters[:order_id])
|
641
689
|
xml.tag! :Amount, amount(money)
|
@@ -644,11 +692,12 @@ module ActiveMerchant #:nodoc:
|
|
644
692
|
add_level_2_tax(xml, parameters)
|
645
693
|
add_level_2_advice_addendum(xml, parameters)
|
646
694
|
|
695
|
+
add_aav(xml, creditcard, three_d_secure)
|
647
696
|
# CustomerAni, AVSPhoneType and AVSDestPhoneType could be added here.
|
648
697
|
|
649
|
-
|
650
|
-
|
651
|
-
|
698
|
+
add_dpanind(xml, creditcard)
|
699
|
+
add_aevv(xml, creditcard, three_d_secure)
|
700
|
+
add_digital_token_cryptogram(xml, creditcard)
|
652
701
|
|
653
702
|
if parameters[:soft_descriptors].is_a?(OrbitalSoftDescriptors)
|
654
703
|
add_soft_descriptors(xml, parameters[:soft_descriptors])
|
@@ -666,6 +715,7 @@ module ActiveMerchant #:nodoc:
|
|
666
715
|
|
667
716
|
add_level_2_purchase(xml, parameters)
|
668
717
|
add_stored_credentials(xml, parameters)
|
718
|
+
add_pymt_brand_program_code(xml, creditcard, three_d_secure)
|
669
719
|
end
|
670
720
|
end
|
671
721
|
xml.target!
|
@@ -48,6 +48,11 @@ module ActiveMerchant #:nodoc:
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def store(credit_card, options={})
|
51
|
+
# The store request requires a currency and amount of at least $1 USD.
|
52
|
+
# This is used for an authorization that is handled internally by Paymill.
|
53
|
+
options[:currency] = 'USD'
|
54
|
+
options[:money] = 100
|
55
|
+
|
51
56
|
save_card(credit_card, options)
|
52
57
|
end
|
53
58
|
|
@@ -12,13 +12,14 @@ module ActiveMerchant #:nodoc:
|
|
12
12
|
self.supported_countries = ['AR', 'BR', 'CL', 'CO', 'MX', 'PA', 'PE']
|
13
13
|
self.default_currency = 'USD'
|
14
14
|
self.money_format = :dollars
|
15
|
-
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club]
|
15
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :naranja]
|
16
16
|
|
17
17
|
BRAND_MAP = {
|
18
18
|
'visa' => 'VISA',
|
19
19
|
'master' => 'MASTERCARD',
|
20
20
|
'american_express' => 'AMEX',
|
21
|
-
'diners_club' => 'DINERS'
|
21
|
+
'diners_club' => 'DINERS',
|
22
|
+
'naranja' => 'NARANJA'
|
22
23
|
}
|
23
24
|
|
24
25
|
MINIMUMS = {
|
@@ -42,7 +42,8 @@ module ActiveMerchant
|
|
42
42
|
|
43
43
|
def initialize(options = {})
|
44
44
|
requires!(options, :login, :password)
|
45
|
-
options[:refund_hash] = Digest::SHA1.hexdigest(options[:rebate_secret]) if options.
|
45
|
+
options[:refund_hash] = Digest::SHA1.hexdigest(options[:rebate_secret]) if options[:rebate_secret].present?
|
46
|
+
options[:credit_hash] = Digest::SHA1.hexdigest(options[:refund_secret]) if options[:refund_secret].present?
|
46
47
|
super
|
47
48
|
end
|
48
49
|
|
@@ -70,9 +71,9 @@ module ActiveMerchant
|
|
70
71
|
commit(request)
|
71
72
|
end
|
72
73
|
|
73
|
-
def credit(money,
|
74
|
-
|
75
|
-
|
74
|
+
def credit(money, creditcard, options = {})
|
75
|
+
request = build_credit_request(money, creditcard, options)
|
76
|
+
commit(request)
|
76
77
|
end
|
77
78
|
|
78
79
|
def void(authorization, options = {})
|
@@ -184,6 +185,22 @@ module ActiveMerchant
|
|
184
185
|
xml.target!
|
185
186
|
end
|
186
187
|
|
188
|
+
def build_credit_request(money, credit_card, options)
|
189
|
+
timestamp = new_timestamp
|
190
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
191
|
+
xml.tag! 'request', 'timestamp' => timestamp, 'type' => 'credit' do
|
192
|
+
add_merchant_details(xml, options)
|
193
|
+
xml.tag! 'orderid', sanitize_order_id(options[:order_id])
|
194
|
+
add_amount(xml, money, options)
|
195
|
+
add_card(xml, credit_card)
|
196
|
+
xml.tag! 'refundhash', @options[:credit_hash] if @options[:credit_hash]
|
197
|
+
xml.tag! 'autosettle', 'flag' => 1
|
198
|
+
add_comments(xml, options)
|
199
|
+
add_signed_digest(xml, timestamp, @options[:login], sanitize_order_id(options[:order_id]), amount(money), (options[:currency] || currency(money)), credit_card.number)
|
200
|
+
end
|
201
|
+
xml.target!
|
202
|
+
end
|
203
|
+
|
187
204
|
def build_void_request(authorization, options)
|
188
205
|
timestamp = new_timestamp
|
189
206
|
xml = Builder::XmlMarkup.new :indent => 2
|
@@ -7,7 +7,7 @@ module ActiveMerchant #:nodoc:
|
|
7
7
|
self.default_currency = 'GBP'
|
8
8
|
self.money_format = :cents
|
9
9
|
self.supported_countries = %w(HK GB AU AD AR BE BR CA CH CN CO CR CY CZ DE DK ES FI FR GI GR HU IE IN IT JP LI LU MC MT MY MX NL NO NZ PA PE PL PT SE SG SI SM TR UM VA)
|
10
|
-
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :maestro, :elo]
|
10
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :maestro, :elo, :naranja]
|
11
11
|
self.currencies_without_fractions = %w(HUF IDR ISK JPY KRW)
|
12
12
|
self.currencies_with_three_decimal_places = %w(BHD KWD OMR RSD TND)
|
13
13
|
self.homepage_url = 'http://www.worldpay.com/'
|
@@ -22,6 +22,7 @@ module ActiveMerchant #:nodoc:
|
|
22
22
|
'maestro' => 'MAESTRO-SSL',
|
23
23
|
'diners_club' => 'DINERS-SSL',
|
24
24
|
'elo' => 'ELO-SSL',
|
25
|
+
'naranja' => 'NARANJA-SSL',
|
25
26
|
'unknown' => 'CARD-SSL'
|
26
27
|
}
|
27
28
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activemerchant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.97.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tobias Luetke
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -413,8 +413,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
413
413
|
- !ruby/object:Gem::Version
|
414
414
|
version: '0'
|
415
415
|
requirements: []
|
416
|
-
|
417
|
-
rubygems_version: 2.7.6
|
416
|
+
rubygems_version: 3.0.3
|
418
417
|
signing_key:
|
419
418
|
specification_version: 4
|
420
419
|
summary: Framework and tools for dealing with credit card transactions.
|