activemerchant 1.42.6 → 1.90.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 (450) hide show
  1. checksums.yaml +5 -13
  2. data/CHANGELOG +1420 -2
  3. data/CONTRIBUTORS +106 -0
  4. data/README.md +107 -103
  5. data/lib/active_merchant/billing/apple_pay_payment_token.rb +22 -0
  6. data/lib/active_merchant/billing/avs_result.rb +12 -13
  7. data/lib/active_merchant/billing/base.rb +13 -16
  8. data/lib/active_merchant/billing/check.rb +35 -24
  9. data/lib/active_merchant/billing/compatibility.rb +117 -0
  10. data/lib/active_merchant/billing/credit_card.rb +196 -81
  11. data/lib/active_merchant/billing/credit_card_formatting.rb +6 -4
  12. data/lib/active_merchant/billing/credit_card_methods.rb +199 -75
  13. data/lib/active_merchant/billing/cvv_result.rb +15 -15
  14. data/lib/active_merchant/billing/gateway.rb +171 -39
  15. data/lib/active_merchant/billing/gateways/adyen.rb +380 -0
  16. data/lib/active_merchant/billing/gateways/allied_wallet.rb +205 -0
  17. data/lib/active_merchant/billing/gateways/authorize_net.rb +933 -604
  18. data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +417 -0
  19. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +74 -54
  20. data/lib/active_merchant/billing/gateways/axcessms.rb +181 -0
  21. data/lib/active_merchant/billing/gateways/balanced.rb +130 -370
  22. data/lib/active_merchant/billing/gateways/bank_frick.rb +225 -0
  23. data/lib/active_merchant/billing/gateways/banwire.rb +23 -12
  24. data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +351 -0
  25. data/lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb +6 -6
  26. data/lib/active_merchant/billing/gateways/be2bill.rb +2 -2
  27. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +109 -32
  28. data/lib/active_merchant/billing/gateways/beanstream.rb +59 -13
  29. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +12 -9
  30. data/lib/active_merchant/billing/gateways/blue_pay.rb +520 -498
  31. data/lib/active_merchant/billing/gateways/blue_snap.rb +347 -0
  32. data/lib/active_merchant/billing/gateways/bogus.rb +80 -46
  33. data/lib/active_merchant/billing/gateways/borgun.rb +220 -0
  34. data/lib/active_merchant/billing/gateways/bpoint.rb +277 -0
  35. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +15 -2
  36. data/lib/active_merchant/billing/gateways/braintree.rb +2 -2
  37. data/lib/active_merchant/billing/gateways/braintree_blue.rb +311 -121
  38. data/lib/active_merchant/billing/gateways/braintree_orange.rb +4 -4
  39. data/lib/active_merchant/billing/gateways/bridge_pay.rb +244 -0
  40. data/lib/active_merchant/billing/gateways/cams.rb +230 -0
  41. data/lib/active_merchant/billing/gateways/card_connect.rb +311 -0
  42. data/lib/active_merchant/billing/gateways/card_save.rb +6 -7
  43. data/lib/active_merchant/billing/gateways/card_stream.rb +235 -89
  44. data/lib/active_merchant/billing/gateways/cardknox.rb +327 -0
  45. data/lib/active_merchant/billing/gateways/cardprocess.rb +254 -0
  46. data/lib/active_merchant/billing/gateways/cashnet.rb +219 -0
  47. data/lib/active_merchant/billing/gateways/cc5.rb +50 -8
  48. data/lib/active_merchant/billing/gateways/cecabank.rb +27 -14
  49. data/lib/active_merchant/billing/gateways/cenpos.rb +327 -0
  50. data/lib/active_merchant/billing/gateways/checkout.rb +214 -0
  51. data/lib/active_merchant/billing/gateways/checkout_v2.rb +233 -0
  52. data/lib/active_merchant/billing/gateways/citrus_pay.rb +22 -0
  53. data/lib/active_merchant/billing/gateways/clearhaus.rb +220 -0
  54. data/lib/active_merchant/billing/gateways/commercegate.rb +142 -0
  55. data/lib/active_merchant/billing/gateways/conekta.rb +91 -97
  56. data/lib/active_merchant/billing/gateways/creditcall.rb +271 -0
  57. data/lib/active_merchant/billing/gateways/credorax.rb +356 -0
  58. data/lib/active_merchant/billing/gateways/ct_payment.rb +268 -0
  59. data/lib/active_merchant/billing/gateways/culqi.rb +277 -0
  60. data/lib/active_merchant/billing/gateways/cyber_source.rb +294 -158
  61. data/lib/active_merchant/billing/gateways/d_local.rb +226 -0
  62. data/lib/active_merchant/billing/gateways/data_cash.rb +59 -347
  63. data/lib/active_merchant/billing/gateways/dibs.rb +199 -0
  64. data/lib/active_merchant/billing/gateways/digitzs.rb +292 -0
  65. data/lib/active_merchant/billing/gateways/ebanx.rb +296 -0
  66. data/lib/active_merchant/billing/gateways/efsnet.rb +24 -39
  67. data/lib/active_merchant/billing/gateways/elavon.rb +146 -147
  68. data/lib/active_merchant/billing/gateways/element.rb +356 -0
  69. data/lib/active_merchant/billing/gateways/epay.rb +41 -31
  70. data/lib/active_merchant/billing/gateways/evo_ca.rb +1 -1
  71. data/lib/active_merchant/billing/gateways/eway.rb +79 -78
  72. data/lib/active_merchant/billing/gateways/eway_managed.rb +35 -36
  73. data/lib/active_merchant/billing/gateways/eway_rapid.rb +369 -228
  74. data/lib/active_merchant/billing/gateways/exact.rb +32 -26
  75. data/lib/active_merchant/billing/gateways/ezic.rb +195 -0
  76. data/lib/active_merchant/billing/gateways/fat_zebra.rb +90 -64
  77. data/lib/active_merchant/billing/gateways/federated_canada.rb +6 -14
  78. data/lib/active_merchant/billing/gateways/finansbank.rb +3 -3
  79. data/lib/active_merchant/billing/gateways/first_giving.rb +142 -0
  80. data/lib/active_merchant/billing/gateways/first_pay.rb +128 -122
  81. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +190 -64
  82. data/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb +446 -0
  83. data/lib/active_merchant/billing/gateways/flo2cash.rb +215 -0
  84. data/lib/active_merchant/billing/gateways/flo2cash_simple.rb +20 -0
  85. data/lib/active_merchant/billing/gateways/forte.rb +270 -0
  86. data/lib/active_merchant/billing/gateways/garanti.rb +29 -27
  87. data/lib/active_merchant/billing/gateways/global_collect.rb +340 -0
  88. data/lib/active_merchant/billing/gateways/global_transport.rb +194 -0
  89. data/lib/active_merchant/billing/gateways/hdfc.rb +35 -36
  90. data/lib/active_merchant/billing/gateways/hps.rb +305 -0
  91. data/lib/active_merchant/billing/gateways/iats_payments.rb +271 -16
  92. data/lib/active_merchant/billing/gateways/in_context_paypal_express.rb +15 -0
  93. data/lib/active_merchant/billing/gateways/inspire.rb +29 -32
  94. data/lib/active_merchant/billing/gateways/instapay.rb +5 -6
  95. data/lib/active_merchant/billing/gateways/ipp.rb +175 -0
  96. data/lib/active_merchant/billing/gateways/iridium.rb +247 -41
  97. data/lib/active_merchant/billing/gateways/itransact.rb +4 -5
  98. data/lib/active_merchant/billing/gateways/iveri.rb +251 -0
  99. data/lib/active_merchant/billing/gateways/jetpay.rb +198 -71
  100. data/lib/active_merchant/billing/gateways/jetpay_v2.rb +437 -0
  101. data/lib/active_merchant/billing/gateways/komoju.rb +115 -0
  102. data/lib/active_merchant/billing/gateways/kushki.rb +219 -0
  103. data/lib/active_merchant/billing/gateways/latitude19.rb +411 -0
  104. data/lib/active_merchant/billing/gateways/linkpoint.rb +45 -43
  105. data/lib/active_merchant/billing/gateways/litle.rb +328 -444
  106. data/lib/active_merchant/billing/gateways/mastercard.rb +267 -0
  107. data/lib/active_merchant/billing/gateways/maxipago.rb +145 -115
  108. data/lib/active_merchant/billing/gateways/mercado_pago.rb +277 -0
  109. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +37 -19
  110. data/lib/active_merchant/billing/gateways/merchant_one.rb +13 -15
  111. data/lib/active_merchant/billing/gateways/merchant_partners.rb +245 -0
  112. data/lib/active_merchant/billing/gateways/merchant_ware.rb +57 -60
  113. data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +59 -48
  114. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +38 -19
  115. data/lib/active_merchant/billing/gateways/mercury.rb +77 -54
  116. data/lib/active_merchant/billing/gateways/metrics_global.rb +11 -30
  117. data/lib/active_merchant/billing/gateways/micropayment.rb +183 -0
  118. data/lib/active_merchant/billing/gateways/migs.rb +81 -22
  119. data/lib/active_merchant/billing/gateways/modern_payments.rb +3 -3
  120. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +23 -25
  121. data/lib/active_merchant/billing/gateways/monei.rb +307 -0
  122. data/lib/active_merchant/billing/gateways/moneris.rb +146 -64
  123. data/lib/active_merchant/billing/gateways/moneris_us.rb +197 -53
  124. data/lib/active_merchant/billing/gateways/money_movers.rb +6 -15
  125. data/lib/active_merchant/billing/gateways/mundipagg.rb +292 -0
  126. data/lib/active_merchant/billing/gateways/nab_transact.rb +86 -64
  127. data/lib/active_merchant/billing/gateways/ncr_secure_pay.rb +165 -0
  128. data/lib/active_merchant/billing/gateways/net_registry.rb +11 -5
  129. data/lib/active_merchant/billing/gateways/netaxept.rb +21 -22
  130. data/lib/active_merchant/billing/gateways/netbanx.rb +290 -0
  131. data/lib/active_merchant/billing/gateways/netbilling.rb +70 -35
  132. data/lib/active_merchant/billing/gateways/netpay.rb +5 -6
  133. data/lib/active_merchant/billing/gateways/network_merchants.rb +241 -0
  134. data/lib/active_merchant/billing/gateways/nmi.rb +274 -10
  135. data/lib/active_merchant/billing/gateways/ogone.rb +90 -47
  136. data/lib/active_merchant/billing/gateways/omise.rb +324 -0
  137. data/lib/active_merchant/billing/gateways/openpay.rb +48 -20
  138. data/lib/active_merchant/billing/gateways/opp.rb +369 -0
  139. data/lib/active_merchant/billing/gateways/optimal_payment.rb +79 -44
  140. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +22 -21
  141. data/lib/active_merchant/billing/gateways/orbital.rb +346 -102
  142. data/lib/active_merchant/billing/gateways/pac_net_raven.rb +48 -29
  143. data/lib/active_merchant/billing/gateways/pagarme.rb +246 -0
  144. data/lib/active_merchant/billing/gateways/pago_facil.rb +122 -0
  145. data/lib/active_merchant/billing/gateways/pay_conex.rb +245 -0
  146. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +67 -48
  147. data/lib/active_merchant/billing/gateways/pay_hub.rb +213 -0
  148. data/lib/active_merchant/billing/gateways/pay_junction.rb +20 -26
  149. data/lib/active_merchant/billing/gateways/pay_junction_v2.rb +188 -0
  150. data/lib/active_merchant/billing/gateways/pay_secure.rb +7 -15
  151. data/lib/active_merchant/billing/gateways/paybox_direct.rb +40 -36
  152. data/lib/active_merchant/billing/gateways/payeezy.rb +410 -0
  153. data/lib/active_merchant/billing/gateways/payex.rb +38 -30
  154. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +62 -36
  155. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +11 -7
  156. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +3 -3
  157. data/lib/active_merchant/billing/gateways/payflow.rb +74 -27
  158. data/lib/active_merchant/billing/gateways/payflow_express.rb +77 -81
  159. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +2 -3
  160. data/lib/active_merchant/billing/gateways/payflow_uk.rb +5 -6
  161. data/lib/active_merchant/billing/gateways/payment_express.rb +54 -45
  162. data/lib/active_merchant/billing/gateways/paymentez.rb +304 -0
  163. data/lib/active_merchant/billing/gateways/paymill.rb +160 -66
  164. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +54 -7
  165. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +4 -0
  166. data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +17 -3
  167. data/lib/active_merchant/billing/gateways/paypal.rb +36 -27
  168. data/lib/active_merchant/billing/gateways/paypal_ca.rb +1 -1
  169. data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +7 -6
  170. data/lib/active_merchant/billing/gateways/paypal_express.rb +32 -4
  171. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +3 -3
  172. data/lib/active_merchant/billing/gateways/payscout.rb +2 -13
  173. data/lib/active_merchant/billing/gateways/paystation.rb +96 -88
  174. data/lib/active_merchant/billing/gateways/payu_in.rb +248 -0
  175. data/lib/active_merchant/billing/gateways/payu_latam.rb +445 -0
  176. data/lib/active_merchant/billing/gateways/payway.rb +8 -8
  177. data/lib/active_merchant/billing/gateways/pin.rb +74 -18
  178. data/lib/active_merchant/billing/gateways/plugnpay.rb +66 -76
  179. data/lib/active_merchant/billing/gateways/pro_pay.rb +326 -0
  180. data/lib/active_merchant/billing/gateways/psigate.rb +30 -30
  181. data/lib/active_merchant/billing/gateways/psl_card.rb +27 -34
  182. data/lib/active_merchant/billing/gateways/qbms.rb +65 -54
  183. data/lib/active_merchant/billing/gateways/quantum.rb +18 -18
  184. data/lib/active_merchant/billing/gateways/quickbooks.rb +290 -0
  185. data/lib/active_merchant/billing/gateways/quickpay/quickpay_common.rb +184 -0
  186. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +295 -0
  187. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb +226 -0
  188. data/lib/active_merchant/billing/gateways/quickpay.rb +10 -350
  189. data/lib/active_merchant/billing/gateways/qvalent.rb +236 -0
  190. data/lib/active_merchant/billing/gateways/realex.rb +78 -48
  191. data/lib/active_merchant/billing/gateways/redsys.rb +310 -170
  192. data/lib/active_merchant/billing/gateways/s5.rb +246 -0
  193. data/lib/active_merchant/billing/gateways/safe_charge.rb +262 -0
  194. data/lib/active_merchant/billing/gateways/sage.rb +415 -119
  195. data/lib/active_merchant/billing/gateways/sage_pay.rb +195 -90
  196. data/lib/active_merchant/billing/gateways/sallie_mae.rb +11 -12
  197. data/lib/active_merchant/billing/gateways/secure_net.rb +51 -43
  198. data/lib/active_merchant/billing/gateways/secure_pay.rb +182 -10
  199. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +25 -14
  200. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +10 -18
  201. data/lib/active_merchant/billing/gateways/securion_pay.rb +264 -0
  202. data/lib/active_merchant/billing/gateways/skip_jack.rb +35 -38
  203. data/lib/active_merchant/billing/gateways/smart_ps.rb +50 -42
  204. data/lib/active_merchant/billing/gateways/so_easy_pay.rb +9 -9
  205. data/lib/active_merchant/billing/gateways/spreedly_core.rb +62 -12
  206. data/lib/active_merchant/billing/gateways/stripe.rb +536 -103
  207. data/lib/active_merchant/billing/gateways/swipe_checkout.rb +12 -18
  208. data/lib/active_merchant/billing/gateways/telr.rb +274 -0
  209. data/lib/active_merchant/billing/gateways/tns.rb +22 -0
  210. data/lib/active_merchant/billing/gateways/trans_first.rb +143 -30
  211. data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +608 -0
  212. data/lib/active_merchant/billing/gateways/transact_pro.rb +224 -0
  213. data/lib/active_merchant/billing/gateways/transax.rb +5 -6
  214. data/lib/active_merchant/billing/gateways/transnational.rb +2 -232
  215. data/lib/active_merchant/billing/gateways/trexle.rb +218 -0
  216. data/lib/active_merchant/billing/gateways/trust_commerce.rb +86 -57
  217. data/lib/active_merchant/billing/gateways/usa_epay.rb +4 -4
  218. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +196 -89
  219. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +157 -32
  220. data/lib/active_merchant/billing/gateways/vanco.rb +294 -0
  221. data/lib/active_merchant/billing/gateways/verifi.rb +42 -49
  222. data/lib/active_merchant/billing/gateways/viaklix.rb +11 -24
  223. data/lib/active_merchant/billing/gateways/visanet_peru.rb +233 -0
  224. data/lib/active_merchant/billing/gateways/webpay.rb +26 -28
  225. data/lib/active_merchant/billing/gateways/wepay.rb +237 -0
  226. data/lib/active_merchant/billing/gateways/wirecard.rb +153 -31
  227. data/lib/active_merchant/billing/gateways/world_net.rb +344 -0
  228. data/lib/active_merchant/billing/gateways/worldpay.rb +207 -63
  229. data/lib/active_merchant/billing/gateways/worldpay_online_payments.rb +215 -0
  230. data/lib/active_merchant/billing/gateways/worldpay_us.rb +221 -0
  231. data/lib/active_merchant/billing/gateways.rb +8 -11
  232. data/lib/active_merchant/billing/model.rb +30 -0
  233. data/lib/active_merchant/billing/network_tokenization_credit_card.rb +39 -0
  234. data/lib/active_merchant/billing/payment_token.rb +21 -0
  235. data/lib/active_merchant/billing/rails.rb +3 -0
  236. data/lib/active_merchant/billing/response.rb +31 -24
  237. data/lib/active_merchant/billing.rb +7 -1
  238. data/lib/active_merchant/connection.rb +195 -0
  239. data/lib/active_merchant/country.rb +335 -0
  240. data/lib/active_merchant/empty.rb +20 -0
  241. data/lib/active_merchant/errors.rb +35 -0
  242. data/lib/active_merchant/net_http_ssl_connection.rb +10 -0
  243. data/lib/active_merchant/network_connection_retries.rb +80 -0
  244. data/lib/active_merchant/post_data.rb +25 -0
  245. data/lib/active_merchant/posts_data.rb +92 -0
  246. data/lib/active_merchant/version.rb +1 -1
  247. data/lib/active_merchant.rb +23 -27
  248. data/lib/activemerchant.rb +1 -1
  249. data/lib/certs/cacert.pem +3988 -0
  250. data/lib/support/gateway_support.rb +7 -9
  251. data/lib/support/outbound_hosts.rb +13 -10
  252. data/lib/support/ssl_verify.rb +6 -7
  253. data/lib/support/ssl_version.rb +87 -0
  254. metadata +148 -323
  255. checksums.yaml.gz.sig +0 -0
  256. data/gem-public_cert.pem +0 -21
  257. data/lib/active_merchant/billing/expiry_date.rb +0 -34
  258. data/lib/active_merchant/billing/gateways/app55.rb +0 -185
  259. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +0 -314
  260. data/lib/active_merchant/billing/gateways/certo_direct.rb +0 -277
  261. data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +0 -249
  262. data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +0 -13
  263. data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +0 -29
  264. data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +0 -66
  265. data/lib/active_merchant/billing/gateways/orbital/avs_result.rb +0 -93
  266. data/lib/active_merchant/billing/gateways/orbital/cvv_result.rb +0 -34
  267. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +0 -93
  268. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +0 -114
  269. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +0 -102
  270. data/lib/active_merchant/billing/gateways/samurai.rb +0 -118
  271. data/lib/active_merchant/billing/gateways/vindicia.rb +0 -361
  272. data/lib/active_merchant/billing/integrations/a1agregator/helper.rb +0 -31
  273. data/lib/active_merchant/billing/integrations/a1agregator/notification.rb +0 -186
  274. data/lib/active_merchant/billing/integrations/a1agregator/status.rb +0 -38
  275. data/lib/active_merchant/billing/integrations/a1agregator.rb +0 -26
  276. data/lib/active_merchant/billing/integrations/action_view_helper.rb +0 -74
  277. data/lib/active_merchant/billing/integrations/alipay/helper.rb +0 -34
  278. data/lib/active_merchant/billing/integrations/alipay/notification.rb +0 -101
  279. data/lib/active_merchant/billing/integrations/alipay.rb +0 -18
  280. data/lib/active_merchant/billing/integrations/authorize_net_sim/helper.rb +0 -229
  281. data/lib/active_merchant/billing/integrations/authorize_net_sim/notification.rb +0 -340
  282. data/lib/active_merchant/billing/integrations/authorize_net_sim.rb +0 -38
  283. data/lib/active_merchant/billing/integrations/bit_pay/helper.rb +0 -64
  284. data/lib/active_merchant/billing/integrations/bit_pay/notification.rb +0 -74
  285. data/lib/active_merchant/billing/integrations/bit_pay/return.rb +0 -10
  286. data/lib/active_merchant/billing/integrations/bit_pay.rb +0 -30
  287. data/lib/active_merchant/billing/integrations/bogus/helper.rb +0 -17
  288. data/lib/active_merchant/billing/integrations/bogus/notification.rb +0 -11
  289. data/lib/active_merchant/billing/integrations/bogus/return.rb +0 -10
  290. data/lib/active_merchant/billing/integrations/bogus.rb +0 -23
  291. data/lib/active_merchant/billing/integrations/chronopay/helper.rb +0 -120
  292. data/lib/active_merchant/billing/integrations/chronopay/notification.rb +0 -158
  293. data/lib/active_merchant/billing/integrations/chronopay/return.rb +0 -10
  294. data/lib/active_merchant/billing/integrations/chronopay.rb +0 -23
  295. data/lib/active_merchant/billing/integrations/citrus/helper.rb +0 -40
  296. data/lib/active_merchant/billing/integrations/citrus/notification.rb +0 -133
  297. data/lib/active_merchant/billing/integrations/citrus/return.rb +0 -40
  298. data/lib/active_merchant/billing/integrations/citrus.rb +0 -51
  299. data/lib/active_merchant/billing/integrations/direc_pay/helper.rb +0 -200
  300. data/lib/active_merchant/billing/integrations/direc_pay/notification.rb +0 -76
  301. data/lib/active_merchant/billing/integrations/direc_pay/return.rb +0 -32
  302. data/lib/active_merchant/billing/integrations/direc_pay/status.rb +0 -37
  303. data/lib/active_merchant/billing/integrations/direc_pay.rb +0 -41
  304. data/lib/active_merchant/billing/integrations/directebanking/helper.rb +0 -90
  305. data/lib/active_merchant/billing/integrations/directebanking/notification.rb +0 -120
  306. data/lib/active_merchant/billing/integrations/directebanking/return.rb +0 -11
  307. data/lib/active_merchant/billing/integrations/directebanking.rb +0 -47
  308. data/lib/active_merchant/billing/integrations/doku/helper.rb +0 -102
  309. data/lib/active_merchant/billing/integrations/doku/notification.rb +0 -69
  310. data/lib/active_merchant/billing/integrations/doku/return.rb +0 -10
  311. data/lib/active_merchant/billing/integrations/doku.rb +0 -24
  312. data/lib/active_merchant/billing/integrations/dotpay/helper.rb +0 -77
  313. data/lib/active_merchant/billing/integrations/dotpay/notification.rb +0 -86
  314. data/lib/active_merchant/billing/integrations/dotpay/return.rb +0 -11
  315. data/lib/active_merchant/billing/integrations/dotpay.rb +0 -22
  316. data/lib/active_merchant/billing/integrations/dwolla/common.rb +0 -23
  317. data/lib/active_merchant/billing/integrations/dwolla/helper.rb +0 -43
  318. data/lib/active_merchant/billing/integrations/dwolla/notification.rb +0 -64
  319. data/lib/active_merchant/billing/integrations/dwolla/return.rb +0 -49
  320. data/lib/active_merchant/billing/integrations/dwolla.rb +0 -23
  321. data/lib/active_merchant/billing/integrations/e_payment_plans/helper.rb +0 -34
  322. data/lib/active_merchant/billing/integrations/e_payment_plans/notification.rb +0 -84
  323. data/lib/active_merchant/billing/integrations/e_payment_plans.rb +0 -48
  324. data/lib/active_merchant/billing/integrations/easy_pay/common.rb +0 -40
  325. data/lib/active_merchant/billing/integrations/easy_pay/helper.rb +0 -36
  326. data/lib/active_merchant/billing/integrations/easy_pay/notification.rb +0 -59
  327. data/lib/active_merchant/billing/integrations/easy_pay.rb +0 -30
  328. data/lib/active_merchant/billing/integrations/epay/helper.rb +0 -55
  329. data/lib/active_merchant/billing/integrations/epay/notification.rb +0 -110
  330. data/lib/active_merchant/billing/integrations/epay.rb +0 -21
  331. data/lib/active_merchant/billing/integrations/first_data/helper.rb +0 -61
  332. data/lib/active_merchant/billing/integrations/first_data/notification.rb +0 -56
  333. data/lib/active_merchant/billing/integrations/first_data.rb +0 -38
  334. data/lib/active_merchant/billing/integrations/gestpay/common.rb +0 -42
  335. data/lib/active_merchant/billing/integrations/gestpay/helper.rb +0 -70
  336. data/lib/active_merchant/billing/integrations/gestpay/notification.rb +0 -85
  337. data/lib/active_merchant/billing/integrations/gestpay/return.rb +0 -10
  338. data/lib/active_merchant/billing/integrations/gestpay.rb +0 -25
  339. data/lib/active_merchant/billing/integrations/helper.rb +0 -117
  340. data/lib/active_merchant/billing/integrations/hi_trust/helper.rb +0 -58
  341. data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +0 -59
  342. data/lib/active_merchant/billing/integrations/hi_trust/return.rb +0 -68
  343. data/lib/active_merchant/billing/integrations/hi_trust.rb +0 -27
  344. data/lib/active_merchant/billing/integrations/ipay88/helper.rb +0 -118
  345. data/lib/active_merchant/billing/integrations/ipay88/notification.rb +0 -103
  346. data/lib/active_merchant/billing/integrations/ipay88/return.rb +0 -29
  347. data/lib/active_merchant/billing/integrations/ipay88.rb +0 -23
  348. data/lib/active_merchant/billing/integrations/liqpay/helper.rb +0 -43
  349. data/lib/active_merchant/billing/integrations/liqpay/notification.rb +0 -89
  350. data/lib/active_merchant/billing/integrations/liqpay/return.rb +0 -83
  351. data/lib/active_merchant/billing/integrations/liqpay.rb +0 -30
  352. data/lib/active_merchant/billing/integrations/maksuturva/helper.rb +0 -119
  353. data/lib/active_merchant/billing/integrations/maksuturva/notification.rb +0 -48
  354. data/lib/active_merchant/billing/integrations/maksuturva.rb +0 -86
  355. data/lib/active_merchant/billing/integrations/moneybookers/helper.rb +0 -75
  356. data/lib/active_merchant/billing/integrations/moneybookers/notification.rb +0 -123
  357. data/lib/active_merchant/billing/integrations/moneybookers.rb +0 -26
  358. data/lib/active_merchant/billing/integrations/nochex/helper.rb +0 -68
  359. data/lib/active_merchant/billing/integrations/nochex/notification.rb +0 -94
  360. data/lib/active_merchant/billing/integrations/nochex/return.rb +0 -10
  361. data/lib/active_merchant/billing/integrations/nochex.rb +0 -88
  362. data/lib/active_merchant/billing/integrations/notification.rb +0 -71
  363. data/lib/active_merchant/billing/integrations/paxum/common.rb +0 -24
  364. data/lib/active_merchant/billing/integrations/paxum/helper.rb +0 -42
  365. data/lib/active_merchant/billing/integrations/paxum/notification.rb +0 -33
  366. data/lib/active_merchant/billing/integrations/paxum.rb +0 -44
  367. data/lib/active_merchant/billing/integrations/pay_fast/common.rb +0 -42
  368. data/lib/active_merchant/billing/integrations/pay_fast/helper.rb +0 -50
  369. data/lib/active_merchant/billing/integrations/pay_fast/notification.rb +0 -134
  370. data/lib/active_merchant/billing/integrations/pay_fast/return.rb +0 -10
  371. data/lib/active_merchant/billing/integrations/pay_fast.rb +0 -70
  372. data/lib/active_merchant/billing/integrations/paydollar/helper.rb +0 -41
  373. data/lib/active_merchant/billing/integrations/paydollar/notification.rb +0 -60
  374. data/lib/active_merchant/billing/integrations/paydollar/return.rb +0 -15
  375. data/lib/active_merchant/billing/integrations/paydollar.rb +0 -59
  376. data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +0 -116
  377. data/lib/active_merchant/billing/integrations/payflow_link/notification.rb +0 -78
  378. data/lib/active_merchant/billing/integrations/payflow_link.rb +0 -21
  379. data/lib/active_merchant/billing/integrations/paypal/helper.rb +0 -119
  380. data/lib/active_merchant/billing/integrations/paypal/notification.rb +0 -227
  381. data/lib/active_merchant/billing/integrations/paypal/return.rb +0 -10
  382. data/lib/active_merchant/billing/integrations/paypal.rb +0 -39
  383. data/lib/active_merchant/billing/integrations/paypal_payments_advanced/helper.rb +0 -15
  384. data/lib/active_merchant/billing/integrations/paypal_payments_advanced.rb +0 -20
  385. data/lib/active_merchant/billing/integrations/paysbuy/helper.rb +0 -15
  386. data/lib/active_merchant/billing/integrations/paysbuy/notification.rb +0 -39
  387. data/lib/active_merchant/billing/integrations/paysbuy.rb +0 -36
  388. data/lib/active_merchant/billing/integrations/payu_in/helper.rb +0 -76
  389. data/lib/active_merchant/billing/integrations/payu_in/notification.rb +0 -154
  390. data/lib/active_merchant/billing/integrations/payu_in/return.rb +0 -36
  391. data/lib/active_merchant/billing/integrations/payu_in.rb +0 -36
  392. data/lib/active_merchant/billing/integrations/payu_in_paisa/helper.rb +0 -19
  393. data/lib/active_merchant/billing/integrations/payu_in_paisa/notification.rb +0 -13
  394. data/lib/active_merchant/billing/integrations/payu_in_paisa/return.rb +0 -16
  395. data/lib/active_merchant/billing/integrations/payu_in_paisa.rb +0 -30
  396. data/lib/active_merchant/billing/integrations/platron/helper.rb +0 -32
  397. data/lib/active_merchant/billing/integrations/platron/notification.rb +0 -113
  398. data/lib/active_merchant/billing/integrations/platron.rb +0 -28
  399. data/lib/active_merchant/billing/integrations/pxpay/helper.rb +0 -112
  400. data/lib/active_merchant/billing/integrations/pxpay/notification.rb +0 -157
  401. data/lib/active_merchant/billing/integrations/pxpay/return.rb +0 -25
  402. data/lib/active_merchant/billing/integrations/pxpay.rb +0 -31
  403. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +0 -96
  404. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +0 -137
  405. data/lib/active_merchant/billing/integrations/quickpay.rb +0 -21
  406. data/lib/active_merchant/billing/integrations/rbkmoney/helper.rb +0 -23
  407. data/lib/active_merchant/billing/integrations/rbkmoney/notification.rb +0 -91
  408. data/lib/active_merchant/billing/integrations/rbkmoney.rb +0 -17
  409. data/lib/active_merchant/billing/integrations/return.rb +0 -42
  410. data/lib/active_merchant/billing/integrations/robokassa/common.rb +0 -19
  411. data/lib/active_merchant/billing/integrations/robokassa/helper.rb +0 -50
  412. data/lib/active_merchant/billing/integrations/robokassa/notification.rb +0 -55
  413. data/lib/active_merchant/billing/integrations/robokassa/return.rb +0 -17
  414. data/lib/active_merchant/billing/integrations/robokassa.rb +0 -49
  415. data/lib/active_merchant/billing/integrations/sage_pay_form/encryption.rb +0 -33
  416. data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +0 -136
  417. data/lib/active_merchant/billing/integrations/sage_pay_form/notification.rb +0 -210
  418. data/lib/active_merchant/billing/integrations/sage_pay_form/return.rb +0 -31
  419. data/lib/active_merchant/billing/integrations/sage_pay_form.rb +0 -37
  420. data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +0 -107
  421. data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +0 -171
  422. data/lib/active_merchant/billing/integrations/two_checkout/return.rb +0 -58
  423. data/lib/active_merchant/billing/integrations/two_checkout.rb +0 -44
  424. data/lib/active_merchant/billing/integrations/valitor/helper.rb +0 -86
  425. data/lib/active_merchant/billing/integrations/valitor/notification.rb +0 -13
  426. data/lib/active_merchant/billing/integrations/valitor/response_fields.rb +0 -97
  427. data/lib/active_merchant/billing/integrations/valitor/return.rb +0 -13
  428. data/lib/active_merchant/billing/integrations/valitor.rb +0 -33
  429. data/lib/active_merchant/billing/integrations/verkkomaksut/helper.rb +0 -88
  430. data/lib/active_merchant/billing/integrations/verkkomaksut/notification.rb +0 -59
  431. data/lib/active_merchant/billing/integrations/verkkomaksut.rb +0 -20
  432. data/lib/active_merchant/billing/integrations/web_pay/common.rb +0 -50
  433. data/lib/active_merchant/billing/integrations/web_pay/helper.rb +0 -68
  434. data/lib/active_merchant/billing/integrations/web_pay/notification.rb +0 -51
  435. data/lib/active_merchant/billing/integrations/web_pay.rb +0 -45
  436. data/lib/active_merchant/billing/integrations/webmoney/common.rb +0 -17
  437. data/lib/active_merchant/billing/integrations/webmoney/helper.rb +0 -40
  438. data/lib/active_merchant/billing/integrations/webmoney/notification.rb +0 -47
  439. data/lib/active_merchant/billing/integrations/webmoney.rb +0 -43
  440. data/lib/active_merchant/billing/integrations/wirecard_checkout_page/common.rb +0 -104
  441. data/lib/active_merchant/billing/integrations/wirecard_checkout_page/helper.rb +0 -145
  442. data/lib/active_merchant/billing/integrations/wirecard_checkout_page/notification.rb +0 -101
  443. data/lib/active_merchant/billing/integrations/wirecard_checkout_page/return.rb +0 -35
  444. data/lib/active_merchant/billing/integrations/wirecard_checkout_page.rb +0 -39
  445. data/lib/active_merchant/billing/integrations/world_pay/helper.rb +0 -101
  446. data/lib/active_merchant/billing/integrations/world_pay/notification.rb +0 -160
  447. data/lib/active_merchant/billing/integrations/world_pay.rb +0 -34
  448. data/lib/active_merchant/billing/integrations.rb +0 -17
  449. data.tar.gz.sig +0 -0
  450. metadata.gz.sig +0 -1
