activemerchant 1.93.0 → 1.98.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +111 -0
- 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 +67 -4
- data/lib/active_merchant/billing/gateway.rb +10 -0
- data/lib/active_merchant/billing/gateways/adyen.rb +106 -22
- data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +43 -10
- 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 +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 +3 -1
- data/lib/active_merchant/billing/gateways/cecabank.rb +7 -7
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +98 -61
- data/lib/active_merchant/billing/gateways/credorax.rb +29 -3
- data/lib/active_merchant/billing/gateways/cyber_source.rb +30 -13
- data/lib/active_merchant/billing/gateways/d_local.rb +1 -1
- data/lib/active_merchant/billing/gateways/decidir.rb +233 -0
- data/lib/active_merchant/billing/gateways/elavon.rb +9 -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/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 +3 -2
- 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 +40 -2
- 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/spreedly_core.rb +43 -29
- data/lib/active_merchant/billing/gateways/stripe.rb +54 -9
- data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +267 -0
- 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 +171 -39
- data/lib/active_merchant/country.rb +1 -0
- data/lib/active_merchant/version.rb +1 -1
- metadata +19 -4
@@ -6,6 +6,10 @@ module ActiveMerchant #:nodoc:
|
|
6
6
|
self.display_name = 'Credorax Gateway'
|
7
7
|
self.homepage_url = 'https://www.credorax.com/'
|
8
8
|
|
9
|
+
# NOTE: the IP address you run the remote tests from will need to be
|
10
|
+
# whitelisted by Credorax; contact support@credorax.com as necessary to
|
11
|
+
# request your IP address be added to the whitelist for your test
|
12
|
+
# account.
|
9
13
|
self.test_url = 'https://intconsole.credorax.com/intenv/service/gateway'
|
10
14
|
|
11
15
|
# The live URL is assigned on a per merchant basis once certification has passed
|
@@ -15,7 +19,7 @@ module ActiveMerchant #:nodoc:
|
|
15
19
|
# ActiveMerchant::Billing::CredoraxGateway.live_url = "https://assigned-subdomain.credorax.net/crax_gate/service/gateway"
|
16
20
|
self.live_url = 'https://assigned-subdomain.credorax.net/crax_gate/service/gateway'
|
17
21
|
|
18
|
-
self.supported_countries = %w(
|
22
|
+
self.supported_countries = %w(AD AT BE BG HR CY CZ DK EE FR DE GI GR GG HU IS IE IM IT JE LV LI LT LU MT MC NO PL PT RO SM SK ES SE CH GB)
|
19
23
|
self.default_currency = 'EUR'
|
20
24
|
self.currencies_without_fractions = %w(CLP JPY KRW PYG VND)
|
21
25
|
self.currencies_with_three_decimal_places = %w(BHD JOD KWD OMR RSD TND)
|
@@ -264,8 +268,30 @@ module ActiveMerchant #:nodoc:
|
|
264
268
|
end
|
265
269
|
|
266
270
|
def add_3d_secure(post, options)
|
267
|
-
|
268
|
-
|
271
|
+
if options[:eci] && options[:xid]
|
272
|
+
add_3d_secure_1_data(post, options)
|
273
|
+
elsif options[:three_d_secure]
|
274
|
+
add_normalized_3d_secure_2_data(post, options)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
def add_3d_secure_1_data(post, options)
|
279
|
+
post[:i8] = build_i8(options[:eci], options[:cavv], options[:xid])
|
280
|
+
end
|
281
|
+
|
282
|
+
def add_normalized_3d_secure_2_data(post, options)
|
283
|
+
three_d_secure_options = options[:three_d_secure]
|
284
|
+
|
285
|
+
post[:i8] = build_i8(
|
286
|
+
three_d_secure_options[:eci],
|
287
|
+
three_d_secure_options[:cavv]
|
288
|
+
)
|
289
|
+
post[:'3ds_version'] = three_d_secure_options[:version]
|
290
|
+
post[:'3ds_dstrxid'] = three_d_secure_options[:ds_transaction_id]
|
291
|
+
end
|
292
|
+
|
293
|
+
def build_i8(eci, cavv=nil, xid=nil)
|
294
|
+
"#{eci}:#{cavv || 'none'}:#{xid || 'none'}"
|
269
295
|
end
|
270
296
|
|
271
297
|
def add_echo(post, options)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module ActiveMerchant #:nodoc:
|
2
2
|
module Billing #:nodoc:
|
3
3
|
# Initial setup instructions can be found in
|
4
|
-
# http://cybersource.com/
|
4
|
+
# http://apps.cybersource.com/library/documentation/dev_guides/SOAP_Toolkits/SOAP_toolkits.pdf
|
5
5
|
#
|
6
6
|
# Important Notes
|
7
7
|
# * For checks you can purchase and store.
|
@@ -24,10 +24,12 @@ 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
|
-
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb, :dankort, :maestro]
|
30
|
-
self.supported_countries = %w(US BR CA CN DK FI FR DE IN JP MX NO SE GB SG LB)
|
31
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb, :dankort, :maestro, :elo]
|
32
|
+
self.supported_countries = %w(US BR CA CN DK FI FR DE IN JP MX NO SE GB SG LB PK)
|
31
33
|
|
32
34
|
self.default_currency = 'USD'
|
33
35
|
self.currencies_without_fractions = %w(JPY)
|
@@ -43,7 +45,8 @@ module ActiveMerchant #:nodoc:
|
|
43
45
|
:diners_club => '005',
|
44
46
|
:jcb => '007',
|
45
47
|
:dankort => '034',
|
46
|
-
:maestro => '042'
|
48
|
+
:maestro => '042',
|
49
|
+
:elo => '054'
|
47
50
|
}
|
48
51
|
|
49
52
|
@@response_codes = {
|
@@ -142,9 +145,10 @@ module ActiveMerchant #:nodoc:
|
|
142
145
|
end
|
143
146
|
end
|
144
147
|
|
145
|
-
# Adds credit to a subscription (stand alone credit).
|
146
|
-
def credit(money,
|
147
|
-
|
148
|
+
# Adds credit to a card or subscription (stand alone credit).
|
149
|
+
def credit(money, creditcard_or_reference, options = {})
|
150
|
+
setup_address_hash(options)
|
151
|
+
commit(build_credit_request(money, creditcard_or_reference, options), :credit, money, options)
|
148
152
|
end
|
149
153
|
|
150
154
|
# Stores a customer subscription/profile with type "on-demand".
|
@@ -261,6 +265,8 @@ module ActiveMerchant #:nodoc:
|
|
261
265
|
add_payment_network_token(xml) if network_tokenization?(creditcard_or_reference)
|
262
266
|
add_business_rules_data(xml, creditcard_or_reference, options)
|
263
267
|
add_stored_credential_options(xml, options)
|
268
|
+
add_issuer_additional_data(xml, options)
|
269
|
+
|
264
270
|
xml.target!
|
265
271
|
end
|
266
272
|
|
@@ -299,6 +305,8 @@ module ActiveMerchant #:nodoc:
|
|
299
305
|
add_payment_network_token(xml) if network_tokenization?(payment_method_or_reference)
|
300
306
|
add_business_rules_data(xml, payment_method_or_reference, options) unless options[:pinless_debit_card]
|
301
307
|
end
|
308
|
+
add_issuer_additional_data(xml, options)
|
309
|
+
|
302
310
|
xml.target!
|
303
311
|
end
|
304
312
|
|
@@ -327,11 +335,10 @@ module ActiveMerchant #:nodoc:
|
|
327
335
|
xml.target!
|
328
336
|
end
|
329
337
|
|
330
|
-
def build_credit_request(money,
|
338
|
+
def build_credit_request(money, creditcard_or_reference, options)
|
331
339
|
xml = Builder::XmlMarkup.new :indent => 2
|
332
340
|
|
333
|
-
|
334
|
-
add_subscription(xml, options, reference)
|
341
|
+
add_payment_method_or_subscription(xml, money, creditcard_or_reference, options)
|
335
342
|
add_credit_service(xml)
|
336
343
|
|
337
344
|
xml.target!
|
@@ -484,6 +491,14 @@ module ActiveMerchant #:nodoc:
|
|
484
491
|
end
|
485
492
|
end
|
486
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
|
+
|
487
502
|
def add_mdd_fields(xml, options)
|
488
503
|
return unless options.keys.any? { |key| key.to_s.start_with?('mdd_field') }
|
489
504
|
|
@@ -549,7 +564,7 @@ module ActiveMerchant #:nodoc:
|
|
549
564
|
xml.tag!('commerceIndicator', 'vbv')
|
550
565
|
xml.tag!('xid', payment_method.payment_cryptogram)
|
551
566
|
end
|
552
|
-
when :
|
567
|
+
when :master
|
553
568
|
xml.tag! 'ucaf' do
|
554
569
|
xml.tag!('authenticationData', payment_method.payment_cryptogram)
|
555
570
|
xml.tag!('collectionIndicator', '2')
|
@@ -712,6 +727,8 @@ module ActiveMerchant #:nodoc:
|
|
712
727
|
|
713
728
|
# Where we actually build the full SOAP request using builder
|
714
729
|
def build_request(body, options)
|
730
|
+
xsd_version = test? ? TEST_XSD_VERSION : PRODUCTION_XSD_VERSION
|
731
|
+
|
715
732
|
xml = Builder::XmlMarkup.new :indent => 2
|
716
733
|
xml.instruct!
|
717
734
|
xml.tag! 's:Envelope', {'xmlns:s' => 'http://schemas.xmlsoap.org/soap/envelope/'} do
|
@@ -724,7 +741,7 @@ module ActiveMerchant #:nodoc:
|
|
724
741
|
end
|
725
742
|
end
|
726
743
|
xml.tag! 's:Body', {'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema'} do
|
727
|
-
xml.tag! 'requestMessage', {'xmlns' => "urn:schemas-cybersource-com:transaction-data-#{
|
744
|
+
xml.tag! 'requestMessage', {'xmlns' => "urn:schemas-cybersource-com:transaction-data-#{xsd_version}"} do
|
728
745
|
add_merchant_data(xml, options)
|
729
746
|
xml << body
|
730
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, :cabal]
|
10
10
|
|
11
11
|
self.homepage_url = 'https://dlocal.com/'
|
12
12
|
self.display_name = 'dLocal'
|
@@ -0,0 +1,233 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class DecidirGateway < Gateway
|
4
|
+
self.test_url = 'https://developers.decidir.com/api/v2'
|
5
|
+
self.live_url = 'https://live.decidir.com/api/v2'
|
6
|
+
|
7
|
+
self.supported_countries = ['AR']
|
8
|
+
self.money_format = :cents
|
9
|
+
self.default_currency = 'ARS'
|
10
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :naranja, :cabal]
|
11
|
+
|
12
|
+
self.homepage_url = 'http://www.decidir.com'
|
13
|
+
self.display_name = 'Decidir'
|
14
|
+
|
15
|
+
STANDARD_ERROR_CODE_MAPPING = {
|
16
|
+
1 => STANDARD_ERROR_CODE[:call_issuer],
|
17
|
+
2 => STANDARD_ERROR_CODE[:call_issuer],
|
18
|
+
3 => STANDARD_ERROR_CODE[:config_error],
|
19
|
+
4 => STANDARD_ERROR_CODE[:pickup_card],
|
20
|
+
5 => STANDARD_ERROR_CODE[:card_declined],
|
21
|
+
7 => STANDARD_ERROR_CODE[:pickup_card],
|
22
|
+
12 => STANDARD_ERROR_CODE[:processing_error],
|
23
|
+
14 => STANDARD_ERROR_CODE[:invalid_number],
|
24
|
+
28 => STANDARD_ERROR_CODE[:processing_error],
|
25
|
+
38 => STANDARD_ERROR_CODE[:incorrect_pin],
|
26
|
+
39 => STANDARD_ERROR_CODE[:invalid_number],
|
27
|
+
43 => STANDARD_ERROR_CODE[:pickup_card],
|
28
|
+
45 => STANDARD_ERROR_CODE[:card_declined],
|
29
|
+
46 => STANDARD_ERROR_CODE[:invalid_number],
|
30
|
+
47 => STANDARD_ERROR_CODE[:card_declined],
|
31
|
+
48 => STANDARD_ERROR_CODE[:card_declined],
|
32
|
+
49 => STANDARD_ERROR_CODE[:invalid_expiry_date],
|
33
|
+
51 => STANDARD_ERROR_CODE[:card_declined],
|
34
|
+
53 => STANDARD_ERROR_CODE[:card_declined],
|
35
|
+
54 => STANDARD_ERROR_CODE[:expired_card],
|
36
|
+
55 => STANDARD_ERROR_CODE[:incorrect_pin],
|
37
|
+
56 => STANDARD_ERROR_CODE[:card_declined],
|
38
|
+
57 => STANDARD_ERROR_CODE[:card_declined],
|
39
|
+
76 => STANDARD_ERROR_CODE[:call_issuer],
|
40
|
+
96 => STANDARD_ERROR_CODE[:processing_error],
|
41
|
+
97 => STANDARD_ERROR_CODE[:processing_error],
|
42
|
+
}
|
43
|
+
|
44
|
+
def initialize(options={})
|
45
|
+
requires!(options, :api_key)
|
46
|
+
super
|
47
|
+
@options[:preauth_mode] ||= false
|
48
|
+
end
|
49
|
+
|
50
|
+
def purchase(money, payment, options={})
|
51
|
+
raise ArgumentError, 'Purchase is not supported on Decidir gateways configured with the preauth_mode option' if @options[:preauth_mode]
|
52
|
+
|
53
|
+
post = {}
|
54
|
+
add_auth_purchase_params(post, money, payment, options)
|
55
|
+
commit(:post, 'payments', post)
|
56
|
+
end
|
57
|
+
|
58
|
+
def authorize(money, payment, options={})
|
59
|
+
raise ArgumentError, 'Authorize is not supported on Decidir gateways unless the preauth_mode option is enabled' unless @options[:preauth_mode]
|
60
|
+
|
61
|
+
post = {}
|
62
|
+
add_auth_purchase_params(post, money, payment, options)
|
63
|
+
commit(:post, 'payments', post)
|
64
|
+
end
|
65
|
+
|
66
|
+
def capture(money, authorization, options={})
|
67
|
+
raise ArgumentError, 'Capture is not supported on Decidir gateways unless the preauth_mode option is enabled' unless @options[:preauth_mode]
|
68
|
+
|
69
|
+
post = {}
|
70
|
+
add_amount(post, money, options)
|
71
|
+
commit(:put, "payments/#{authorization}", post)
|
72
|
+
end
|
73
|
+
|
74
|
+
def refund(money, authorization, options={})
|
75
|
+
post = {}
|
76
|
+
add_amount(post, money, options)
|
77
|
+
commit(:post, "payments/#{authorization}/refunds", post)
|
78
|
+
end
|
79
|
+
|
80
|
+
def void(authorization, options={})
|
81
|
+
post = {}
|
82
|
+
commit(:post, "payments/#{authorization}/refunds", post)
|
83
|
+
end
|
84
|
+
|
85
|
+
def verify(credit_card, options={})
|
86
|
+
raise ArgumentError, 'Verify is not supported on Decidir gateways unless the preauth_mode option is enabled' unless @options[:preauth_mode]
|
87
|
+
|
88
|
+
MultiResponse.run(:use_first_response) do |r|
|
89
|
+
r.process { authorize(100, credit_card, options) }
|
90
|
+
r.process(:ignore_result) { void(r.authorization, options) }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def supports_scrubbing?
|
95
|
+
true
|
96
|
+
end
|
97
|
+
|
98
|
+
def scrub(transcript)
|
99
|
+
transcript.
|
100
|
+
gsub(%r((apikey: )\w+)i, '\1[FILTERED]').
|
101
|
+
gsub(%r((\"card_number\\\":\\\")\d+), '\1[FILTERED]').
|
102
|
+
gsub(%r((\"security_code\\\":\\\")\d+), '\1[FILTERED]').
|
103
|
+
gsub(%r((\"emv_issuer_data\\\":\\\")\d+), '\1[FILTERED]')
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
def add_auth_purchase_params(post, money, credit_card, options)
|
109
|
+
post[:payment_method_id] = options[:payment_method_id] ? options[:payment_method_id].to_i : 1
|
110
|
+
post[:site_transaction_id] = options[:order_id]
|
111
|
+
post[:bin] = credit_card.number[0..5]
|
112
|
+
post[:payment_type] = options[:payment_type] || 'single'
|
113
|
+
post[:installments] = options[:installments] ? options[:installments].to_i : 1
|
114
|
+
post[:description] = options[:description] if options[:description]
|
115
|
+
post[:email] = options[:email] if options[:email]
|
116
|
+
post[:sub_payments] = []
|
117
|
+
|
118
|
+
add_invoice(post, money, options)
|
119
|
+
add_payment(post, credit_card, options)
|
120
|
+
end
|
121
|
+
|
122
|
+
def add_invoice(post, money, options)
|
123
|
+
add_amount(post, money, options)
|
124
|
+
post[:currency] = (options[:currency] || currency(money))
|
125
|
+
end
|
126
|
+
|
127
|
+
def add_amount(post, money, options)
|
128
|
+
currency = (options[:currency] || currency(money))
|
129
|
+
post[:amount] = localized_amount(money, currency).to_i
|
130
|
+
end
|
131
|
+
|
132
|
+
def add_payment(post, credit_card, options)
|
133
|
+
card_data = {}
|
134
|
+
card_data[:card_number] = credit_card.number
|
135
|
+
card_data[:card_expiration_month] = format(credit_card.month, :two_digits)
|
136
|
+
card_data[:card_expiration_year] = format(credit_card.year, :two_digits)
|
137
|
+
card_data[:security_code] = credit_card.verification_value if credit_card.verification_value?
|
138
|
+
card_data[:card_holder_name] = credit_card.name if credit_card.name
|
139
|
+
|
140
|
+
# additional data used for Visa transactions
|
141
|
+
card_data[:card_holder_door_number] = options[:card_holder_door_number].to_i if options[:card_holder_door_number]
|
142
|
+
card_data[:card_holder_birthday] = options[:card_holder_birthday] if options[:card_holder_birthday]
|
143
|
+
|
144
|
+
card_data[:card_holder_identification] = {}
|
145
|
+
card_data[:card_holder_identification][:type] = options[:card_holder_identification_type] if options[:card_holder_identification_type]
|
146
|
+
card_data[:card_holder_identification][:number] = options[:card_holder_identification_number] if options[:card_holder_identification_number]
|
147
|
+
|
148
|
+
post[:card_data] = card_data
|
149
|
+
end
|
150
|
+
|
151
|
+
def headers(options = {})
|
152
|
+
{
|
153
|
+
'apikey' => @options[:api_key],
|
154
|
+
'Content-type' => 'application/json',
|
155
|
+
'Cache-Control' => 'no-cache'
|
156
|
+
}
|
157
|
+
end
|
158
|
+
|
159
|
+
def commit(method, endpoint, parameters, options={})
|
160
|
+
url = "#{(test? ? test_url : live_url)}/#{endpoint}"
|
161
|
+
|
162
|
+
begin
|
163
|
+
raw_response = ssl_request(method, url, post_data(parameters), headers(options))
|
164
|
+
response = parse(raw_response)
|
165
|
+
rescue ResponseError => e
|
166
|
+
raw_response = e.response.body
|
167
|
+
response = parse(raw_response)
|
168
|
+
end
|
169
|
+
|
170
|
+
success = success_from(response)
|
171
|
+
Response.new(
|
172
|
+
success,
|
173
|
+
message_from(success, response),
|
174
|
+
response,
|
175
|
+
authorization: authorization_from(response),
|
176
|
+
test: test?,
|
177
|
+
error_code: success ? nil : error_code_from(response)
|
178
|
+
)
|
179
|
+
end
|
180
|
+
|
181
|
+
def post_data(parameters = {})
|
182
|
+
parameters.to_json
|
183
|
+
end
|
184
|
+
|
185
|
+
def parse(body)
|
186
|
+
JSON.parse(body)
|
187
|
+
rescue JSON::ParserError
|
188
|
+
{
|
189
|
+
'message' => "A non-JSON response was received from Decidir where one was expected. The raw response was:\n\n#{body}"
|
190
|
+
}
|
191
|
+
end
|
192
|
+
|
193
|
+
def message_from(success, response)
|
194
|
+
return response['status'] if success
|
195
|
+
return response['message'] if response['message']
|
196
|
+
|
197
|
+
message = nil
|
198
|
+
|
199
|
+
if error = response.dig('status_details', 'error')
|
200
|
+
message = error.dig('reason', 'description')
|
201
|
+
elsif response['error_type']
|
202
|
+
if response['validation_errors']
|
203
|
+
message = response['validation_errors'].map { |errors| "#{errors['code']}: #{errors['param']}" }.join(', ')
|
204
|
+
end
|
205
|
+
message ||= response['error_type']
|
206
|
+
end
|
207
|
+
|
208
|
+
message
|
209
|
+
end
|
210
|
+
|
211
|
+
def success_from(response)
|
212
|
+
response['status'] == 'approved' || response['status'] == 'pre_approved'
|
213
|
+
end
|
214
|
+
|
215
|
+
def authorization_from(response)
|
216
|
+
response['id']
|
217
|
+
end
|
218
|
+
|
219
|
+
def error_code_from(response)
|
220
|
+
error_code = nil
|
221
|
+
if error = response.dig('status_details', 'error')
|
222
|
+
code = error.dig('reason', 'id')
|
223
|
+
error_code = STANDARD_ERROR_CODE_MAPPING[code]
|
224
|
+
error_code ||= error['type']
|
225
|
+
elsif response['error_type']
|
226
|
+
error_code = response['error_type'] if response['validation_errors']
|
227
|
+
end
|
228
|
+
|
229
|
+
error_code || STANDARD_ERROR_CODE[:processing_error]
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
@@ -42,6 +42,7 @@ module ActiveMerchant #:nodoc:
|
|
42
42
|
else
|
43
43
|
add_creditcard(form, payment_method)
|
44
44
|
end
|
45
|
+
add_currency(form, money, options)
|
45
46
|
add_address(form, options)
|
46
47
|
add_customer_data(form, options)
|
47
48
|
add_test_mode(form, options)
|
@@ -54,6 +55,7 @@ module ActiveMerchant #:nodoc:
|
|
54
55
|
add_salestax(form, options)
|
55
56
|
add_invoice(form, options)
|
56
57
|
add_creditcard(form, creditcard)
|
58
|
+
add_currency(form, money, options)
|
57
59
|
add_address(form, options)
|
58
60
|
add_customer_data(form, options)
|
59
61
|
add_test_mode(form, options)
|
@@ -69,6 +71,7 @@ module ActiveMerchant #:nodoc:
|
|
69
71
|
add_approval_code(form, authorization)
|
70
72
|
add_invoice(form, options)
|
71
73
|
add_creditcard(form, options[:credit_card])
|
74
|
+
add_currency(form, money, options)
|
72
75
|
add_customer_data(form, options)
|
73
76
|
add_test_mode(form, options)
|
74
77
|
else
|
@@ -102,6 +105,7 @@ module ActiveMerchant #:nodoc:
|
|
102
105
|
form = {}
|
103
106
|
add_invoice(form, options)
|
104
107
|
add_creditcard(form, creditcard)
|
108
|
+
add_currency(form, money, options)
|
105
109
|
add_address(form, options)
|
106
110
|
add_customer_data(form, options)
|
107
111
|
add_test_mode(form, options)
|
@@ -178,6 +182,11 @@ module ActiveMerchant #:nodoc:
|
|
178
182
|
form[:last_name] = truncate(creditcard.last_name, 30)
|
179
183
|
end
|
180
184
|
|
185
|
+
def add_currency(form, money, options)
|
186
|
+
currency = options[:currency] || currency(money)
|
187
|
+
form[:transaction_currency] = currency if currency && (@options[:multi_currency] || options[:multi_currency])
|
188
|
+
end
|
189
|
+
|
181
190
|
def add_token(form, token)
|
182
191
|
form[:token] = token
|
183
192
|
end
|