activemerchant 1.133.0 → 1.137.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.
Files changed (183) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +240 -0
  3. data/lib/active_merchant/billing/check.rb +2 -2
  4. data/lib/active_merchant/billing/compatibility.rb +4 -4
  5. data/lib/active_merchant/billing/credit_card.rb +11 -8
  6. data/lib/active_merchant/billing/credit_card_formatting.rb +4 -0
  7. data/lib/active_merchant/billing/credit_card_methods.rb +59 -6
  8. data/lib/active_merchant/billing/gateway.rb +9 -0
  9. data/lib/active_merchant/billing/gateways/adyen.rb +162 -43
  10. data/lib/active_merchant/billing/gateways/airwallex.rb +26 -12
  11. data/lib/active_merchant/billing/gateways/alelo.rb +23 -5
  12. data/lib/active_merchant/billing/gateways/authorize_net.rb +43 -35
  13. data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +10 -6
  14. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +1 -3
  15. data/lib/active_merchant/billing/gateways/axcessms.rb +6 -2
  16. data/lib/active_merchant/billing/gateways/banwire.rb +4 -2
  17. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +7 -3
  18. data/lib/active_merchant/billing/gateways/blue_pay.rb +13 -5
  19. data/lib/active_merchant/billing/gateways/blue_snap.rb +5 -5
  20. data/lib/active_merchant/billing/gateways/braintree/token_nonce.rb +65 -20
  21. data/lib/active_merchant/billing/gateways/braintree_blue.rb +226 -73
  22. data/lib/active_merchant/billing/gateways/braintree_orange.rb +1 -1
  23. data/lib/active_merchant/billing/gateways/card_connect.rb +5 -2
  24. data/lib/active_merchant/billing/gateways/card_stream.rb +4 -6
  25. data/lib/active_merchant/billing/gateways/cashnet.rb +1 -1
  26. data/lib/active_merchant/billing/gateways/cecabank/cecabank_common.rb +36 -0
  27. data/lib/active_merchant/billing/gateways/cecabank/cecabank_json.rb +316 -0
  28. data/lib/active_merchant/billing/gateways/cecabank/cecabank_xml.rb +220 -0
  29. data/lib/active_merchant/billing/gateways/cecabank.rb +7 -240
  30. data/lib/active_merchant/billing/gateways/checkout_v2.rb +238 -34
  31. data/lib/active_merchant/billing/gateways/commerce_hub.rb +63 -6
  32. data/lib/active_merchant/billing/gateways/credorax.rb +3 -5
  33. data/lib/active_merchant/billing/gateways/cyber_source.rb +185 -47
  34. data/lib/active_merchant/billing/gateways/cyber_source_rest.rb +102 -58
  35. data/lib/active_merchant/billing/gateways/d_local.rb +26 -15
  36. data/lib/active_merchant/billing/gateways/data_cash.rb +21 -17
  37. data/lib/active_merchant/billing/gateways/datatrans.rb +279 -0
  38. data/lib/active_merchant/billing/gateways/decidir.rb +53 -18
  39. data/lib/active_merchant/billing/gateways/decidir_plus.rb +4 -1
  40. data/lib/active_merchant/billing/gateways/deepstack.rb +382 -0
  41. data/lib/active_merchant/billing/gateways/ebanx.rb +40 -36
  42. data/lib/active_merchant/billing/gateways/efsnet.rb +6 -2
  43. data/lib/active_merchant/billing/gateways/elavon.rb +99 -33
  44. data/lib/active_merchant/billing/gateways/element.rb +36 -7
  45. data/lib/active_merchant/billing/gateways/epay.rb +6 -2
  46. data/lib/active_merchant/billing/gateways/evo_ca.rb +6 -2
  47. data/lib/active_merchant/billing/gateways/eway.rb +4 -2
  48. data/lib/active_merchant/billing/gateways/eway_managed.rb +6 -2
  49. data/lib/active_merchant/billing/gateways/exact.rb +6 -2
  50. data/lib/active_merchant/billing/gateways/fat_zebra.rb +31 -3
  51. data/lib/active_merchant/billing/gateways/federated_canada.rb +6 -2
  52. data/lib/active_merchant/billing/gateways/first_pay/first_pay_common.rb +15 -0
  53. data/lib/active_merchant/billing/gateways/first_pay/first_pay_json.rb +190 -0
  54. data/lib/active_merchant/billing/gateways/first_pay/first_pay_xml.rb +183 -0
  55. data/lib/active_merchant/billing/gateways/first_pay.rb +6 -172
  56. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +6 -2
  57. data/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb +7 -3
  58. data/lib/active_merchant/billing/gateways/flex_charge.rb +347 -0
  59. data/lib/active_merchant/billing/gateways/garanti.rb +4 -2
  60. data/lib/active_merchant/billing/gateways/global_collect.rb +45 -37
  61. data/lib/active_merchant/billing/gateways/hi_pay.rb +286 -0
  62. data/lib/active_merchant/billing/gateways/hps.rb +1 -1
  63. data/lib/active_merchant/billing/gateways/iats_payments.rb +7 -2
  64. data/lib/active_merchant/billing/gateways/inspire.rb +6 -4
  65. data/lib/active_merchant/billing/gateways/instapay.rb +7 -4
  66. data/lib/active_merchant/billing/gateways/ipg.rb +9 -5
  67. data/lib/active_merchant/billing/gateways/iridium.rb +15 -5
  68. data/lib/active_merchant/billing/gateways/itransact.rb +6 -2
  69. data/lib/active_merchant/billing/gateways/iveri.rb +3 -3
  70. data/lib/active_merchant/billing/gateways/ixopay.rb +2 -2
  71. data/lib/active_merchant/billing/gateways/jetpay.rb +4 -2
  72. data/lib/active_merchant/billing/gateways/jetpay_v2.rb +4 -2
  73. data/lib/active_merchant/billing/gateways/kushki.rb +72 -12
  74. data/lib/active_merchant/billing/gateways/linkpoint.rb +6 -2
  75. data/lib/active_merchant/billing/gateways/litle.rb +33 -50
  76. data/lib/active_merchant/billing/gateways/mastercard.rb +4 -4
  77. data/lib/active_merchant/billing/gateways/maxipago.rb +2 -2
  78. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +8 -5
  79. data/lib/active_merchant/billing/gateways/merchant_ware.rb +11 -4
  80. data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +11 -4
  81. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +19 -3
  82. data/lib/active_merchant/billing/gateways/mercury.rb +6 -2
  83. data/lib/active_merchant/billing/gateways/metrics_global.rb +8 -6
  84. data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +1 -0
  85. data/lib/active_merchant/billing/gateways/migs.rb +6 -2
  86. data/lib/active_merchant/billing/gateways/mit.rb +8 -3
  87. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +18 -10
  88. data/lib/active_merchant/billing/gateways/monei.rb +1 -1
  89. data/lib/active_merchant/billing/gateways/moneris.rb +9 -3
  90. data/lib/active_merchant/billing/gateways/money_movers.rb +6 -2
  91. data/lib/active_merchant/billing/gateways/nab_transact.rb +12 -4
  92. data/lib/active_merchant/billing/gateways/net_registry.rb +6 -2
  93. data/lib/active_merchant/billing/gateways/netbanx.rb +1 -3
  94. data/lib/active_merchant/billing/gateways/netbilling.rb +6 -2
  95. data/lib/active_merchant/billing/gateways/network_merchants.rb +6 -2
  96. data/lib/active_merchant/billing/gateways/nmi.rb +18 -6
  97. data/lib/active_merchant/billing/gateways/ogone.rb +6 -2
  98. data/lib/active_merchant/billing/gateways/openpay.rb +4 -2
  99. data/lib/active_merchant/billing/gateways/opp.rb +1 -2
  100. data/lib/active_merchant/billing/gateways/optimal_payment.rb +6 -2
  101. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +1 -3
  102. data/lib/active_merchant/billing/gateways/orbital.rb +83 -24
  103. data/lib/active_merchant/billing/gateways/pac_net_raven.rb +7 -4
  104. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +6 -2
  105. data/lib/active_merchant/billing/gateways/pay_hub.rb +4 -2
  106. data/lib/active_merchant/billing/gateways/pay_junction.rb +6 -2
  107. data/lib/active_merchant/billing/gateways/pay_secure.rb +6 -2
  108. data/lib/active_merchant/billing/gateways/pay_trace.rb +31 -18
  109. data/lib/active_merchant/billing/gateways/payeezy.rb +19 -8
  110. data/lib/active_merchant/billing/gateways/payex.rb +4 -2
  111. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +1 -1
  112. data/lib/active_merchant/billing/gateways/payflow.rb +1 -3
  113. data/lib/active_merchant/billing/gateways/payment_express.rb +8 -4
  114. data/lib/active_merchant/billing/gateways/paymentez.rb +23 -11
  115. data/lib/active_merchant/billing/gateways/paysafe.rb +12 -11
  116. data/lib/active_merchant/billing/gateways/payscout.rb +7 -4
  117. data/lib/active_merchant/billing/gateways/paystation.rb +7 -3
  118. data/lib/active_merchant/billing/gateways/payway.rb +6 -2
  119. data/lib/active_merchant/billing/gateways/payway_dot_com.rb +2 -2
  120. data/lib/active_merchant/billing/gateways/pin.rb +22 -4
  121. data/lib/active_merchant/billing/gateways/plexo.rb +49 -10
  122. data/lib/active_merchant/billing/gateways/plugnpay.rb +6 -2
  123. data/lib/active_merchant/billing/gateways/priority.rb +6 -5
  124. data/lib/active_merchant/billing/gateways/psigate.rb +6 -2
  125. data/lib/active_merchant/billing/gateways/psl_card.rb +6 -2
  126. data/lib/active_merchant/billing/gateways/qbms.rb +6 -2
  127. data/lib/active_merchant/billing/gateways/quantum.rb +6 -2
  128. data/lib/active_merchant/billing/gateways/quickbooks.rb +6 -5
  129. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +7 -4
  130. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb +6 -2
  131. data/lib/active_merchant/billing/gateways/rapyd.rb +148 -46
  132. data/lib/active_merchant/billing/gateways/reach.rb +11 -4
  133. data/lib/active_merchant/billing/gateways/redsys.rb +2 -10
  134. data/lib/active_merchant/billing/gateways/redsys_rest.rb +507 -0
  135. data/lib/active_merchant/billing/gateways/s5.rb +3 -3
  136. data/lib/active_merchant/billing/gateways/safe_charge.rb +36 -16
  137. data/lib/active_merchant/billing/gateways/sage.rb +12 -4
  138. data/lib/active_merchant/billing/gateways/sage_pay.rb +79 -5
  139. data/lib/active_merchant/billing/gateways/sallie_mae.rb +6 -2
  140. data/lib/active_merchant/billing/gateways/secure_net.rb +6 -2
  141. data/lib/active_merchant/billing/gateways/secure_pay.rb +8 -6
  142. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +12 -4
  143. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +6 -2
  144. data/lib/active_merchant/billing/gateways/securion_pay.rb +24 -10
  145. data/lib/active_merchant/billing/gateways/shift4.rb +17 -20
  146. data/lib/active_merchant/billing/gateways/shift4_v2.rb +117 -0
  147. data/lib/active_merchant/billing/gateways/simetrik.rb +17 -11
  148. data/lib/active_merchant/billing/gateways/skip_jack.rb +6 -2
  149. data/lib/active_merchant/billing/gateways/smart_ps.rb +7 -4
  150. data/lib/active_merchant/billing/gateways/so_easy_pay.rb +4 -2
  151. data/lib/active_merchant/billing/gateways/spreedly_core.rb +2 -4
  152. data/lib/active_merchant/billing/gateways/stripe.rb +53 -21
  153. data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +199 -50
  154. data/lib/active_merchant/billing/gateways/sum_up.rb +223 -0
  155. data/lib/active_merchant/billing/gateways/swipe_checkout.rb +4 -2
  156. data/lib/active_merchant/billing/gateways/telr.rb +3 -4
  157. data/lib/active_merchant/billing/gateways/trans_first.rb +1 -2
  158. data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +8 -16
  159. data/lib/active_merchant/billing/gateways/transact_pro.rb +1 -1
  160. data/lib/active_merchant/billing/gateways/trust_commerce.rb +6 -2
  161. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +9 -8
  162. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +6 -2
  163. data/lib/active_merchant/billing/gateways/vanco.rb +2 -4
  164. data/lib/active_merchant/billing/gateways/vantiv_express.rb +587 -0
  165. data/lib/active_merchant/billing/gateways/verifi.rb +6 -2
  166. data/lib/active_merchant/billing/gateways/viaklix.rb +6 -2
  167. data/lib/active_merchant/billing/gateways/visanet_peru.rb +2 -2
  168. data/lib/active_merchant/billing/gateways/vpos.rb +3 -3
  169. data/lib/active_merchant/billing/gateways/wirecard.rb +7 -3
  170. data/lib/active_merchant/billing/gateways/wompi.rb +5 -0
  171. data/lib/active_merchant/billing/gateways/worldpay.rb +140 -73
  172. data/lib/active_merchant/billing/gateways/worldpay_online_payments.rb +13 -10
  173. data/lib/active_merchant/billing/gateways/xpay.rb +242 -0
  174. data/lib/active_merchant/billing/network_tokenization_credit_card.rb +1 -1
  175. data/lib/active_merchant/billing/response.rb +2 -2
  176. data/lib/active_merchant/connection.rb +3 -17
  177. data/lib/active_merchant/country.rb +1 -0
  178. data/lib/active_merchant/errors.rb +10 -0
  179. data/lib/active_merchant/version.rb +1 -1
  180. data/lib/support/gateway_support.rb +2 -2
  181. data/lib/support/ssl_verify.rb +4 -4
  182. data/lib/support/ssl_version.rb +6 -6
  183. metadata +30 -9