@@ -1,726 +1,1055 @@
1
- module ActiveMerchant #:nodoc:
2
- module Billing #:nodoc:
3
- # For more information on the Authorize.Net Gateway please visit their {Integration Center}[http://developer.authorize.net/]
4
- #
5
- # The login and password are not the username and password you use to
6
- # login to the Authorize.Net Merchant Interface. Instead, you will
7
- # use the API Login ID as the login and Transaction Key as the
8
- # password.
9
- #
10
- # ==== How to Get Your API Login ID and Transaction Key
11
- #
12
- # 1. Log into the Merchant Interface
13
- # 2. Select Settings from the Main Menu
14
- # 3. Click on API Login ID and Transaction Key in the Security section
15
- # 4. Type in the answer to the secret question configured on setup
16
- # 5. Click Submit
17
- #
18
- # ==== Automated Recurring Billing (ARB)
19
- #
20
- # Automated Recurring Billing (ARB) is an optional service for submitting and managing recurring, or subscription-based, transactions.
21
- #
22
- # To use recurring, update_recurring, cancel_recurring and status_recurring ARB must be enabled for your account.
23
- #
24
- # Information about ARB is available on the {Authorize.Net website}[http://www.authorize.net/solutions/merchantsolutions/merchantservices/automatedrecurringbilling/].
25
- # Information about the ARB API is available at the {Authorize.Net Integration Center}[http://developer.authorize.net/]
1
+ require 'nokogiri'
2
+
3
+ module ActiveMerchant
4
+ module Billing
26
5
  class AuthorizeNetGateway < Gateway
