activemerchant 1.79.2 → 1.129.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (279) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG +1391 -0
  3. data/README.md +29 -14
  4. data/lib/active_merchant/billing/avs_result.rb +25 -28
  5. data/lib/active_merchant/billing/base.rb +0 -13
  6. data/lib/active_merchant/billing/check.rb +55 -22
  7. data/lib/active_merchant/billing/compatibility.rb +10 -12
  8. data/lib/active_merchant/billing/credit_card.rb +82 -62
  9. data/lib/active_merchant/billing/credit_card_formatting.rb +4 -4
  10. data/lib/active_merchant/billing/credit_card_methods.rb +328 -58
  11. data/lib/active_merchant/billing/cvv_result.rb +0 -1
  12. data/lib/active_merchant/billing/gateway.rb +61 -56
  13. data/lib/active_merchant/billing/gateways/adyen.rb +562 -87
  14. data/lib/active_merchant/billing/gateways/airwallex.rb +370 -0
  15. data/lib/active_merchant/billing/gateways/alelo.rb +256 -0
  16. data/lib/active_merchant/billing/gateways/allied_wallet.rb +35 -36
  17. data/lib/active_merchant/billing/gateways/authorize_net.rb +297 -196
  18. data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +31 -24
  19. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +94 -98
  20. data/lib/active_merchant/billing/gateways/axcessms.rb +64 -66
  21. data/lib/active_merchant/billing/gateways/balanced.rb +72 -65
  22. data/lib/active_merchant/billing/gateways/bambora_apac.rb +222 -0
  23. data/lib/active_merchant/billing/gateways/bank_frick.rb +16 -16
  24. data/lib/active_merchant/billing/gateways/banwire.rb +12 -12
  25. data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +140 -69
  26. data/lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb +7 -7
  27. data/lib/active_merchant/billing/gateways/be2bill.rb +7 -7
  28. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +115 -115
  29. data/lib/active_merchant/billing/gateways/beanstream.rb +39 -13
  30. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +1 -2
  31. data/lib/active_merchant/billing/gateways/blue_pay.rb +87 -58
  32. data/lib/active_merchant/billing/gateways/blue_snap.rb +405 -104
  33. data/lib/active_merchant/billing/gateways/bogus.rb +34 -30
  34. data/lib/active_merchant/billing/gateways/borgun.rb +97 -47
  35. data/lib/active_merchant/billing/gateways/bpoint.rb +20 -20
  36. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -3
  37. data/lib/active_merchant/billing/gateways/braintree/token_nonce.rb +113 -0
  38. data/lib/active_merchant/billing/gateways/braintree.rb +1 -1
  39. data/lib/active_merchant/billing/gateways/braintree_blue.rb +561 -259
  40. data/lib/active_merchant/billing/gateways/braintree_orange.rb +1 -1
  41. data/lib/active_merchant/billing/gateways/bridge_pay.rb +53 -54
  42. data/lib/active_merchant/billing/gateways/cams.rb +31 -31
  43. data/lib/active_merchant/billing/gateways/card_connect.rb +85 -33
  44. data/lib/active_merchant/billing/gateways/card_save.rb +7 -9
  45. data/lib/active_merchant/billing/gateways/card_stream.rb +187 -169
  46. data/lib/active_merchant/billing/gateways/cardknox.rb +24 -25
  47. data/lib/active_merchant/billing/gateways/cardprocess.rb +9 -7
  48. data/lib/active_merchant/billing/gateways/cashnet.rb +43 -27
  49. data/lib/active_merchant/billing/gateways/cc5.rb +14 -17
  50. data/lib/active_merchant/billing/gateways/cecabank.rb +62 -52
  51. data/lib/active_merchant/billing/gateways/cenpos.rb +63 -62
  52. data/lib/active_merchant/billing/gateways/checkout.rb +21 -23
  53. data/lib/active_merchant/billing/gateways/checkout_v2.rb +391 -113
  54. data/lib/active_merchant/billing/gateways/citrus_pay.rb +1 -3
  55. data/lib/active_merchant/billing/gateways/clearhaus.rb +40 -41
  56. data/lib/active_merchant/billing/gateways/commerce_hub.rb +361 -0
  57. data/lib/active_merchant/billing/gateways/commercegate.rb +11 -12
  58. data/lib/active_merchant/billing/gateways/conekta.rb +35 -30
  59. data/lib/active_merchant/billing/gateways/creditcall.rb +59 -59
  60. data/lib/active_merchant/billing/gateways/credorax.rb +326 -145
  61. data/lib/active_merchant/billing/gateways/ct_payment.rb +269 -0
  62. data/lib/active_merchant/billing/gateways/culqi.rb +53 -53
  63. data/lib/active_merchant/billing/gateways/cyber_source/cyber_source_common.rb +36 -0
  64. data/lib/active_merchant/billing/gateways/cyber_source.rb +566 -208
  65. data/lib/active_merchant/billing/gateways/cyber_source_rest.rb +456 -0
  66. data/lib/active_merchant/billing/gateways/d_local.rb +342 -0
  67. data/lib/active_merchant/billing/gateways/data_cash.rb +40 -56
  68. data/lib/active_merchant/billing/gateways/decidir.rb +358 -0
  69. data/lib/active_merchant/billing/gateways/decidir_plus.rb +344 -0
  70. data/lib/active_merchant/billing/gateways/dibs.rb +34 -40
  71. data/lib/active_merchant/billing/gateways/digitzs.rb +48 -45
  72. data/lib/active_merchant/billing/gateways/ebanx.rb +110 -60
  73. data/lib/active_merchant/billing/gateways/efsnet.rb +46 -50
  74. data/lib/active_merchant/billing/gateways/elavon.rb +351 -189
  75. data/lib/active_merchant/billing/gateways/element.rb +106 -56
  76. data/lib/active_merchant/billing/gateways/epay.rb +74 -64
  77. data/lib/active_merchant/billing/gateways/evo_ca.rb +13 -14
  78. data/lib/active_merchant/billing/gateways/eway.rb +74 -73
  79. data/lib/active_merchant/billing/gateways/eway_managed.rb +85 -87
  80. data/lib/active_merchant/billing/gateways/eway_rapid.rb +105 -60
  81. data/lib/active_merchant/billing/gateways/exact.rb +29 -37
  82. data/lib/active_merchant/billing/gateways/ezic.rb +21 -22
  83. data/lib/active_merchant/billing/gateways/fat_zebra.rb +70 -48
  84. data/lib/active_merchant/billing/gateways/federated_canada.rb +11 -13
  85. data/lib/active_merchant/billing/gateways/finansbank.rb +3 -4
  86. data/lib/active_merchant/billing/gateways/first_giving.rb +23 -23
  87. data/lib/active_merchant/billing/gateways/first_pay.rb +33 -13
  88. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +106 -105
  89. data/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb +505 -0
  90. data/lib/active_merchant/billing/gateways/flo2cash.rb +36 -36
  91. data/lib/active_merchant/billing/gateways/flo2cash_simple.rb +2 -2
  92. data/lib/active_merchant/billing/gateways/forte.rb +70 -40
  93. data/lib/active_merchant/billing/gateways/garanti.rb +24 -31
  94. data/lib/active_merchant/billing/gateways/global_collect.rb +378 -154
  95. data/lib/active_merchant/billing/gateways/global_transport.rb +12 -13
  96. data/lib/active_merchant/billing/gateways/hdfc.rb +55 -57
  97. data/lib/active_merchant/billing/gateways/hps.rb +236 -69
  98. data/lib/active_merchant/billing/gateways/iats_payments.rb +61 -39
  99. data/lib/active_merchant/billing/gateways/in_context_paypal_express.rb +1 -1
  100. data/lib/active_merchant/billing/gateways/inspire.rb +41 -47
  101. data/lib/active_merchant/billing/gateways/instapay.rb +10 -14
  102. data/lib/active_merchant/billing/gateways/ipg.rb +420 -0
  103. data/lib/active_merchant/billing/gateways/ipp.rb +25 -24
  104. data/lib/active_merchant/billing/gateways/iridium.rb +243 -244
  105. data/lib/active_merchant/billing/gateways/itransact.rb +14 -14
  106. data/lib/active_merchant/billing/gateways/iveri.rb +73 -34
  107. data/lib/active_merchant/billing/gateways/ixopay.rb +320 -0
  108. data/lib/active_merchant/billing/gateways/jetpay.rb +145 -152
  109. data/lib/active_merchant/billing/gateways/jetpay_v2.rb +154 -159
  110. data/lib/active_merchant/billing/gateways/komoju.rb +16 -16
  111. data/lib/active_merchant/billing/gateways/kushki.rb +127 -57
  112. data/lib/active_merchant/billing/gateways/latitude19.rb +111 -115
  113. data/lib/active_merchant/billing/gateways/linkpoint.rb +82 -85
  114. data/lib/active_merchant/billing/gateways/litle.rb +247 -53
  115. data/lib/active_merchant/billing/gateways/mastercard.rb +41 -23
  116. data/lib/active_merchant/billing/gateways/maxipago.rb +5 -5
  117. data/lib/active_merchant/billing/gateways/mercado_pago.rb +135 -49
  118. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +62 -29
  119. data/lib/active_merchant/billing/gateways/merchant_one.rb +16 -20
  120. data/lib/active_merchant/billing/gateways/merchant_partners.rb +40 -40
  121. data/lib/active_merchant/billing/gateways/merchant_ware.rb +54 -60
  122. data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +42 -44
  123. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +52 -14
  124. data/lib/active_merchant/billing/gateways/mercury.rb +47 -51
  125. data/lib/active_merchant/billing/gateways/metrics_global.rb +32 -42
  126. data/lib/active_merchant/billing/gateways/micropayment.rb +42 -45
  127. data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +7 -7
  128. data/lib/active_merchant/billing/gateways/migs.rb +45 -40
  129. data/lib/active_merchant/billing/gateways/mit.rb +260 -0
  130. data/lib/active_merchant/billing/gateways/modern_payments.rb +2 -2
  131. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +29 -31
  132. data/lib/active_merchant/billing/gateways/moka.rb +290 -0
  133. data/lib/active_merchant/billing/gateways/monei.rb +255 -138
  134. data/lib/active_merchant/billing/gateways/moneris.rb +226 -88
  135. data/lib/active_merchant/billing/gateways/money_movers.rb +11 -13
  136. data/lib/active_merchant/billing/gateways/mundipagg.rb +117 -43
  137. data/lib/active_merchant/billing/gateways/nab_transact.rb +28 -31
  138. data/lib/active_merchant/billing/gateways/ncr_secure_pay.rb +13 -15
  139. data/lib/active_merchant/billing/gateways/net_registry.rb +12 -12
  140. data/lib/active_merchant/billing/gateways/netaxept.rb +33 -34
  141. data/lib/active_merchant/billing/gateways/netbanx.rb +167 -80
  142. data/lib/active_merchant/billing/gateways/netbilling.rb +27 -30
  143. data/lib/active_merchant/billing/gateways/netpay.rb +10 -10
  144. data/lib/active_merchant/billing/gateways/network_merchants.rb +7 -11
  145. data/lib/active_merchant/billing/gateways/nmi.rb +134 -48
  146. data/lib/active_merchant/billing/gateways/ogone.rb +88 -58
  147. data/lib/active_merchant/billing/gateways/omise.rb +30 -31
  148. data/lib/active_merchant/billing/gateways/openpay.rb +45 -26
  149. data/lib/active_merchant/billing/gateways/opp.rb +166 -144
  150. data/lib/active_merchant/billing/gateways/optimal_payment.rb +67 -64
  151. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +5 -7
  152. data/lib/active_merchant/billing/gateways/orbital.rb +726 -382
  153. data/lib/active_merchant/billing/gateways/pac_net_raven.rb +26 -27
  154. data/lib/active_merchant/billing/gateways/pagarme.rb +47 -56
  155. data/lib/active_merchant/billing/gateways/pago_facil.rb +12 -14
  156. data/lib/active_merchant/billing/gateways/pay_arc.rb +392 -0
  157. data/lib/active_merchant/billing/gateways/pay_conex.rb +39 -40
  158. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +65 -65
  159. data/lib/active_merchant/billing/gateways/pay_hub.rb +39 -39
  160. data/lib/active_merchant/billing/gateways/pay_junction.rb +37 -37
  161. data/lib/active_merchant/billing/gateways/pay_junction_v2.rb +70 -54
  162. data/lib/active_merchant/billing/gateways/pay_secure.rb +15 -17
  163. data/lib/active_merchant/billing/gateways/pay_trace.rb +450 -0
  164. data/lib/active_merchant/billing/gateways/paybox_direct.rb +71 -47
  165. data/lib/active_merchant/billing/gateways/payeezy.rb +159 -32
  166. data/lib/active_merchant/billing/gateways/payex.rb +39 -42
  167. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +41 -36
  168. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +11 -8
  169. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +3 -3
  170. data/lib/active_merchant/billing/gateways/payflow.rb +178 -54
  171. data/lib/active_merchant/billing/gateways/payflow_express.rb +61 -65
  172. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +0 -1
  173. data/lib/active_merchant/billing/gateways/payflow_uk.rb +1 -2
  174. data/lib/active_merchant/billing/gateways/payment_express.rb +66 -58
  175. data/lib/active_merchant/billing/gateways/paymentez.rb +114 -25
  176. data/lib/active_merchant/billing/gateways/paymill.rb +134 -133
  177. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +2 -1
  178. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +4 -0
  179. data/lib/active_merchant/billing/gateways/paypal.rb +27 -14
  180. data/lib/active_merchant/billing/gateways/paypal_ca.rb +1 -1
  181. data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +2 -2
  182. data/lib/active_merchant/billing/gateways/paypal_express.rb +5 -2
  183. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +1 -1
  184. data/lib/active_merchant/billing/gateways/paysafe.rb +420 -0
  185. data/lib/active_merchant/billing/gateways/payscout.rb +10 -13
  186. data/lib/active_merchant/billing/gateways/paystation.rb +79 -82
  187. data/lib/active_merchant/billing/gateways/payu_in.rb +59 -58
  188. data/lib/active_merchant/billing/gateways/payu_latam.rb +139 -97
  189. data/lib/active_merchant/billing/gateways/payway.rb +27 -27
  190. data/lib/active_merchant/billing/gateways/payway_dot_com.rb +253 -0
  191. data/lib/active_merchant/billing/gateways/pin.rb +87 -34
  192. data/lib/active_merchant/billing/gateways/plexo.rb +308 -0
  193. data/lib/active_merchant/billing/gateways/plugnpay.rb +82 -82
  194. data/lib/active_merchant/billing/gateways/priority.rb +392 -0
  195. data/lib/active_merchant/billing/gateways/pro_pay.rb +139 -140
  196. data/lib/active_merchant/billing/gateways/psigate.rb +44 -44
  197. data/lib/active_merchant/billing/gateways/psl_card.rb +29 -37
  198. data/lib/active_merchant/billing/gateways/qbms.rb +75 -76
  199. data/lib/active_merchant/billing/gateways/quantum.rb +21 -23
  200. data/lib/active_merchant/billing/gateways/quickbooks.rb +142 -55
  201. data/lib/active_merchant/billing/gateways/quickpay/quickpay_common.rb +103 -107
  202. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +156 -158
  203. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb +7 -8
  204. data/lib/active_merchant/billing/gateways/quickpay.rb +1 -3
  205. data/lib/active_merchant/billing/gateways/qvalent.rb +137 -68
  206. data/lib/active_merchant/billing/gateways/rapyd.rb +319 -0
  207. data/lib/active_merchant/billing/gateways/reach.rb +277 -0
  208. data/lib/active_merchant/billing/gateways/realex.rb +132 -50
  209. data/lib/active_merchant/billing/gateways/redsys.rb +382 -186
  210. data/lib/active_merchant/billing/gateways/s5.rb +16 -16
  211. data/lib/active_merchant/billing/gateways/safe_charge.rb +83 -47
  212. data/lib/active_merchant/billing/gateways/sage.rb +49 -48
  213. data/lib/active_merchant/billing/gateways/sage_pay.rb +76 -83
  214. data/lib/active_merchant/billing/gateways/sallie_mae.rb +13 -15
  215. data/lib/active_merchant/billing/gateways/secure_net.rb +32 -40
  216. data/lib/active_merchant/billing/gateways/secure_pay.rb +30 -40
  217. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +23 -26
  218. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +14 -16
  219. data/lib/active_merchant/billing/gateways/securion_pay.rb +69 -31
  220. data/lib/active_merchant/billing/gateways/shift4.rb +342 -0
  221. data/lib/active_merchant/billing/gateways/simetrik.rb +368 -0
  222. data/lib/active_merchant/billing/gateways/skip_jack.rb +52 -53
  223. data/lib/active_merchant/billing/gateways/smart_ps.rb +51 -60
  224. data/lib/active_merchant/billing/gateways/so_easy_pay.rb +29 -29
  225. data/lib/active_merchant/billing/gateways/spreedly_core.rb +66 -47
  226. data/lib/active_merchant/billing/gateways/stripe.rb +309 -148
  227. data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +556 -0
  228. data/lib/active_merchant/billing/gateways/swipe_checkout.rb +18 -23
  229. data/lib/active_merchant/billing/gateways/telr.rb +46 -48
  230. data/lib/active_merchant/billing/gateways/tns.rb +8 -7
  231. data/lib/active_merchant/billing/gateways/trans_first.rb +37 -37
  232. data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +249 -245
  233. data/lib/active_merchant/billing/gateways/transact_pro.rb +25 -27
  234. data/lib/active_merchant/billing/gateways/transax.rb +6 -8
  235. data/lib/active_merchant/billing/gateways/transnational.rb +1 -2
  236. data/lib/active_merchant/billing/gateways/trexle.rb +22 -18
  237. data/lib/active_merchant/billing/gateways/trust_commerce.rb +161 -88
  238. data/lib/active_merchant/billing/gateways/usa_epay.rb +5 -6
  239. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +231 -238
  240. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +129 -55
  241. data/lib/active_merchant/billing/gateways/vanco.rb +42 -33
  242. data/lib/active_merchant/billing/gateways/verifi.rb +52 -53
  243. data/lib/active_merchant/billing/gateways/viaklix.rb +18 -22
  244. data/lib/active_merchant/billing/gateways/visanet_peru.rb +115 -74
  245. data/lib/active_merchant/billing/gateways/vpos.rb +223 -0
  246. data/lib/active_merchant/billing/gateways/webpay.rb +9 -9
  247. data/lib/active_merchant/billing/gateways/wepay.rb +38 -41
  248. data/lib/active_merchant/billing/gateways/wirecard.rb +36 -37
  249. data/lib/active_merchant/billing/gateways/wompi.rb +197 -0
  250. data/lib/active_merchant/billing/gateways/world_net.rb +39 -38
  251. data/lib/active_merchant/billing/gateways/worldpay.rb +756 -142
  252. data/lib/active_merchant/billing/gateways/worldpay_online_payments.rb +73 -83
  253. data/lib/active_merchant/billing/gateways/worldpay_us.rb +31 -31
  254. data/lib/active_merchant/billing/model.rb +2 -2
  255. data/lib/active_merchant/billing/network_tokenization_credit_card.rb +3 -3
  256. data/lib/active_merchant/billing/rails.rb +1 -1
  257. data/lib/active_merchant/billing/response.rb +32 -13
  258. data/lib/active_merchant/billing/three_d_secure_eci_mapper.rb +27 -0
  259. data/lib/active_merchant/billing.rb +1 -0
  260. data/lib/active_merchant/connection.rb +24 -38
  261. data/lib/active_merchant/country.rb +9 -5
  262. data/lib/active_merchant/errors.rb +4 -1
  263. data/lib/active_merchant/net_http_ssl_connection.rb +2 -0
  264. data/lib/active_merchant/network_connection_retries.rb +28 -31
  265. data/lib/active_merchant/post_data.rb +5 -3
  266. data/lib/active_merchant/posts_data.rb +5 -7
  267. data/lib/active_merchant/version.rb +1 -1
  268. data/lib/active_merchant.rb +3 -3
  269. data/lib/activemerchant.rb +1 -1
  270. data/lib/certs/cacert.pem +1592 -2329
  271. data/lib/support/gateway_support.rb +8 -10
  272. data/lib/support/ssl_verify.rb +9 -14
  273. data/lib/support/ssl_version.rb +9 -10
  274. metadata +98 -37
  275. data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +0 -246
  276. data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +0 -13
  277. data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +0 -29
  278. data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +0 -66
  279. data/lib/active_merchant/billing/gateways/moneris_us.rb +0 -309