@@ -20,14 +20,14 @@ module ActiveMerchant #:nodoc:
20
20
  def purchase(amount, payment_method, options = {})
21
21
  MultiResponse.run() do |r|
22
22
  r.process { tokenize(amount, payment_method, options) }
23
- r.process { charge(amount, r.authorization, options) }
23
+ r.process { charge(amount, r.authorization, options, payment_method) }
24
24
  end
25
25
  end
26
26
 
27
27
  def authorize(amount, payment_method, options = {})
28
28
  MultiResponse.run() do |r|
29
29
  r.process { tokenize(amount, payment_method, options) }
30
- r.process { preauthorize(amount, r.authorization, options) }
30
+ r.process { preauthorize(amount, r.authorization, options, payment_method) }
31
31
  end
32
32
  end
33
33
 
@@ -48,8 +48,9 @@ module ActiveMerchant #:nodoc:
48
48
  post = {}
49
49
  post[:ticketNumber] = authorization
50
50
  add_full_response(post, options)
51
+ add_invoice(action, post, amount, options)
51
52
 
52
- commit(action, post)
53
+ commit(action, post, options)
53
54
  end
54
55
 
55
56
  def void(authorization, options = {})
@@ -89,7 +90,7 @@ module ActiveMerchant #:nodoc:
89
90
  commit(action, post)