27
- API_VERSION = '3.1'
6
+ include Empty
28
7
 
29
- class_attribute :arb_test_url, :arb_live_url
8
+ self.test_url = 'https://apitest.authorize.net/xml/v1/request.api'
9
+ self.live_url = 'https://api2.authorize.net/xml/v1/request.api'
30
10
 
31
- self.test_url = "https://test.authorize.net/gateway/transact.dll"
32
- self.live_url = "https://secure.authorize.net/gateway/transact.dll"
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)
12
+ self.default_currency = 'USD'
13
+ self.money_format = :dollars
14
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb, :maestro]
33
15
 
34
- self.arb_test_url = 'https://apitest.authorize.net/xml/v1/request.api'
35
- self.arb_live_url = 'https://api.authorize.net/xml/v1/request.api'
16
+ self.homepage_url = 'http://www.authorize.net/'
17
+ self.display_name = 'Authorize.Net'
36
18
 
37
- class_attribute :duplicate_window
19
+ # Authorize.net has slightly different definitions for returned AVS codes
20
+ # that have been mapped to the closest equivalent AM standard AVSResult codes
21
+ # Authorize.net's descriptions noted below
22
+ STANDARD_AVS_CODE_MAPPING = {
23
+ 'A' => 'A', # Street Address: Match -- First 5 Digits of ZIP: No Match
24
+ 'B' => 'I', # Address not provided for AVS check or street address match, postal code could not be verified
25
+ 'E' => 'E', # AVS Error
26
+ 'G' => 'G', # Non U.S. Card Issuing Bank
27
+ 'N' => 'N', # Street Address: No Match -- First 5 Digits of ZIP: No Match
28
+ 'P' => 'I', # AVS not applicable for this transaction
29
+ 'R' => 'R', # Retry, System Is Unavailable
30
+ 'S' => 'S', # AVS Not Supported by Card Issuing Bank
31
+ 'U' => 'U', # Address Information For This Cardholder Is Unavailable
32
+ 'W' => 'W', # Street Address: No Match -- All 9 Digits of ZIP: Match
33
+ 'X' => 'X', # Street Address: Match -- All 9 Digits of ZIP: Match
34
+ 'Y' => 'Y', # Street Address: Match - First 5 Digits of ZIP: Match
35
+ 'Z' => 'Z' # Street Address: No Match - First 5 Digits of ZIP: Match
36
+ }
38
37
 