@@ -8,10 +8,10 @@ module ActiveMerchant
8
8
  self.test_url = 'https://apitest.authorize.net/xml/v1/request.api'
9
9
  self.live_url = 'https://api2.authorize.net/xml/v1/request.api'
10
10
 
11
- self.supported_countries = %w(AD AT AU BE BG CA CH CY CZ DE DK EE ES FI FR GB GI GR HU IE IL IS IT LI LT LU LV MC MT NL NO PL PT RO SE SI SK SM TR US VA)
11
+ self.supported_countries = %w(AU CA US)
12
12
  self.default_currency = 'USD'
13
13
  self.money_format = :dollars
14
- self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb, :maestro]
14
+ self.supported_cardtypes = %i[visa master american_express discover diners_club jcb maestro]
15
15
 
16
16
  self.homepage_url = 'http://www.authorize.net/'
17
17
  self.display_name = 'Authorize.Net'
@@ -54,25 +54,25 @@ module ActiveMerchant
54
54
  '37' => STANDARD_ERROR_CODE[:invalid_expiry_date],
55
55
  '378' => STANDARD_ERROR_CODE[:invalid_cvc],
56
56
  '38' => STANDARD_ERROR_CODE[:expired_card],
57
- '384' => STANDARD_ERROR_CODE[:config_error],
57
+ '384' => STANDARD_ERROR_CODE[:config_error]
58
58
  }
