activemerchant 1.123.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 +131 -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/credit_card_methods.rb +6 -3
- data/lib/active_merchant/billing/gateway.rb +1 -1
- data/lib/active_merchant/billing/gateways/adyen.rb +61 -9
- data/lib/active_merchant/billing/gateways/card_stream.rb +17 -13
- 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 +12 -6
- 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 +111 -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/mit.rb +260 -0
- data/lib/active_merchant/billing/gateways/moka.rb +24 -11
- data/lib/active_merchant/billing/gateways/mundipagg.rb +8 -6
- data/lib/active_merchant/billing/gateways/nmi.rb +15 -1
- data/lib/active_merchant/billing/gateways/orbital.rb +19 -3
- data/lib/active_merchant/billing/gateways/pay_arc.rb +9 -7
- data/lib/active_merchant/billing/gateways/pay_conex.rb +3 -1
- data/lib/active_merchant/billing/gateways/pay_trace.rb +1 -1
- data/lib/active_merchant/billing/gateways/payflow.rb +14 -6
- data/lib/active_merchant/billing/gateways/paymentez.rb +9 -2
- data/lib/active_merchant/billing/gateways/paysafe.rb +144 -23
- 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/realex.rb +18 -0
- data/lib/active_merchant/billing/gateways/safe_charge.rb +6 -2
- data/lib/active_merchant/billing/gateways/stripe.rb +27 -7
- data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +96 -38
- data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +2 -1
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +2 -1
- 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 +196 -64
- data/lib/active_merchant/billing/network_tokenization_credit_card.rb +1 -1
- data/lib/active_merchant/billing/response.rb +4 -0
- data/lib/active_merchant/version.rb +1 -1
- metadata +7 -2
@@ -5,34 +5,42 @@ 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)
|
21
26
|
add_confirmation_method(post, options)
|
22
27
|
add_customer(post, options)
|
23
|
-
|
24
|
-
return
|
28
|
+
result = add_payment_method_token(post, payment_method, options)
|
29
|
+
return result if result.is_a?(ActiveMerchant::Billing::Response)
|
25
30
|
|
26
31
|
add_external_three_d_secure_auth_data(post, options)
|
27
32
|
add_metadata(post, options)
|
28
33
|
add_return_url(post, options)
|
29
34
|
add_connected_account(post, options)
|
35
|
+
add_radar_data(post, options)
|
30
36
|
add_shipping_address(post, options)
|
31
37
|
setup_future_usage(post, options)
|
32
38
|
add_exemption(post, options)
|
33
39
|
add_stored_credentials(post, options)
|
34
40
|
add_ntid(post, options)
|
41
|
+
add_claim_without_transaction_id(post, options)
|
35
42
|
add_error_on_requires_action(post, options)
|
43
|
+
add_fulfillment_date(post, options)
|
36
44
|
request_three_d_secure(post, options)
|
37
45
|
|
38
46
|
CREATE_INTENT_ATTRIBUTES.each do |attribute|
|
@@ -48,23 +56,24 @@ module ActiveMerchant #:nodoc:
|
|
48
56
|
|
49
57
|
def confirm_intent(intent_id, payment_method, options = {})
|
50
58
|
post = {}
|
51
|
-
|
52
|
-
return
|
59
|
+
result = add_payment_method_token(post, payment_method, options)
|
60
|
+
return result if result.is_a?(ActiveMerchant::Billing::Response)
|
53
61
|
|
54
62
|
CONFIRM_INTENT_ATTRIBUTES.each do |attribute|
|
55
63
|
add_whitelisted_attribute(post, options, attribute)
|
56
64
|
end
|
65
|
+
|
57
66
|
commit(:post, "payment_intents/#{intent_id}/confirm", post, options)
|
58
67
|
end
|
59
68
|
|
60
69
|
def create_payment_method(payment_method, options = {})
|
61
|
-
post_data =
|
70
|
+
post_data = add_payment_method_data(payment_method, options)
|
62
71
|
|
63
72
|
options = format_idempotency_key(options, 'pm')
|
64
73
|
commit(:post, 'payment_methods', post_data, options)
|
65
74
|
end
|
66
75
|
|
67
|
-
def
|
76
|
+
def add_payment_method_data(payment_method, options = {})
|
68
77
|
post_data = {}
|
69
78
|
post_data[:type] = 'card'
|
70
79
|
post_data[:card] = {}
|
@@ -73,6 +82,7 @@ module ActiveMerchant #:nodoc:
|
|
73
82
|
post_data[:card][:exp_year] = payment_method.year
|
74
83
|
post_data[:card][:cvc] = payment_method.verification_value if payment_method.verification_value
|
75
84
|
add_billing_address(post_data, options)
|
85
|
+
add_name_only(post_data, payment_method) if post_data[:billing_details].nil?
|
76
86
|
post_data
|
77
87
|
end
|
78
88
|
|
@@ -80,14 +90,15 @@ module ActiveMerchant #:nodoc:
|
|
80
90
|
post = {}
|
81
91
|
add_amount(post, money, options)
|
82
92
|
|
83
|
-
|
84
|
-
return
|
93
|
+
result = add_payment_method_token(post, payment_method, options)
|
94
|
+
return result if result.is_a?(ActiveMerchant::Billing::Response)
|
85
95
|
|
86
96
|
add_payment_method_types(post, options)
|
87
97
|
add_customer(post, options)
|
88
98
|
add_metadata(post, options)
|
89
99
|
add_shipping_address(post, options)
|
90
100
|
add_connected_account(post, options)
|
101
|
+
add_fulfillment_date(post, options)
|
91
102
|
|
92
103
|
UPDATE_INTENT_ATTRIBUTES.each do |attribute|
|
93
104
|
add_whitelisted_attribute(post, options, attribute)
|
@@ -98,11 +109,12 @@ module ActiveMerchant #:nodoc:
|
|
98
109
|
def create_setup_intent(payment_method, options = {})
|
99
110
|
post = {}
|
100
111
|
add_customer(post, options)
|
101
|
-
|
102
|
-
return
|
112
|
+
result = add_payment_method_token(post, payment_method, options)
|
113
|
+
return result if result.is_a?(ActiveMerchant::Billing::Response)
|
103
114
|
|
104
115
|
add_metadata(post, options)
|
105
116
|
add_return_url(post, options)
|
117
|
+
add_fulfillment_date(post, options)
|
106
118
|
post[:on_behalf_of] = options[:on_behalf_of] if options[:on_behalf_of]
|
107
119
|
post[:usage] = options[:usage] if %w(on_session off_session).include?(options[:usage])
|
108
120
|
post[:description] = options[:description] if options[:description]
|
@@ -178,8 +190,8 @@ module ActiveMerchant #:nodoc:
|
|
178
190
|
# If customer option is provided, create a payment method and attach to customer id
|
179
191
|
# Otherwise, create a customer, then attach
|
180
192
|
if payment_method.is_a?(StripePaymentToken) || payment_method.is_a?(ActiveMerchant::Billing::CreditCard)
|
181
|
-
|
182
|
-
return
|
193
|
+
result = add_payment_method_token(params, payment_method, options)
|
194
|
+
return result if result.is_a?(ActiveMerchant::Billing::Response)
|
183
195
|
|
184
196
|
if options[:customer]
|
185
197
|
customer_id = options[:customer]
|
@@ -187,6 +199,7 @@ module ActiveMerchant #:nodoc:
|
|
187
199
|
post[:description] = options[:description] if options[:description]
|
188
200
|
post[:email] = options[:email] if options[:email]
|
189
201
|
options = format_idempotency_key(options, 'customer')
|
202
|
+
post[:expand] = [:sources]
|
190
203
|
customer = commit(:post, 'customers', post, options)
|
191
204
|
customer_id = customer.params['id']
|
192
205
|
end
|
@@ -212,6 +225,16 @@ module ActiveMerchant #:nodoc:
|
|
212
225
|
create_setup_intent(payment_method, options.merge!(confirm: true))
|
213
226
|
end
|
214
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
|
+
|
215
238
|
private
|
216
239
|
|
217
240
|
def off_session_request?(options = {})
|
@@ -242,6 +265,16 @@ module ActiveMerchant #:nodoc:
|
|
242
265
|
post[:customer] = customer if customer.start_with?('cus_')
|
243
266
|
end
|
244
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
|
+
|
245
278
|
def add_return_url(post, options)
|
246
279
|
return unless options[:confirm]
|
247
280
|
|
@@ -250,35 +283,36 @@ module ActiveMerchant #:nodoc:
|
|
250
283
|
end
|
251
284
|
|
252
285
|
def add_payment_method_token(post, payment_method, options)
|
253
|
-
return if payment_method.nil?
|
254
|
-
|
255
|
-
if payment_method.is_a?(ActiveMerchant::Billing::CreditCard)
|
256
|
-
if off_session_request?(options)
|
257
|
-
post[:payment_method_data] = create_payment_method_data(payment_method, options)
|
258
|
-
return
|
259
|
-
else
|
260
|
-
p = create_payment_method(payment_method, options)
|
261
|
-
return p unless p.success?
|
262
|
-
|
263
|
-
payment_method = p.params['id']
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
286
|
case payment_method
|
268
287
|
when StripePaymentToken
|
269
288
|
post[:payment_method] = payment_method.payment_data['id']
|
270
289
|
when String
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
post[:customer] = customer_id
|
275
|
-
else
|
276
|
-
token = payment_method
|
277
|
-
end
|
278
|
-
post[:payment_method] = token
|
290
|
+
extract_token_from_string_and_maybe_add_customer_id(post, payment_method)
|
291
|
+
when ActiveMerchant::Billing::CreditCard
|
292
|
+
get_payment_method_data_from_card(post, payment_method, options)
|
279
293
|
end
|
294
|
+
end
|
280
295
|
|
281
|
-
|
296
|
+
def extract_token_from_string_and_maybe_add_customer_id(post, payment_method)
|
297
|
+
if payment_method.include?('|')
|
298
|
+
customer_id, payment_method = payment_method.split('|')
|
299
|
+
post[:customer] = customer_id
|
300
|
+
end
|
301
|
+
|
302
|
+
post[:payment_method] = payment_method
|
303
|
+
end
|
304
|
+
|
305
|
+
def get_payment_method_data_from_card(post, payment_method, options)
|
306
|
+
return create_payment_method_and_extract_token(post, payment_method, options) unless off_session_request?(options)
|
307
|
+
|
308
|
+
post[:payment_method_data] = add_payment_method_data(payment_method, options)
|
309
|
+
end
|
310
|
+
|
311
|
+
def create_payment_method_and_extract_token(post, payment_method, options)
|
312
|
+
payment_method_response = create_payment_method(payment_method, options)
|
313
|
+
return payment_method_response if payment_method_response.failure?
|
314
|
+
|
315
|
+
add_payment_method_token(post, payment_method_response.params['id'], options)
|
282
316
|
end
|
283
317
|
|
284
318
|
def add_payment_method_types(post, options)
|
@@ -326,6 +360,19 @@ module ActiveMerchant #:nodoc:
|
|
326
360
|
post[:payment_method_options][:card][:mit_exemption][:network_transaction_id] = options[:network_transaction_id] if options[:network_transaction_id]
|
327
361
|
end
|
328
362
|
|
363
|
+
def add_claim_without_transaction_id(post, options = {})
|
364
|
+
return if options[:stored_credential] || options[:network_transaction_id] || options[:ds_transaction_id]
|
365
|
+
return unless options[:claim_without_transaction_id]
|
366
|
+
|
367
|
+
post[:payment_method_options] ||= {}
|
368
|
+
post[:payment_method_options][:card] ||= {}
|
369
|
+
post[:payment_method_options][:card][:mit_exemption] = {}
|
370
|
+
|
371
|
+
# Stripe PI accepts claim_without_transaction_id for transactions without transaction ids.
|
372
|
+
# Gateway validation for this field occurs through a different service, before the transaction request is sent to the gateway.
|
373
|
+
post[:payment_method_options][:card][:mit_exemption][:claim_without_transaction_id] = options[:claim_without_transaction_id]
|
374
|
+
end
|
375
|
+
|
329
376
|
def add_error_on_requires_action(post, options = {})
|
330
377
|
return unless options[:confirm]
|
331
378
|
|
@@ -375,6 +422,13 @@ module ActiveMerchant #:nodoc:
|
|
375
422
|
post[:billing_details][:phone] = billing[:phone] if billing[:phone]
|
376
423
|
end
|
377
424
|
|
425
|
+
def add_name_only(post, payment_method)
|
426
|
+
post[:billing_details] = {} unless post[:billing_details]
|
427
|
+
|
428
|
+
name = [payment_method.first_name, payment_method.last_name].compact.join(' ')
|
429
|
+
post[:billing_details][:name] = name
|
430
|
+
end
|
431
|
+
|
378
432
|
def add_shipping_address(post, options = {})
|
379
433
|
return unless shipping = options[:shipping]
|
380
434
|
|
@@ -408,6 +462,10 @@ module ActiveMerchant #:nodoc:
|
|
408
462
|
|
409
463
|
super(response, options)
|
410
464
|
end
|
465
|
+
|
466
|
+
def add_currency(post, options, money)
|
467
|
+
post[:currency] = options[:currency] || currency(money)
|
468
|
+
end
|
411
469
|
end
|
412
470
|
end
|
413
471
|
end
|
@@ -317,7 +317,8 @@ module ActiveMerchant #:nodoc:
|
|
317
317
|
gsub(%r((<[^>]+pan>)[^<]+(<))i, '\1[FILTERED]\2').
|
318
318
|
gsub(%r((<[^>]+sec>)[^<]+(<))i, '\1[FILTERED]\2').
|
319
319
|
gsub(%r((<[^>]+id>)[^<]+(<))i, '\1[FILTERED]\2').
|
320
|
-
gsub(%r((<[^>]+regKey>)[^<]+(<))i, '\1[FILTERED]\2')
|
320
|
+
gsub(%r((<[^>]+regKey>)[^<]+(<))i, '\1[FILTERED]\2').
|
321
|
+
gsub(%r((<[^>]+acctNr>)[^<]+(<))i, '\1[FILTERED]\2')
|
321
322
|
end
|
322
323
|
|
323
324
|
private
|
@@ -331,7 +331,8 @@ module ActiveMerchant #:nodoc:
|
|
331
331
|
gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]').
|
332
332
|
gsub(%r((&?cc=)\d*(&?)), '\1[FILTERED]\2').
|
333
333
|
gsub(%r((&?password=)[^&]+(&?)), '\1[FILTERED]\2').
|
334
|
-
gsub(%r((&?cvv=)\d*(&?)), '\1[FILTERED]\2')
|
334
|
+
gsub(%r((&?cvv=)\d*(&?)), '\1[FILTERED]\2').
|
335
|
+
gsub(%r((&?account=)\d*(&?)), '\1[FILTERED]\2')
|
335
336
|
end
|
336
337
|
|
337
338
|
private
|
@@ -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
|