39
- APPROVED, DECLINED, ERROR, FRAUD_REVIEW = 1, 2, 3, 4
38
+ STANDARD_ERROR_CODE_MAPPING = {
39
+ '2127' => STANDARD_ERROR_CODE[:incorrect_address],
40
+ '22' => STANDARD_ERROR_CODE[:card_declined],
41
+ '227' => STANDARD_ERROR_CODE[:incorrect_address],
42
+ '23' => STANDARD_ERROR_CODE[:card_declined],
43
+ '2315' => STANDARD_ERROR_CODE[:invalid_number],
44
+ '2316' => STANDARD_ERROR_CODE[:invalid_expiry_date],
45
+ '2317' => STANDARD_ERROR_CODE[:expired_card],
46
+ '235' => STANDARD_ERROR_CODE[:processing_error],
47
+ '237' => STANDARD_ERROR_CODE[:invalid_number],
48
+ '24' => STANDARD_ERROR_CODE[:pickup_card],
49
+ '244' => STANDARD_ERROR_CODE[:incorrect_cvc],
50
+ '300' => STANDARD_ERROR_CODE[:config_error],
51
+ '3153' => STANDARD_ERROR_CODE[:processing_error],
52
+ '3155' => STANDARD_ERROR_CODE[:unsupported_feature],
53
+ '36' => STANDARD_ERROR_CODE[:incorrect_number],
54
+ '37' => STANDARD_ERROR_CODE[:invalid_expiry_date],
55
+ '378' => STANDARD_ERROR_CODE[:invalid_cvc],
56
+ '38' => STANDARD_ERROR_CODE[:expired_card],
57
+ '384' => STANDARD_ERROR_CODE[:config_error],
58
+ }
40
59
 
41
- RESPONSE_CODE, RESPONSE_REASON_CODE, RESPONSE_REASON_TEXT, AUTHORIZATION_CODE = 0, 2, 3, 4
42
- AVS_RESULT_CODE, TRANSACTION_ID, CARD_CODE_RESPONSE_CODE, CARDHOLDER_AUTH_CODE = 5, 6, 38, 39
60
+ MARKET_TYPE = {
61
+ :moto => '1',
62
+ :retail => '2'
63
+ }
43
64
 
44
- self.default_currency = 'USD'
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'
76
+ }
45
77
 
46
- self.supported_countries = ['US', 'CA', 'GB']
47
- self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb]
48
- self.homepage_url = 'http://www.authorize.net/'
49
- self.display_name = 'Authorize.Net'
78
+ class_attribute :duplicate_window
50
79
 
51
- CARD_CODE_ERRORS = %w( N S )
52
- AVS_ERRORS = %w( A E N R W Z )
53
- AVS_REASON_CODES = %w(27 45)
80
+ APPROVED, DECLINED, ERROR, FRAUD_REVIEW = 1, 2, 3, 4
54
81
  TRANSACTION_ALREADY_ACTIONED = %w(310 311)
55
82
 
56
- AUTHORIZE_NET_ARB_NAMESPACE = 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'
83
+ CARD_CODE_ERRORS = %w(N S)
84
+ AVS_ERRORS = %w(A E I N R W Z)
85
+ AVS_REASON_CODES = %w(27 45)
86
+
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/
90
+ }.freeze
57
91
 
58
- RECURRING_ACTIONS = {
59
- :create => 'ARBCreateSubscription',
60
- :update => 'ARBUpdateSubscription',
61
- :cancel => 'ARBCancelSubscription',
62
- :status => 'ARBGetSubscriptionStatus'
63
- }
92
+ APPLE_PAY_DATA_DESCRIPTOR = 'COMMON.APPLE.INAPP.PAYMENT'
64
93
 
65
- # Creates a new AuthorizeNetGateway
66
- #
67
- # The gateway requires that a valid login and password be passed
68
- # in the +options+ hash.
69
- #
70
- # ==== Options
71
- #
72
- # * <tt>:login</tt> -- The Authorize.Net API Login ID (REQUIRED)
73
- # * <tt>:password</tt> -- The Authorize.Net Transaction Key. (REQUIRED)
74
- # * <tt>:test</tt> -- +true+ or +false+. If true, perform transactions against the test server.
75
- # Otherwise, perform transactions against the production server.
76
- def initialize(options = {})
94
+ PAYMENT_METHOD_NOT_SUPPORTED_ERROR = '155'
95
+ INELIGIBLE_FOR_ISSUING_CREDIT_ERROR = '54'
96
+
97
+ def initialize(options={})
77
98
  requires!(options, :login, :password)
78
99
  super
79
100
  end
80
101
 
81
- # Performs an authorization, which reserves the funds on the customer's credit card, but does not
82
- # charge the card.
83
- #
84
- # ==== Parameters
85
- #
86
- # * <tt>money</tt> -- The amount to be authorized as an Integer value in cents.
87
- # * <tt>paysource</tt> -- The CreditCard or Check details for the transaction.
88
- # * <tt>options</tt> -- A hash of optional parameters.
89
- def authorize(money, paysource, options = {})
90
- post = {}
91
- add_currency_code(post, money, options)
92
- add_invoice(post, options)
93
- add_payment_source(post, paysource, options)
94
- add_address(post, options)
95
- add_customer_data(post, options)
96
- add_duplicate_window(post)
97
-
98
- commit('AUTH_ONLY', money, post)
99
- end
100
-
101
- # Perform a purchase, which is essentially an authorization and capture in a single operation.
102
- #
103
- # ==== Parameters
104
- #
105
- # * <tt>money</tt> -- The amount to be purchased as an Integer value in cents.
106
- # * <tt>paysource</tt> -- The CreditCard or Check details for the transaction.
107
- # * <tt>options</tt> -- A hash of optional parameters.
108
- def purchase(money, paysource, options = {})
109
- post = {}
110
- add_currency_code(post, money, options)
111
- add_invoice(post, options)
112
- add_payment_source(post, paysource, options)
113
- add_address(post, options)
114
- add_customer_data(post, options)
115
- add_duplicate_window(post)
116
-
117
- commit('AUTH_CAPTURE', money, post)
118
- end
119
-
120
- # Captures the funds from an authorized transaction.
121
- #
122
- # ==== Parameters
123
- #
124
- # * <tt>money</tt> -- The amount to be captured as an Integer value in cents.
125
- # * <tt>authorization</tt> -- The authorization returned from the previous authorize request.
126
- def capture(money, authorization, options = {})
127
- post = {:trans_id => authorization}
128
- add_customer_data(post, options)
129
- add_invoice(post, options)
130
- commit('PRIOR_AUTH_CAPTURE', money, post)
131
- end
132
-
133
- # Void a previous transaction
134
- #
135
- # ==== Parameters
136
- #
137
- # * <tt>authorization</tt> - The authorization returned from the previous authorize request.
138
- def void(authorization, options = {})
139
- post = {:trans_id => authorization}
140
- add_duplicate_window(post)
141
- commit('VOID', nil, post)
142
- end
143
-
144
- # Refund a transaction.
145
- #
146
- # This transaction indicates to the gateway that
147
- # money should flow from the merchant to the customer.
148
- #
149
- # ==== Parameters
150
- #
151
- # * <tt>money</tt> -- The amount to be credited to the customer as an Integer value in cents.
152
- # * <tt>identification</tt> -- The ID of the original transaction against which the refund is being issued.
153
- # * <tt>options</tt> -- A hash of parameters.
154
- #
155
- # ==== Options
156
- #
157
- # * <tt>:card_number</tt> -- The credit card number the refund is being issued to. (REQUIRED)
158
- # You can either pass the last four digits of the card number or the full card number.
159
- # * <tt>:first_name</tt> -- The first name of the account being refunded.
160
- # * <tt>:last_name</tt> -- The last name of the account being refunded.
161
- # * <tt>:zip</tt> -- The postal code of the account being refunded.
162
- def refund(money, identification, options = {})
163
- requires!(options, :card_number)
164
-
165
- post = { :trans_id => identification,
166
- :card_num => options[:card_number]
167
- }
168
-
169
- post[:first_name] = options[:first_name] if options[:first_name]
170
- post[:last_name] = options[:last_name] if options[:last_name]
171
- post[:zip] = options[:zip] if options[:zip]
172
-
173
- add_invoice(post, options)
174
- add_duplicate_window(post)
175
-
176
- commit('CREDIT', money, post)
177
- end
178
-
179
- def credit(money, identification, options = {})
180
- deprecated CREDIT_DEPRECATION_MESSAGE
181
- refund(money, identification, options)
182
- end
183
-
184
- # Create a recurring payment.
185
- #
186
- # This transaction creates a new Automated Recurring Billing (ARB) subscription. Your account must have ARB enabled.
187
- #
188
- # ==== Parameters
189
- #
190
- # * <tt>money</tt> -- The amount to be charged to the customer at each interval as an Integer value in cents.
191
- # * <tt>creditcard</tt> -- The CreditCard details for the transaction.
192
- # * <tt>options</tt> -- A hash of parameters.
193
- #
194
- # ==== Options
195
- #
196
- # * <tt>:interval</tt> -- A hash containing information about the interval of time between payments. Must
197
- # contain the keys <tt>:length</tt> and <tt>:unit</tt>. <tt>:unit</tt> can be either <tt>:months</tt> or <tt>:days</tt>.
198
- # If <tt>:unit</tt> is <tt>:months</tt> then <tt>:length</tt> must be an integer between 1 and 12 inclusive.
199
- # If <tt>:unit</tt> is <tt>:days</tt> then <tt>:length</tt> must be an integer between 7 and 365 inclusive.
200
- # For example, to charge the customer once every three months the hash would be
201
- # +:interval => { :unit => :months, :length => 3 }+ (REQUIRED)
202
- # * <tt>:duration</tt> -- A hash containing keys for the <tt>:start_date</tt> the subscription begins (also the date the
203
- # initial billing occurs) and the total number of billing <tt>:occurrences</tt> or payments for the subscription. (REQUIRED)
204
- def recurring(money, creditcard, options={})
205
- requires!(options, :interval, :duration, :billing_address)
206
- requires!(options[:interval], :length, [:unit, :days, :months])
207
- requires!(options[:duration], :start_date, :occurrences)
208
- requires!(options[:billing_address], :first_name, :last_name)
209
-
210
- options[:credit_card] = creditcard
211
- options[:amount] = money
212
-
213
- request = build_recurring_request(:create, options)
214
- recurring_commit(:create, request)
215
- end
216
-
217
- # Update a recurring payment's details.
218
- #
219
- # This transaction updates an existing Automated Recurring Billing (ARB) subscription. Your account must have ARB enabled
220
- # and the subscription must have already been created previously by calling +recurring()+. The ability to change certain
221
- # details about a recurring payment is dependent on transaction history and cannot be determined until after calling
222
- # +update_recurring()+. See the ARB XML Guide for such conditions.
223
- #
224
- # ==== Parameters
225
- #
226
- # * <tt>options</tt> -- A hash of parameters.
227
- #
228
- # ==== Options
229
- #
230
- # * <tt>:subscription_id</tt> -- A string containing the <tt>:subscription_id</tt> of the recurring payment already in place
231
- # for a given credit card. (REQUIRED)
232
- def update_recurring(options={})
233
- requires!(options, :subscription_id)
234
- request = build_recurring_request(:update, options)
235
- recurring_commit(:update, request)
236
- end
237
-
238
- # Cancel a recurring payment.
239
- #
240
- # This transaction cancels an existing Automated Recurring Billing (ARB) subscription. Your account must have ARB enabled
241
- # and the subscription must have already been created previously by calling recurring()
242
- #
243
- # ==== Parameters
244
- #
245
- # * <tt>subscription_id</tt> -- A string containing the +subscription_id+ of the recurring payment already in place
246
- # for a given credit card. (REQUIRED)
247
- def cancel_recurring(subscription_id)
248
- request = build_recurring_request(:cancel, :subscription_id => subscription_id)
249
- recurring_commit(:cancel, request)
250
- end
251
-
252
- # Get Subscription Status of a recurring payment.
253
- #
254
- # This transaction gets the status of an existing Automated Recurring Billing (ARB) subscription. Your account must have ARB enabled.
255
- #
256
- # ==== Parameters
257
- #
258
- # * <tt>subscription_id</tt> -- A string containing the +subscription_id+ of the recurring payment already in place
259
- # for a given credit card. (REQUIRED)
260
- def status_recurring(subscription_id)
261
- request = build_recurring_request(:status, :subscription_id => subscription_id)
262
- recurring_commit(:status, request)
102
+ def purchase(amount, payment, options = {})
103
+ if payment.is_a?(String)
104
+ commit(:cim_purchase, options) do |xml|
105
+ add_cim_auth_purchase(xml, 'profileTransAuthCapture', amount, payment, options)
106
+ end
107
+ else
108
+ commit(:purchase) do |xml|
109
+ add_auth_purchase(xml, 'authCaptureTransaction', amount, payment, options)
110
+ end
111
+ end
263
112
  end
264
113
 
265
- private
114
+ def authorize(amount, payment, options={})
115
+ if payment.is_a?(String)
116
+ commit(:cim_authorize, options) do |xml|
117
+ add_cim_auth_purchase(xml, 'profileTransAuthOnly', amount, payment, options)
118
+ end
119
+ else
120
+ commit(:authorize) do |xml|
121
+ add_auth_purchase(xml, 'authOnlyTransaction', amount, payment, options)
122
+ end
123
+ end
124
+ end
125
+
126
+ def capture(amount, authorization, options={})
127
+ if auth_was_for_cim?(authorization)
128
+ cim_capture(amount, authorization, options)
129
+ else
130
+ normal_capture(amount, authorization, options)
131
+ end
132
+ end
133
+
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
266
140
 