59
59
 
60
60
  MARKET_TYPE = {
61
- :moto => '1',
62
- :retail => '2'
61
+ moto: '1',
62
+ retail: '2'
63
63
  }
64
64
 
65
65
  DEVICE_TYPE = {
66
- :unknown => '1',
67
- :unattended_terminal => '2',
68
- :self_service_terminal => '3',
69
- :electronic_cash_register => '4',
70
- :personal_computer_terminal => '5',
71
- :airpay => '6',
72
- :wireless_pos => '7',
73
- :website => '8',
74
- :dial_terminal => '9',
75
- :virtual_terminal => '10'
66
+ unknown: '1',
67
+ unattended_terminal: '2',
68
+ self_service_terminal: '3',
69
+ electronic_cash_register: '4',
70
+ personal_computer_terminal: '5',
71
+ airpay: '6',
72
+ wireless_pos: '7',
73
+ website: '8',
74
+ dial_terminal: '9',
75
+ virtual_terminal: '10'
76
76
  }
77
77
 
78
78
  class_attribute :duplicate_window
@@ -85,45 +85,44 @@ module ActiveMerchant
85
85
  AVS_REASON_CODES = %w(27 45)
86
86
 
87
87
  TRACKS = {
88
- 1 => /^%(?<format_code>.)(?<pan>[\d]{1,19}+)\^(?<name>.{2,26})\^(?<expiration>[\d]{0,4}|\^)(?<service_code>[\d]{0,3}|\^)(?<discretionary_data>.*)\?\Z/,
89
- 2 => /\A;(?<pan>[\d]{1,19}+)=(?<expiration>[\d]{0,4}|=)(?<service_code>[\d]{0,3}|=)(?<discretionary_data>.*)\?\Z/
88
+ 1 => /^%(?<format_code>.)(?<pan>[\d]{1,19}+)\^(?<name>.{2,26})\^(?<expiration>[\d]{0,4}|\^)(?<service_code>[\d]{0,3}|\^)(?<discretionary_data>.*)\?\Z/,
89
+ 2 => /\A;(?<pan>[\d]{1,19}+)=(?<expiration>[\d]{0,4}|=)(?<service_code>[\d]{0,3}|=)(?<discretionary_data>.*)\?\Z/
90
90
  }.freeze