90
91
  end
91
92
 
92
- def charge(amount, authorization, options)
93
+ def charge(amount, authorization, options, payment_method = {})
93
94
  action = 'charge'
94
95
 
95
96
  post = {}
@@ -100,11 +101,13 @@ module ActiveMerchant #:nodoc:
100
101
  add_metadata(post, options)
101
102
  add_months(post, options)
102
103
  add_deferred(post, options)
104
+ add_three_d_secure(post, payment_method, options)
105
+ add_product_details(post, options)
103
106
 
104
107
  commit(action, post)
105
108
  end
106
109
 
107
- def preauthorize(amount, authorization, options)
110
+ def preauthorize(amount, authorization, options, payment_method = {})
108
111
  action = 'preAuthorization'
109
112
 
110
113
  post = {}
@@ -114,6 +117,7 @@ module ActiveMerchant #:nodoc:
114
117
  add_metadata(post, options)
115
118
  add_months(post, options)
116
119
  add_deferred(post, options)
120
+ add_three_d_secure(post, payment_method, options)
117
121
 
118
122
  commit(action, post)
119
123
  end
@@ -133,9 +137,9 @@ module ActiveMerchant #:nodoc:
133
137
  end
134
138
 
135
139
  def add_amount_defaults(sum, money, options)
136
- sum[:subtotalIva] = amount(money).to_f
140
+ sum[:subtotalIva] = 0
137
141
  sum[:iva] = 0