267
- def commit(action, money, parameters)
268
- parameters[:amount] = amount(money) unless action == 'VOID'
141
+ return response if response.success?
142
+ return response unless options[:force_full_refund_if_unsettled]
269
143
 
270
- url = test? ? self.test_url : self.live_url
271
- data = ssl_post url, post_data(action, parameters)
144
+ if response.params['response_reason_code'] == INELIGIBLE_FOR_ISSUING_CREDIT_ERROR
145
+ void(authorization, options)
146
+ else
147
+ response
148
+ end
149
+ end
272
150
 
273
- response = parse(data)
274
- response[:action] = action
151
+ def void(authorization, options={})
152
+ if auth_was_for_cim?(authorization)
153
+ cim_void(authorization, options)
154
+ else
155
+ normal_void(authorization, options)
156
+ end
157
+ end
275
158
 
276
- message = message_from(response)
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
277
163
 
278
- Response.new(success?(response), message, response,
279
- :test => test?,
280
- :authorization => response[:transaction_id],
281
- :fraud_review => fraud_review?(response),
282
- :avs_result => { :code => response[:avs_result_code] },
283
- :cvv_result => response[:card_code]
284
- )
164
+ commit(:credit) do |xml|
165
+ add_order_id(xml, options)
166
+ xml.transactionRequest do
167
+ xml.transactionType('refundTransaction')
168
+ xml.amount(amount(amount))
169
+
170
+ add_payment_source(xml, payment, options, :credit)
171
+ xml.refTransId(transaction_id_from(options[:transaction_id])) if options[:transaction_id]
172
+ add_invoice(xml, 'refundTransaction', options)
173
+ add_customer_data(xml, payment, options)
174
+ add_settings(xml, payment, options)
175
+ add_user_fields(xml, amount, options)
176
+ end
177
+ end
285
178
  end
286
179
 
287
- def success?(response)
288
- response[:response_code] == APPROVED && TRANSACTION_ALREADY_ACTIONED.exclude?(response[:response_reason_code])
180
+ def verify(credit_card, options = {})
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) }
184
+ end
289
185
  end
290
186
 
291
- def fraud_review?(response)
292
- response[:response_code] == FRAUD_REVIEW
187
+ def store(credit_card, options = {})
188
+ if options[:customer_profile_id]
189
+ create_customer_payment_profile(credit_card, options)
190
+ else
191
+ create_customer_profile(credit_card, options)
192
+ end
293
193
  end
294
194
 
295
- def parse(body)
296
- fields = split(body)
195
+ def unstore(authorization)
196
+ customer_profile_id, _, _ = split_authorization(authorization)
297
197
 
298
- results = {
299
- :response_code => fields[RESPONSE_CODE].to_i,
300
- :response_reason_code => fields[RESPONSE_REASON_CODE],
301
- :response_reason_text => fields[RESPONSE_REASON_TEXT],
302
- :avs_result_code => fields[AVS_RESULT_CODE],
303
- :transaction_id => fields[TRANSACTION_ID],
304
- :card_code => fields[CARD_CODE_RESPONSE_CODE],
305
- :authorization_code => fields[AUTHORIZATION_CODE],
306
- :cardholder_authentication_code => fields[CARDHOLDER_AUTH_CODE]
307
- }
308
- results
198
+ delete_customer_profile(customer_profile_id)
309
199
  end
310
200
 
311
- def post_data(action, parameters = {})
312
- post = {}
201
+ def verify_credentials
202
+ response = commit(:verify_credentials) {}
203
+ response.success?
204
+ end
313
205
 
314
- post[:version] = API_VERSION
315
- post[:login] = @options[:login]
316
- post[:tran_key] = @options[:password]
317
- post[:relay_response] = "FALSE"
318
- post[:type] = action
319
- post[:delim_data] = "TRUE"
320
- post[:delim_char] = ","
321
- post[:encap_char] = "$"
322
- post[:solution_ID] = application_id if application_id.present? && application_id != "ActiveMerchant"
206
+ def supports_scrubbing?
207
+ true
208
+ end
323
209
 
324
- request = post.merge(parameters).collect { |key, value| "x_#{key}=#{CGI.escape(value.to_s)}" }.join("&")
325
- request
210
+ def scrub(transcript)
211
+ transcript.
212
+ gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]').
213
+ gsub(%r((<transactionKey>).+(</transactionKey>)), '\1[FILTERED]\2').
214
+ gsub(%r((<cardNumber>).+(</cardNumber>)), '\1[FILTERED]\2').
215
+ gsub(%r((<cardCode>).+(</cardCode>)), '\1[FILTERED]\2').
216
+ gsub(%r((<track1>).+(</track1>)), '\1[FILTERED]\2').
217
+ gsub(%r((<track2>).+(</track2>)), '\1[FILTERED]\2').
218
+ gsub(/(<routingNumber>).+(<\/routingNumber>)/, '\1[FILTERED]\2').
219
+ gsub(/(<accountNumber>).+(<\/accountNumber>)/, '\1[FILTERED]\2').
220
+ gsub(%r((<cryptogram>).+(</cryptogram>)), '\1[FILTERED]\2')
326
221
  end
327
222
 
328
- def add_currency_code(post, money, options)
329
- post[:currency_code] = options[:currency] || currency(money)
223
+ def supports_network_tokenization?
224
+ 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='
232
+ })
233
+
234
+ request = post_data(:authorize) do |xml|
235
+ add_auth_purchase(xml, 'authOnlyTransaction', 1, card, {})
236
+ end
237
+ raw_response = ssl_post(url, request, headers)
238
+ response = parse(:authorize, raw_response)
239
+ response[:response_reason_code].to_s != PAYMENT_METHOD_NOT_SUPPORTED_ERROR
330
240
  end
331
241
 
332
- def add_invoice(post, options)
333
- post[:invoice_num] = options[:order_id]
334
- post[:description] = options[:description]
242
+ private
243
+
244
+ def add_auth_purchase(xml, transaction_type, amount, payment, options)
245
+ add_order_id(xml, options)
246
+ xml.transactionRequest do
247
+ xml.transactionType(transaction_type)
248
+ xml.amount(amount(amount))
249
+ add_payment_source(xml, payment, options)
250
+ add_invoice(xml, transaction_type, options)
251
+ add_tax_fields(xml, options)
252
+ add_duty_fields(xml, options)
253
+ add_shipping_fields(xml, options)
254
+ add_tax_exempt_status(xml, options)
255
+ add_po_number(xml, options)
256
+ add_customer_data(xml, payment, options)
257
+ add_market_type_device_type(xml, payment, options)
258
+ add_settings(xml, payment, options)
259
+ add_user_fields(xml, amount, options)
260
+ add_ship_from_address(xml, options)
261
+ end
335
262
  end
336
263
 
337
- def add_creditcard(post, creditcard, options={})
338
- post[:card_num] = creditcard.number
339
- post[:card_code] = creditcard.verification_value if creditcard.verification_value?
340
- post[:exp_date] = expdate(creditcard)
341
- post[:first_name] = creditcard.first_name
342
- post[:last_name] = creditcard.last_name
264
+ def add_cim_auth_purchase(xml, transaction_type, amount, payment, options)
265
+ add_order_id(xml, options)
266
+ xml.transaction do
267
+ xml.send(transaction_type) do
268
+ xml.amount(amount(amount))
269
+ add_tax_fields(xml, options)
270
+ add_shipping_fields(xml, options)
271
+ add_duty_fields(xml, options)
272
+ add_payment_source(xml, payment, options)
273
+ add_invoice(xml, transaction_type, options)
274
+ add_tax_exempt_status(xml, options)
275
+ end
276
+ end
277
+ add_extra_options_for_cim(xml, options)
278
+ end
279
+
280
+ def cim_capture(amount, authorization, options)
281
+ commit(:cim_capture, options) do |xml|
282
+ add_order_id(xml, options)
283
+ xml.transaction do
284
+ xml.profileTransPriorAuthCapture do
285
+ xml.amount(amount(amount))
286
+ add_tax_fields(xml, options)
287
+ add_shipping_fields(xml, options)
288
+ add_duty_fields(xml, options)
289
+ xml.transId(transaction_id_from(authorization))
290
+ end
291
+ end
292
+ add_extra_options_for_cim(xml, options)
293
+ end
294
+ end
295
+
296
+ def normal_capture(amount, authorization, options)
297
+ commit(:capture) do |xml|
298
+ add_order_id(xml, options)
299
+ xml.transactionRequest do
300
+ xml.transactionType('priorAuthCaptureTransaction')
301
+ xml.amount(amount(amount))
302
+ add_tax_fields(xml, options)
303
+ add_duty_fields(xml, options)
304
+ add_shipping_fields(xml, options)
305
+ add_tax_exempt_status(xml, options)
306
+ add_po_number(xml, options)
307
+ xml.refTransId(transaction_id_from(authorization))
308
+ add_invoice(xml, 'capture', options)
309
+ add_user_fields(xml, amount, options)
310
+ end
311
+ end
312
+ end
313
+
314
+ def cim_refund(amount, authorization, options)
315
+ transaction_id, card_number, _ = split_authorization(authorization)
316
+
317
+ commit(:cim_refund, options) do |xml|
318
+ add_order_id(xml, options)
319
+ xml.transaction do
320
+ xml.profileTransRefund do
321
+ xml.amount(amount(amount))
322
+ add_tax_fields(xml, options)
323
+ add_shipping_fields(xml, options)
324
+ add_duty_fields(xml, options)
325
+ xml.creditCardNumberMasked(card_number)
326
+ add_invoice(xml, 'profileTransRefund', options)
327
+ xml.transId(transaction_id)
328
+ end
329
+ end
330
+ add_extra_options_for_cim(xml, options)
331
+ end
332
+ end
333
+
334
+ def normal_refund(amount, authorization, options)
335
+ transaction_id, card_number, _ = split_authorization(authorization)
336
+
337
+ commit(:refund) do |xml|
338
+ xml.transactionRequest do
339
+ xml.transactionType('refundTransaction')
340
+ xml.amount(amount.nil? ? 0 : amount(amount))
341
+ xml.payment do
342
+ if options[:routing_number]
343
+ xml.bankAccount do
344
+ xml.accountType(options[:account_type])
345
+ xml.routingNumber(options[:routing_number])
346
+ xml.accountNumber(options[:account_number])
347
+ xml.nameOnAccount("#{options[:first_name]} #{options[:last_name]}")
348
+ end
349
+ else
350
+ xml.creditCard do
351
+ xml.cardNumber(card_number || options[:card_number])
352
+ xml.expirationDate('XXXX')
353
+ end
354
+ end
355
+ end
356
+ xml.refTransId(transaction_id)
357
+
358
+ add_invoice(xml, 'refundTransaction', options)
359
+ add_tax_fields(xml, options)
360
+ add_duty_fields(xml, options)
361
+ add_shipping_fields(xml, options)
362
+ add_tax_exempt_status(xml, options)
363
+ add_po_number(xml, options)
364
+ add_customer_data(xml, nil, options)
365
+ add_user_fields(xml, amount, options)
366
+ end
367
+ end
368
+ end
369
+
370
+ def cim_void(authorization, options)
371
+ commit(:cim_void, options) do |xml|
372
+ add_order_id(xml, options)
373
+ xml.transaction do
374
+ xml.profileTransVoid do
375
+ xml.transId(transaction_id_from(authorization))
376
+ end
377
+ end
378
+ add_extra_options_for_cim(xml, options)
379
+ end
343
380
  end
344
381
 
345
- def add_payment_source(params, source, options={})
346
- if card_brand(source) == "check"
347
- add_check(params, source, options)
382
+ def normal_void(authorization, options)
383
+ commit(:void) do |xml|
384
+ add_order_id(xml, options)
385
+ xml.transactionRequest do
386
+ xml.transactionType('voidTransaction')
387
+ xml.refTransId(transaction_id_from(authorization))
388
+ end
389
+ end
390
+ end
391
+
392
+ def add_payment_source(xml, source, options, action = nil)
393
+ return unless source
394
+ if source.is_a?(String)
395
+ add_token_payment_method(xml, source, options)
396
+ elsif card_brand(source) == 'check'
397
+ add_check(xml, source)
398
+ elsif card_brand(source) == 'apple_pay'
399
+ add_apple_pay_payment_token(xml, source)
348
400
  else