91
91
 
92
- APPLE_PAY_DATA_DESCRIPTOR = "COMMON.APPLE.INAPP.PAYMENT"
92
+ APPLE_PAY_DATA_DESCRIPTOR = 'COMMON.APPLE.INAPP.PAYMENT'
93
+ PAYMENT_METHOD_NOT_SUPPORTED_ERROR = '155'
94
+ INELIGIBLE_FOR_ISSUING_CREDIT_ERROR = '54'
93
95
 
94
- PAYMENT_METHOD_NOT_SUPPORTED_ERROR = "155"
95
- INELIGIBLE_FOR_ISSUING_CREDIT_ERROR = "54"
96
-
97
- def initialize(options={})
96
+ def initialize(options = {})
98
97
  requires!(options, :login, :password)
99
98
  super
100
99
  end
101
100
 
102
101
  def purchase(amount, payment, options = {})
103
102
  if payment.is_a?(String)
104
- commit(:cim_purchase) do |xml|
105
- add_cim_auth_purchase(xml, "profileTransAuthCapture", amount, payment, options)
103
+ commit(:cim_purchase, options) do |xml|
104
+ add_cim_auth_purchase(xml, 'profileTransAuthCapture', amount, payment, options)
106
105
  end
107
106
  else
108
107
  commit(:purchase) do |xml|
109
- add_auth_purchase(xml, "authCaptureTransaction", amount, payment, options)
108
+ add_auth_purchase(xml, 'authCaptureTransaction', amount, payment, options)
110
109
  end
111
110
  end
112
111
  end
113
112
 
114
- def authorize(amount, payment, options={})
113
+ def authorize(amount, payment, options = {})
115
114
  if payment.is_a?(String)
116
- commit(:cim_authorize) do |xml|
117
- add_cim_auth_purchase(xml, "profileTransAuthOnly", amount, payment, options)
115
+ commit(:cim_authorize, options) do |xml|
116
+ add_cim_auth_purchase(xml, 'profileTransAuthOnly', amount, payment, options)
118
117
  end
119
118
  else
120
119
  commit(:authorize) do |xml|
121
- add_auth_purchase(xml, "authOnlyTransaction", amount, payment, options)
120
+ add_auth_purchase(xml, 'authOnlyTransaction', amount, payment, options)
122
121
  end
123
122
  end
124
123
  end
125
124
 
126
- def capture(amount, authorization, options={})
125
+ def capture(amount, authorization, options = {})
127
126
  if auth_was_for_cim?(authorization)
128
127
  cim_capture(amount, authorization, options)
129
128
  else
@@ -131,24 +130,25 @@ module ActiveMerchant
131
130
  end
132
131
  end
133
132
 
134
- def refund(amount, authorization, options={})
135
- response = if auth_was_for_cim?(authorization)
136
- cim_refund(amount, authorization, options)
137
- else
138
- normal_refund(amount, authorization, options)
139
- end
133
+ def refund(amount, authorization, options = {})
134
+ response =
135
+ if auth_was_for_cim?(authorization)
136
+ cim_refund(amount, authorization, options)
137
+ else
138
+ normal_refund(amount, authorization, options)
139
+ end
140
140
 
141
141
  return response if response.success?
142
142
  return response unless options[:force_full_refund_if_unsettled]
143
143
 
144
- if response.params["response_reason_code"] == INELIGIBLE_FOR_ISSUING_CREDIT_ERROR
144
+ if response.params['response_reason_code'] == INELIGIBLE_FOR_ISSUING_CREDIT_ERROR
145
145
  void(authorization, options)
146
146
  else
147
147
  response
148
148
  end
149
149
  end
150
150
 
151
- def void(authorization, options={})
151
+ def void(authorization, options = {})
152
152
  if auth_was_for_cim?(authorization)
153
153
  cim_void(authorization, options)
154
154
  else
@@ -156,10 +156,8 @@ module ActiveMerchant
156
156
  end
157
157
  end
158
158
 
159
- def credit(amount, payment, options={})
160
- if payment.is_a?(String)
161
- raise ArgumentError, "Reference credits are not supported. Please supply the original credit card or use the #refund method."
162
- end
159
+ def credit(amount, payment, options = {})
160
+ raise ArgumentError, 'Reference credits are not supported. Please supply the original credit card or use the #refund method.' if payment.is_a?(String)
163
161
 
164
162
  commit(:credit) do |xml|
165
163
  add_order_id(xml, options)
@@ -177,11 +175,29 @@ module ActiveMerchant
177
175
  end
178
176
  end
179
177
 
180
- def verify(credit_card, options = {})
178
+ def verify(payment_method, options = {})
179
+ amount = amount_for_verify(options)
180
+
181
181
  MultiResponse.run(:use_first_response) do |r|
182
- r.process { authorize(100, credit_card, options) }
183
- r.process(:ignore_result) { void(r.authorization, options) }
182
+ r.process { authorize(amount, payment_method, options) }
183
+ r.process(:ignore_result) { void(r.authorization, options) } unless amount == 0
184
184
  end
185
+ rescue ArgumentError => e
186
+ Response.new(false, e.message)
187
+ end
188
+
189
+ def amount_for_verify(options)
190
+ return 100 unless options[:verify_amount].present?
191
+
192
+ amount = options[:verify_amount]
193
+ raise ArgumentError.new 'verify_amount value must be an integer' unless amount.is_a?(Integer) && !amount.negative? || amount.is_a?(String) && amount.match?(/^\d+$/) && !amount.to_i.negative?
194
+ raise ArgumentError.new 'Billing address including zip code is required for a 0 amount verify' if amount.to_i.zero? && !validate_billing_address_values?(options)
195
+
196
+ amount.to_i
197
+ end
198
+
199
+ def validate_billing_address_values?(options)
200
+ options.dig(:billing_address, :zip).present? && options.dig(:billing_address, :address1).present?
185
201
  end
186
202
 
187
203
  def store(credit_card, options = {})
@@ -193,13 +209,13 @@ module ActiveMerchant
193
209
  end
194
210
 
195
211
  def unstore(authorization)
196
- customer_profile_id, _, _ = split_authorization(authorization)
212
+ customer_profile_id, = split_authorization(authorization)
197
213
 
198
214
  delete_customer_profile(customer_profile_id)
199
215
  end
200
216
 
201
217
  def verify_credentials
202
- response = commit(:verify_credentials) { }
218
+ response = commit(:verify_credentials) {}
203
219
  response.success?
204
220
  end
205
221
 
@@ -222,17 +238,17 @@ module ActiveMerchant
222
238
 
223
239
  def supports_network_tokenization?
224
240
  card = Billing::NetworkTokenizationCreditCard.new({
225
- :number => "4111111111111111",
226
- :month => 12,
227
- :year => 20,
228
- :first_name => 'John',
229
- :last_name => 'Smith',
230
- :brand => 'visa',
231
- :payment_cryptogram => 'EHuWW9PiBkWvqE5juRwDzAUFBAk='
241
+ number: '4111111111111111',
242
+ month: 12,
243
+ year: 20,
244
+ first_name: 'John',
245
+ last_name: 'Smith',
246
+ brand: 'visa',
247
+ payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk='
232
248
  })
233
249
 
234
250
  request = post_data(:authorize) do |xml|
235
- add_auth_purchase(xml, "authOnlyTransaction", 1, card, {})
251
+ add_auth_purchase(xml, 'authOnlyTransaction', 1, card, {})
236
252
  end
237
253
  raw_response = ssl_post(url, request, headers)
238
254
  response = parse(:authorize, raw_response)
@@ -257,6 +273,9 @@ module ActiveMerchant
257
273
  add_market_type_device_type(xml, payment, options)
258
274
  add_settings(xml, payment, options)
259
275
  add_user_fields(xml, amount, options)
276
+ add_ship_from_address(xml, options)
277
+ add_processing_options(xml, options)
278
+ add_subsequent_auth_information(xml, options)
260
279
  end
261
280
  end
262
281
 
