activemerchant 1.126.0 → 1.129.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +241 -0
  3. data/lib/active_merchant/billing/check.rb +40 -8
  4. data/lib/active_merchant/billing/credit_card.rb +28 -1
  5. data/lib/active_merchant/billing/credit_card_methods.rb +79 -23
  6. data/lib/active_merchant/billing/gateways/adyen.rb +67 -8
  7. data/lib/active_merchant/billing/gateways/airwallex.rb +40 -11
  8. data/lib/active_merchant/billing/gateways/alelo.rb +256 -0
  9. data/lib/active_merchant/billing/gateways/authorize_net.rb +21 -4
  10. data/lib/active_merchant/billing/gateways/beanstream.rb +18 -0
  11. data/lib/active_merchant/billing/gateways/blue_snap.rb +22 -1
  12. data/lib/active_merchant/billing/gateways/bogus.rb +4 -0
  13. data/lib/active_merchant/billing/gateways/borgun.rb +56 -16
  14. data/lib/active_merchant/billing/gateways/braintree_blue.rb +64 -17
  15. data/lib/active_merchant/billing/gateways/card_connect.rb +27 -9
  16. data/lib/active_merchant/billing/gateways/card_stream.rb +23 -0
  17. data/lib/active_merchant/billing/gateways/checkout_v2.rb +228 -57
  18. data/lib/active_merchant/billing/gateways/commerce_hub.rb +361 -0
  19. data/lib/active_merchant/billing/gateways/credorax.rb +47 -27
  20. data/lib/active_merchant/billing/gateways/cyber_source/cyber_source_common.rb +36 -0
  21. data/lib/active_merchant/billing/gateways/cyber_source.rb +100 -26
  22. data/lib/active_merchant/billing/gateways/cyber_source_rest.rb +456 -0
  23. data/lib/active_merchant/billing/gateways/d_local.rb +44 -5
  24. data/lib/active_merchant/billing/gateways/decidir.rb +15 -4
  25. data/lib/active_merchant/billing/gateways/ebanx.rb +36 -24
  26. data/lib/active_merchant/billing/gateways/element.rb +21 -1
  27. data/lib/active_merchant/billing/gateways/global_collect.rb +73 -22
  28. data/lib/active_merchant/billing/gateways/ipg.rb +13 -8
  29. data/lib/active_merchant/billing/gateways/iveri.rb +39 -3
  30. data/lib/active_merchant/billing/gateways/kushki.rb +21 -1
  31. data/lib/active_merchant/billing/gateways/litle.rb +25 -5
  32. data/lib/active_merchant/billing/gateways/mastercard.rb +1 -8
  33. data/lib/active_merchant/billing/gateways/mercado_pago.rb +17 -0
  34. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +44 -10
  35. data/lib/active_merchant/billing/gateways/monei.rb +2 -0
  36. data/lib/active_merchant/billing/gateways/moneris.rb +20 -5
  37. data/lib/active_merchant/billing/gateways/mundipagg.rb +3 -0
  38. data/lib/active_merchant/billing/gateways/ogone.rb +35 -7
  39. data/lib/active_merchant/billing/gateways/openpay.rb +20 -3
  40. data/lib/active_merchant/billing/gateways/orbital.rb +43 -22
  41. data/lib/active_merchant/billing/gateways/pay_trace.rb +64 -18
  42. data/lib/active_merchant/billing/gateways/payeezy.rb +59 -4
  43. data/lib/active_merchant/billing/gateways/paymentez.rb +18 -6
  44. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +4 -0
  45. data/lib/active_merchant/billing/gateways/paysafe.rb +22 -14
  46. data/lib/active_merchant/billing/gateways/payu_latam.rb +3 -0
  47. data/lib/active_merchant/billing/gateways/plexo.rb +308 -0
  48. data/lib/active_merchant/billing/gateways/priority.rb +29 -6
  49. data/lib/active_merchant/billing/gateways/rapyd.rb +110 -49
  50. data/lib/active_merchant/billing/gateways/reach.rb +277 -0
  51. data/lib/active_merchant/billing/gateways/redsys.rb +9 -5
  52. data/lib/active_merchant/billing/gateways/sage_pay.rb +1 -1
  53. data/lib/active_merchant/billing/gateways/securion_pay.rb +40 -0
  54. data/lib/active_merchant/billing/gateways/shift4.rb +342 -0
  55. data/lib/active_merchant/billing/gateways/simetrik.rb +28 -22
  56. data/lib/active_merchant/billing/gateways/stripe.rb +21 -1
  57. data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +62 -22
  58. data/lib/active_merchant/billing/gateways/tns.rb +2 -5
  59. data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +1 -1
  60. data/lib/active_merchant/billing/gateways/trust_commerce.rb +14 -3
  61. data/lib/active_merchant/billing/gateways/vanco.rb +12 -3
  62. data/lib/active_merchant/billing/gateways/visanet_peru.rb +1 -1
  63. data/lib/active_merchant/billing/gateways/vpos.rb +7 -4
  64. data/lib/active_merchant/billing/gateways/wompi.rb +8 -4
  65. data/lib/active_merchant/billing/gateways/worldpay.rb +117 -9
  66. data/lib/active_merchant/billing/response.rb +15 -1
  67. data/lib/active_merchant/connection.rb +0 -2
  68. data/lib/active_merchant/country.rb +1 -0
  69. data/lib/active_merchant/errors.rb +4 -1
  70. data/lib/active_merchant/version.rb +1 -1
  71. metadata +24 -3