349
- add_creditcard(params, source, options)
401
+ add_credit_card(xml, source, action)
402
+ end
403
+ end
404
+
405
+ def camel_case_lower(key)
406
+ String(key).split('_').inject([]) { |buffer, e| buffer.push(buffer.empty? ? e : e.capitalize) }.join
407
+ end
408
+
409
+ def add_settings(xml, source, options)
410
+ xml.transactionSettings do
411
+ if options[:recurring]
412
+ xml.setting do
413
+ xml.settingName('recurringBilling')
414
+ xml.settingValue('true')
415
+ end
416
+ end
417
+ if options[:disable_partial_auth]
418
+ xml.setting do
419
+ xml.settingName('allowPartialAuth')
420
+ xml.settingValue('false')
421
+ end
422
+ end
423
+ if options[:duplicate_window]
424
+ set_duplicate_window(xml, options[:duplicate_window])
425
+ elsif self.class.duplicate_window
426
+ ActiveMerchant.deprecated 'Using the duplicate_window class_attribute is deprecated. Use the transaction options hash instead.'
427
+ set_duplicate_window(xml, self.class.duplicate_window)
428
+ end
429
+ if options.key?(:email_customer)
430
+ xml.setting do
431
+ xml.settingName('emailCustomer')
432
+ xml.settingValue(options[:email_customer] ? 'true' : 'false')
433
+ end
434
+ end
435
+ if options[:header_email_receipt]
436
+ xml.setting do
437
+ xml.settingName('headerEmailReceipt')
438
+ xml.settingValue(options[:header_email_receipt])
439
+ end
440
+ end
441
+ if options[:test_request]
442
+ xml.setting do
443
+ xml.settingName('testRequest')
444
+ xml.settingValue('1')
445
+ end
446
+ end
350
447
  end
351
448
  end
352
449
 
353
- def add_check(post, check, options)
354
- post[:method] = "ECHECK"
355
- post[:bank_name] = check.bank_name
356
- post[:bank_aba_code] = check.routing_number
357
- post[:bank_acct_num] = check.account_number
358
- post[:bank_acct_type] = check.account_type
359
- post[:echeck_type] = "WEB"
360
- post[:bank_acct_name] = check.name
361
- post[:bank_check_number] = check.number if check.number.present?
362
- post[:recurring_billing] = (options[:recurring] ? "TRUE" : "FALSE")
450
+ def set_duplicate_window(xml, value)
451
+ xml.setting do
452
+ xml.settingName('duplicateWindow')
453
+ xml.settingValue(value)
454
+ end
363
455
  end
364
456
 
365
- def add_customer_data(post, options)
366
- if options.has_key? :email
367
- post[:email] = options[:email]
368
- post[:email_customer] = false
457
+ def add_user_fields(xml, amount, options)
458
+ xml.userFields do
459
+ if currency = (options[:currency] || currency(amount))
460
+ xml.userField do
461
+ xml.name('x_currency_code')
462
+ xml.value(currency)
463
+ end
464
+ end
465
+ if application_id.present?
466
+ xml.userField do
467
+ xml.name('x_solution_id')
468
+ xml.value(application_id)
469
+ end
470
+ end
369
471
  end
472
+ end
370
473
 
371
- if options.has_key? :customer
372
- post[:cust_id] = options[:customer] if Float(options[:customer]) rescue nil
474
+ def add_credit_card(xml, credit_card, action)
475
+ if credit_card.track_data
476
+ add_swipe_data(xml, credit_card)
477
+ else
478
+ xml.payment do
479
+ xml.creditCard do
480
+ xml.cardNumber(truncate(credit_card.number, 16))
481
+ xml.expirationDate(format(credit_card.month, :two_digits) + '/' + format(credit_card.year, :four_digits))
482
+ if credit_card.valid_card_verification_value?(credit_card.verification_value, credit_card.brand)
483
+ xml.cardCode(credit_card.verification_value)
484
+ end
485
+ if credit_card.is_a?(NetworkTokenizationCreditCard) && action != :credit
486
+ xml.cryptogram(credit_card.payment_cryptogram)
487
+ end
488
+ end
489
+ end
373
490
  end
491
+ end
374
492
 
375
- if options.has_key? :ip
376
- post[:customer_ip] = options[:ip]
493
+ def add_swipe_data(xml, credit_card)
494
+ TRACKS.each do |key, regex|
495
+ if regex.match(credit_card.track_data)
496
+ @valid_track_data = true
497
+ xml.payment do
498
+ xml.trackData do
499
+ xml.public_send(:"track#{key}", credit_card.track_data)
500
+ end
501
+ end
502
+ end
377
503
  end
504
+ end
378
505
 
379
- if options.has_key? :cardholder_authentication_value
380
- post[:cardholder_authentication_value] = options[:cardholder_authentication_value]
506
+ def add_token_payment_method(xml, token, options)
507
+ customer_profile_id, customer_payment_profile_id, _ = split_authorization(token)
508
+ customer_profile_id = options[:customer_profile_id] if options[:customer_profile_id]
509
+ customer_payment_profile_id = options[:customer_payment_profile_id] if options[:customer_payment_profile_id]
510
+ xml.customerProfileId(customer_profile_id)
511
+ xml.customerPaymentProfileId(customer_payment_profile_id)
512
+ end
513
+
514
+ def add_apple_pay_payment_token(xml, apple_pay_payment_token)
515
+ xml.payment do
516
+ xml.opaqueData do
517
+ xml.dataDescriptor(APPLE_PAY_DATA_DESCRIPTOR)
518
+ xml.dataValue(Base64.strict_encode64(apple_pay_payment_token.payment_data.to_json))
519
+ end
381
520
  end
521
+ end
382
522
 
383
- if options.has_key? :authentication_indicator
384
- post[:authentication_indicator] = options[:authentication_indicator]
523
+ def add_market_type_device_type(xml, payment, options)
524
+ return if payment.is_a?(String) || card_brand(payment) == 'check' || card_brand(payment) == 'apple_pay'
525
+ if valid_track_data
526
+ xml.retail do
527
+ xml.marketType(options[:market_type] || MARKET_TYPE[:retail])
528
+ xml.deviceType(options[:device_type] || DEVICE_TYPE[:wireless_pos])
529
+ end
530
+ elsif payment.manual_entry
531
+ xml.retail do
532
+ xml.marketType(options[:market_type] || MARKET_TYPE[:moto])
533
+ end
534
+ else
535
+ if options[:market_type]
536
+ xml.retail do
537
+ xml.marketType(options[:market_type])
538
+ end
539
+ end
385
540
  end
541
+ end
386
542
 
543
+ def valid_track_data
544
+ @valid_track_data ||= false
387
545
  end
388
546
 
389
- # x_duplicate_window won't be sent by default, because sending it changes the response.
390
- # "If this field is present in the request with or without a value, an enhanced duplicate transaction response will be sent."
391
- # (as of 2008-12-30) http://www.authorize.net/support/AIM_guide_SCC.pdf
392
- def add_duplicate_window(post)
393
- unless duplicate_window.nil?
394
- post[:duplicate_window] = duplicate_window
547
+ def add_check(xml, check)
548
+ xml.payment do
549
+ xml.bankAccount do
550
+ xml.routingNumber(check.routing_number)
551
+ xml.accountNumber(check.account_number)
552
+ xml.nameOnAccount(truncate(check.name, 22))
553
+ xml.bankName(check.bank_name)
554
+ xml.checkNumber(check.number)
555
+ end
395
556
  end
396
557
  end
397
558
 
398
- def add_address(post, options)
399
- if address = options[:billing_address] || options[:address]
400
- post[:address] = address[:address1].to_s
401
- post[:company] = address[:company].to_s
402
- post[:phone] = address[:phone].to_s
403
- post[:zip] = address[:zip].to_s
404
- post[:city] = address[:city].to_s
405
- post[:country] = address[:country].to_s
406
- post[:state] = address[:state].blank? ? 'n/a' : address[:state]
559
+ def add_customer_data(xml, payment_source, options)
560
+ xml.customer do
561
+ xml.id(options[:customer]) unless empty?(options[:customer]) || options[:customer] !~ /^\w+$/
562
+ xml.email(options[:email]) unless empty?(options[:email])
407
563
  end
408
564
 
409
- if address = options[:shipping_address]
410
- post[:ship_to_first_name] = address[:first_name].to_s
411
- post[:ship_to_last_name] = address[:last_name].to_s
412
- post[:ship_to_address] = address[:address1].to_s
413
- post[:ship_to_company] = address[:company].to_s
414
- post[:ship_to_phone] = address[:phone].to_s
415
- post[:ship_to_zip] = address[:zip].to_s
416
- post[:ship_to_city] = address[:city].to_s
417
- post[:ship_to_country] = address[:country].to_s
418
- post[:ship_to_state] = address[:state].blank? ? 'n/a' : address[:state]
565
+ add_billing_address(xml, payment_source, options)
566
+ add_shipping_address(xml, options)
567
+
568
+ xml.customerIP(options[:ip]) unless empty?(options[:ip])
569
+
570
+ xml.cardholderAuthentication do
571
+ three_d_secure = options.fetch(:three_d_secure, {})
572
+ xml.authenticationIndicator(
573
+ options[:authentication_indicator] || three_d_secure[:eci])
574
+ xml.cardholderAuthenticationValue(
575
+ options[:cardholder_authentication_value] || three_d_secure[:cavv])
419
576
  end
420
577
  end
421
578
 
422
- # Make a ruby type out of the response string
423
- def normalize(field)
424
- case field
425
- when "true" then true
426
- when "false" then false
427
- when "" then nil
428
- when "null" then nil
429
- else field
579
+ def add_billing_address(xml, payment_source, options)
580
+ address = options[:billing_address] || options[:address] || {}
581
+
582
+ xml.billTo do
583
+ first_name, last_name = names_from(payment_source, address, options)
584
+ state = state_from(address, options)
585
+ full_address = "#{address[:address1]} #{address[:address2]}".strip
586
+
587
+ xml.firstName(truncate(first_name, 50)) unless empty?(first_name)
588
+ xml.lastName(truncate(last_name, 50)) unless empty?(last_name)
589
+ xml.company(truncate(address[:company], 50)) unless empty?(address[:company])
590
+ xml.address(truncate(full_address, 60))
591
+ xml.city(truncate(address[:city], 40))
592
+ xml.state(truncate(state, 40))
593
+ xml.zip(truncate((address[:zip] || options[:zip]), 20))
594
+ xml.country(truncate(address[:country], 60))
595
+ xml.phoneNumber(truncate(address[:phone], 25)) unless empty?(address[:phone])
596
+ xml.faxNumber(truncate(address[:fax], 25)) unless empty?(address[:fax])
430
597
  end
431
598
  end
432
599
 
433
- def message_from(results)
434
- if results[:response_code] == DECLINED
435
- return CVVResult.messages[ results[:card_code] ] if CARD_CODE_ERRORS.include?(results[:card_code])
436
- if AVS_REASON_CODES.include?(results[:response_reason_code]) && AVS_ERRORS.include?(results[:avs_result_code])
437
- return AVSResult.messages[ results[:avs_result_code] ]
600
+ def add_shipping_address(xml, options, root_node='shipTo')
601
+ address = options[:shipping_address] || options[:address]
602
+ return unless address
603
+
604
+ xml.send(root_node) do
605
+ first_name, last_name = if address[:name]
606
+ split_names(address[:name])
607
+ else
608
+ [address[:first_name], address[:last_name]]
438
609
  end
610
+ full_address = "#{address[:address1]} #{address[:address2]}".strip
611
+
612
+ xml.firstName(truncate(first_name, 50)) unless empty?(first_name)
613
+ xml.lastName(truncate(last_name, 50)) unless empty?(last_name)
614
+ xml.company(truncate(address[:company], 50)) unless empty?(address[:company])
615
+ xml.address(truncate(full_address, 60))
616
+ xml.city(truncate(address[:city], 40))
617
+ xml.state(truncate(address[:state], 40))
618
+ xml.zip(truncate(address[:zip], 20))
619
+ xml.country(truncate(address[:country], 60))
620
+ end
621
+ end
622
+
623
+ def add_ship_from_address(xml, options, root_node='shipFrom')
624
+ address = options[:ship_from_address]
625
+ return unless address
626
+
627
+ xml.send(root_node) do
628
+ xml.zip(truncate(address[:zip], 20)) unless empty?(address[:zip])
629
+ xml.country(truncate(address[:country], 60)) unless empty?(address[:country])
439
630
  end
631
+ end
440
632
 
441
- (results[:response_reason_text] ? results[:response_reason_text].chomp('.') : '')
633
+ def add_order_id(xml, options)
634
+ xml.refId(truncate(options[:order_id], 20))
442
635
  end
443
636
 
444
- def expdate(creditcard)
445
- year = sprintf("%.4i", creditcard.year)
446
- month = sprintf("%.2i", creditcard.month)
637
+ def add_invoice(xml, transaction_type, options)
638
+ xml.order do
639
+ xml.invoiceNumber(truncate(options[:order_id], 20))
640
+ xml.description(truncate(options[:description], 255))
641
+ xml.purchaseOrderNumber(options[:po_number]) if options[:po_number] && transaction_type.start_with?('profileTrans')
642
+ xml.summaryCommodityCode(truncate(options[:summary_commodity_code], 4)) if options[:summary_commodity_code] && !transaction_type.start_with?('profileTrans')
643
+ end
447
644
 