@@ -273,10 +292,11 @@ module ActiveMerchant
273
292
  add_tax_exempt_status(xml, options)
274
293
  end
275
294
  end
295
+ add_extra_options_for_cim(xml, options)
276
296
  end
277
297
 
278
298
  def cim_capture(amount, authorization, options)
279
- commit(:cim_capture) do |xml|
299
+ commit(:cim_capture, options) do |xml|
280
300
  add_order_id(xml, options)
281
301
  xml.transaction do
282
302
  xml.profileTransPriorAuthCapture do
@@ -287,6 +307,7 @@ module ActiveMerchant
287
307
  xml.transId(transaction_id_from(authorization))
288
308
  end
289
309
  end
310
+ add_extra_options_for_cim(xml, options)
290
311
  end
291
312
  end
292
313
 
@@ -302,16 +323,16 @@ module ActiveMerchant
302
323
  add_tax_exempt_status(xml, options)
303
324
  add_po_number(xml, options)
304
325
  xml.refTransId(transaction_id_from(authorization))
305
- add_invoice(xml, "capture", options)
326
+ add_invoice(xml, 'capture', options)
306
327
  add_user_fields(xml, amount, options)
307
328
  end
308
329
  end
309
330
  end
310
331
 
311
332
  def cim_refund(amount, authorization, options)
312
- transaction_id, card_number, _ = split_authorization(authorization)
333
+ transaction_id, card_number, = split_authorization(authorization)
313
334
 
314
- commit(:cim_refund) do |xml|
335
+ commit(:cim_refund, options) do |xml|
315
336
  add_order_id(xml, options)
316
337
  xml.transaction do
317
338
  xml.profileTransRefund do
@@ -320,24 +341,34 @@ module ActiveMerchant
320
341
  add_shipping_fields(xml, options)
321
342
  add_duty_fields(xml, options)
322
343
  xml.creditCardNumberMasked(card_number)
323
- add_invoice(xml, "profileTransRefund", options)
344
+ add_invoice(xml, 'profileTransRefund', options)
324
345
  xml.transId(transaction_id)
325
346
  end
326
347
  end
348
+ add_extra_options_for_cim(xml, options)
327
349
  end
328
350
  end
329
351
 
330
352
  def normal_refund(amount, authorization, options)
331
- transaction_id, card_number, _ = split_authorization(authorization)
353
+ transaction_id, card_number, = split_authorization(authorization)
332
354
 
333
355
  commit(:refund) do |xml|
334
356
  xml.transactionRequest do
335
357
  xml.transactionType('refundTransaction')
336
358
  xml.amount(amount.nil? ? 0 : amount(amount))
337
359
  xml.payment do
338
- xml.creditCard do
339
- xml.cardNumber(card_number || options[:card_number])
340
- xml.expirationDate('XXXX')
360
+ if options[:routing_number]
361
+ xml.bankAccount do
362
+ xml.accountType(options[:account_type])
363
+ xml.routingNumber(options[:routing_number])
364
+ xml.accountNumber(options[:account_number])
365
+ xml.nameOnAccount("#{options[:first_name]} #{options[:last_name]}")
366
+ end
367
+ else
368
+ xml.creditCard do
369
+ xml.cardNumber(card_number || options[:card_number])
370
+ xml.expirationDate('XXXX')
371
+ end
341
372
  end
342
373
  end
343
374
  xml.refTransId(transaction_id)
@@ -355,13 +386,14 @@ module ActiveMerchant
355
386
  end
356
387
 
357
388
  def cim_void(authorization, options)
358
- commit(:cim_void) do |xml|
389
+ commit(:cim_void, options) do |xml|
359
390
  add_order_id(xml, options)
360
391
  xml.transaction do
361
392
  xml.profileTransVoid do
362
393
  xml.transId(transaction_id_from(authorization))
363
394
  end
364
395
  end
396
+ add_extra_options_for_cim(xml, options)
365
397
  end
366
398
  end
367
399
 
@@ -377,6 +409,7 @@ module ActiveMerchant
377
409
 
378
410
  def add_payment_source(xml, source, options, action = nil)
379
411
  return unless source
412
+
380
413
  if source.is_a?(String)
381
414
  add_token_payment_method(xml, source, options)
382
415
  elsif card_brand(source) == 'check'
@@ -389,45 +422,45 @@ module ActiveMerchant
389
422
  end
390
423
 
391
424
  def camel_case_lower(key)
392
- String(key).split('_').inject([]){ |buffer,e| buffer.push(buffer.empty? ? e : e.capitalize) }.join
425
+ String(key).split('_').inject([]) { |buffer, e| buffer.push(buffer.empty? ? e : e.capitalize) }.join
393
426
  end
394
427
 
395
428
  def add_settings(xml, source, options)
396
429
  xml.transactionSettings do
397
- if options[:recurring]
430
+ if options[:recurring] || subsequent_recurring_transaction?(options)
398
431
  xml.setting do
399
- xml.settingName("recurringBilling")
400
- xml.settingValue("true")
432
+ xml.settingName('recurringBilling')
433
+ xml.settingValue('true')
401
434
  end
402
435
  end
403
436
  if options[:disable_partial_auth]
404
437
  xml.setting do
405
- xml.settingName("allowPartialAuth")
406
- xml.settingValue("false")
438
+ xml.settingName('allowPartialAuth')
439
+ xml.settingValue('false')
407
440
  end
408
441
  end
409
442
  if options[:duplicate_window]
410
443
  set_duplicate_window(xml, options[:duplicate_window])
411
444
  elsif self.class.duplicate_window
412
- ActiveMerchant.deprecated "Using the duplicate_window class_attribute is deprecated. Use the transaction options hash instead."
445
+ ActiveMerchant.deprecated 'Using the duplicate_window class_attribute is deprecated. Use the transaction options hash instead.'
413
446
  set_duplicate_window(xml, self.class.duplicate_window)
414
447
  end
415
448
  if options.key?(:email_customer)
416
449
  xml.setting do
417
- xml.settingName("emailCustomer")
418
- xml.settingValue(options[:email_customer] ? "true" : "false")
450
+ xml.settingName('emailCustomer')
451
+ xml.settingValue(options[:email_customer] ? 'true' : 'false')
419
452
  end
420
453
  end
421
454
  if options[:header_email_receipt]
422
455
  xml.setting do
423
- xml.settingName("headerEmailReceipt")
456
+ xml.settingName('headerEmailReceipt')
424
457
  xml.settingValue(options[:header_email_receipt])
425
458
  end
426
459
  end
427
460
  if options[:test_request]
428
461
  xml.setting do
429
- xml.settingName("testRequest")
430
- xml.settingValue("1")
462
+ xml.settingName('testRequest')
463
+ xml.settingValue('1')
431
464
  end
432
465
  end
433
466
  end
@@ -435,7 +468,7 @@ module ActiveMerchant
435
468
 
436
469
  def set_duplicate_window(xml, value)
437
470
  xml.setting do
438
- xml.settingName("duplicateWindow")
471
+ xml.settingName('duplicateWindow')
439
472
  xml.settingValue(value)
440
473
  end
441
474
  end
@@ -444,13 +477,13 @@ module ActiveMerchant
444
477
  xml.userFields do
445
478
  if currency = (options[:currency] || currency(amount))
446
479
  xml.userField do
447
- xml.name("x_currency_code")
480
+ xml.name('x_currency_code')
448
481
  xml.value(currency)
449
482
  end
450
483
  end
451
484
  if application_id.present?
452
485
  xml.userField do
453
- xml.name("x_solution_id")
486
+ xml.name('x_solution_id')
454
487
  xml.value(application_id)
455
488
  end
456
489
  end
@@ -465,12 +498,8 @@ module ActiveMerchant
465
498
  xml.creditCard do
466
499
  xml.cardNumber(truncate(credit_card.number, 16))
467
500
  xml.expirationDate(format(credit_card.month, :two_digits) + '/' + format(credit_card.year, :four_digits))