@@ -33,7 +33,14 @@ module ActiveMerchant #:nodoc:
33
33
  store: 'customer/create',
34
34
  redact: 'customer/delete',
35
35
  level_3_visa: 'level_three/visa',
36
- level_3_mastercard: 'level_three/mastercard'
36
+ level_3_mastercard: 'level_three/mastercard',
37
+ ach_sale: 'checks/sale/by_account',
38
+ ach_customer_sale: 'checks/sale/by_customer',
39
+ ach_authorize: 'checks/hold/by_account',
40
+ ach_customer_authorize: 'checks/hold/by_customer',
41
+ ach_refund: 'checks/refund/by_transaction',
42
+ ach_capture: 'checks/manage/fund',
43
+ ach_void: 'checks/manage/void'
37
44
  }
38
45
 
39
46
  def initialize(options = {})
@@ -52,7 +59,15 @@ module ActiveMerchant #:nodoc:
52
59
  end
53
60
  else
54
61
  post = build_purchase_request(money, payment_or_customer_id, options)
55
- post[:customer_id] ? endpoint = ENDPOINTS[:customer_id_sale] : endpoint = ENDPOINTS[:keyed_sale]
62
+ endpoint = if payment_or_customer_id.kind_of?(Check)
63
+ ENDPOINTS[:ach_sale]
64
+ elsif options[:check_transaction]
65
+ ENDPOINTS[:ach_customer_sale]
66
+ elsif post[:customer_id]
67
+ ENDPOINTS[:customer_id_sale]
68
+ else
69
+ ENDPOINTS[:keyed_sale]
70
+ end
56
71
  response = commit(endpoint, post)
57
72
  check_token_response(response, endpoint, post, options)
58
73
  end
@@ -63,12 +78,16 @@ module ActiveMerchant #:nodoc:
63
78
  add_amount(post, money, options)
64
79
  if customer_id?(payment_or_customer_id)
65
80
  post[:customer_id] = payment_or_customer_id
66
- endpoint = ENDPOINTS[:customer_id_auth]
81
+ endpoint = if options[:check_transaction]
82
+ ENDPOINTS[:ach_customer_authorize]
83
+ else
84
+ ENDPOINTS[:customer_id_auth]
85
+ end
67
86
  else
68
87
  add_payment(post, payment_or_customer_id)
69
88
  add_address(post, payment_or_customer_id, options)
70
89
  add_customer_data(post, options)
71
- endpoint = ENDPOINTS[:keyed_auth]
90
+ endpoint = payment_or_customer_id.kind_of?(Check) ? ENDPOINTS[:ach_authorize] : ENDPOINTS[:keyed_auth]
72
91
  end
73
92
  response = commit(endpoint, post)
74
93
  check_token_response(response, endpoint, post, options)
@@ -82,8 +101,13 @@ module ActiveMerchant #:nodoc:
82
101
  end
83
102
  else