448
- "#{month}#{year[-2..-1]}"
645
+ # Authorize.net API requires lineItems to be placed directly after order tag
646
+ if options[:line_items]
647
+ xml.lineItems do
648
+ options[:line_items].each do |line_item|
649
+ xml.lineItem do
650
+ line_item.each do |key, value|
651
+ xml.send(camel_case_lower(key), value)
652
+ end
653
+ end
654
+ end
655
+ end
656
+ end
449
657
  end
450
658
 
451
- def split(response)
452
- response[1..-2].split(/\$,\$/)
659
+ def add_tax_fields(xml, options)
660
+ tax = options[:tax]
661
+ if tax.is_a?(Hash)
662
+ xml.tax do
663
+ xml.amount(amount(tax[:amount].to_i))
664
+ xml.name(tax[:name])
665
+ xml.description(tax[:description])
666
+ end
667
+ end
453
668
  end
454
669
 
455
- # ARB
670
+ def add_duty_fields(xml, options)
671
+ duty = options[:duty]
672
+ if duty.is_a?(Hash)
673
+ xml.duty do
674
+ xml.amount(amount(duty[:amount].to_i))
675
+ xml.name(duty[:name])
676
+ xml.description(duty[:description])
677
+ end
678
+ end
679
+ end
456
680
 
457
- # Builds recurring billing request
458
- def build_recurring_request(action, options = {})
459
- unless RECURRING_ACTIONS.include?(action)
460
- raise StandardError, "Invalid Automated Recurring Billing Action: #{action}"
681
+ def add_shipping_fields(xml, options)
682
+ shipping = options[:shipping]
683
+ if shipping.is_a?(Hash)
684
+ xml.shipping do
685
+ xml.amount(amount(shipping[:amount].to_i))
686
+ xml.name(shipping[:name])
687
+ xml.description(shipping[:description])
688
+ end
461
689
  end
690
+ end
691
+
692
+ def add_tax_exempt_status(xml, options)
693
+ xml.taxExempt(options[:tax_exempt]) if options[:tax_exempt]
694
+ end
695
+
696
+ def add_po_number(xml, options)
697
+ xml.poNumber(options[:po_number]) if options[:po_number]
698
+ end
699
+
700
+ def add_extra_options_for_cim(xml, options)
701
+ xml.extraOptions("x_delim_char=#{options[:delimiter]}") if options[:delimiter]
702
+ end
462
703
 
463
- xml = Builder::XmlMarkup.new(:indent => 2)
464
- xml.instruct!(:xml, :version => '1.0', :encoding => 'utf-8')
465
- xml.tag!("#{RECURRING_ACTIONS[action]}Request", :xmlns => AUTHORIZE_NET_ARB_NAMESPACE) do
466
- add_arb_merchant_authentication(xml)
467
- # Merchant-assigned reference ID for the request
468
- xml.tag!('refId', options[:ref_id]) if options[:ref_id]
469
- send("build_arb_#{action}_subscription_request", xml, options)
704
+ def create_customer_payment_profile(credit_card, options)
705
+ commit(:cim_store_update, options) do |xml|
706
+ xml.customerProfileId options[:customer_profile_id]
707
+ xml.paymentProfile do
708
+ add_billing_address(xml, credit_card, options)
709
+ xml.payment do
710
+ xml.creditCard do
711
+ xml.cardNumber(truncate(credit_card.number, 16))
712
+ xml.expirationDate(format(credit_card.year, :four_digits) + '-' + format(credit_card.month, :two_digits))
713
+ xml.cardCode(credit_card.verification_value) if credit_card.verification_value
714
+ end
715
+ end
716
+ end
470
717
  end
471
718
  end
472
719
 
473
- # Contains the merchant’s payment gateway account authentication information
474
- def add_arb_merchant_authentication(xml)
475
- xml.tag!('merchantAuthentication') do
476
- xml.tag!('name', @options[:login])
477
- xml.tag!('transactionKey', @options[:password])
720
+ def create_customer_profile(credit_card, options)
721
+ commit(:cim_store, options) do |xml|
722
+ xml.profile do
723
+ xml.merchantCustomerId(truncate(options[:merchant_customer_id], 20) || SecureRandom.hex(10))
724
+ xml.description(truncate(options[:description], 255)) unless empty?(options[:description])
725
+ xml.email(options[:email]) unless empty?(options[:email])
726
+
727
+ xml.paymentProfiles do
728
+ xml.customerType('individual')
729
+ add_billing_address(xml, credit_card, options)
730
+ add_shipping_address(xml, options, 'shipToList')
731
+ xml.payment do
732
+ xml.creditCard do
733
+ xml.cardNumber(truncate(credit_card.number, 16))
734
+ xml.expirationDate(format(credit_card.year, :four_digits) + '-' + format(credit_card.month, :two_digits))
735
+ xml.cardCode(credit_card.verification_value) if credit_card.verification_value
736
+ end
737
+ end
738
+ end
739
+ end
478
740
  end
479
741
  end
480
742
 
481
- # Builds body for ARBCreateSubscriptionRequest
482
- def build_arb_create_subscription_request(xml, options)
483
- # Subscription
484
- add_arb_subscription(xml, options)
743
+ def delete_customer_profile(customer_profile_id)
744
+ commit(:cim_store_delete_customer, options) do |xml|
745
+ xml.customerProfileId(customer_profile_id)
746
+ end
747
+ end
485
748
 
486
- xml.target!
749
+ def names_from(payment_source, address, options)
750
+ if payment_source && !payment_source.is_a?(PaymentToken) && !payment_source.is_a?(String)
751
+ first_name, last_name = split_names(address[:name])
752
+ [(payment_source.first_name || first_name), (payment_source.last_name || last_name)]
753
+ else
754
+ [options[:first_name], options[:last_name]]
755
+ end
487
756
  end
488
757
 
489
- # Builds body for ARBUpdateSubscriptionRequest
490
- def build_arb_update_subscription_request(xml, options)
491
- xml.tag!('subscriptionId', options[:subscription_id])
492
- # Adds Subscription
493
- add_arb_subscription(xml, options)
758
+ def state_from(address, options)
759
+ if ['US', 'CA'].include?(address[:country])
760
+ address[:state] || 'NC'
761
+ else
762
+ address[:state] || 'n/a'
763
+ end
764
+ end
494
765
 
495
- xml.target!
766
+ def headers
767
+ { 'Content-Type' => 'text/xml' }
496
768
  end
497
769
 
498
- # Builds body for ARBCancelSubscriptionRequest
499
- def build_arb_cancel_subscription_request(xml, options)
500
- xml.tag!('subscriptionId', options[:subscription_id])
770
+ def url
771
+ test? ? test_url : live_url
772
+ end
501
773
 
502
- xml.target!
774
+ def parse(action, raw_response, options = {})
775
+ if is_cim_action?(action) || action == :verify_credentials
776
+ parse_cim(raw_response, options)
777
+ else
778
+ parse_normal(action, raw_response)
779
+ end
503
780
  end
504
781
 
505
- # Builds body for ARBGetSubscriptionStatusRequest
506
- def build_arb_status_subscription_request(xml, options)
507
- xml.tag!('subscriptionId', options[:subscription_id])
782
+ def commit(action, options = {}, &payload)
783
+ raw_response = ssl_post(url, post_data(action, &payload), headers)
784
+ response = parse(action, raw_response, options)
785
+
786
+ avs_result_code = response[:avs_result_code].upcase if response[:avs_result_code]
787
+ avs_result = AVSResult.new(code: STANDARD_AVS_CODE_MAPPING[avs_result_code])
788
+ cvv_result = CVVResult.new(response[:card_code])
789
+ if using_live_gateway_in_test_mode?(response)
790
+ Response.new(false, 'Using a live Authorize.net account in Test Mode is not permitted.')
791
+ else
792
+ Response.new(
793
+ success_from(action, response),
794
+ message_from(action, response, avs_result, cvv_result),
795
+ response,
796
+ authorization: authorization_from(action, response),
797
+ test: test?,
798
+ avs_result: avs_result,
799
+ cvv_result: cvv_result,
800
+ fraud_review: fraud_review?(response),
801
+ error_code: map_error_code(response[:response_code], response[:response_reason_code])
802
+ )
803
+ end
804
+ end
508
805
 
509
- xml.target!
806
+ def is_cim_action?(action)
807
+ action.to_s.start_with?('cim')
510
808
  end
511
809
 
512
- # Adds subscription information
513
- def add_arb_subscription(xml, options)
514
- xml.tag!('subscription') do
515
- # Merchant-assigned name for the subscription (optional)
516
- xml.tag!('name', options[:subscription_name]) if options[:subscription_name]
517
- # Contains information about the payment schedule
518
- add_arb_payment_schedule(xml, options)
519
- # The amount to be billed to the customer
520
- # for each payment in the subscription
521
- xml.tag!('amount', amount(options[:amount])) if options[:amount]
522
- if trial = options[:trial]
523
- # The amount to be charged for each payment during a trial period (conditional)
524
- xml.tag!('trialAmount', amount(trial[:amount])) if trial[:amount]
810
+ def post_data(action)
811
+ Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
812
+ xml.send(root_for(action), 'xmlns' => 'AnetApi/xml/v1/schema/AnetApiSchema.xsd') do
813
+ add_authentication(xml)
814
+ yield(xml)
525
815
  end
526
- # Contains either the customer’s credit card
527
- # or bank account payment information
528
- add_arb_payment(xml, options)
529
- # Contains order information (optional)
530
- add_arb_order(xml, options)
531
- # Contains information about the customer
532
- add_arb_customer(xml, options)
533
- # Contains the customer's billing address information
534
- add_arb_address(xml, 'billTo', options[:billing_address])
535
- # Contains the customer's shipping address information (optional)
536
- add_arb_address(xml, 'shipTo', options[:shipping_address])
816
+ end.to_xml(indent: 0)
817
+ end
818
+
819
+ def root_for(action)
820
+ if action == :cim_store
821
+ 'createCustomerProfileRequest'
822
+ elsif action == :cim_store_update
823
+ 'createCustomerPaymentProfileRequest'
824
+ elsif action == :cim_store_delete_customer
825
+ 'deleteCustomerProfileRequest'
826
+ elsif action == :verify_credentials
827
+ 'authenticateTestRequest'
828
+ elsif is_cim_action?(action)
829
+ 'createCustomerProfileTransactionRequest'
830
+ else
831
+ 'createTransactionRequest'
537
832
  end
538
833
  end
539
834
 
540
- # Adds information about the interval of time between payments
541
- def add_arb_interval(xml, options)
542
- interval = options[:interval]
543
- return unless interval
544
- xml.tag!('interval') do
545
- # The measurement of time, in association with the Interval Unit,
546
- # that is used to define the frequency of the billing occurrences
547
- xml.tag!('length', interval[:length])
548
- # The unit of time, in association with the Interval Length,
549
- # between each billing occurrence
550
- xml.tag!('unit', interval[:unit].to_s)
551
- end
835
+ def add_authentication(xml)
836
+ xml.merchantAuthentication do
837
+ xml.name(@options[:login])
838
+ xml.transactionKey(@options[:password])
839
+ end
552
840
  end
553
841
 