468
- if credit_card.valid_card_verification_value?(credit_card.verification_value, credit_card.brand)
469
- xml.cardCode(credit_card.verification_value)
470
- end
471
- if credit_card.is_a?(NetworkTokenizationCreditCard) && action != :credit
472
- xml.cryptogram(credit_card.payment_cryptogram)
473
- end
501
+ xml.cardCode(credit_card.verification_value) if credit_card.valid_card_verification_value?(credit_card.verification_value, credit_card.brand)
502
+ xml.cryptogram(credit_card.payment_cryptogram) if credit_card.is_a?(NetworkTokenizationCreditCard) && action != :credit
474
503
  end
475
504
  end
476
505
  end
@@ -478,7 +507,7 @@ module ActiveMerchant
478
507
 
479
508
  def add_swipe_data(xml, credit_card)
480
509
  TRACKS.each do |key, regex|
481
- if regex.match(credit_card.track_data)
510
+ if regex.match?(credit_card.track_data)
482
511
  @valid_track_data = true
483
512
  xml.payment do
484
513
  xml.trackData do
@@ -490,7 +519,7 @@ module ActiveMerchant
490
519
  end
491
520
 
492
521
  def add_token_payment_method(xml, token, options)
493
- customer_profile_id, customer_payment_profile_id, _ = split_authorization(token)
522
+ customer_profile_id, customer_payment_profile_id, = split_authorization(token)
494
523
  customer_profile_id = options[:customer_profile_id] if options[:customer_profile_id]
495
524
  customer_payment_profile_id = options[:customer_payment_profile_id] if options[:customer_payment_profile_id]
496
525
  xml.customerProfileId(customer_profile_id)
@@ -508,6 +537,7 @@ module ActiveMerchant
508
537
 
509
538
  def add_market_type_device_type(xml, payment, options)
510
539
  return if payment.is_a?(String) || card_brand(payment) == 'check' || card_brand(payment) == 'apple_pay'
540
+
511
541
  if valid_track_data
512
542
  xml.retail do
513
543
  xml.marketType(options[:market_type] || MARKET_TYPE[:retail])
@@ -533,6 +563,7 @@ module ActiveMerchant
533
563
  def add_check(xml, check)
534
564
  xml.payment do
535
565
  xml.bankAccount do
566
+ xml.accountType(check.account_type)
536
567
  xml.routingNumber(check.routing_number)
537
568
  xml.accountNumber(check.account_number)
538
569
  xml.nameOnAccount(truncate(check.name, 22))
@@ -553,12 +584,16 @@ module ActiveMerchant
553
584
 
554
585
  xml.customerIP(options[:ip]) unless empty?(options[:ip])
555
586
 
556
- xml.cardholderAuthentication do
557
- three_d_secure = options.fetch(:three_d_secure, {})
558
- xml.authenticationIndicator(
559
- options[:authentication_indicator] || three_d_secure[:eci])
560
- xml.cardholderAuthenticationValue(
561
- options[:cardholder_authentication_value] || three_d_secure[:cavv])
587
+ if !empty?(options.fetch(:three_d_secure, {})) || options[:authentication_indicator] || options[:cardholder_authentication_value]
588
+ xml.cardholderAuthentication do
589
+ three_d_secure = options.fetch(:three_d_secure, {})
590
+ xml.authenticationIndicator(
591
+ options[:authentication_indicator] || three_d_secure[:eci]
592
+ )
593
+ xml.cardholderAuthenticationValue(
594
+ options[:cardholder_authentication_value] || three_d_secure[:cavv]
595
+ )
596
+ end
562
597
  end
563
598
  end
564
599
 
@@ -583,16 +618,17 @@ module ActiveMerchant
583
618
  end
584
619
  end
585
620
 
586
- def add_shipping_address(xml, options, root_node="shipTo")
621
+ def add_shipping_address(xml, options, root_node = 'shipTo')
587
622
  address = options[:shipping_address] || options[:address]
588
623
  return unless address
589
624
 
590
625
  xml.send(root_node) do
591
- first_name, last_name = if address[:name]
592
- split_names(address[:name])
593
- else
594
- [address[:first_name], address[:last_name]]
595
- end
626
+ first_name, last_name =
627
+ if address[:name]
628
+ split_names(address[:name])
629
+ else
630
+ [address[:first_name], address[:last_name]]
631
+ end
596
632
  full_address = "#{address[:address1]} #{address[:address2]}".strip
597
633
 
598
634
  xml.firstName(truncate(first_name, 50)) unless empty?(first_name)
@@ -604,7 +640,16 @@ module ActiveMerchant
604
640
  xml.zip(truncate(address[:zip], 20))
605
641
  xml.country(truncate(address[:country], 60))
606
642
  end
643
+ end
607
644
 
645
+ def add_ship_from_address(xml, options, root_node = 'shipFrom')
646
+ address = options[:ship_from_address]
647
+ return unless address
648
+
649
+ xml.send(root_node) do
650
+ xml.zip(truncate(address[:zip], 20)) unless empty?(address[:zip])
651
+ xml.country(truncate(address[:country], 60)) unless empty?(address[:country])
652
+ end
608
653
  end
609
654
 
610
655
  def add_order_id(xml, options)
@@ -615,7 +660,8 @@ module ActiveMerchant
615
660
  xml.order do
616
661
  xml.invoiceNumber(truncate(options[:order_id], 20))
617
662
  xml.description(truncate(options[:description], 255))
618
- xml.purchaseOrderNumber(options[:po_number]) if options[:po_number] && transaction_type.start_with?("profileTrans")
663
+ xml.purchaseOrderNumber(options[:po_number]) if options[:po_number] && transaction_type.start_with?('profileTrans')
664
+ xml.summaryCommodityCode(truncate(options[:summary_commodity_code], 4)) if options[:summary_commodity_code] && !transaction_type.start_with?('profileTrans')
619
665
  end
620
666
 
621
667
  # Authorize.net API requires lineItems to be placed directly after order tag
@@ -673,8 +719,37 @@ module ActiveMerchant
673
719
  xml.poNumber(options[:po_number]) if options[:po_number]
674
720
  end
675
721
 
722
+ def add_extra_options_for_cim(xml, options)
723
+ xml.extraOptions("x_delim_char=#{options[:delimiter]}") if options[:delimiter]
724
+ end
725
+
726
+ def add_processing_options(xml, options)
727
+ return unless options[:stored_credential]
728
+
729
+ xml.processingOptions do
730
+ if options[:stored_credential][:initial_transaction] && options[:stored_credential][:reason_type] == 'recurring'
731
+ xml.isFirstRecurringPayment 'true'
732
+ elsif options[:stored_credential][:initial_transaction]
733
+ xml.isFirstSubsequentAuth 'true'
734
+ elsif options[:stored_credential][:initiator] == 'cardholder'
735
+ xml.isStoredCredentials 'true'
736
+ else
737
+ xml.isSubsequentAuth 'true'
738
+ end
739
+ end
740
+ end
741
+
742
+ def add_subsequent_auth_information(xml, options)
743
+ return unless options.dig(:stored_credential, :initiator) == 'merchant'
744
+
745
+ xml.subsequentAuthInformation do
746
+ xml.reason options[:stored_credential_reason_type_override] if options[:stored_credential_reason_type_override]
747
+ xml.originalNetworkTransId options[:stored_credential][:network_transaction_id] if options[:stored_credential][:network_transaction_id]
748
+ end
749
+ end
750
+
676
751
  def create_customer_payment_profile(credit_card, options)
677
- commit(:cim_store_update) do |xml|
752
+ commit(:cim_store_update, options) do |xml|
678
753
  xml.customerProfileId options[:customer_profile_id]
679
754
  xml.paymentProfile do
680
755
  add_billing_address(xml, credit_card, options)
@@ -690,16 +765,16 @@ module ActiveMerchant
690
765
  end
691
766
 
692
767
  def create_customer_profile(credit_card, options)
693
- commit(:cim_store) do |xml|
768
+ commit(:cim_store, options) do |xml|
694
769
  xml.profile do
695
770
  xml.merchantCustomerId(truncate(options[:merchant_customer_id], 20) || SecureRandom.hex(10))
696
771
  xml.description(truncate(options[:description], 255)) unless empty?(options[:description])
697
772
  xml.email(options[:email]) unless empty?(options[:email])
698
773
 
