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
@@ -111,13 +111,12 @@ module ActiveMerchant #:nodoc:
111
111
  end
112
112
 
113
113
  def build_request(action, params)
114
+ envelope_obj = { 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
115
+ 'xmlns:env' => 'http://schemas.xmlsoap.org/soap/envelope/',
116
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance' }
114
117
  xml = Builder::XmlMarkup.new indent: 2
115
118
  xml.instruct!
116
- xml.tag! 'env:Envelope',
117
- { 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
118
- 'xmlns:env' => 'http://schemas.xmlsoap.org/soap/envelope/',
119
- 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance' } do
120
-
119
+ xml.tag! 'env:Envelope', envelope_obj do
121
120
  xml.tag! 'env:Body' do
122
121
  xml.tag! action, { 'xmlns' => xmlns(action) } do
123
122
  xml.tag! 'clientId', @options[:login]
@@ -146,15 +145,24 @@ module ActiveMerchant #:nodoc:
146
145
  end
147
146
 
148
147
  def commit(action, params)
149
- data = ssl_post(url(action), build_request(action, params),
150
- { 'Content-Type' => 'text/xml; charset=utf-8',
151
- 'SOAPAction' => "#{xmlns(action)}#{action}" })
148
+ data = ssl_post(
149
+ url(action),
150
+ build_request(action, params),
151
+ {
152
+ 'Content-Type' => 'text/xml; charset=utf-8',
153
+ 'SOAPAction' => "#{xmlns(action)}#{action}"
154
+ }
155
+ )
152
156
 
153
157
  response = parse(action, data)
154
- Response.new(successful?(action, response), message_from(action, response), response,
158
+ Response.new(
159
+ successful?(action, response),
160
+ message_from(action, response),
161
+ response,
155
162
  test: test?,
156
163
  authorization: authorization_from(action, response),
157
- avs_result: { code: response[:avs_code] })
164
+ avs_result: { code: response[:avs_code] }
165
+ )
158
166
  end
159
167
 
160
168
  def authorization_from(action, response)
@@ -337,7 +337,7 @@ module ActiveMerchant #:nodoc:
337
337
  endpoint = translate_action_endpoint(action, options)
338
338
  headers = {
339
339
  'Content-Type': 'application/json;charset=UTF-8',
340
- 'Authorization': @options[:api_key],
340
+ Authorization: @options[:api_key],
341
341
  'User-Agent': 'MONEI/Shopify/0.1.0'
342
342
  }
343
343
 
@@ -54,6 +54,7 @@ module ActiveMerchant #:nodoc:
54
54
  post[:crypt_type] = options[:crypt_type] || @options[:crypt_type]
55
55
  add_external_mpi_fields(post, options)
56
56
  add_stored_credential(post, options)
57
+ add_cust_id(post, options)
57
58
  action = if post[:cavv] || options[:three_d_secure]
58
59
  'cavv_preauth'
59
60
  elsif post[:data_key].blank?
@@ -78,6 +79,7 @@ module ActiveMerchant #:nodoc:
78
79
  post[:crypt_type] = options[:crypt_type] || @options[:crypt_type]
79
80
  add_external_mpi_fields(post, options)
80
81
  add_stored_credential(post, options)
82
+ add_cust_id(post, options)
81
83
  action = if post[:cavv] || options[:three_d_secure]
82
84
  'cavv_purchase'
83
85
  elsif post[:data_key].blank?
@@ -216,7 +218,7 @@ module ActiveMerchant #:nodoc:
216
218
  three_d_secure_options = options[:three_d_secure]
217
219
 
218
220
  post[:threeds_version] = three_d_secure_options[:version]
219
- post[:crypt_type] = three_d_secure_options[:eci]
221
+ post[:crypt_type] = three_d_secure_options.dig(:eci)&.to_s&.sub!(/^0/, '')
220
222
  post[:cavv] = three_d_secure_options[:cavv]
221
223
  post[:threeds_server_trans_id] = three_d_secure_options[:three_ds_server_trans_id]
222
224
  post[:ds_trans_id] = three_d_secure_options[:ds_transaction_id]
@@ -248,6 +250,10 @@ module ActiveMerchant #:nodoc:
248
250
  post[:payment_information] = options[:payment_information] if options[:payment_information]
249
251
  end
250
252
 
253
+ def add_cust_id(post, options)
254
+ post[:cust_id] = options[:cust_id] if options[:cust_id]
255
+ end
256
+
251
257
  def add_stored_credential(post, options)
252
258
  add_cof(post, options)
253
259
  # if any of :issuer_id, :payment_information, or :payment_indicator is not passed,
@@ -467,8 +473,8 @@ module ActiveMerchant #:nodoc:
467
473
  'indrefund' => %i[order_id cust_id amount pan expdate crypt_type],
468
474
  'completion' => %i[order_id comp_amount txn_number crypt_type],
469
475
  'purchasecorrection' => %i[order_id txn_number crypt_type],
470
- 'cavv_preauth' => %i[order_id cust_id amount pan expdate cavv crypt_type wallet_indicator],
471
- 'cavv_purchase' => %i[order_id cust_id amount pan expdate cavv crypt_type wallet_indicator],
476
+ 'cavv_preauth' => %i[order_id cust_id amount pan expdate cavv crypt_type wallet_indicator threeds_version threeds_server_trans_id ds_trans_id],
477
+ 'cavv_purchase' => %i[order_id cust_id amount pan expdate cavv crypt_type wallet_indicator threeds_version threeds_server_trans_id ds_trans_id],
472
478
  'card_verification' => %i[order_id cust_id pan expdate crypt_type avs_info cvd_info cof_info],
473
479
  'transact' => %i[order_id cust_id amount pan expdate crypt_type],
474
480
  'Batchcloseall' => [],
@@ -113,11 +113,15 @@ module ActiveMerchant #:nodoc:
113
113
  response = parse(data)
114
114
  message = message_from(response)
115
115
 
116
- Response.new(success?(response), message, response,
116
+ Response.new(
117
+ success?(response),
118
+ message,
119
+ response,
117
120
  test: test?,
118
121
  authorization: response['transactionid'],
119
122
  avs_result: { code: response['avsresponse'] },
120
- cvv_result: response['cvvresponse'])
123
+ cvv_result: response['cvvresponse']
124
+ )
121
125
  end
122
126
 
123
127
  def success?(response)
@@ -233,16 +233,24 @@ module ActiveMerchant #:nodoc:
233
233
  def commit(action, request)
234
234
  response = parse(ssl_post(test? ? self.test_url : self.live_url, build_request(action, request)))
235
235
 
236
- Response.new(success?(response), message_from(response), response,
236
+ Response.new(
237
+ success?(response),
238
+ message_from(response),
239
+ response,
237
240
  test: test?,
238
- authorization: authorization_from(action, response))
241
+ authorization: authorization_from(action, response)
242
+ )
239
243
  end
240
244
 
241
245
  def commit_periodic(action, request)
242
246
  response = parse(ssl_post(test? ? self.test_periodic_url : self.live_periodic_url, build_periodic_request(action, request)))
243
- Response.new(success?(response), message_from(response), response,
247
+ Response.new(
248
+ success?(response),
249
+ message_from(response),
250
+ response,
244
251
  test: test?,
245
- authorization: authorization_from(action, response))
252
+ authorization: authorization_from(action, response)
253
+ )
246
254
  end
247
255
 
248
256
  def success?(response)
@@ -144,8 +144,12 @@ module ActiveMerchant
144
144
  # get gateway response
145
145
  response = parse(ssl_post(self.live_url, post_data(action, params)))
146
146
 
147
- Response.new(response['status'] == 'approved', message_from(response), response,
148
- authorization: authorization_from(response, action))
147
+ Response.new(
148
+ response['status'] == 'approved',
149
+ message_from(response),
150
+ response,
151
+ authorization: authorization_from(response, action)
152
+ )
149
153
  end
150
154
 
151
155
  def post_data(action, params)
@@ -233,7 +233,7 @@ module ActiveMerchant #:nodoc:
233
233
  end
234
234
 
235
235
  def map_3ds(three_d_secure_options)
236
- mapped = {
236
+ {
237
237
  eci: three_d_secure_options[:eci],
238
238
  cavv: three_d_secure_options[:cavv],
239
239
  xid: three_d_secure_options[:xid],
@@ -241,8 +241,6 @@ module ActiveMerchant #:nodoc:
241
241
  threeDSecureVersion: three_d_secure_options[:version],
242
242
  directoryServerTransactionId: three_d_secure_options[:ds_transaction_id]
243
243
  }
244
-
245
- mapped
246
244
  end
247
245
 
248
246
  def parse(body)
@@ -193,11 +193,15 @@ module ActiveMerchant #:nodoc:
193
193
  def commit(action, parameters)
194
194
  response = parse(ssl_post(self.live_url, post_data(action, parameters)))
195
195
 
196
- Response.new(success?(response), message_from(response), response,
196
+ Response.new(
197
+ success?(response),
198
+ message_from(response),
199
+ response,
197
200
  test: test_response?(response),
198
201
  authorization: response[:trans_id],
199
202
  avs_result: { code: response[:avs_code] },
200
- cvv_result: response[:cvv2_code])
203
+ cvv_result: response[:cvv2_code]
204
+ )
201
205
  rescue ActiveMerchant::ResponseError => e
202
206
  raise unless e.response.code =~ /^[67]\d\d$/
203
207
 
@@ -200,11 +200,15 @@ module ActiveMerchant #:nodoc:
200
200
 
201
201
  authorization = authorization_from(success, parameters, raw)
202
202
 
203
- Response.new(success, raw['responsetext'], raw,
203
+ Response.new(
204
+ success,
205
+ raw['responsetext'],
206
+ raw,
204
207
  test: test?,
205
208
  authorization: authorization,
206
209
  avs_result: { code: raw['avsresponse'] },
207
- cvv_result: raw['cvvresponse'])
210
+ cvv_result: raw['cvvresponse']
211
+ )
208
212
  end
209
213
 
210
214
  def build_request(action, parameters)
@@ -8,7 +8,7 @@ module ActiveMerchant #:nodoc:
8
8
  self.test_url = self.live_url = 'https://secure.networkmerchants.com/api/transact.php'
9
9
  self.default_currency = 'USD'
10
10
  self.money_format = :dollars
11
- self.supported_countries = ['US']
11
+ self.supported_countries = %w[US CA]
12
12
  self.supported_cardtypes = %i[visa master american_express discover]
13
13
  self.homepage_url = 'http://nmi.com/'
14
14
  self.display_name = 'NMI'
@@ -134,6 +134,7 @@ module ActiveMerchant #:nodoc:
134
134
  gsub(%r((cvv=)\d+), '\1[FILTERED]').
135
135
  gsub(%r((checkaba=)\d+), '\1[FILTERED]').
136
136
  gsub(%r((checkaccount=)\d+), '\1[FILTERED]').
137
+ gsub(%r((cavv=)[^&\n]*), '\1[FILTERED]').
137
138
  gsub(%r((cryptogram=)[^&]+(&?)), '\1[FILTERED]\2')
138
139
  end
139
140
 
@@ -166,7 +167,7 @@ module ActiveMerchant #:nodoc:
166
167
  elsif payment_method.is_a?(NetworkTokenizationCreditCard)
167
168
  post[:ccnumber] = payment_method.number
168
169
  post[:ccexp] = exp_date(payment_method)
169
- post[:token_cryptogram] = payment_method.payment_cryptogram
170
+ add_network_token_fields(post, payment_method)
170
171
  elsif card_brand(payment_method) == 'check'
171
172
  post[:payment] = 'check'
172
173
  post[:firstname] = payment_method.first_name
@@ -187,6 +188,17 @@ module ActiveMerchant #:nodoc:
187
188
  end
188
189
  end
189
190
 
191
+ def add_network_token_fields(post, payment_method)
192
+ if payment_method.source == :apple_pay || payment_method.source == :google_pay
193
+ post[:cavv] = payment_method.payment_cryptogram
194
+ post[:eci] = payment_method.eci
195
+ post[:decrypted_applepay_data] = 1
196
+ post[:decrypted_googlepay_data] = 1
197
+ else
198
+ post[:token_cryptogram] = payment_method.payment_cryptogram
199
+ end
200
+ end
201
+
190
202
  def add_stored_credential(post, options)
191
203
  return unless (stored_credential = options[:stored_credential])
192
204
 
@@ -212,7 +224,8 @@ module ActiveMerchant #:nodoc:
212
224
  else
213
225
  post[:stored_credential_indicator] = 'used'
214
226
  # should only send :initial_transaction_id if it is a MIT
215
- post[:initial_transaction_id] = stored_credential[:network_transaction_id] if post[:initiated_by] == 'merchant'
227
+ ntid = options[:network_transaction_id] || stored_credential[:network_transaction_id]
228
+ post[:initial_transaction_id] = ntid if post[:initiated_by] == 'merchant'
216
229
  end
217
230
  end
218
231
 
@@ -334,8 +347,7 @@ module ActiveMerchant #:nodoc:
334
347
  end
335
348
 
336
349
  def headers
337
- headers = { 'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8' }
338
- headers
350
+ { 'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8' }
339
351
  end
340
352
 
341
353
  def post_data(action, params)
@@ -347,7 +359,7 @@ module ActiveMerchant #:nodoc:
347
359
  end
348
360
 
349
361
  def parse(body)
350
- Hash[CGI::parse(body).map { |k, v| [k.intern, v.first] }]
362
+ CGI::parse(body).map { |k, v| [k.intern, v.first] }.to_h
351
363
  end
352
364
 
353
365
  def success_from(response)
@@ -263,7 +263,7 @@ module ActiveMerchant #:nodoc:
263
263
  end
264
264
 
265
265
  def add_payment_source(post, payment_source, options)
266
- add_d3d(post, options) if options[:d3d]
266
+ add_d3d(post, options) if options[:d3d] || three_d_secure(options)
267
267
  if payment_source.is_a?(String)
268
268
  add_alias(post, payment_source, options[:alias_operation])
269
269
  add_eci(post, options[:eci] || '9')
@@ -460,7 +460,7 @@ module ActiveMerchant #:nodoc:
460
460
  raise "Unknown signature algorithm #{algorithm}"
461
461
  end
462
462
 
463
- filtered_params = signed_parameters.compact
463
+ filtered_params = signed_parameters.reject { |_k, v| v.nil? || v == '' }
464
464
  sha_encryptor.hexdigest(
465
465
  filtered_params.sort_by { |k, _v| k.upcase }.map { |k, v| "#{k.upcase}=#{v}#{secret}" }.join('')
466
466
  ).upcase
@@ -494,6 +494,10 @@ module ActiveMerchant #:nodoc:
494
494
  end
495
495
  response_hash
496
496
  end
497
+
498
+ def three_d_secure(options)
499
+ options[:three_d_secure] ? options[:three_d_secure][:required] : false
500
+ end
497
501
  end
498
502
 
499
503
  class OgoneResponse < Response
@@ -201,11 +201,13 @@ module ActiveMerchant #:nodoc:
201
201
  response = http_request(method, resource, parameters, options)
202
202
  success = !error?(response)
203
203
 
204
- Response.new(success,
204
+ Response.new(
205
+ success,
205
206
  (success ? response['error_code'] : response['description']),
206
207
  response,
207
208
  test: test?,
208
- authorization: response['id'])
209
+ authorization: response['id']
210
+ )
209
211
  end
210
212
 
211
213
  def http_request(method, resource, parameters = {}, options = {})
@@ -125,8 +125,7 @@ module ActiveMerchant #:nodoc:
125
125
  def purchase(money, payment, options = {})
126
126
  # debit
127
127
  options[:registrationId] = payment if payment.is_a?(String)
128
- execute_dbpa(options[:risk_workflow] ? 'PA.CP' : 'DB',
129
- money, payment, options)
128
+ execute_dbpa(options[:risk_workflow] ? 'PA.CP' : 'DB', money, payment, options)
130
129
  end
131
130
 
132
131
  def authorize(money, payment, options = {})
@@ -121,11 +121,15 @@ module ActiveMerchant #:nodoc:
121
121
  txnRequest = escape_uri(xml)
122
122
  response = parse(ssl_post(test? ? self.test_url : self.live_url, "txnMode=#{action}&txnRequest=#{txnRequest}"))
123
123
 
124
- Response.new(successful?(response), message_from(response), hash_from_xml(response),
124
+ Response.new(
125
+ successful?(response),
126
+ message_from(response),
127
+ hash_from_xml(response),
125
128
  test: test?,
126
129
  authorization: authorization_from(response),
127
130
  avs_result: { code: avs_result_from(response) },
128
- cvv_result: cvv_result_from(response))
131
+ cvv_result: cvv_result_from(response)
132
+ )
129
133
  end
130
134
 
131
135
  # The upstream is picky and so we can't use CGI.escape like we want to
@@ -33,9 +33,7 @@ module ActiveMerchant #:nodoc:
33
33
  errors << [:merchant_phone, 'is required to follow "NNN-NNN-NNNN" or "NNN-AAAAAAA" format'] if !empty?(self.merchant_phone) && !self.merchant_phone.match(PHONE_FORMAT_1) && !self.merchant_phone.match(PHONE_FORMAT_2)
34
34
 
35
35
  %i[merchant_email merchant_url].each do |attr|
36
- unless self.send(attr).blank?
37
- errors << [attr, 'is required to be 13 bytes or less'] if self.send(attr).bytesize > 13
38
- end
36
+ errors << [attr, 'is required to be 13 bytes or less'] if !self.send(attr).blank? && (self.send(attr).bytesize > 13)
39
37
  end
40
38
 
41
39
  errors_hash(errors)
@@ -30,7 +30,7 @@ module ActiveMerchant #:nodoc:
30
30
  class OrbitalGateway < Gateway
31
31
  include Empty
32
32
 
33
- API_VERSION = '9.0'
33
+ API_VERSION = '9.5'
34
34
 
35
35
  POST_HEADERS = {
36
36
  'MIME-Version' => '1.1',
@@ -193,6 +193,10 @@ module ActiveMerchant #:nodoc:
193
193
  'checking' => 'C'
194
194
  }
195
195
 
196
+ # safetech token flags
197
+ GET_TOKEN = 'GT'
198
+ USE_TOKEN = 'UT'
199
+
196
200
  def initialize(options = {})
197
201
  requires!(options, :merchant_id)
198
202
  requires!(options, :login, :password) unless options[:ip_authentication]
@@ -253,6 +257,11 @@ module ActiveMerchant #:nodoc:
253
257
  commit(order, :refund, options[:retry_logic], options[:trace_number])
254
258
  end
255
259
 
260
+ # Orbital save a payment method if the TokenTxnType is 'GT', that's why we use this as the default value for store
261
+ def store(creditcard, options = {})
262
+ authorize(0, creditcard, options.merge({ token_txn_type: GET_TOKEN }))
263
+ end
264
+
256
265
  def void(authorization, options = {}, deprecated = {})
257
266
  if !options.kind_of?(Hash)
258
267
  ActiveMerchant.deprecated('Calling the void method with an amount parameter is deprecated and will be removed in a future version.')
@@ -487,6 +496,35 @@ module ActiveMerchant #:nodoc:
487
496
  end
488
497
  end
489
498
 
499
+ def add_level2_card_and_more_tax(xml, options = {})
500
+ if (level2 = options[:level_2_data])
501
+ xml.tag! :PCardRequestorName, byte_limit(level2[:requestor_name], 38) if level2[:requestor_name]
502
+ xml.tag! :PCardLocalTaxRate, byte_limit(level2[:local_tax_rate], 5) if level2[:local_tax_rate]
503
+ # Canadian Merchants Only
504
+ xml.tag! :PCardNationalTax, byte_limit(level2[:national_tax], 12) if level2[:national_tax]
505
+ xml.tag! :PCardPstTaxRegNumber, byte_limit(level2[:pst_tax_reg_number], 15) if level2[:pst_tax_reg_number]
506
+ xml.tag! :PCardCustomerVatRegNumber, byte_limit(level2[:customer_vat_reg_number], 13) if level2[:customer_vat_reg_number]
507
+ # Canadian Merchants Only
508
+ xml.tag! :PCardMerchantVatRegNumber, byte_limit(level2[:merchant_vat_reg_number], 20) if level2[:merchant_vat_reg_number]
509
+ xml.tag! :PCardTotalTaxAmount, byte_limit(level2[:total_tax_amount], 12) if level2[:total_tax_amount]
510
+ end
511
+ end
512
+
513
+ def add_card_commodity_code(xml, options = {})
514
+ if (level2 = options[:level_2_data]) && (level2[:commodity_code])
515
+ xml.tag! :PCardCommodityCode, byte_limit(level2[:commodity_code], 4)
516
+ end
517
+ end
518
+
519
+ def add_level3_vat_fields(xml, options = {})
520
+ if (level3 = options[:level_3_data])
521
+ xml.tag! :PC3InvoiceDiscTreatment, byte_limit(level3[:invoice_discount_treatment], 1) if level3[:invoice_discount_treatment]
522
+ xml.tag! :PC3TaxTreatment, byte_limit(level3[:tax_treatment], 1) if level3[:tax_treatment]
523
+ xml.tag! :PC3UniqueVATInvoiceRefNum, byte_limit(level3[:unique_vat_invoice_ref], 15) if level3[:unique_vat_invoice_ref]
524
+ xml.tag! :PC3ShipVATRate, byte_limit(level3[:ship_vat_rate], 4) if level3[:ship_vat_rate]
525
+ end
526
+ end
527
+
490
528
  #=====ADDRESS FIELDS=====
491
529
 
492
530
  def add_address(xml, payment_source, options)
@@ -536,9 +574,9 @@ module ActiveMerchant #:nodoc:
536
574
  end
537
575
 
538
576
  def billing_name(payment_source, options)
539
- if payment_source&.name.present?
577
+ if !payment_source.is_a?(String) && payment_source&.name.present?
540
578
  payment_source.name[0..29]
541
- elsif options[:billing_address][:name].present?
579
+ elsif options[:billing_address] && options[:billing_address][:name].present?
542
580
  options[:billing_address][:name][0..29]
543
581
  end
544
582
  end
@@ -555,10 +593,17 @@ module ActiveMerchant #:nodoc:
555
593
  options[:billing_address] || options[:address]
556
594
  end
557
595
 
596
+ def add_safetech_token_data(xml, payment_source, options)
597
+ payment_source_token = split_authorization(payment_source).values_at(2).first
598
+ xml.tag! :CardBrand, options[:card_brand]
599
+ xml.tag! :AccountNum, payment_source_token
600
+ end
601
+
558
602
  #=====PAYMENT SOURCE FIELDS=====
559
603
 
560
604
  # Payment can be done through either Credit Card or Electronic Check
561
605
  def add_payment_source(xml, payment_source, options = {})
606
+ add_safetech_token_data(xml, payment_source, options) if payment_source.is_a?(String)
562
607
  payment_source.is_a?(Check) ? add_echeck(xml, payment_source, options) : add_credit_card(xml, payment_source, options)
563
608
  end
564
609
 
@@ -576,10 +621,10 @@ module ActiveMerchant #:nodoc:
576
621
  end
577
622
 
578
623
  def add_credit_card(xml, credit_card, options)
579
- xml.tag! :AccountNum, credit_card.number if credit_card
580
- xml.tag! :Exp, expiry_date(credit_card) if credit_card
624
+ xml.tag! :AccountNum, credit_card.number if credit_card.is_a?(CreditCard)
625
+ xml.tag! :Exp, expiry_date(credit_card) if credit_card.is_a?(CreditCard)
581
626
  add_currency_fields(xml, options[:currency])
582
- add_verification_value(xml, credit_card) if credit_card
627
+ add_verification_value(xml, credit_card) if credit_card.is_a?(CreditCard)
583
628
  end
584
629
 
585
630
  def add_verification_value(xml, credit_card)
@@ -679,7 +724,7 @@ module ActiveMerchant #:nodoc:
679
724
  add_mc_sca_recurring(xml, credit_card, parameters, three_d_secure)
680
725
  add_mc_program_protocol(xml, credit_card, three_d_secure)
681
726
  add_mc_directory_trans_id(xml, credit_card, three_d_secure)
682
- add_mc_ucafind(xml, credit_card, three_d_secure)
727
+ add_mc_ucafind(xml, credit_card, three_d_secure, parameters)
683
728
  end
684
729
 
685
730
  def add_mc_sca_merchant_initiated(xml, credit_card, parameters, three_d_secure)
@@ -708,10 +753,16 @@ module ActiveMerchant #:nodoc:
708
753
  xml.tag!(:MCDirectoryTransID, three_d_secure[:ds_transaction_id]) if three_d_secure[:ds_transaction_id]
709
754
  end
710
755
 
711
- def add_mc_ucafind(xml, credit_card, three_d_secure)
756
+ def add_mc_ucafind(xml, credit_card, three_d_secure, options)
712
757
  return unless three_d_secure
713
758
 
714
- xml.tag! :UCAFInd, '4'
759
+ if options[:alternate_ucaf_flow]
760
+ return unless %w(4 6 7).include?(three_d_secure[:eci])
761
+
762
+ xml.tag! :UCAFInd, options[:ucaf_collection_indicator] if options[:ucaf_collection_indicator]
763
+ else
764
+ xml.tag! :UCAFInd, options[:ucaf_collection_indicator] || '4'
765
+ end
715
766
  end
716
767
 
717
768
  #=====SCA (STORED CREDENTIAL) FIELDS=====
@@ -886,13 +937,19 @@ module ActiveMerchant #:nodoc:
886
937
  request.call(remote_url(:secondary))
887
938
  end
888
939
 
889
- Response.new(success?(response, message_type), message_from(response), response,
940
+ authorization = authorization_string(response[:tx_ref_num], response[:order_id], response[:safetech_token], response[:card_brand])
941
+
942
+ Response.new(
943
+ success?(response, message_type),
944
+ message_from(response),
945
+ response,
890
946
  {
891
- authorization: authorization_string(response[:tx_ref_num], response[:order_id]),
947
+ authorization: authorization,
892
948
  test: self.test?,
893
949
  avs_result: OrbitalGateway::AVSResult.new(response[:avs_resp_code]),
894
950
  cvv_result: OrbitalGateway::CVVResult.new(response[:cvv2_resp_code])
895
- })
951
+ }
952
+ )
896
953
  end
897
954
 
898
955
  def remote_url(url = :primary)
@@ -981,35 +1038,34 @@ module ActiveMerchant #:nodoc:
981
1038
  xml.tag! :OrderID, format_order_id(parameters[:order_id])
982
1039
  xml.tag! :Amount, amount(money)
983
1040
  xml.tag! :Comments, parameters[:comments] if parameters[:comments]
984
-
985
1041
  add_level2_tax(xml, parameters)
986
1042
  add_level2_advice_addendum(xml, parameters)
987
-
988
1043
  add_aav(xml, payment_source, three_d_secure)
989
1044
  # CustomerAni, AVSPhoneType and AVSDestPhoneType could be added here.
990
-
991
1045
  add_soft_descriptors(xml, parameters[:soft_descriptors])
992
- add_payment_action_ind(xml, parameters[:payment_action_ind])
993
- add_dpanind(xml, payment_source, parameters[:industry_type])
994
- add_aevv(xml, payment_source, three_d_secure)
995
- add_digital_token_cryptogram(xml, payment_source, three_d_secure)
996
-
997
- xml.tag! :ECPSameDayInd, parameters[:same_day] if parameters[:same_day] && payment_source.is_a?(Check)
998
-
999
1046
  set_recurring_ind(xml, parameters)
1000
1047
 
1001
1048
  # Append Transaction Reference Number at the end for Refund transactions
1002
1049
  add_tx_ref_num(xml, parameters[:authorization]) if action == REFUND && payment_source.nil?
1003
-
1004
1050
  add_level2_purchase(xml, parameters)
1005
1051
  add_level3_purchase(xml, parameters)
1006
1052
  add_level3_tax(xml, parameters)
1007
1053
  add_line_items(xml, parameters) if parameters[:line_items]
1008
- add_ecp_details(xml, payment_source, parameters) if payment_source.is_a?(Check)
1009
1054
  add_card_indicators(xml, parameters)
1055
+ add_payment_action_ind(xml, parameters[:payment_action_ind])
1056
+ add_dpanind(xml, payment_source, parameters[:industry_type])
1057
+ add_aevv(xml, payment_source, three_d_secure)
1058
+ add_level2_card_and_more_tax(xml, parameters)
1059
+ add_digital_token_cryptogram(xml, payment_source, three_d_secure)
1060
+ xml.tag! :ECPSameDayInd, parameters[:same_day] if parameters[:same_day] && payment_source.is_a?(Check)
1061
+ add_ecp_details(xml, payment_source, parameters) if payment_source.is_a?(Check)
1062
+
1010
1063
  add_stored_credentials(xml, parameters)
1011
1064
  add_pymt_brand_program_code(xml, payment_source, three_d_secure)
1065
+ xml.tag! :TokenTxnType, parameters[:token_txn_type] if parameters[:token_txn_type]
1012
1066
  add_mastercard_fields(xml, payment_source, parameters, three_d_secure) if mastercard?(payment_source)
1067
+ add_card_commodity_code(xml, parameters)
1068
+ add_level3_vat_fields(xml, parameters)
1013
1069
  end
1014
1070
  end
1015
1071
  xml.target!
@@ -1031,6 +1087,9 @@ module ActiveMerchant #:nodoc:
1031
1087
  add_level3_purchase(xml, parameters)
1032
1088
  add_level3_tax(xml, parameters)
1033
1089
  add_line_items(xml, parameters) if parameters[:line_items]
1090
+ add_level2_card_and_more_tax(xml, parameters)
1091
+ add_card_commodity_code(xml, parameters)
1092
+ add_level3_vat_fields(xml, parameters)
1034
1093
  end
1035
1094
  end
1036
1095
  xml.target!
@@ -121,7 +121,10 @@ module ActiveMerchant #:nodoc:
121
121
 
122
122
  test_mode = test? || message =~ /TESTMODE/
123
123
 
124
- Response.new(success?(response), message, response,
124
+ Response.new(
125
+ success?(response),
126
+ message,
127
+ response,
125
128
  test: test_mode,
126
129
  authorization: response['TrackingNumber'],
127
130
  fraud_review: fraud_review?(response),
@@ -129,7 +132,8 @@ module ActiveMerchant #:nodoc:
129
132
  postal_match: AVS_POSTAL_CODES[response['AVSPostalResponseCode']],
130
133
  street_match: AVS_ADDRESS_CODES[response['AVSAddressResponseCode']]
131
134
  },
132
- cvv_result: CVV2_CODES[response['CVV2ResponseCode']])
135
+ cvv_result: CVV2_CODES[response['CVV2ResponseCode']]
136
+ )
133
137
  end
134
138
 
135
139
  def url(action)
@@ -178,8 +182,7 @@ module ActiveMerchant #:nodoc:
178
182
  post['RequestID'] = request_id
179
183
  post['Signature'] = signature(action, post, parameters)
180
184
 
181
- request = post.merge(parameters).collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join('&')
182
- request
185
+ post.merge(parameters).collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join('&')
183
186
  end
184
187
 
185
188
  def timestamp
@@ -264,9 +264,13 @@ module ActiveMerchant #:nodoc:
264
264
 
265
265
  def commit(action, request, authorization = nil)
266
266
  response = parse(action, ssl_post(self.live_url, request))
267
- Response.new(successful?(response), message_from(response), response,
267
+ Response.new(
268
+ successful?(response),
269
+ message_from(response),
270
+ response,
268
271
  test: test?,
269
- authorization: authorization || response[:tid])
272
+ authorization: authorization || response[:tid]
273
+ )
270
274
  end
271
275
 
272
276
  def message_from(response)