554
- # Adds information about the subscription duration
555
- def add_arb_duration(xml, options)
556
- duration = options[:duration]
557
- return unless duration
558
- # The date the subscription begins
559
- # (also the date the initial billing occurs)
560
- xml.tag!('startDate', duration[:start_date]) if duration[:start_date]
561
- # Number of billing occurrences or payments for the subscription
562
- xml.tag!('totalOccurrences', duration[:occurrences]) if duration[:occurrences]
563
- end
564
-
565
- def add_arb_payment_schedule(xml, options)
566
- return unless options[:interval] || options[:duration]
567
- xml.tag!('paymentSchedule') do
568
- # Contains information about the interval of time between payments
569
- add_arb_interval(xml, options)
570
- add_arb_duration(xml, options)
571
- if trial = options[:trial]
572
- # Number of billing occurrences or payments in the trial period (optional)
573
- xml.tag!('trialOccurrences', trial[:occurrences]) if trial[:occurrences]
574
- end
575
- end
576
- end
577
-
578
- # Adds customer's credit card or bank account payment information
579
- def add_arb_payment(xml, options)
580
- return unless options[:credit_card] || options[:bank_account]
581
- xml.tag!('payment') do
582
- # Contains the customer’s credit card information
583
- add_arb_credit_card(xml, options)
584
- # Contains the customer’s bank account information
585
- add_arb_bank_account(xml, options)
586
- end
587
- end
588
-
589
- # Adds customer’s credit card information
590
- # Note: This element should only be included
591
- # when the payment method is credit card.
592
- def add_arb_credit_card(xml, options)
593
- credit_card = options[:credit_card]
594
- return unless credit_card
595
- xml.tag!('creditCard') do
596
- # The credit card number used for payment of the subscription
597
- xml.tag!('cardNumber', credit_card.number)
598
- # The expiration date of the credit card used for the subscription
599
- xml.tag!('expirationDate', arb_expdate(credit_card))
600
- end
601
- end
602
-
603
- # Adds customer’s bank account information
604
- # Note: This element should only be included
605
- # when the payment method is bank account.
606
- def add_arb_bank_account(xml, options)
607
- bank_account = options[:bank_account]
608
- return unless bank_account
609
- xml.tag!('bankAccount') do
610
- # The type of bank account used for payment of the subscription
611
- xml.tag!('accountType', bank_account[:account_type])
612
- # The routing number of the customer’s bank
613
- xml.tag!('routingNumber', bank_account[:routing_number])
614
- # The bank account number used for payment of the subscription
615
- xml.tag!('accountNumber', bank_account[:account_number])
616
- # The full name of the individual associated
617
- # with the bank account number
618
- xml.tag!('nameOfAccount', bank_account[:name_of_account])
619
- # The full name of the individual associated
620
- # with the bank account number (optional)
621
- xml.tag!('bankName', bank_account[:bank_name]) if bank_account[:bank_name]
622
- # The type of electronic check transaction used for the subscription
623
- xml.tag!('echeckType', bank_account[:echeck_type])
624
- end
625
- end
626
-
627
- # Adds order information (optional)
628
- def add_arb_order(xml, options)
629
- order = options[:order]
630
- return unless order
631
- xml.tag!('order') do
632
- # Merchant-assigned invoice number for the subscription (optional)
633
- xml.tag!('invoiceNumber', order[:invoice_number])
634
- # Description of the subscription (optional)
635
- xml.tag!('description', order[:description])
636
- end
637
- end
638
-
639
- # Adds information about the customer
640
- def add_arb_customer(xml, options)
641
- customer = options[:customer]
642
- return unless customer
643
- xml.tag!('customer') do
644
- xml.tag!('type', customer[:type]) if customer[:type]
645
- xml.tag!('id', customer[:id]) if customer[:id]
646
- xml.tag!('email', customer[:email]) if customer[:email]
647
- xml.tag!('phoneNumber', customer[:phone_number]) if customer[:phone_number]
648
- xml.tag!('faxNumber', customer[:fax_number]) if customer[:fax_number]
649
- add_arb_drivers_license(xml, options)
650
- xml.tag!('taxId', customer[:tax_id]) if customer[:tax_id]
651
- end
652
- end
653
-
654
- # Adds the customer's driver's license information (conditional)
655
- def add_arb_drivers_license(xml, options)
656
- return unless customer = options[:customer]
657
- return unless drivers_license = customer[:drivers_license]
658
- xml.tag!('driversLicense') do
659
- # The customer's driver's license number
660
- xml.tag!('number', drivers_license[:number])
661
- # The customer's driver's license state
662
- xml.tag!('state', drivers_license[:state])
663
- # The customer's driver's license date of birth
664
- xml.tag!('dateOfBirth', drivers_license[:date_of_birth])
665
- end
666
- end
667
-
668
- # Adds address information
669
- def add_arb_address(xml, container_name, address)
670
- return if address.blank?
671
- xml.tag!(container_name) do
672
- xml.tag!('firstName', address[:first_name])
673
- xml.tag!('lastName', address[:last_name])
674
- xml.tag!('company', address[:company])
675
- xml.tag!('address', address[:address1])
676
- xml.tag!('city', address[:city])
677
- xml.tag!('state', address[:state])
678
- xml.tag!('zip', address[:zip])
679
- xml.tag!('country', address[:country])
680
- end
681
- end
682
-
683
- def arb_expdate(credit_card)
684
- sprintf('%04d-%02d', credit_card.year, credit_card.month)
685
- end
686
-
687
- def recurring_commit(action, request)
688
- url = test? ? arb_test_url : arb_live_url
689
- xml = ssl_post(url, request, "Content-Type" => "text/xml")
690
-
691
- response = recurring_parse(action, xml)
692
-
693
- message = response[:message] || response[:text]
694
- test_mode = test? || message =~ /Test Mode/
695
- success = response[:result_code] == 'Ok'
696
-
697
- Response.new(success, message, response,
698
- :test => test_mode,
699
- :authorization => response[:subscription_id]
700
- )
701
- end
702
-
703
- def recurring_parse(action, xml)
842
+ def parse_normal(action, body)
843
+ doc = Nokogiri::XML(body)
844
+ doc.remove_namespaces!
845
+
846
+ response = {action: action}
847
+
848
+ response[:response_code] = if(element = doc.at_xpath('//transactionResponse/responseCode'))
849
+ (empty?(element.content) ? nil : element.content.to_i)
850
+ end
851
+
852
+ if(element = doc.at_xpath('//errors/error'))
853
+ response[:response_reason_code] = element.at_xpath('errorCode').content[/0*(\d+)$/, 1]
854
+ response[:response_reason_text] = element.at_xpath('errorText').content.chomp('.')
855
+ elsif(element = doc.at_xpath('//transactionResponse/messages/message'))
856
+ response[:response_reason_code] = element.at_xpath('code').content[/0*(\d+)$/, 1]
857
+ response[:response_reason_text] = element.at_xpath('description').content.chomp('.')
858
+ elsif(element = doc.at_xpath('//messages/message'))
859
+ response[:response_reason_code] = element.at_xpath('code').content[/0*(\d+)$/, 1]
860
+ response[:response_reason_text] = element.at_xpath('text').content.chomp('.')
861
+ else
862
+ response[:response_reason_code] = nil
863
+ response[:response_reason_text] = ''
864
+ end
865
+
866
+ response[:avs_result_code] = if(element = doc.at_xpath('//avsResultCode'))
867
+ (empty?(element.content) ? nil : element.content)
868
+ end
869
+
870
+ response[:transaction_id] = if(element = doc.at_xpath('//transId'))
871
+ (empty?(element.content) ? nil : element.content)
872
+ end
873
+
874
+ response[:card_code] = if(element = doc.at_xpath('//cvvResultCode'))
875
+ (empty?(element.content) ? nil : element.content)
876
+ end
877
+
878
+ response[:authorization_code] = if(element = doc.at_xpath('//authCode'))
879
+ (empty?(element.content) ? nil : element.content)
880
+ end
881
+
882
+ response[:cardholder_authentication_code] = if(element = doc.at_xpath('//cavvResultCode'))
883
+ (empty?(element.content) ? nil : element.content)
884
+ end
885
+
886
+ response[:account_number] = if(element = doc.at_xpath('//accountNumber'))
887
+ (empty?(element.content) ? nil : element.content[-4..-1])
888
+ end
889
+
890
+ response[:test_request] = if(element = doc.at_xpath('//testRequest'))
891
+ (empty?(element.content) ? nil : element.content)
892
+ end
893
+
894
+ response[:full_response_code] = if(element = doc.at_xpath('//messages/message/code'))
895
+ (empty?(element.content) ? nil : element.content)
896
+ end
897
+
898
+ response
899
+ end
900
+
901
+ def parse_cim(body, options)
704
902
  response = {}
705
- xml = REXML::Document.new(xml)
706
- root = REXML::XPath.first(xml, "//#{RECURRING_ACTIONS[action]}Response") ||
707
- REXML::XPath.first(xml, "//ErrorResponse")
708
- if root
709
- root.elements.to_a.each do |node|
710
- recurring_parse_element(response, node)
711
- end
903
+
904
+ doc = Nokogiri::XML(body).remove_namespaces!
905
+
906
+ if (element = doc.at_xpath('//messages/message'))
907
+ response[:message_code] = element.at_xpath('code').content[/0*(\d+)$/, 1]
908
+ response[:message_text] = element.at_xpath('text').content.chomp('.')
909
+ end
910
+
911
+ response[:result_code] = if(element = doc.at_xpath('//messages/resultCode'))
912
+ (empty?(element.content) ? nil : element.content)
913
+ end
914
+
915
+ response[:test_request] = if(element = doc.at_xpath('//testRequest'))
916
+ (empty?(element.content) ? nil : element.content)
917
+ end
918
+
919
+ response[:customer_profile_id] = if(element = doc.at_xpath('//customerProfileId'))
920
+ (empty?(element.content) ? nil : element.content)
712
921
  end
713
922
 
923
+ response[:customer_payment_profile_id] = if(element = doc.at_xpath('//customerPaymentProfileIdList/numericString'))
924
+ (empty?(element.content) ? nil : element.content)
925
+ end
926
+
927
+ response[:customer_payment_profile_id] = if(element = doc.at_xpath('//customerPaymentProfileIdList/numericString') ||
928
+ doc.at_xpath('//customerPaymentProfileId'))
929
+ (empty?(element.content) ? nil : element.content)
930
+ end
931
+
932
+ response[:direct_response] = if(element = doc.at_xpath('//directResponse'))
933
+ (empty?(element.content) ? nil : element.content)
934
+ end
935
+
936
+ response.merge!(parse_direct_response_elements(response, options))
937
+
714
938
  response
715
939
  end
716
940
 
717
- def recurring_parse_element(response, node)
718
- if node.has_elements?
719
- node.elements.each{|e| recurring_parse_element(response, e) }
941
+ def success_from(action, response)
942
+ if cim?(action) || (action == :verify_credentials)
943
+ response[:result_code] == 'Ok'
720
944
  else
721
- response[node.name.underscore.to_sym] = node.text
945
+ [APPROVED, FRAUD_REVIEW].include?(response[:response_code]) && TRANSACTION_ALREADY_ACTIONED.exclude?(response[:response_reason_code])
722
946
  end
723
947
  end
948
+
949
+ def message_from(action, response, avs_result, cvv_result)
950
+ if response[:response_code] == DECLINED
951
+ if CARD_CODE_ERRORS.include?(cvv_result.code)
952
+ return cvv_result.message
953
+ elsif(AVS_REASON_CODES.include?(response[:response_reason_code]) && AVS_ERRORS.include?(avs_result.code))
954
+ return avs_result.message
955
+ end
956
+ end
957
+
958
+ response[:response_reason_text] || response[:message_text]
959
+ end
960
+
961
+ def authorization_from(action, response)
962
+ if cim?(action)
963
+ [response[:customer_profile_id], response[:customer_payment_profile_id], action].join('#')
964
+ else
965
+ [response[:transaction_id], response[:account_number], action].join('#')
966
+ end
967
+ end
968
+
969
+ def split_authorization(authorization)
970
+ authorization.split('#')
971
+ end
972
+
973
+ def cim?(action)
974
+ (action == :cim_store) || (action == :cim_store_update) || (action == :cim_store_delete_customer)
975
+ end
976
+
977
+ def transaction_id_from(authorization)
978
+ transaction_id, _, _ = split_authorization(authorization)
979
+ transaction_id
980
+ end
981
+
982
+ def fraud_review?(response)
983
+ (response[:response_code] == FRAUD_REVIEW)
984
+ end
985
+
986
+ def using_live_gateway_in_test_mode?(response)
987
+ !test? && response[:test_request] == '1'
988
+ end
989
+
990
+ def map_error_code(response_code, response_reason_code)
991
+ STANDARD_ERROR_CODE_MAPPING["#{response_code}#{response_reason_code}"]
992
+ end
993
+
994
+ def auth_was_for_cim?(authorization)
995
+ _, _, action = split_authorization(authorization)
996
+ action && is_cim_action?(action)
997
+ end
998
+
999
+ def parse_direct_response_elements(response, options)
1000
+ params = response[:direct_response]
1001
+ return {} unless params
1002
+
1003
+ parts = params.split(options[:delimiter] || ',')
1004
+ {
1005
+ response_code: parts[0].to_i,
1006
+ response_subcode: parts[1],
1007
+ response_reason_code: parts[2],
1008
+ response_reason_text: parts[3],
1009
+ approval_code: parts[4],
1010
+ avs_result_code: parts[5],
1011
+ transaction_id: parts[6],
1012
+ invoice_number: parts[7],
1013
+ order_description: parts[8],
1014
+ amount: parts[9],
1015
+ method: parts[10],
1016
+ transaction_type: parts[11],
1017
+ customer_id: parts[12],
1018
+ first_name: parts[13],
1019
+ last_name: parts[14],
1020
+ company: parts[15],
1021
+ address: parts[16],
1022
+ city: parts[17],
1023
+ state: parts[18],
1024
+ zip_code: parts[19],
1025
+ country: parts[20],
1026
+ phone: parts[21],
1027
+ fax: parts[22],
1028
+ email_address: parts[23],
1029
+ ship_to_first_name: parts[24],
1030
+ ship_to_last_name: parts[25],
1031
+ ship_to_company: parts[26],
1032
+ ship_to_address: parts[27],
1033
+ ship_to_city: parts[28],
1034
+ ship_to_state: parts[29],
1035
+ ship_to_zip_code: parts[30],
1036
+ ship_to_country: parts[31],
1037
+ tax: parts[32],
1038
+ duty: parts[33],
1039
+ freight: parts[34],
1040
+ tax_exempt: parts[35],
1041
+ purchase_order_number: parts[36],
1042
+ md5_hash: parts[37],
1043
+ card_code: parts[38],
1044
+ cardholder_authentication_verification_response: parts[39],
1045
+ account_number: parts[50] || '',
1046
+ card_type: parts[51] || '',
1047
+ split_tender_id: parts[52] || '',
1048
+ requested_amount: parts[53] || '',
1049
+ balance_on_card: parts[54] || '',
1050
+ }
1051
+ end
1052
+
724
1053
  end
725
1054
  end
726
1055
  end