699
774
  xml.paymentProfiles do
700
- xml.customerType("individual")
775
+ xml.customerType('individual')
701
776
  add_billing_address(xml, credit_card, options)
702
- add_shipping_address(xml, options, "shipToList")
777
+ add_shipping_address(xml, options, 'shipToList')
703
778
  xml.payment do
704
779
  xml.creditCard do
705
780
  xml.cardNumber(truncate(credit_card.number, 16))
@@ -713,7 +788,7 @@ module ActiveMerchant
713
788
  end
714
789
 
715
790
  def delete_customer_profile(customer_profile_id)
716
- commit(:cim_store_delete_customer) do |xml|
791
+ commit(:cim_store_delete_customer, options) do |xml|
717
792
  xml.customerProfileId(customer_profile_id)
718
793
  end
719
794
  end
@@ -728,13 +803,17 @@ module ActiveMerchant
728
803
  end
729
804
 
730
805
  def state_from(address, options)
731
- if ["US", "CA"].include?(address[:country])
806
+ if %w[US CA].include?(address[:country])
732
807
  address[:state] || 'NC'
733
808
  else
734
809
  address[:state] || 'n/a'
735
810
  end
736
811
  end
737
812
 
813
+ def subsequent_recurring_transaction?(options)
814
+ options.dig(:stored_credential, :reason_type) == 'recurring' && !options.dig(:stored_credential, :initial_transaction)
815
+ end
816
+
738
817
  def headers
739
818
  { 'Content-Type' => 'text/xml' }
740
819
  end
@@ -743,23 +822,23 @@ module ActiveMerchant
743
822
  test? ? test_url : live_url
744
823
  end
745
824
 
746
- def parse(action, raw_response)
747
- if is_cim_action?(action) || action == :verify_credentials
748
- parse_cim(raw_response)
825
+ def parse(action, raw_response, options = {})
826
+ if cim_action?(action) || action == :verify_credentials
827
+ parse_cim(raw_response, options)
749
828
  else
750
829
  parse_normal(action, raw_response)
751
830
  end
752
831
  end
753
832
 
754
- def commit(action, &payload)
833
+ def commit(action, options = {}, &payload)
755
834
  raw_response = ssl_post(url, post_data(action, &payload), headers)
756
- response = parse(action, raw_response)
835
+ response = parse(action, raw_response, options)
757
836
 
758
837
  avs_result_code = response[:avs_result_code].upcase if response[:avs_result_code]
759
838
  avs_result = AVSResult.new(code: STANDARD_AVS_CODE_MAPPING[avs_result_code])
760
839
  cvv_result = CVVResult.new(response[:card_code])
761
840
  if using_live_gateway_in_test_mode?(response)
762
- Response.new(false, "Using a live Authorize.net account in Test Mode is not permitted.")
841
+ Response.new(false, 'Using a live Authorize.net account in Test Mode is not permitted.')
763
842
  else
