activemerchant 1.124.0 → 1.125.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 +85 -0
- data/lib/active_merchant/billing/check.rb +5 -8
- data/lib/active_merchant/billing/credit_card.rb +10 -0
- data/lib/active_merchant/billing/gateway.rb +1 -1
- data/lib/active_merchant/billing/gateways/cashnet.rb +15 -5
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +33 -4
- data/lib/active_merchant/billing/gateways/cyber_source.rb +11 -3
- data/lib/active_merchant/billing/gateways/d_local.rb +4 -5
- data/lib/active_merchant/billing/gateways/decidir_plus.rb +173 -0
- data/lib/active_merchant/billing/gateways/ebanx.rb +16 -1
- data/lib/active_merchant/billing/gateways/elavon.rb +6 -3
- data/lib/active_merchant/billing/gateways/element.rb +20 -2
- data/lib/active_merchant/billing/gateways/global_collect.rb +106 -16
- data/lib/active_merchant/billing/gateways/ipg.rb +416 -0
- data/lib/active_merchant/billing/gateways/kushki.rb +7 -0
- data/lib/active_merchant/billing/gateways/mercado_pago.rb +3 -1
- data/lib/active_merchant/billing/gateways/mundipagg.rb +8 -6
- data/lib/active_merchant/billing/gateways/nmi.rb +2 -1
- data/lib/active_merchant/billing/gateways/orbital.rb +17 -2
- data/lib/active_merchant/billing/gateways/pay_trace.rb +1 -1
- data/lib/active_merchant/billing/gateways/payflow.rb +1 -1
- data/lib/active_merchant/billing/gateways/paymentez.rb +9 -2
- data/lib/active_merchant/billing/gateways/paysafe.rb +41 -5
- data/lib/active_merchant/billing/gateways/payu_latam.rb +6 -1
- data/lib/active_merchant/billing/gateways/payway_dot_com.rb +3 -3
- data/lib/active_merchant/billing/gateways/pin.rb +31 -4
- data/lib/active_merchant/billing/gateways/priority.rb +347 -0
- data/lib/active_merchant/billing/gateways/safe_charge.rb +1 -0
- data/lib/active_merchant/billing/gateways/stripe.rb +20 -10
- data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +37 -3
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +20 -6
- data/lib/active_merchant/billing/gateways/wompi.rb +193 -0
- data/lib/active_merchant/billing/gateways/worldpay.rb +181 -64
- data/lib/active_merchant/billing/network_tokenization_credit_card.rb +1 -1
- data/lib/active_merchant/version.rb +1 -1
- metadata +6 -2
@@ -23,9 +23,9 @@ module ActiveMerchant #:nodoc:
|
|
23
23
|
'unchecked' => 'P'
|
24
24
|
}
|
25
25
|
|
26
|
-
DEFAULT_API_VERSION = '
|
26
|
+
DEFAULT_API_VERSION = '2020-08-27'
|
27
27
|
|
28
|
-
self.supported_countries = %w(AT AU BE BG BR CA CH CY CZ DE DK EE ES FI FR GB GR HK IE IT JP LT LU LV MT MX NL NO NZ PL PT RO SE SG SI SK US)
|
28
|
+
self.supported_countries = %w(AE AT AU BE BG BR CA CH CY CZ DE DK EE ES FI FR GB GR HK HU IE IN IT JP LT LU LV MT MX MY NL NO NZ PL PT RO SE SG SI SK US)
|
29
29
|
self.default_currency = 'USD'
|
30
30
|
self.money_format = :cents
|
31
31
|
self.supported_cardtypes = %i[visa master american_express discover jcb diners_club maestro unionpay]
|
@@ -223,9 +223,10 @@ module ActiveMerchant #:nodoc:
|
|
223
223
|
|
224
224
|
post[:default_card] = r.params['id'] if options[:set_default] && r.success? && !r.params['id'].blank?
|
225
225
|
|
226
|
-
r.process { update_customer(options[:customer], post) } if post.count > 0
|
226
|
+
r.process { update_customer(options[:customer], post.merge(expand: [:sources])) } if post.count > 0
|
227
227
|
end
|
228
228
|
else
|
229
|
+
post[:expand] = [:sources]
|
229
230
|
commit(:post, 'customers', post.merge(params), options)
|
230
231
|
end
|
231
232
|
end
|
@@ -294,6 +295,17 @@ module ActiveMerchant #:nodoc:
|
|
294
295
|
true
|
295
296
|
end
|
296
297
|
|
298
|
+
# Helper method to prevent hitting the external_account limit from remote test runs
|
299
|
+
def delete_latest_test_external_account(account)
|
300
|
+
return unless test?
|
301
|
+
|
302
|
+
auth_header = { 'Authorization': "Bearer #{options[:login]}" }
|
303
|
+
url = "#{live_url}accounts/#{CGI.escape(account)}/external_accounts"
|
304
|
+
accounts_response = JSON.parse(ssl_get("#{url}?limit=100", auth_header))
|
305
|
+
to_delete = accounts_response['data'].reject { |ac| ac['default_for_currency'] }
|
306
|
+
ssl_request(:delete, "#{url}/#{to_delete.first['id']}", nil, auth_header)
|
307
|
+
end
|
308
|
+
|
297
309
|
private
|
298
310
|
|
299
311
|
class StripePaymentToken < PaymentToken
|
@@ -534,7 +546,6 @@ module ActiveMerchant #:nodoc:
|
|
534
546
|
post[:metadata].merge!(options[:metadata]) if options[:metadata]
|
535
547
|
post[:metadata][:email] = options[:email] if options[:email]
|
536
548
|
post[:metadata][:order_id] = options[:order_id] if options[:order_id]
|
537
|
-
post.delete(:metadata) if post[:metadata].empty?
|
538
549
|
end
|
539
550
|
|
540
551
|
def add_emv_metadata(post, creditcard)
|
@@ -573,11 +584,11 @@ module ActiveMerchant #:nodoc:
|
|
573
584
|
end
|
574
585
|
|
575
586
|
def add_radar_data(post, options = {})
|
576
|
-
|
587
|
+
radar_options = {}
|
588
|
+
radar_options[:session] = options[:radar_session_id] if options[:radar_session_id]
|
589
|
+
radar_options[:skip_rules] = ['all'] if options[:skip_radar_rules]
|
577
590
|
|
578
|
-
post[:radar_options] =
|
579
|
-
session: options[:radar_session_id]
|
580
|
-
}
|
591
|
+
post[:radar_options] = radar_options unless radar_options.empty?
|
581
592
|
end
|
582
593
|
|
583
594
|
def parse(body)
|
@@ -668,7 +679,6 @@ module ActiveMerchant #:nodoc:
|
|
668
679
|
card = card_from_response(response)
|
669
680
|
avs_code = AVS_CODE_TRANSLATOR["line1: #{card['address_line1_check']}, zip: #{card['address_zip_check']}"]
|
670
681
|
cvc_code = CVC_CODE_TRANSLATOR[card['cvc_check']]
|
671
|
-
|
672
682
|
Response.new(success,
|
673
683
|
message_from(success, response),
|
674
684
|
response,
|
@@ -764,7 +774,7 @@ module ActiveMerchant #:nodoc:
|
|
764
774
|
country: 'US',
|
765
775
|
currency: 'usd',
|
766
776
|
routing_number: bank_account.routing_number,
|
767
|
-
|
777
|
+
account_holder_name: bank_account.name,
|
768
778
|
account_holder_type: account_holder_type
|
769
779
|
}
|
770
780
|
}
|
@@ -5,16 +5,21 @@ module ActiveMerchant #:nodoc:
|
|
5
5
|
# This gateway uses the current Stripe {Payment Intents API}[https://stripe.com/docs/api/payment_intents].
|
6
6
|
# For the legacy API, see the Stripe gateway
|
7
7
|
class StripePaymentIntentsGateway < StripeGateway
|
8
|
-
self.supported_countries = %w(AT AU BE BG BR CA CH CY CZ DE DK EE ES FI FR GB GR HK IE IT JP LT LU LV MT MX NL NO NZ PL PT RO SE SG SI SK US)
|
9
|
-
|
10
8
|
ALLOWED_METHOD_STATES = %w[automatic manual].freeze
|
11
9
|
ALLOWED_CANCELLATION_REASONS = %w[duplicate fraudulent requested_by_customer abandoned].freeze
|
12
10
|
CREATE_INTENT_ATTRIBUTES = %i[description statement_descriptor_suffix statement_descriptor receipt_email save_payment_method]
|
13
11
|
CONFIRM_INTENT_ATTRIBUTES = %i[receipt_email return_url save_payment_method setup_future_usage off_session]
|
14
12
|
UPDATE_INTENT_ATTRIBUTES = %i[description statement_descriptor_suffix statement_descriptor receipt_email setup_future_usage]
|
15
|
-
DEFAULT_API_VERSION = '
|
13
|
+
DEFAULT_API_VERSION = '2020-08-27'
|
14
|
+
NO_WALLET_SUPPORT = %w(apple_pay google_pay android_pay)
|
16
15
|
|
17
16
|
def create_intent(money, payment_method, options = {})
|
17
|
+
card_source_pay = payment_method.source.to_s if defined?(payment_method.source)
|
18
|
+
card_brand_pay = card_brand(payment_method) unless payment_method.is_a?(String) || payment_method.nil?
|
19
|
+
if NO_WALLET_SUPPORT.include?(card_source_pay) || NO_WALLET_SUPPORT.include?(card_brand_pay)
|
20
|
+
store_apple_or_google_pay_token = 'Direct Apple Pay and Google Pay transactions are not supported. Those payment methods must be stored before use.'
|
21
|
+
return Response.new(false, store_apple_or_google_pay_token)
|
22
|
+
end
|
18
23
|
post = {}
|
19
24
|
add_amount(post, money, options, true)
|
20
25
|
add_capture_method(post, options)
|
@@ -35,6 +40,7 @@ module ActiveMerchant #:nodoc:
|
|
35
40
|
add_ntid(post, options)
|
36
41
|
add_claim_without_transaction_id(post, options)
|
37
42
|
add_error_on_requires_action(post, options)
|
43
|
+
add_fulfillment_date(post, options)
|
38
44
|
request_three_d_secure(post, options)
|
39
45
|
|
40
46
|
CREATE_INTENT_ATTRIBUTES.each do |attribute|
|
@@ -56,6 +62,7 @@ module ActiveMerchant #:nodoc:
|
|
56
62
|
CONFIRM_INTENT_ATTRIBUTES.each do |attribute|
|
57
63
|
add_whitelisted_attribute(post, options, attribute)
|
58
64
|
end
|
65
|
+
|
59
66
|
commit(:post, "payment_intents/#{intent_id}/confirm", post, options)
|
60
67
|
end
|
61
68
|
|
@@ -91,6 +98,7 @@ module ActiveMerchant #:nodoc:
|
|
91
98
|
add_metadata(post, options)
|
92
99
|
add_shipping_address(post, options)
|
93
100
|
add_connected_account(post, options)
|
101
|
+
add_fulfillment_date(post, options)
|
94
102
|
|
95
103
|
UPDATE_INTENT_ATTRIBUTES.each do |attribute|
|
96
104
|
add_whitelisted_attribute(post, options, attribute)
|
@@ -106,6 +114,7 @@ module ActiveMerchant #:nodoc:
|
|
106
114
|
|
107
115
|
add_metadata(post, options)
|
108
116
|
add_return_url(post, options)
|
117
|
+
add_fulfillment_date(post, options)
|
109
118
|
post[:on_behalf_of] = options[:on_behalf_of] if options[:on_behalf_of]
|
110
119
|
post[:usage] = options[:usage] if %w(on_session off_session).include?(options[:usage])
|
111
120
|
post[:description] = options[:description] if options[:description]
|
@@ -190,6 +199,7 @@ module ActiveMerchant #:nodoc:
|
|
190
199
|
post[:description] = options[:description] if options[:description]
|
191
200
|
post[:email] = options[:email] if options[:email]
|
192
201
|
options = format_idempotency_key(options, 'customer')
|
202
|
+
post[:expand] = [:sources]
|
193
203
|
customer = commit(:post, 'customers', post, options)
|
194
204
|
customer_id = customer.params['id']
|
195
205
|
end
|
@@ -215,6 +225,16 @@ module ActiveMerchant #:nodoc:
|
|
215
225
|
create_setup_intent(payment_method, options.merge!(confirm: true))
|
216
226
|
end
|
217
227
|
|
228
|
+
def setup_purchase(money, options = {})
|
229
|
+
requires!(options, :payment_method_types)
|
230
|
+
post = {}
|
231
|
+
add_currency(post, options, money)
|
232
|
+
add_amount(post, money, options)
|
233
|
+
add_payment_method_types(post, options)
|
234
|
+
add_metadata(post, options)
|
235
|
+
commit(:post, 'payment_intents', post, options)
|
236
|
+
end
|
237
|
+
|
218
238
|
private
|
219
239
|
|
220
240
|
def off_session_request?(options = {})
|
@@ -245,6 +265,16 @@ module ActiveMerchant #:nodoc:
|
|
245
265
|
post[:customer] = customer if customer.start_with?('cus_')
|
246
266
|
end
|
247
267
|
|
268
|
+
def add_fulfillment_date(post, options)
|
269
|
+
post[:fulfillment_date] = options[:fulfillment_date].to_i if options[:fulfillment_date]
|
270
|
+
end
|
271
|
+
|
272
|
+
def add_metadata(post, options = {})
|
273
|
+
super
|
274
|
+
|
275
|
+
post[:metadata][:event_type] = options[:event_type] if options[:event_type]
|
276
|
+
end
|
277
|
+
|
248
278
|
def add_return_url(post, options)
|
249
279
|
return unless options[:confirm]
|
250
280
|
|
@@ -432,6 +462,10 @@ module ActiveMerchant #:nodoc:
|
|
432
462
|
|
433
463
|
super(response, options)
|
434
464
|
end
|
465
|
+
|
466
|
+
def add_currency(post, options, money)
|
467
|
+
post[:currency] = options[:currency] || currency(money)
|
468
|
+
end
|
435
469
|
end
|
436
470
|
end
|
437
471
|
end
|
@@ -16,7 +16,8 @@ module ActiveMerchant #:nodoc:
|
|
16
16
|
refund: 'cc:refund',
|
17
17
|
void: 'cc:void',
|
18
18
|
void_release: 'cc:void:release',
|
19
|
-
check_purchase: 'check:sale'
|
19
|
+
check_purchase: 'check:sale',
|
20
|
+
store: 'cc:save'
|
20
21
|
}
|
21
22
|
|
22
23
|
STANDARD_ERROR_CODE_MAPPING = {
|
@@ -43,14 +44,14 @@ module ActiveMerchant #:nodoc:
|
|
43
44
|
super
|
44
45
|
end
|
45
46
|
|
46
|
-
def authorize(money,
|
47
|
+
def authorize(money, payment, options = {})
|
47
48
|
post = {}
|
48
49
|
|
49
50
|
add_amount(post, money)
|
50
51
|
add_invoice(post, options)
|
51
|
-
add_payment(post,
|
52
|
-
unless
|
53
|
-
add_address(post,
|
52
|
+
add_payment(post, payment)
|
53
|
+
unless payment.is_a?(CreditCard) && payment.track_data.present?
|
54
|
+
add_address(post, payment, options)
|
54
55
|
add_customer_data(post, options)
|
55
56
|
end
|
56
57
|
add_split_payments(post, options)
|
@@ -97,6 +98,12 @@ module ActiveMerchant #:nodoc:
|
|
97
98
|
commit(:refund, post)
|
98
99
|
end
|
99
100
|
|
101
|
+
def store(payment, options = {})
|
102
|
+
post = {}
|
103
|
+
add_payment(post, payment, options)
|
104
|
+
commit(:store, post)
|
105
|
+
end
|
106
|
+
|
100
107
|
def verify(creditcard, options = {})
|
101
108
|
MultiResponse.run(:use_first_response) do |r|
|
102
109
|
r.process { authorize(1, creditcard, options) }
|
@@ -213,6 +220,8 @@ module ActiveMerchant #:nodoc:
|
|
213
220
|
elsif payment.respond_to?(:track_data) && payment.track_data.present?
|
214
221
|
post[:magstripe] = payment.track_data
|
215
222
|
post[:cardpresent] = true
|
223
|
+
elsif payment.is_a?(String)
|
224
|
+
post[:card] = payment
|
216
225
|
else
|
217
226
|
post[:card] = payment.number
|
218
227
|
post[:cvv2] = payment.verification_value if payment.verification_value?
|
@@ -299,6 +308,7 @@ module ActiveMerchant #:nodoc:
|
|
299
308
|
status: fields['UMstatus'],
|
300
309
|
auth_code: fields['UMauthCode'],
|
301
310
|
ref_num: fields['UMrefNum'],
|
311
|
+
card_ref: fields['UMcardRef'],
|
302
312
|
batch: fields['UMbatch'],
|
303
313
|
avs_result: fields['UMavsResult'],
|
304
314
|
avs_result_code: fields['UMavsResultCode'],
|
@@ -321,7 +331,7 @@ module ActiveMerchant #:nodoc:
|
|
321
331
|
error_code = (STANDARD_ERROR_CODE_MAPPING[response[:error_code]] || STANDARD_ERROR_CODE[:processing_error]) unless approved
|
322
332
|
Response.new(approved, message_from(response), response,
|
323
333
|
test: test?,
|
324
|
-
authorization: response
|
334
|
+
authorization: authorization_from(action, response),
|
325
335
|
cvv_result: response[:cvv2_result_code],
|
326
336
|
avs_result: { code: response[:avs_result_code] },
|
327
337
|
error_code: error_code)
|
@@ -337,6 +347,10 @@ module ActiveMerchant #:nodoc:
|
|
337
347
|
end
|
338
348
|
end
|
339
349
|
|
350
|
+
def authorization_from(action, response)
|
351
|
+
return (action == :store ? response[:card_ref] : response[:ref_num])
|
352
|
+
end
|
353
|
+
|
340
354
|
def post_data(action, parameters = {})
|
341
355
|
parameters[:command] = TRANSACTIONS[action]
|
342
356
|
parameters[:key] = @options[:login]
|
@@ -0,0 +1,193 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class WompiGateway < Gateway
|
4
|
+
self.test_url = 'https://sync.sandbox.wompi.co/v1'
|
5
|
+
self.live_url = 'https://sync.production.wompi.co/v1'
|
6
|
+
|
7
|
+
self.supported_countries = ['CO']
|
8
|
+
self.default_currency = 'COP'
|
9
|
+
self.supported_cardtypes = %i[visa master american_express]
|
10
|
+
|
11
|
+
self.homepage_url = 'https://wompi.co/'
|
12
|
+
self.display_name = 'Wompi'
|
13
|
+
|
14
|
+
self.money_format = :cents
|
15
|
+
|
16
|
+
def initialize(options = {})
|
17
|
+
## Sandbox keys have prefix pub_test_ and prv_test_
|
18
|
+
## Production keys have prefix pub_prod_ and prv_prod_
|
19
|
+
begin
|
20
|
+
requires!(options, :prod_private_key, :prod_public_key)
|
21
|
+
rescue ArgumentError
|
22
|
+
begin
|
23
|
+
requires!(options, :test_private_key, :test_public_key)
|
24
|
+
rescue ArgumentError
|
25
|
+
raise ArgumentError, 'Gateway requires both test_private_key and test_public_key, or both prod_private_key and prod_public_key'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
super
|
29
|
+
end
|
30
|
+
|
31
|
+
def purchase(money, payment, options = {})
|
32
|
+
post = {
|
33
|
+
reference: options[:reference] || generate_reference,
|
34
|
+
public_key: public_key
|
35
|
+
}
|
36
|
+
add_invoice(post, money, options)
|
37
|
+
add_card(post, payment, options)
|
38
|
+
|
39
|
+
commit('sale', post, '/transactions_sync')
|
40
|
+
end
|
41
|
+
|
42
|
+
def authorize(money, payment, options = {})
|
43
|
+
post = {
|
44
|
+
public_key: public_key,
|
45
|
+
type: 'CARD',
|
46
|
+
financial_operation: 'PREAUTHORIZATION'
|
47
|
+
}
|
48
|
+
add_auth_params(post, money, payment, options)
|
49
|
+
|
50
|
+
commit('authorize', post, '/payment_sources_sync')
|
51
|
+
end
|
52
|
+
|
53
|
+
def capture(money, authorization, options = {})
|
54
|
+
post = {
|
55
|
+
reference: options[:reference] || generate_reference,
|
56
|
+
public_key: public_key,
|
57
|
+
payment_source_id: authorization.to_i
|
58
|
+
}
|
59
|
+
add_invoice(post, money, options)
|
60
|
+
commit('capture', post, '/transactions_sync')
|
61
|
+
end
|
62
|
+
|
63
|
+
def refund(money, authorization, options = {})
|
64
|
+
post = { amount_in_cents: amount(money).to_i, transaction_id: authorization.to_s }
|
65
|
+
commit('refund', post, '/refunds_sync')
|
66
|
+
end
|
67
|
+
|
68
|
+
def void(authorization, options = {})
|
69
|
+
commit('void', {}, "/transactions/#{authorization}/void_sync")
|
70
|
+
end
|
71
|
+
|
72
|
+
def supports_scrubbing?
|
73
|
+
true
|
74
|
+
end
|
75
|
+
|
76
|
+
def scrub(transcript)
|
77
|
+
transcript.gsub(/(Bearer )\w+/, '\1[REDACTED]').
|
78
|
+
gsub(/(\\\"number\\\":\\\")\d+/, '\1[REDACTED]').
|
79
|
+
gsub(/(\\\"cvc\\\":\\\")\d+/, '\1[REDACTED]').
|
80
|
+
gsub(/(\\\"phone_number\\\":\\\")\+?\d+/, '\1[REDACTED]').
|
81
|
+
gsub(/(\\\"email\\\":\\\")\S+\\\",/, '\1[REDACTED]\",').
|
82
|
+
gsub(/(\\\"legal_id\\\":\\\")\d+/, '\1[REDACTED]')
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def headers
|
88
|
+
{
|
89
|
+
'Authorization' => "Bearer #{private_key}",
|
90
|
+
'Content-Type' => 'application/json'
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
def generate_reference
|
95
|
+
SecureRandom.alphanumeric(12)
|
96
|
+
end
|
97
|
+
|
98
|
+
def private_key
|
99
|
+
test? ? options[:test_private_key] : options[:prod_private_key]
|
100
|
+
end
|
101
|
+
|
102
|
+
def public_key
|
103
|
+
test? ? options[:test_public_key] : options[:prod_public_key]
|
104
|
+
end
|
105
|
+
|
106
|
+
def add_invoice(post, money, options)
|
107
|
+
post[:amount_in_cents] = amount(money).to_i
|
108
|
+
post[:currency] = (options[:currency] || currency(money))
|
109
|
+
end
|
110
|
+
|
111
|
+
def add_card(post, card, options)
|
112
|
+
payment_method = {
|
113
|
+
type: 'CARD'
|
114
|
+
}
|
115
|
+
add_basic_card_info(payment_method, card, options)
|
116
|
+
post[:payment_method] = payment_method
|
117
|
+
end
|
118
|
+
|
119
|
+
def add_auth_params(post, money, card, options)
|
120
|
+
data = {
|
121
|
+
amount_in_cents: amount(money).to_i,
|
122
|
+
currency: (options[:currency] || currency(money))
|
123
|
+
}
|
124
|
+
add_basic_card_info(data, card, options)
|
125
|
+
post[:data] = data
|
126
|
+
end
|
127
|
+
|
128
|
+
def add_basic_card_info(post, card, options)
|
129
|
+
installments = options[:installments] ? options[:installments].to_i : 1
|
130
|
+
cvc = card.verification_value || nil
|
131
|
+
|
132
|
+
post[:number] = card.number
|
133
|
+
post[:exp_month] = card.month.to_s.rjust(2, '0')
|
134
|
+
post[:exp_year] = card.year.to_s[2..3]
|
135
|
+
post[:installments] = installments
|
136
|
+
post[:card_holder] = card.name
|
137
|
+
post[:cvc] = cvc if cvc && !cvc.empty?
|
138
|
+
end
|
139
|
+
|
140
|
+
def parse(body)
|
141
|
+
JSON.parse(body)
|
142
|
+
end
|
143
|
+
|
144
|
+
def commit(action, parameters, endpoint)
|
145
|
+
url = (test? ? test_url : live_url) + endpoint
|
146
|
+
response = parse(ssl_post(url, post_data(action, parameters), headers))
|
147
|
+
Response.new(
|
148
|
+
success_from(response),
|
149
|
+
message_from(response),
|
150
|
+
response,
|
151
|
+
authorization: authorization_from(response),
|
152
|
+
avs_result: nil,
|
153
|
+
cvv_result: nil,
|
154
|
+
test: test?,
|
155
|
+
error_code: error_code_from(response)
|
156
|
+
)
|
157
|
+
end
|
158
|
+
|
159
|
+
def handle_response(response)
|
160
|
+
case response.code.to_i
|
161
|
+
when 200...300, 401, 404, 422
|
162
|
+
response.body
|
163
|
+
else
|
164
|
+
raise ResponseError.new(response)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def success_from(response)
|
169
|
+
success_statuses.include? response.dig('data', 'status')
|
170
|
+
end
|
171
|
+
|
172
|
+
def success_statuses
|
173
|
+
%w(APPROVED AVAILABLE)
|
174
|
+
end
|
175
|
+
|
176
|
+
def message_from(response)
|
177
|
+
response.dig('data', 'status_message') || response.dig('error', 'reason') || response.dig('error', 'messages').to_json
|
178
|
+
end
|
179
|
+
|
180
|
+
def authorization_from(response)
|
181
|
+
response.dig('data', 'transaction_id') || response.dig('data', 'id') || response.dig('data', 'transaction', 'id')
|
182
|
+
end
|
183
|
+
|
184
|
+
def post_data(action, parameters = {})
|
185
|
+
parameters.to_json
|
186
|
+
end
|
187
|
+
|
188
|
+
def error_code_from(response)
|
189
|
+
response.dig('error', 'type') unless success_from(response)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|