138
- sum[:subtotalIva0] = 0
142
+ sum[:subtotalIva0] = amount(money).to_f
139
143
 
140
144
  sum[:ice] = 0 if sum[:currency] != 'COP'
141
145
  end
@@ -183,7 +187,8 @@ module ActiveMerchant #:nodoc:
183
187
  end
184
188
 
185
189
  def add_full_response(post, options)
186
- post[:fullResponse] = options[:full_response].to_s.casecmp('true').zero? if options[:full_response]
190
+ # this is the only currently accepted value for this field, previously it was 'true'
191
+ post[:fullResponse] = 'v2' unless options[:full_response] == 'false' || options[:full_response].blank?
187
192
  end
188
193
 
189
194
  def add_metadata(post, options)
@@ -204,6 +209,59 @@ module ActiveMerchant #:nodoc:
204
209
  }
205
210
  end
206
211
 
212
+ def add_product_details(post, options)
213
+ return unless options[:product_details]
214
+
215
+ product_items_array = []
216
+ options[:product_details].each do |item|
217
+ product_items_obj = {}
218
+
219
+ product_items_obj[:id] = item[:id] if item[:id]
220
+ product_items_obj[:title] = item[:title] if item[:title]
221
+ product_items_obj[:price] = item[:price].to_i if item[:price]
222
+ product_items_obj[:sku] = item[:sku] if item[:sku]
223
+ product_items_obj[:quantity] = item[:quantity].to_i if item[:quantity]
224
+
225
+ product_items_array << product_items_obj
226
+ end
227
+
228
+ product_items = {
229
+ product: product_items_array
230
+ }
231
+
232
+ post[:productDetails] = product_items
233
+ end
234
+
235
+ def add_three_d_secure(post, payment_method, options)
236
+ three_d_secure = options[:three_d_secure]
237
+ return unless three_d_secure.present?
238
+
239
+ post[:threeDomainSecure] = {
240
+ eci: three_d_secure[:eci],
241
+ specificationVersion: three_d_secure[:version]
242
+ }
243
+
244
+ if payment_method.brand == 'master'
245
+ post[:threeDomainSecure][:acceptRisk] = three_d_secure[:eci] == '00'
246
+ post[:threeDomainSecure][:ucaf] = three_d_secure[:cavv]
247
+ post[:threeDomainSecure][:directoryServerTransactionID] = three_d_secure[:ds_transaction_id]
248
+ case three_d_secure[:eci]
249
+ when '07'
250
+ post[:threeDomainSecure][:collectionIndicator] = '0'
251
+ when '06'
252
+ post[:threeDomainSecure][:collectionIndicator] = '1'
253
+ else
254
+ post[:threeDomainSecure][:collectionIndicator] = '2'
255
+ end
256
+ elsif payment_method.brand == 'visa'
257
+ post[:threeDomainSecure][:acceptRisk] = three_d_secure[:eci] == '07'
258
+ post[:threeDomainSecure][:cavv] = three_d_secure[:cavv]
259
+ post[:threeDomainSecure][:xid] = three_d_secure[:xid] if three_d_secure[:xid].present?
260
+ else
261
+ raise ArgumentError.new 'Kushki supports 3ds2 authentication for only Visa and Mastercard brands.'
262
+ end
263
+ end
264
+
207
265
  ENDPOINT = {
208
266
  'tokenize' => 'tokens',
209
267
  'charge' => 'charges',
@@ -213,10 +271,10 @@ module ActiveMerchant #:nodoc:
213
271
  'capture' => 'capture'
214
272
  }
215
273
 
216
- def commit(action, params)
274
+ def commit(action, params, options = {})
217
275
  response =
218
276
  begin
219
- parse(ssl_invoke(action, params))
277
+ parse(ssl_invoke(action, params, options))
220
278
  rescue ResponseError => e
221
279
  parse(e.response.body)
222
280
  end
@@ -233,9 +291,11 @@ module ActiveMerchant #:nodoc:
233
291
  )
234
292
  end
235
293
 
236
- def ssl_invoke(action, params)
294
+ def ssl_invoke(action, params, options)
237
295
  if %w[void refund].include?(action)
238
- ssl_request(:delete, url(action, params), nil, headers(action))
296
+ # removes ticketNumber from request for partial refunds because gateway will reject if included in request body
297
+ data = options[:partial_refund] == true ? post_data(params.except(:ticketNumber)) : nil
298
+ ssl_request(:delete, url(action, params), data, headers(action))
239
299
  else
240
300
  ssl_post(url(action, params), post_data(params), headers(action))
241
301
  end
@@ -263,11 +263,15 @@ module ActiveMerchant #:nodoc:
263
263
  def commit(money, creditcard, options = {})
264
264
  response = parse(ssl_post(test? ? self.test_url : self.live_url, post_data(money, creditcard, options)))
265
265
 
266
- Response.new(successful?(response), response[:message], response,
266
+ Response.new(
267
+ successful?(response),
268
+ response[:message],
269
+ response,
267
270
  test: test?,
268
271
  authorization: response[:ordernum],
269
272
  avs_result: { code: response[:avs].to_s[2, 1] },
270
- cvv_result: response[:avs].to_s[3, 1])
273
+ cvv_result: response[:avs].to_s[3, 1]
274
+ )
271
275
  end