84
103
  post = build_capture_request(money, authorization, options)
85
- response = commit(ENDPOINTS[:capture], post)
86
- check_token_response(response, ENDPOINTS[:capture], post, options)
104
+ endpoint = if options[:check_transaction]
105
+ ENDPOINTS[:ach_capture]
106
+ else
107
+ ENDPOINTS[:capture]
108
+ end
109
+ response = commit(endpoint, post)
110
+ check_token_response(response, endpoint, post, options)
87
111
  end
88
112
  end
89
113
 
@@ -91,17 +115,29 @@ module ActiveMerchant #:nodoc:
91
115
  # currently only support full and partial refunds of settled transactions via a transaction ID
92
116
  post = {}
93
117
  add_amount(post, money, options)
94
- post[:transaction_id] = authorization
95
- response = commit(ENDPOINTS[:transaction_refund], post)
96
- check_token_response(response, ENDPOINTS[:transaction_refund], post, options)
118
+ if options[:check_transaction]
119
+ post[:check_transaction_id] = authorization
120
+ endpoint = ENDPOINTS[:ach_refund]
121
+ else
122
+ post[:transaction_id] = authorization
123
+ endpoint = ENDPOINTS[:transaction_refund]
124
+ end
125
+ response = commit(endpoint, post)
126
+ check_token_response(response, endpoint, post, options)
97
127
  end
98
128
 
99
129
  def void(authorization, options = {})
100
130
  post = {}
101
- post[:transaction_id] = authorization
131
+ if options[:check_transaction]
132
+ post[:check_transaction_id] = authorization
133
+ endpoint = ENDPOINTS[:ach_void]
134
+ else
135
+ post[:transaction_id] = authorization
136
+ endpoint = ENDPOINTS[:transaction_void]
137
+ end
102
138
 
103
- response = commit(ENDPOINTS[:transaction_void], post)
104
- check_token_response(response, ENDPOINTS[:transaction_void], post, options)
139
+ response = commit(endpoint, post)
140
+ check_token_response(response, endpoint, post, options)
105
141
  end
106
142
 
107
143
  def verify(credit_card, options = {})
@@ -175,7 +211,11 @@ module ActiveMerchant #:nodoc:
175
211
 
176
212
  def build_capture_request(money, authorization, options)
177
213
  post = {}
178
- post[:transaction_id] = authorization
214
+ if options[:check_transaction]
215
+ post[:check_transaction_id] = authorization
216
+ else
217
+ post[:transaction_id] = authorization
218
+ end
179
219
  add_amount(post, money, options)
180
220
 
181
221
  post
@@ -234,10 +274,16 @@ module ActiveMerchant #:nodoc:
234
274
  end
235
275
 
236
276
  def add_payment(post, payment)
237
- post[:credit_card] = {}
238
- post[:credit_card][:number] = payment.number
239
- post[:credit_card][:expiration_month] = payment.month
240
- post[:credit_card][:expiration_year] = payment.year
277
+ if payment.kind_of?(Check)
278
+ post[:check] = {}
279
+ post[:check][:account_number] = payment.account_number
280
+ post[:check][:routing_number] = payment.routing_number
281
+ else
282
+ post[:credit_card] = {}
283
+ post[:credit_card][:number] = payment.number
284
+ post[:credit_card][:expiration_month] = payment.month
285
+ post[:credit_card][:expiration_year] = payment.year
286
+ end
241
287
  end
242
288
 
243
289
  def add_level_3_data(post, options)
@@ -380,7 +426,7 @@ module ActiveMerchant #:nodoc:
380
426
  if action == ENDPOINTS[:store]
381
427
  response['customer_id']
382
428
  else
383
- response['transaction_id']
429
+ response['transaction_id'] || response['check_transaction_id']
384
430
  end
385
431
  end
386
432
 
@@ -41,6 +41,7 @@ module ActiveMerchant
41
41
  add_soft_descriptors(params, options)
42
42
  add_level2_data(params, options)
43
43
  add_stored_credentials(params, options)
44
+ add_external_three_ds(params, payment_method, options)
44
45
 
45
46
  commit(params, options)
46
47
  end
@@ -56,6 +57,7 @@ module ActiveMerchant
56
57
  add_soft_descriptors(params, options)