764
843
  Response.new(
765
844
  success_from(action, response),
@@ -775,8 +854,8 @@ module ActiveMerchant
775
854
  end
776
855
  end
777
856
 
778
- def is_cim_action?(action)
779
- action.to_s.start_with?("cim")
857
+ def cim_action?(action)
858
+ action.to_s.start_with?('cim')
780
859
  end
781
860
 
782
861
  def post_data(action)
@@ -790,17 +869,17 @@ module ActiveMerchant
790
869
 
791
870
  def root_for(action)
792
871
  if action == :cim_store
793
- "createCustomerProfileRequest"
872
+ 'createCustomerProfileRequest'
794
873
  elsif action == :cim_store_update
795
- "createCustomerPaymentProfileRequest"
874
+ 'createCustomerPaymentProfileRequest'
796
875
  elsif action == :cim_store_delete_customer
797
- "deleteCustomerProfileRequest"
876
+ 'deleteCustomerProfileRequest'
798
877
  elsif action == :verify_credentials
799
- "authenticateTestRequest"
800
- elsif is_cim_action?(action)
801
- "createCustomerProfileTransactionRequest"
878
+ 'authenticateTestRequest'
879
+ elsif cim_action?(action)
880
+ 'createCustomerProfileTransactionRequest'
802
881
  else
803
- "createTransactionRequest"
882
+ 'createTransactionRequest'
804
883
  end
805
884
  end
806
885
 
@@ -815,100 +894,123 @@ module ActiveMerchant
815
894
  doc = Nokogiri::XML(body)
816
895
  doc.remove_namespaces!
817
896
 
818
- response = {action: action}
819
-
820
- response[:response_code] = if(element = doc.at_xpath("//transactionResponse/responseCode"))
821
- (empty?(element.content) ? nil : element.content.to_i)
822
- end
823
-
824
- if(element = doc.at_xpath("//errors/error"))
825
- response[:response_reason_code] = element.at_xpath("errorCode").content[/0*(\d+)$/, 1]
826
- response[:response_reason_text] = element.at_xpath("errorText").content.chomp('.')
827
- elsif(element = doc.at_xpath("//transactionResponse/messages/message"))
828
- response[:response_reason_code] = element.at_xpath("code").content[/0*(\d+)$/, 1]
829
- response[:response_reason_text] = element.at_xpath("description").content.chomp('.')
830
- elsif(element = doc.at_xpath("//messages/message"))
831
- response[:response_reason_code] = element.at_xpath("code").content[/0*(\d+)$/, 1]
832
- response[:response_reason_text] = element.at_xpath("text").content.chomp('.')
897
+ response = { action: action }
898
+
899
+ response[:response_code] = if (element = doc.at_xpath('//transactionResponse/responseCode'))
900
+ empty?(element.content) ? nil : element.content.to_i
901
+ end
902
+
903
+ if (element = doc.at_xpath('//errors/error'))
904
+ response[:response_reason_code] = element.at_xpath('errorCode').content[/0*(\d+)$/, 1]
905
+ response[:response_reason_text] = element.at_xpath('errorText').content.chomp('.')
906
+ elsif (element = doc.at_xpath('//transactionResponse/messages/message'))
907
+ response[:response_reason_code] = element.at_xpath('code').content[/0*(\d+)$/, 1]
908
+ response[:response_reason_text] = element.at_xpath('description').content.chomp('.')
909
+ elsif (element = doc.at_xpath('//messages/message'))
910
+ response[:response_reason_code] = element.at_xpath('code').content[/0*(\d+)$/, 1]
911
+ response[:response_reason_text] = element.at_xpath('text').content.chomp('.')
833
912
  else
834
913
  response[:response_reason_code] = nil
835
- response[:response_reason_text] = ""
914
+ response[:response_reason_text] = ''
836
915
  end
837
916
 
838
- response[:avs_result_code] = if(element = doc.at_xpath("//avsResultCode"))
839
- (empty?(element.content) ? nil : element.content)
840
- end
917
+ response[:avs_result_code] =
918
+ if (element = doc.at_xpath('//avsResultCode'))
919
+ empty?(element.content) ? nil : element.content
920
+ end
841
921
 
842
- response[:transaction_id] = if(element = doc.at_xpath("//transId"))
843
- (empty?(element.content) ? nil : element.content)
844
- end
922
+ response[:transaction_id] =
923
+ if element = doc.at_xpath('//transId')
924
+ empty?(element.content) ? nil : element.content
925
+ end
845
926
 
846
- response[:card_code] = if(element = doc.at_xpath("//cvvResultCode"))
847
- (empty?(element.content) ? nil : element.content)
848
- end
927
+ response[:card_code] =
928
+ if element = doc.at_xpath('//cvvResultCode')
929
+ empty?(element.content) ? nil : element.content
930
+ end
849
931
 
850
- response[:authorization_code] = if(element = doc.at_xpath("//authCode"))
851
- (empty?(element.content) ? nil : element.content)
852
- end
932
+ response[:authorization_code] =
933
+ if element = doc.at_xpath('//authCode')
934
+ empty?(element.content) ? nil : element.content
935
+ end
853
936
 
854
- response[:cardholder_authentication_code] = if(element = doc.at_xpath("//cavvResultCode"))
855
- (empty?(element.content) ? nil : element.content)
856
- end
937
+ response[:cardholder_authentication_code] =
938
+ if element = doc.at_xpath('//cavvResultCode')
939
+ empty?(element.content) ? nil : element.content
940
+ end
857
941
 
858
- response[:account_number] = if(element = doc.at_xpath("//accountNumber"))
859
- (empty?(element.content) ? nil : element.content[-4..-1])
860
- end
942
+ response[:account_number] =
943
+ if element = doc.at_xpath('//accountNumber')
944
+ empty?(element.content) ? nil : element.content[-4..-1]
945
+ end
861
946
 
862
- response[:test_request] = if(element = doc.at_xpath("//testRequest"))
863
- (empty?(element.content) ? nil : element.content)
864
- end
947
+ response[:test_request] =
948
+ if element = doc.at_xpath('//testRequest')
949
+ empty?(element.content) ? nil : element.content
950
+ end
951
+
952
+ response[:full_response_code] =
953
+ if element = doc.at_xpath('//messages/message/code')
954
+ empty?(element.content) ? nil : element.content
955
+ end
956
+
957
+ response[:network_trans_id] =
958
+ if element = doc.at_xpath('//networkTransId')
959
+ empty?(element.content) ? nil : element.content
960
+ end
865
961
 
866
962
  response
867
963
  end
868
964
 
869
- def parse_cim(body)
965
+ def parse_cim(body, options)
870
966
  response = {}
871
967
 
872
968
  doc = Nokogiri::XML(body).remove_namespaces!
873
969
 
874
- if (element = doc.at_xpath("//messages/message"))
875
- response[:message_code] = element.at_xpath("code").content[/0*(\d+)$/, 1]
876
- response[:message_text] = element.at_xpath("text").content.chomp('.')
970
+ if element = doc.at_xpath('//messages/message')
971
+ response[:message_code] = element.at_xpath('code').content[/0*(\d+)$/, 1]
972
+ response[:message_text] = element.at_xpath('text').content.chomp('.')
877
973
  end
878
974
 
879
- response[:result_code] = if(element = doc.at_xpath("//messages/resultCode"))
880
- (empty?(element.content) ? nil : element.content)
881
- end
975
+ response[:result_code] =
976
+ if element = doc.at_xpath('//messages/resultCode')
977
+ empty?(element.content) ? nil : element.content
978
+ end
882
979
 
883
- response[:test_request] = if(element = doc.at_xpath("//testRequest"))
884
- (empty?(element.content) ? nil : element.content)
885
- end
980
+ response[:test_request] =
981
+ if element = doc.at_xpath('//testRequest')
982
+ empty?(element.content) ? nil : element.content
983
+ end
886
984
 
887
- response[:customer_profile_id] = if(element = doc.at_xpath("//customerProfileId"))
888
- (empty?(element.content) ? nil : element.content)
889
- end
985
+ response[:customer_profile_id] =
986
+ if element = doc.at_xpath('//customerProfileId')
987
+ empty?(element.content) ? nil : element.content
988
+ end
890
989
 
891
- response[:customer_payment_profile_id] = if(element = doc.at_xpath("//customerPaymentProfileIdList/numericString"))
892
- (empty?(element.content) ? nil : element.content)
893
- end
990
+ response[:customer_payment_profile_id] =
991
+ if element = doc.at_xpath('//customerPaymentProfileIdList/numericString')
992
+ empty?(element.content) ? nil : element.content
993
+ end
894
994
 
895
- response[:customer_payment_profile_id] = if(element = doc.at_xpath("//customerPaymentProfileIdList/numericString") ||
896
- doc.at_xpath("//customerPaymentProfileId"))
897
- (empty?(element.content) ? nil : element.content)
898
- end
995
+ response[:customer_payment_profile_id] =
996
+ if element = doc.at_xpath('//customerPaymentProfileIdList/numericString') ||
997
+ doc.at_xpath('//customerPaymentProfileId')
998
+ empty?(element.content) ? nil : element.content
999
+ end
899
1000
 
900
- response[:direct_response] = if(element = doc.at_xpath("//directResponse"))
901
- (empty?(element.content) ? nil : element.content)
902
- end
1001
+ response[:direct_response] =
1002
+ if element = doc.at_xpath('//directResponse')
1003
+ empty?(element.content) ? nil : element.content
1004
+ end
903
1005
 
904
- response.merge!(parse_direct_response_elements(response))
1006
+ response.merge!(parse_direct_response_elements(response, options))
905
1007
 
906
1008
  response
907
1009
  end
908
1010
 
909
1011
  def success_from(action, response)
910
1012
  if cim?(action) || (action == :verify_credentials)
911
- response[:result_code] == "Ok"
1013
+ response[:result_code] == 'Ok'
912
1014
  else
913
1015
  [APPROVED, FRAUD_REVIEW].include?(response[:response_code]) && TRANSACTION_ALREADY_ACTIONED.exclude?(response[:response_reason_code])
914
1016
  end
@@ -918,7 +1020,7 @@ module ActiveMerchant
918
1020
  if response[:response_code] == DECLINED
919
1021
  if CARD_CODE_ERRORS.include?(cvv_result.code)
920
1022
  return cvv_result.message
921
- elsif(AVS_REASON_CODES.include?(response[:response_reason_code]) && AVS_ERRORS.include?(avs_result.code))
1023
+ elsif AVS_REASON_CODES.include?(response[:response_reason_code]) && AVS_ERRORS.include?(avs_result.code)
922
1024
  return avs_result.message
923
1025
  end
924
1026
  end
@@ -928,14 +1030,14 @@ module ActiveMerchant
928
1030
 
929
1031
  def authorization_from(action, response)
930
1032
  if cim?(action)
931
- [response[:customer_profile_id], response[:customer_payment_profile_id], action].join("#")
1033
+ [response[:customer_profile_id], response[:customer_payment_profile_id], action].join('#')
932
1034
  else
933
- [response[:transaction_id], response[:account_number], action].join("#")
1035
+ [response[:transaction_id], response[:account_number], action].join('#')
934
1036
  end
935
1037
  end
936
1038
 
937
1039
  def split_authorization(authorization)
938
- authorization.split("#")
1040
+ authorization.split('#')
939
1041
  end
940
1042
 
941
1043
  def cim?(action)
@@ -943,7 +1045,7 @@ module ActiveMerchant
943
1045
  end
944
1046
 
945
1047
  def transaction_id_from(authorization)
946
- transaction_id, _, _ = split_authorization(authorization)
1048
+ transaction_id, = split_authorization(authorization)
947
1049
  transaction_id
948
1050
  end
949
1051
 
@@ -952,7 +1054,7 @@ module ActiveMerchant
952
1054
  end
953
1055
 
954
1056
  def using_live_gateway_in_test_mode?(response)
955
- !test? && response[:test_request] == "1"
1057
+ !test? && response[:test_request] == '1'
956
1058
  end
957
1059
 
958
1060
  def map_error_code(response_code, response_reason_code)
@@ -961,14 +1063,14 @@ module ActiveMerchant
961
1063
 
962
1064
  def auth_was_for_cim?(authorization)
963
1065
  _, _, action = split_authorization(authorization)
964
- action && is_cim_action?(action)
1066
+ action && cim_action?(action)
965
1067
  end
966
1068
 
967
- def parse_direct_response_elements(response)
968
- params = response[:direct_response]
1069
+ def parse_direct_response_elements(response, options)
1070
+ params = response[:direct_response]&.tr('"', '')
969
1071
  return {} unless params
970
1072
 
971
- parts = params.split(',')
1073
+ parts = params.split(options[:delimiter] || ',')
972
1074
  {
973
1075
  response_code: parts[0].to_i,
974
1076
  response_subcode: parts[1],
@@ -1014,10 +1116,9 @@ module ActiveMerchant
1014
1116
  card_type: parts[51] || '',
1015
1117
  split_tender_id: parts[52] || '',
1016
1118
  requested_amount: parts[53] || '',
1017
- balance_on_card: parts[54] || '',
1119
+ balance_on_card: parts[54] || ''
1018
1120
  }
1019
1121
  end
1020
-
1021
1122
  end
1022
1123
  end
1023
1124
  end