272
276
 
273
277
  def successful?(response)
@@ -111,14 +111,15 @@ module ActiveMerchant #:nodoc:
111
111
  doc.lineItemData do
112
112
  level_3_data[:line_items].each do |line_item|
113
113
  doc.itemSequenceNumber(line_item[:item_sequence_number]) if line_item[:item_sequence_number]
114
- doc.commodityCode(line_item[:commodity_code]) if line_item[:commodity_code]
115
114
  doc.itemDescription(line_item[:item_description]) if line_item[:item_description]
116
115
  doc.productCode(line_item[:product_code]) if line_item[:product_code]
117
116
  doc.quantity(line_item[:quantity]) if line_item[:quantity]
118
117
  doc.unitOfMeasure(line_item[:unit_of_measure]) if line_item[:unit_of_measure]
119
118
  doc.taxAmount(line_item[:tax_amount]) if line_item[:tax_amount]
120
- doc.itemDiscountAmount(line_item[:discount_per_line_item]) unless line_item[:discount_per_line_item] < 0
121
- doc.unitCost(line_item[:unit_cost]) unless line_item[:unit_cost] < 0
119
+ doc.lineItemTotal(line_item[:line_item_total]) if line_item[:line_item_total]
120
+ doc.itemDiscountAmount(line_item[:discount_per_line_item].to_i) unless line_item[:discount_per_line_item].to_i < 0
121
+ doc.commodityCode(line_item[:commodity_code]) if line_item[:commodity_code]
122
+ doc.unitCost(line_item[:unit_cost].to_i) unless line_item[:unit_cost].to_i < 0
122
123
  doc.detailTax do
123
124
  doc.taxIncludedInTotal(line_item[:tax_included_in_total]) if line_item[:tax_included_in_total]
124
125
  doc.taxAmount(line_item[:tax_amount]) if line_item[:tax_amount]
@@ -310,7 +311,15 @@ module ActiveMerchant #:nodoc:
310
311
  def add_auth_purchase_params(doc, money, payment_method, options)
311
312
  doc.orderId(truncate(options[:order_id], 24))
312
313
  doc.amount(money)
313
- add_order_source(doc, payment_method, options)
314
+
315
+ if options.dig(:stored_credential, :initial_transaction) == false
316
+ # orderSource needs to be added at the top of doc and
317
+ # processingType near the end
318
+ source_for_subsequent_stored_credential_txns(doc, options)
319
+ else
320
+ add_order_source(doc, payment_method, options)
321
+ end
322
+
314
323
  add_billing_address(doc, payment_method, options)
315
324
  add_shipping_address(doc, payment_method, options)
316
325
  add_payment_method(doc, payment_method, options)
@@ -382,8 +391,9 @@ module ActiveMerchant #:nodoc:
382
391
  doc.track(payment_method.track_data)
383
392
  end
384
393
  elsif check?(payment_method)
394
+ account_type = payment_method.account_type || payment_method.account_holder_type
385
395
  doc.echeck do
386
- doc.accType(payment_method.account_type.capitalize)
396
+ doc.accType(account_type&.capitalize)
387
397
  doc.accNum(payment_method.account_number)
388
398
  doc.routingNum(payment_method.routing_number)
389
399
  doc.checkNum(payment_method.number) if payment_method.number
@@ -409,16 +419,17 @@ module ActiveMerchant #:nodoc:
409
419
  end
410
420
 
411
421
  def add_stored_credential_params(doc, options = {})
412
- return unless options[:stored_credential]
422
+ return unless stored_credential = options[:stored_credential]
413
423
 
414
- if options[:stored_credential][:initial_transaction]
415
- add_stored_credential_params_initial(doc, options)
424
+ if stored_credential[:initial_transaction]
425
+ add_stored_credential_for_initial_txn(doc, options)
416
426
  else
417
- add_stored_credential_params_used(doc, options)
427
+ doc.processingType("#{stored_credential[:initiator]}InitiatedCOF") if stored_credential[:reason_type] == 'unscheduled'
428
+ doc.originalNetworkTransactionId(stored_credential[:network_transaction_id]) if stored_credential[:initiator] == 'merchant'
418
429
  end
419
430
  end
420
431
 
421
- def add_stored_credential_params_initial(doc, options)
432
+ def add_stored_credential_for_initial_txn(doc, options)
422
433
  case options[:stored_credential][:reason_type]
423
434
  when 'unscheduled'
424
435
  doc.processingType('initialCOF')
@@ -429,15 +440,15 @@ module ActiveMerchant #:nodoc:
429
440
  end
430
441
  end
431
442
 
432
- def add_stored_credential_params_used(doc, options)
433
- if options[:stored_credential][:reason_type] == 'unscheduled'
434
- if options[:stored_credential][:initiator] == 'merchant'
435
- doc.processingType('merchantInitiatedCOF')
436
- else
437
- doc.processingType('cardholderInitiatedCOF')
438
- end
443
+ def source_for_subsequent_stored_credential_txns(doc, options)
444
+ case options[:stored_credential][:reason_type]
445
+ when 'unscheduled'
446
+ doc.orderSource('ecommerce')
447
+ when 'installment'
448
+ doc.orderSource('installment')
449
+ when 'recurring'
450
+ doc.orderSource('recurring')
439
451
  end
440
- doc.originalNetworkTransactionId(options[:stored_credential][:network_transaction_id])
441
452
  end