57
58
  add_level2_data(params, options)
58
59
  add_stored_credentials(params, options)
60
+ add_external_three_ds(params, payment_method, options)
59
61
 
60
62
  commit(params, options)
61
63
  end
@@ -125,6 +127,7 @@ module ActiveMerchant
125
127
  gsub(%r((Apikey: )(\w|-)+), '\1[FILTERED]').
126
128
  gsub(%r((\\?"card_number\\?":\\?")\d+), '\1[FILTERED]').
127
129
  gsub(%r((\\?"cvv\\?":\\?")\d+), '\1[FILTERED]').
130
+ gsub(%r((\\?"cvv\\?":\\?)\d+), '\1[FILTERED]').
128
131
  gsub(%r((\\?"account_number\\?":\\?")\d+), '\1[FILTERED]').
129
132
  gsub(%r((\\?"routing_number\\?":\\?")\d+), '\1[FILTERED]').
130
133
  gsub(%r((\\?card_number=)\d+(&?)), '\1[FILTERED]').
@@ -132,11 +135,33 @@ module ActiveMerchant
132
135
  gsub(%r((\\?apikey=)\w+(&?)), '\1[FILTERED]').
133
136
  gsub(%r{(\\?"credit_card\.card_number\\?":)(\\?"[^"]+\\?")}, '\1[FILTERED]').
134
137
  gsub(%r{(\\?"credit_card\.cvv\\?":)(\\?"[^"]+\\?")}, '\1[FILTERED]').
135
- gsub(%r{(\\?"apikey\\?":)(\\?"[^"]+\\?")}, '\1[FILTERED]')
138
+ gsub(%r{(\\?"apikey\\?":)(\\?"[^"]+\\?")}, '\1[FILTERED]').
139
+ gsub(%r{(\\?"cavv\\?":)(\\?"[^"]+\\?")}, '\1[FILTERED]').
140
+ gsub(%r{(\\?"xid\\?":)(\\?"[^"]+\\?")}, '\1[FILTERED]')
136
141
  end
137
142
 
138
143
  private
139
144
 
145
+ def add_external_three_ds(params, payment_method, options)
146
+ return unless three_ds = options[:three_d_secure]
147
+
148
+ params[:'3DS'] = {
149
+ program_protocol: three_ds[:version][0],
150
+ directory_server_transaction_id: three_ds[:ds_transaction_id],
151
+ cardholder_name: payment_method.name,
152
+ card_number: payment_method.number,
153
+ exp_date: format_exp_date(payment_method.month, payment_method.year),
154
+ cvv: payment_method.verification_value,
155
+ xid: three_ds[:acs_transaction_id],
156
+ cavv: three_ds[:cavv],
157
+ wallet_provider_id: 'NO_WALLET',
158
+ type: 'D'
159
+ }.compact
160
+
161
+ params[:eci_indicator] = options[:three_d_secure][:eci]
162
+ params[:method] = '3DS'
163
+ end
164
+
140
165
  def add_invoice(params, options)
141
166
  params[:merchant_ref] = options[:order_id]
142
167
  end
@@ -152,6 +177,8 @@ module ActiveMerchant
152
177
  def add_authorization_info(params, authorization, options = {})
153
178
  transaction_id, transaction_tag, method, = authorization.split('|')
154
179
  params[:method] = method == 'token' ? 'credit_card' : method
180
+ # If the previous transaction `method` value was 3DS, it needs to be set to `credit_card` on follow up transactions
181
+ params[:method] = 'credit_card' if method == '3DS'
155
182
 
156
183
  if options[:reversal_id]
157
184
  params[:reversal_id] = options[:reversal_id]
@@ -178,6 +205,8 @@ module ActiveMerchant
178
205
  add_echeck(params, payment_method, options)
179
206
  elsif payment_method.is_a? String
180
207
  add_token(params, payment_method, options)
208
+ elsif payment_method.is_a? NetworkTokenizationCreditCard
209
+ add_network_tokenization(params, payment_method, options)
181
210
  else
182
211
  add_creditcard(params, payment_method)
183
212
  end
@@ -190,7 +219,7 @@ module ActiveMerchant
190
219
  tele_check[:check_type] = 'P'
191
220
  tele_check[:routing_number] = echeck.routing_number
192
221
  tele_check[:account_number] = echeck.account_number
193
- tele_check[:accountholder_name] = "#{echeck.first_name} #{echeck.last_name}"
222
+ tele_check[:accountholder_name] = name_from_payment_method(echeck)
194
223
  tele_check[:customer_id_type] = options[:customer_id_type] if options[:customer_id_type]
195
224
  tele_check[:customer_id_number] = options[:customer_id_number] if options[:customer_id_number]
196
225
  tele_check[:client_email] = options[:client_email] if options[:client_email]
@@ -233,10 +262,37 @@ module ActiveMerchant
233
262
  card
234
263
  end
235
264
 
265
+ def add_network_tokenization(params, payment_method, options)
266
+ nt_card = {}
267
+ nt_card[:type] = 'D'
268
+ nt_card[:cardholder_name] = name_from_payment_method(payment_method) || name_from_address(options)
269
+ nt_card[:card_number] = payment_method.number
270
+ nt_card[:exp_date] = format_exp_date(payment_method.month, payment_method.year)
271
+ nt_card[:cvv] = payment_method.verification_value
272
+ nt_card[:xid] = payment_method.payment_cryptogram unless payment_method.payment_cryptogram.empty? || payment_method.brand.include?('american_express')
273
+ nt_card[:cavv] = payment_method.payment_cryptogram unless payment_method.payment_cryptogram.empty?
274
+ nt_card[:wallet_provider_id] = 'APPLE_PAY'
275
+
276
+ params['3DS'] = nt_card
277
+ params[:method] = '3DS'
278
+ params[:eci_indicator] = payment_method.eci.nil? ? '5' : payment_method.eci
279
+ end
280
+
236
281
  def format_exp_date(month, year)
237
282
  "#{format(month, :two_digits)}#{format(year, :two_digits)}"
238
283
  end
239
284
 
285
+ def name_from_address(options)
286
+ return unless address = options[:billing_address]
287
+ return address[:name] if address[:name]
288
+ end
289
+
290
+ def name_from_payment_method(payment_method)
291
+ return unless payment_method.first_name && payment_method.last_name
292
+
293
+ return "#{payment_method.first_name} #{payment_method.last_name}"
294
+ end
295
+
240
296
  def add_address(params, options)
241
297
  address = options[:billing_address]
242
298
  return unless address
@@ -279,8 +335,7 @@ module ActiveMerchant
279
335
  end
280
336
 
281
337
  def original_transaction_id(options)
282
- return options[:cardbrand_original_transaction_id] if options[:cardbrand_original_transaction_id]
283
- return options[:stored_credential][:network_transaction_id] if options.dig(:stored_credential, :network_transaction_id)
338
+ return options[:cardbrand_original_transaction_id] || options.dig(:stored_credential, :network_transaction_id)
284
339
  end
285
340
 
286
341
  def initiator(options)
@@ -137,6 +137,10 @@ module ActiveMerchant #:nodoc:
137
137
  commit_card('delete', post)
138
138
  end
139
139
 
140
+ def inquire(authorization, options = {})
141
+ commit_transaction('inquire', authorization)
142
+ end
143
+
140
144
  def supports_scrubbing?
141
145
  true
142
146
  end
@@ -232,12 +236,20 @@ module ActiveMerchant #:nodoc:
232
236
  end
233
237
 
234
238
  def commit_raw(object, action, parameters)
235
- url = "#{(test? ? test_url : live_url)}#{object}/#{action}"
236
-
237
- begin
238
- raw_response = ssl_post(url, post_data(parameters), headers)
239
- rescue ResponseError => e
240
- raw_response = e.response.body
239
+ if action == 'inquire'
240
+ url = "#{(test? ? test_url : live_url)}#{object}/#{parameters}"
241
+ begin
242
+ raw_response = ssl_get(url, headers)
243
+ rescue ResponseError => e
244
+ raw_response = e.response.body
245
+ end
246
+ else
247
+ url = "#{(test? ? test_url : live_url)}#{object}/#{action}"
248
+ begin
249
+ raw_response = ssl_post(url, post_data(parameters), headers)
250
+ rescue ResponseError => e
251
+ raw_response = e.response.body
252
+ end
241
253
  end
242
254
 
243
255
  begin
@@ -13,6 +13,10 @@ module ActiveMerchant #:nodoc:
13
13
  (@params['PaymentDetails']||{})
14
14
  end
15
15
 
16
+ def checkout_status
17
+ (@params['CheckoutStatus']||{})
18
+ end
19
+
16
20
  def name
17
21
  payer = (info['PayerName']||{})
18
22
  [payer['FirstName'], payer['MiddleName'], payer['LastName']].compact.join(' ')
@@ -17,14 +17,8 @@ module ActiveMerchant #:nodoc:
17
17
 
18
18
  def purchase(money, payment, options = {})
19
19
  post = {}
20
- add_invoice(post, money, options)
21
- add_payment(post, payment)
22
- add_billing_address(post, options)
23
- add_merchant_details(post, options)
20
+ add_auth_purchase_params(post, money, payment, options)
24
21
  add_airline_travel_details(post, options)
25
- add_customer_data(post, payment, options) unless payment.is_a?(String)
26
- add_three_d_secure(post, payment, options) if options[:three_d_secure]
27
- add_stored_credential(post, options) if options[:stored_credential]
28
22
  add_split_pay_details(post, options)
29
23
  post[:settleWithAuth] = true
30
24
 
@@ -33,13 +27,7 @@ module ActiveMerchant #:nodoc:
33
27
 
34
28
  def authorize(money, payment, options = {})
35
29
  post = {}
36
- add_invoice(post, money, options)
37
- add_payment(post, payment)
38
- add_billing_address(post, options)
39
- add_merchant_details(post, options)
40
- add_customer_data(post, payment, options) unless payment.is_a?(String)
41
- add_three_d_secure(post, payment, options) if options[:three_d_secure]
42
- add_stored_credential(post, options) if options[:stored_credential]
30
+ add_auth_purchase_params(post, money, payment, options)
43
31
 
44
32
  commit(:post, 'auths', post, options)
45
33
  end
@@ -111,6 +99,17 @@ module ActiveMerchant #:nodoc:
111
99
 
112
100
  private
113
101
 
102
+ def add_auth_purchase_params(post, money, payment, options)
103
+ add_invoice(post, money, options)
104
+ add_payment(post, payment)
105
+ add_billing_address(post, options)
106
+ add_merchant_details(post, options)
107
+ add_customer_data(post, payment, options) unless payment.is_a?(String)
108
+ add_three_d_secure(post, payment, options) if options[:three_d_secure]
109
+ add_stored_credential(post, options) if options[:stored_credential]
110
+ add_funding_transaction(post, options)
111
+ end
112
+
114
113
  # Customer data can be included in transactions where the payment method is a credit card
115
114
  # but should not be sent when the payment method is a token
116
115
  def add_customer_data(post, creditcard, options)
@@ -286,6 +285,15 @@ module ActiveMerchant #:nodoc:
286
285
  post[:splitpay] = split_pay
287
286
  end
288
287
 
288
+ def add_funding_transaction(post, options)
289
+ return unless options[:funding_transaction]
290
+
291
+ post[:fundingTransaction] = {}
292
+ post[:fundingTransaction][:type] = options[:funding_transaction]
293
+ post[:profile] ||= {}
294
+ post[:profile][:merchantCustomerId] = options[:customer_id] || SecureRandom.hex(12)
295
+ end
296
+
289
297
  def add_stored_credential(post, options)
290
298
  return unless options[:stored_credential]
291
299
 
@@ -313,6 +313,9 @@ module ActiveMerchant #:nodoc:
313
313
  def add_extra_parameters(post, options)
314
314
  extra_parameters = {}
315
315
  extra_parameters[:INSTALLMENTS_NUMBER] = options[:installments_number] || 1
316
+ extra_parameters[:EXTRA1] = options[:extra_1] if options[:extra_1]
317
+ extra_parameters[:EXTRA2] = options[:extra_2] if options[:extra_2]
318
+ extra_parameters[:EXTRA3] = options[:extra_3] if options[:extra_3]
316
319
  post[:transaction][:extraParameters] = extra_parameters
317
320
  end
318
321