442
453
 
443
454
  def add_billing_address(doc, payment_method, options)
@@ -479,8 +490,7 @@ module ActiveMerchant #:nodoc:
479
490
  end
480
491
 
481
492
  def add_order_source(doc, payment_method, options)
482
- order_source = order_source(options)
483
- if order_source
493
+ if order_source = options[:order_source]
484
494
  doc.orderSource(order_source)
485
495
  elsif payment_method.is_a?(NetworkTokenizationCreditCard) && payment_method.source == :apple_pay
486
496
  doc.orderSource('applepay')
@@ -493,31 +503,6 @@ module ActiveMerchant #:nodoc:
493
503
  end
494
504
  end
495
505
 
496
- def order_source(options = {})
497
- return options[:order_source] unless options[:stored_credential]
498
-
499
- order_source = nil
500
-
501
- case options[:stored_credential][:reason_type]
502
- when 'unscheduled'
503
- if options[:stored_credential][:initiator] == 'merchant'
504
- # For merchant-initiated, we should always set order source to
505
- # 'ecommerce'
506
- order_source = 'ecommerce'
507
- else
508
- # For cardholder-initiated, we rely on #add_order_source's
509
- # default logic to set orderSource appropriately
510
- order_source = options[:order_source]
511
- end
512
- when 'installment'
513
- order_source = 'installment'
514
- when 'recurring'
515
- order_source = 'recurring'
516
- end
517
-
518
- order_source
519
- end
520
-
521
506
  def add_pos(doc, payment_method)
522
507
  return unless payment_method.respond_to?(:track_data) && payment_method.track_data.present?
523
508
 
@@ -576,7 +561,7 @@ module ActiveMerchant #:nodoc:
576
561
  end
577
562
 
578
563
  def success_from(kind, parsed)
579
- return %w(000 001 010).any?(parsed[:response]) unless kind == :registerToken
564
+ return %w(000 001 010 141 142).any?(parsed[:response]) unless kind == :registerToken
580
565
 
581
566
  %w(000 801 802).include?(parsed[:response])
582
567
  end
@@ -618,11 +603,9 @@ module ActiveMerchant #:nodoc:
618
603
  }
619
604
  end
620
605
 
621
- def build_xml_request
606
+ def build_xml_request(&block)
622
607
  builder = Nokogiri::XML::Builder.new
623
- builder.__send__('litleOnlineRequest', root_attributes) do |doc|
624
- yield(doc)
625
- end
608
+ builder.__send__('litleOnlineRequest', root_attributes, &block)
626
609
  builder.doc.root.to_xml
627
610
  end
628
611
 
@@ -10,7 +10,7 @@ module ActiveMerchant
10
10
  if options[:pay_mode]
11
11
  post = new_post
12
12
  add_invoice(post, amount, options)
13
- add_reference(post, *new_authorization)
13
+ add_reference(post, *new_authorization(options))
14
14
  add_payment_method(post, payment_method)
15
15
  add_customer_data(post, payment_method, options)
16
16
  add_3dsecure_id(post, options)
@@ -27,7 +27,7 @@ module ActiveMerchant
27
27
  def authorize(amount, payment_method, options = {})
28
28
  post = new_post
29
29
  add_invoice(post, amount, options)
30
- add_reference(post, *new_authorization)
30
+ add_reference(post, *new_authorization(options))
31
31
  add_payment_method(post, payment_method)
32
32
  add_customer_data(post, payment_method, options)
33
33
  add_3dsecure_id(post, options)
@@ -264,9 +264,9 @@ module ActiveMerchant
264
264
  authorization.split('|')
265
265
  end
266
266
 
267
- def new_authorization
267
+ def new_authorization(options)
268
268
  # Must be unique within a merchant id.
269
- orderid = SecureRandom.uuid
269
+ orderid = options[:order_id] || SecureRandom.uuid
270
270
 
271
271
  # Must be unique within an order id.
272
272
  transactionid = '1'
@@ -79,8 +79,8 @@ module ActiveMerchant #:nodoc:
79
79
 
80
80
  private
81
81
 
82
- def commit(action)
83
- request = build_xml_request(action) { |doc| yield(doc) }
82
+ def commit(action, &block)
83
+ request = build_xml_request(action, &block)
84
84
  response = parse(ssl_post(url, request, 'Content-Type' => 'text/xml'))
85
85
 
86
86
  Response.new(
@@ -180,7 +180,7 @@ module ActiveMerchant #:nodoc:
180
180
 
181
181
  def commit(action, money, parameters)
182
182
  url = test? ? self.test_url : self.live_url
183
- parameters[:transaction_amount] = amount(money) if money unless action == 'V'
183
+ parameters[:transaction_amount] = amount(money) if !(action == 'V') && money
184
184
 
185
185
  response =
186
186
  begin
@@ -189,11 +189,15 @@ module ActiveMerchant #:nodoc:
189
189
  { 'error_code' => '404', 'auth_response_text' => e.to_s }
190
190
  end
191
191
 
192
- Response.new(success_from(response), message_from(response), response,
192
+ Response.new(
193
+ success_from(response),
194
+ message_from(response),
195
+ response,
193
196
  authorization: authorization_from(response),
194
197
  test: test?,
195
198
  cvv_result: response['cvv2_result'],
196
- avs_result: { code: response['avs_result'] })
199
+ avs_result: { code: response['avs_result'] }
200
+ )
197
201
  end
198
202
 
199
203
  def authorization_from(response)
@@ -220,8 +224,7 @@ module ActiveMerchant #:nodoc:
220
224
  post[:profile_key] = @options[:password]
221
225
  post[:transaction_type] = action if action
222
226
 
223
- request = post.merge(parameters).map { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join('&')
224
- request
227
+ post.merge(parameters).map { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join('&')
225
228
  end
226
229
  end
227
230
  end
@@ -290,19 +290,26 @@ module ActiveMerchant #:nodoc:
290
290
 
291
291
  def commit(action, request, v4 = false)
292
292
  begin
293
- data = ssl_post(url(v4), request,
293
+ data = ssl_post(
294
+ url(v4),
295
+ request,
294
296
  'Content-Type' => 'text/xml; charset=utf-8',
295
- 'SOAPAction' => soap_action(action, v4))
297
+ 'SOAPAction' => soap_action(action, v4)
298
+ )
296
299
  response = parse(action, data)
297
300
  rescue ActiveMerchant::ResponseError => e
298
301
  response = parse_error(e.response)
299
302
  end
300
303
 
301
- Response.new(response[:success], response[:message], response,
304
+ Response.new(
305
+ response[:success],
306
+ response[:message],
307
+ response,
302
308
  test: test?,
303
309
  authorization: authorization_from(response),
304
310
  avs_result: { code: response['AVSResponse'] },
305
- cvv_result: response['CVResponse'])
311
+ cvv_result: response['CVResponse']
312
+ )
306
313
  end
307
314
 
308
315
  def authorization_from(response)
@@ -261,19 +261,26 @@ module ActiveMerchant #:nodoc:
261
261
 
262
262
  def commit(action, request)
263
263
  begin
264
- data = ssl_post(url, request,
264
+ data = ssl_post(
265
+ url,
266
+ request,
265
267
  'Content-Type' => 'text/xml; charset=utf-8',
266
- 'SOAPAction' => soap_action(action))
268
+ 'SOAPAction' => soap_action(action)
269
+ )
267
270
  response = parse(action, data)
268
271
  rescue ActiveMerchant::ResponseError => e
269
272
  response = parse_error(e.response, action)
270
273
  end
271
274
 
272
- Response.new(response[:success], response[:message], response,
275
+ Response.new(
276
+ response[:success],
277
+ response[:message],
278
+ response,
273
279
  test: test?,
274
280
  authorization: authorization_from(response),
275
281
  avs_result: { code: response['AvsResponse'] },
276
- cvv_result: response['CvResponse'])
282
+ cvv_result: response['CvResponse']
283
+ )
277
284
  end
278
285
 
279
286
  def authorization_from(response)
@@ -32,6 +32,8 @@ module ActiveMerchant #:nodoc:
32
32
  add_payment_method(post, payment_method)
33
33
  add_recurring_flag(post, options)
34
34
  add_soft_descriptors(post, options)
35
+ add_three_ds(post, options)
36
+ post['storeID'] = options[:store_id] if options[:store_id]
35
37
  commit('processAuth', post)
36
38
  end
37
39
 
@@ -43,6 +45,8 @@ module ActiveMerchant #:nodoc:
43
45
  add_payment_method(post, payment_method)
44
46
  add_recurring_flag(post, options)
45
47
  add_soft_descriptors(post, options)
48
+ add_three_ds(post, options)
49
+ post['storeID'] = options[:store_id] if options[:store_id]
46
50
  commit('processCard', post)
47
51
  end
48
52
 
@@ -111,9 +115,9 @@ module ActiveMerchant #:nodoc:
111
115
  post['customerCity'] = address[:city]
112
116
  post['customerAddress'] = address[:address1]
113
117
  post['customerPostCode'] = address[:zip]
114
- post['customerIP'] = address[:ip]
115
- post['customerPhone'] = address[:phone]
116
- post['customerEmail'] = address[:email]
118
+ post['customerIP'] = address[:ip] || options[:ip]
119
+ post['customerPhone'] = address[:phone] || address[:phone_number]
120
+ post['customerEmail'] = address[:email] || options[:email]
117
121
  end
118
122
 
119
123
  def add_order_id(post, options)
@@ -184,6 +188,18 @@ module ActiveMerchant #:nodoc:
184
188
  )
185
189
  end
186
190
 
191
+ def add_three_ds(post, options)
192
+ return unless three_d_secure = options[:three_d_secure]
193
+
194
+ post.merge!({
195
+ threeDSEci: three_d_secure[:eci],
196
+ threeDSXid: three_d_secure[:xid] || three_d_secure[:ds_transaction_id],
197
+ threeDSCavv: three_d_secure[:cavv],
198
+ threeDSStatus: three_d_secure[:authentication_response_status],
199
+ threeDSV2Version: three_d_secure[:version]
200
+ }.compact)
201
+ end
202
+
187
203
  def parse(body)
188
204
  xml = REXML::Document.new(body)
189
205
 
@@ -302,12 +302,16 @@ module ActiveMerchant #:nodoc:
302
302
  success = SUCCESS_CODES.include?(response[:cmd_status])
303
303
  message = success ? 'Success' : message_from(response)
304
304
 
305
- Response.new(success, message, response,
305
+ Response.new(
306
+ success,
307
+ message,
308
+ response,
306
309
  test: test?,
307
310
  authorization: authorization_from(response),
308
311
  avs_result: { code: response[:avs_result] },
309
312
  cvv_result: response[:cvv_result],
310
- error_code: success ? nil : STANDARD_ERROR_CODE_MAPPING[response[:dsix_return_code]])
313
+ error_code: success ? nil : STANDARD_ERROR_CODE_MAPPING[response[:dsix_return_code]]
314
+ )
311
315
  end
312
316
 
313
317
  def message_from(response)
@@ -175,12 +175,16 @@ module ActiveMerchant #:nodoc:
175
175
  # (TESTMODE) Successful Sale
176
176
  test_mode = test? || message =~ /TESTMODE/
177
177
 
178
- Response.new(success?(response), message, response,
178
+ Response.new(
179
+ success?(response),
180
+ message,
181
+ response,
179
182
  test: test_mode,
180
183
  authorization: response[:transaction_id],
181
184
  fraud_review: fraud_review?(response),
182
185
  avs_result: { code: response[:avs_result_code] },
183
- cvv_result: response[:card_code])
186
+ cvv_result: response[:card_code]
187
+ )
184
188
  end
185
189
 
186
190
  def success?(response)
@@ -194,7 +198,7 @@ module ActiveMerchant #:nodoc:
194
198
  def parse(body)
195
199
  fields = split(body)
196
200
 
197
- results = {
201
+ {
198
202
  response_code: fields[RESPONSE_CODE].to_i,
199
203
  response_reason_code: fields[RESPONSE_REASON_CODE],
200
204
  response_reason_text: fields[RESPONSE_REASON_TEXT],
@@ -202,7 +206,6 @@ module ActiveMerchant #:nodoc:
202
206
  transaction_id: fields[TRANSACTION_ID],
203
207
  card_code: fields[CARD_CODE_RESPONSE_CODE]
204
208
  }
205
- results
206
209
  end
207
210
 
208
211
  def post_data(action, parameters = {})
@@ -218,8 +221,7 @@ module ActiveMerchant #:nodoc:
218
221
  post[:encap_char] = '$'
219
222
  post[:solution_ID] = application_id if application_id
220
223
 
221
- request = post.merge(parameters).collect { |key, value| "x_#{key}=#{CGI.escape(value.to_s)}" }.join('&')
222
- request
224
+ post.merge(parameters).collect { |key, value| "x_#{key}=#{CGI.escape(value.to_s)}" }.join('&')
223
225
  end
224
226
 
225
227
  def add_invoice(post, options)
@@ -71,6 +71,7 @@ module ActiveMerchant
71
71
 
72
72
  class CreditCardType
73
73
  attr_accessor :am_code, :migs_code, :migs_long_code, :name
74
+
74
75
  def initialize(am_code, migs_code, migs_long_code, name)
75
76
  @am_code = am_code
76
77
  @migs_code = migs_code
@@ -281,12 +281,16 @@ module ActiveMerchant #:nodoc:
281
281
  cvv_result_code = response[:CSCResultCode]
282
282
  cvv_result_code = 'P' if cvv_result_code == 'Unsupported'
283
283
 
284
- Response.new(success?(response), response[:Message], response,
284
+ Response.new(
285
+ success?(response),
286
+ response[:Message],
287
+ response,
285
288
  test: test?,
286
289
  authorization: response[:TransactionNo],
287
290
  fraud_review: fraud_review?(response),
288
291
  avs_result: { code: avs_response_code },
289
- cvv_result: cvv_result_code)
292
+ cvv_result: cvv_result_code
293
+ )
290
294
  end
291
295
 
292
296
  def success?(response)
@@ -7,6 +7,7 @@ module ActiveMerchant #:nodoc:
7
7
  module Billing #:nodoc:
8
8
  class MitGateway < Gateway
9
9
  self.live_url = 'https://wpy.mitec.com.mx/ModuloUtilWS/activeCDP.htm'
10
+ self.test_url = 'https://scqa.mitec.com.mx/ModuloUtilWS/activeCDP.htm'
10
11
 
11
12
  self.supported_countries = ['MX']
12
13
  self.default_currency = 'MXN'
@@ -41,7 +42,7 @@ module ActiveMerchant #:nodoc:
41
42
  # original message
42
43
  full_data = unpacked[0].bytes.slice(16, unpacked[0].bytes.length)
43
44
  # Creates the engine
44
- engine = OpenSSL::Cipher::AES128.new(:CBC)
45
+ engine = OpenSSL::Cipher.new('aes-128-cbc')
45
46
  # Set engine as decrypt mode
46
47
  engine.decrypt
47
48
  # Converts the key from hex to bytes
@@ -54,7 +55,7 @@ module ActiveMerchant #:nodoc:
54
55
 
55
56
  def encrypt(val, keyinhex)
56
57
  # Creates the engine motor
57
- engine = OpenSSL::Cipher::AES128.new(:CBC)
58
+ engine = OpenSSL::Cipher.new('aes-128-cbc')
58
59
  # Set engine as encrypt mode
59
60
  engine.encrypt
60
61
  # Converts the key from hex to bytes
@@ -220,8 +221,12 @@ module ActiveMerchant #:nodoc:
220
221
  post[:name_client] = [payment.first_name, payment.last_name].join(' ')
221
222
  end
222
223
 
224
+ def url
225
+ test? ? test_url : live_url
226
+ end
227
+
223
228
  def commit(action, parameters)
224
- raw_response = ssl_post(live_url, parameters, { 'Content-type' => 'text/plain' })
229
+ raw_response = ssl_post(url, parameters, { 'Content-type' => 'text/plain' })
225
230
  response = JSON.parse(decrypt(raw_response, @options[:key_session]))
226
231
 
227
232
  Response.new(