swiss-crm-activemerchant 1.0.12

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 (287) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +4033 -0
  3. data/CONTRIBUTORS +568 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +252 -0
  6. data/lib/active_merchant/billing/apple_pay_payment_token.rb +22 -0
  7. data/lib/active_merchant/billing/avs_result.rb +95 -0
  8. data/lib/active_merchant/billing/base.rb +48 -0
  9. data/lib/active_merchant/billing/check.rb +112 -0
  10. data/lib/active_merchant/billing/compatibility.rb +118 -0
  11. data/lib/active_merchant/billing/credit_card.rb +451 -0
  12. data/lib/active_merchant/billing/credit_card_formatting.rb +24 -0
  13. data/lib/active_merchant/billing/credit_card_methods.rb +512 -0
  14. data/lib/active_merchant/billing/cvv_result.rb +37 -0
  15. data/lib/active_merchant/billing/gateway.rb +332 -0
  16. data/lib/active_merchant/billing/gateways/adyen.rb +774 -0
  17. data/lib/active_merchant/billing/gateways/airwallex.rb +370 -0
  18. data/lib/active_merchant/billing/gateways/alelo.rb +256 -0
  19. data/lib/active_merchant/billing/gateways/allied_wallet.rb +205 -0
  20. data/lib/active_merchant/billing/gateways/authorize_net.rb +1125 -0
  21. data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +424 -0
  22. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +977 -0
  23. data/lib/active_merchant/billing/gateways/axcessms.rb +242 -0
  24. data/lib/active_merchant/billing/gateways/balanced.rb +263 -0
  25. data/lib/active_merchant/billing/gateways/bambora_apac.rb +222 -0
  26. data/lib/active_merchant/billing/gateways/bank_frick.rb +225 -0
  27. data/lib/active_merchant/billing/gateways/banwire.rb +116 -0
  28. data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +397 -0
  29. data/lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb +15 -0
  30. data/lib/active_merchant/billing/gateways/be2bill.rb +131 -0
  31. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +474 -0
  32. data/lib/active_merchant/billing/gateways/beanstream.rb +238 -0
  33. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +57 -0
  34. data/lib/active_merchant/billing/gateways/blue_pay.rb +549 -0
  35. data/lib/active_merchant/billing/gateways/blue_snap.rb +644 -0
  36. data/lib/active_merchant/billing/gateways/bogus.rb +190 -0
  37. data/lib/active_merchant/billing/gateways/borgun.rb +272 -0
  38. data/lib/active_merchant/billing/gateways/bpoint.rb +277 -0
  39. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +28 -0
  40. data/lib/active_merchant/billing/gateways/braintree/token_nonce.rb +113 -0
  41. data/lib/active_merchant/billing/gateways/braintree.rb +19 -0
  42. data/lib/active_merchant/billing/gateways/braintree_blue.rb +952 -0
  43. data/lib/active_merchant/billing/gateways/braintree_orange.rb +19 -0
  44. data/lib/active_merchant/billing/gateways/bridge_pay.rb +244 -0
  45. data/lib/active_merchant/billing/gateways/cams.rb +230 -0
  46. data/lib/active_merchant/billing/gateways/card_connect.rb +338 -0
  47. data/lib/active_merchant/billing/gateways/card_save.rb +21 -0
  48. data/lib/active_merchant/billing/gateways/card_stream.rb +394 -0
  49. data/lib/active_merchant/billing/gateways/cardknox.rb +327 -0
  50. data/lib/active_merchant/billing/gateways/cardprocess.rb +256 -0
  51. data/lib/active_merchant/billing/gateways/cashnet.rb +235 -0
  52. data/lib/active_merchant/billing/gateways/cc5.rb +198 -0
  53. data/lib/active_merchant/billing/gateways/cecabank.rb +249 -0
  54. data/lib/active_merchant/billing/gateways/cenpos.rb +328 -0
  55. data/lib/active_merchant/billing/gateways/checkout.rb +212 -0
  56. data/lib/active_merchant/billing/gateways/checkout_v2.rb +587 -0
  57. data/lib/active_merchant/billing/gateways/citrus_pay.rb +21 -0
  58. data/lib/active_merchant/billing/gateways/clearhaus.rb +219 -0
  59. data/lib/active_merchant/billing/gateways/commerce_hub.rb +366 -0
  60. data/lib/active_merchant/billing/gateways/commercegate.rb +142 -0
  61. data/lib/active_merchant/billing/gateways/conekta.rb +230 -0
  62. data/lib/active_merchant/billing/gateways/creditcall.rb +272 -0
  63. data/lib/active_merchant/billing/gateways/credorax.rb +526 -0
  64. data/lib/active_merchant/billing/gateways/ct_payment.rb +269 -0
  65. data/lib/active_merchant/billing/gateways/culqi.rb +279 -0
  66. data/lib/active_merchant/billing/gateways/cyber_source/cyber_source_common.rb +36 -0
  67. data/lib/active_merchant/billing/gateways/cyber_source.rb +1148 -0
  68. data/lib/active_merchant/billing/gateways/cyber_source_rest.rb +454 -0
  69. data/lib/active_merchant/billing/gateways/d_local.rb +343 -0
  70. data/lib/active_merchant/billing/gateways/data_cash.rb +302 -0
  71. data/lib/active_merchant/billing/gateways/decidir.rb +358 -0
  72. data/lib/active_merchant/billing/gateways/decidir_plus.rb +344 -0
  73. data/lib/active_merchant/billing/gateways/dibs.rb +199 -0
  74. data/lib/active_merchant/billing/gateways/digitzs.rb +295 -0
  75. data/lib/active_merchant/billing/gateways/ebanx.rb +346 -0
  76. data/lib/active_merchant/billing/gateways/efsnet.rb +215 -0
  77. data/lib/active_merchant/billing/gateways/elavon.rb +475 -0
  78. data/lib/active_merchant/billing/gateways/element.rb +406 -0
  79. data/lib/active_merchant/billing/gateways/epay.rb +296 -0
  80. data/lib/active_merchant/billing/gateways/evo_ca.rb +307 -0
  81. data/lib/active_merchant/billing/gateways/eway.rb +226 -0
  82. data/lib/active_merchant/billing/gateways/eway_managed.rb +289 -0
  83. data/lib/active_merchant/billing/gateways/eway_rapid.rb +578 -0
  84. data/lib/active_merchant/billing/gateways/exact.rb +219 -0
  85. data/lib/active_merchant/billing/gateways/ezic.rb +195 -0
  86. data/lib/active_merchant/billing/gateways/fat_zebra.rb +223 -0
  87. data/lib/active_merchant/billing/gateways/federated_canada.rb +158 -0
  88. data/lib/active_merchant/billing/gateways/finansbank.rb +22 -0
  89. data/lib/active_merchant/billing/gateways/first_giving.rb +143 -0
  90. data/lib/active_merchant/billing/gateways/first_pay.rb +182 -0
  91. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +452 -0
  92. data/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb +505 -0
  93. data/lib/active_merchant/billing/gateways/flo2cash.rb +215 -0
  94. data/lib/active_merchant/billing/gateways/flo2cash_simple.rb +20 -0
  95. data/lib/active_merchant/billing/gateways/fluidpay.rb +275 -0
  96. data/lib/active_merchant/billing/gateways/forte.rb +286 -0
  97. data/lib/active_merchant/billing/gateways/garanti.rb +256 -0
  98. data/lib/active_merchant/billing/gateways/global_collect.rb +580 -0
  99. data/lib/active_merchant/billing/gateways/global_transport.rb +193 -0
  100. data/lib/active_merchant/billing/gateways/hdfc.rb +205 -0
  101. data/lib/active_merchant/billing/gateways/hps.rb +472 -0
  102. data/lib/active_merchant/billing/gateways/iats_payments.rb +312 -0
  103. data/lib/active_merchant/billing/gateways/in_context_paypal_express.rb +15 -0
  104. data/lib/active_merchant/billing/gateways/inspire.rb +213 -0
  105. data/lib/active_merchant/billing/gateways/instapay.rb +159 -0
  106. data/lib/active_merchant/billing/gateways/ipg.rb +420 -0
  107. data/lib/active_merchant/billing/gateways/ipp.rb +176 -0
  108. data/lib/active_merchant/billing/gateways/iridium.rb +467 -0
  109. data/lib/active_merchant/billing/gateways/itransact.rb +448 -0
  110. data/lib/active_merchant/billing/gateways/iveri.rb +290 -0
  111. data/lib/active_merchant/billing/gateways/ixopay.rb +320 -0
  112. data/lib/active_merchant/billing/gateways/jetpay.rb +395 -0
  113. data/lib/active_merchant/billing/gateways/jetpay_v2.rb +432 -0
  114. data/lib/active_merchant/billing/gateways/klarna.rb +317 -0
  115. data/lib/active_merchant/billing/gateways/komoju.rb +115 -0
  116. data/lib/active_merchant/billing/gateways/kushki.rb +297 -0
  117. data/lib/active_merchant/billing/gateways/latitude19.rb +412 -0
  118. data/lib/active_merchant/billing/gateways/linkpoint.rb +448 -0
  119. data/lib/active_merchant/billing/gateways/litle.rb +643 -0
  120. data/lib/active_merchant/billing/gateways/mastercard.rb +286 -0
  121. data/lib/active_merchant/billing/gateways/maxipago.rb +220 -0
  122. data/lib/active_merchant/billing/gateways/mercado_pago.rb +348 -0
  123. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +228 -0
  124. data/lib/active_merchant/billing/gateways/merchant_one.rb +110 -0
  125. data/lib/active_merchant/billing/gateways/merchant_partners.rb +245 -0
  126. data/lib/active_merchant/billing/gateways/merchant_ware.rb +313 -0
  127. data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +284 -0
  128. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +248 -0
  129. data/lib/active_merchant/billing/gateways/mercury.rb +352 -0
  130. data/lib/active_merchant/billing/gateways/metrics_global.rb +293 -0
  131. data/lib/active_merchant/billing/gateways/micropayment.rb +182 -0
  132. data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +100 -0
  133. data/lib/active_merchant/billing/gateways/migs.rb +329 -0
  134. data/lib/active_merchant/billing/gateways/mit.rb +260 -0
  135. data/lib/active_merchant/billing/gateways/modern_payments.rb +37 -0
  136. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +215 -0
  137. data/lib/active_merchant/billing/gateways/moka.rb +290 -0
  138. data/lib/active_merchant/billing/gateways/monei.rb +424 -0
  139. data/lib/active_merchant/billing/gateways/moneris.rb +488 -0
  140. data/lib/active_merchant/billing/gateways/money_movers.rb +150 -0
  141. data/lib/active_merchant/billing/gateways/mundipagg.rb +366 -0
  142. data/lib/active_merchant/billing/gateways/nab_transact.rb +299 -0
  143. data/lib/active_merchant/billing/gateways/ncr_secure_pay.rb +163 -0
  144. data/lib/active_merchant/billing/gateways/net_registry.rb +198 -0
  145. data/lib/active_merchant/billing/gateways/netaxept.rb +180 -0
  146. data/lib/active_merchant/billing/gateways/netbanx.rb +376 -0
  147. data/lib/active_merchant/billing/gateways/netbilling.rb +229 -0
  148. data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
  149. data/lib/active_merchant/billing/gateways/network_merchants.rb +238 -0
  150. data/lib/active_merchant/billing/gateways/nmi.rb +396 -0
  151. data/lib/active_merchant/billing/gateways/ogone.rb +509 -0
  152. data/lib/active_merchant/billing/gateways/omise.rb +323 -0
  153. data/lib/active_merchant/billing/gateways/openpay.rb +246 -0
  154. data/lib/active_merchant/billing/gateways/opp.rb +394 -0
  155. data/lib/active_merchant/billing/gateways/optimal_payment.rb +331 -0
  156. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +45 -0
  157. data/lib/active_merchant/billing/gateways/orbital.rb +1267 -0
  158. data/lib/active_merchant/billing/gateways/pac_net_raven.rb +206 -0
  159. data/lib/active_merchant/billing/gateways/pagarme.rb +239 -0
  160. data/lib/active_merchant/billing/gateways/pago_facil.rb +120 -0
  161. data/lib/active_merchant/billing/gateways/pay_arc.rb +392 -0
  162. data/lib/active_merchant/billing/gateways/pay_conex.rb +245 -0
  163. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +277 -0
  164. data/lib/active_merchant/billing/gateways/pay_hub.rb +213 -0
  165. data/lib/active_merchant/billing/gateways/pay_junction.rb +390 -0
  166. data/lib/active_merchant/billing/gateways/pay_junction_v2.rb +206 -0
  167. data/lib/active_merchant/billing/gateways/pay_secure.rb +110 -0
  168. data/lib/active_merchant/billing/gateways/pay_trace.rb +450 -0
  169. data/lib/active_merchant/billing/gateways/paybox_direct.rb +224 -0
  170. data/lib/active_merchant/billing/gateways/payeezy.rb +513 -0
  171. data/lib/active_merchant/billing/gateways/payex.rb +409 -0
  172. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +235 -0
  173. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +42 -0
  174. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  175. data/lib/active_merchant/billing/gateways/payflow.rb +473 -0
  176. data/lib/active_merchant/billing/gateways/payflow_express.rb +220 -0
  177. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +14 -0
  178. data/lib/active_merchant/billing/gateways/payflow_uk.rb +20 -0
  179. data/lib/active_merchant/billing/gateways/payment_express.rb +373 -0
  180. data/lib/active_merchant/billing/gateways/paymentez.rb +365 -0
  181. data/lib/active_merchant/billing/gateways/paymill.rb +369 -0
  182. data/lib/active_merchant/billing/gateways/paynetworx.rb +228 -0
  183. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +718 -0
  184. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +69 -0
  185. data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +262 -0
  186. data/lib/active_merchant/billing/gateways/paypal.rb +136 -0
  187. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  188. data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +44 -0
  189. data/lib/active_merchant/billing/gateways/paypal_express.rb +272 -0
  190. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +30 -0
  191. data/lib/active_merchant/billing/gateways/paypal_standard.rb +281 -0
  192. data/lib/active_merchant/billing/gateways/paysafe.rb +420 -0
  193. data/lib/active_merchant/billing/gateways/payscout.rb +159 -0
  194. data/lib/active_merchant/billing/gateways/paystation.rb +204 -0
  195. data/lib/active_merchant/billing/gateways/payu_in.rb +249 -0
  196. data/lib/active_merchant/billing/gateways/payu_latam.rb +482 -0
  197. data/lib/active_merchant/billing/gateways/payway.rb +207 -0
  198. data/lib/active_merchant/billing/gateways/payway_dot_com.rb +253 -0
  199. data/lib/active_merchant/billing/gateways/pin.rb +273 -0
  200. data/lib/active_merchant/billing/gateways/pixxels.rb +263 -0
  201. data/lib/active_merchant/billing/gateways/plexo.rb +308 -0
  202. data/lib/active_merchant/billing/gateways/plugnpay.rb +283 -0
  203. data/lib/active_merchant/billing/gateways/priority.rb +392 -0
  204. data/lib/active_merchant/billing/gateways/pro_pay.rb +325 -0
  205. data/lib/active_merchant/billing/gateways/psigate.rb +227 -0
  206. data/lib/active_merchant/billing/gateways/psl_card.rb +295 -0
  207. data/lib/active_merchant/billing/gateways/qbms.rb +302 -0
  208. data/lib/active_merchant/billing/gateways/quantum.rb +274 -0
  209. data/lib/active_merchant/billing/gateways/quickbooks.rb +377 -0
  210. data/lib/active_merchant/billing/gateways/quickpay/quickpay_common.rb +184 -0
  211. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +297 -0
  212. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb +226 -0
  213. data/lib/active_merchant/billing/gateways/quickpay.rb +24 -0
  214. data/lib/active_merchant/billing/gateways/qvalent.rb +305 -0
  215. data/lib/active_merchant/billing/gateways/rapyd.rb +319 -0
  216. data/lib/active_merchant/billing/gateways/reach.rb +277 -0
  217. data/lib/active_merchant/billing/gateways/realex.rb +400 -0
  218. data/lib/active_merchant/billing/gateways/redsys.rb +723 -0
  219. data/lib/active_merchant/billing/gateways/s5.rb +247 -0
  220. data/lib/active_merchant/billing/gateways/safe_charge.rb +298 -0
  221. data/lib/active_merchant/billing/gateways/sage.rb +446 -0
  222. data/lib/active_merchant/billing/gateways/sage_pay.rb +434 -0
  223. data/lib/active_merchant/billing/gateways/sallie_mae.rb +141 -0
  224. data/lib/active_merchant/billing/gateways/secure_net.rb +260 -0
  225. data/lib/active_merchant/billing/gateways/secure_pay.rb +191 -0
  226. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +290 -0
  227. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +103 -0
  228. data/lib/active_merchant/billing/gateways/securion_pay.rb +305 -0
  229. data/lib/active_merchant/billing/gateways/shift4.rb +345 -0
  230. data/lib/active_merchant/billing/gateways/simetrik.rb +368 -0
  231. data/lib/active_merchant/billing/gateways/skip_jack.rb +450 -0
  232. data/lib/active_merchant/billing/gateways/smart_ps.rb +274 -0
  233. data/lib/active_merchant/billing/gateways/so_easy_pay.rb +194 -0
  234. data/lib/active_merchant/billing/gateways/spreedly_core.rb +354 -0
  235. data/lib/active_merchant/billing/gateways/stripe.rb +866 -0
  236. data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +602 -0
  237. data/lib/active_merchant/billing/gateways/swipe_checkout.rb +151 -0
  238. data/lib/active_merchant/billing/gateways/telr.rb +273 -0
  239. data/lib/active_merchant/billing/gateways/tns.rb +23 -0
  240. data/lib/active_merchant/billing/gateways/trans_first.rb +240 -0
  241. data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +612 -0
  242. data/lib/active_merchant/billing/gateways/transact_pro.rb +222 -0
  243. data/lib/active_merchant/billing/gateways/transax.rb +21 -0
  244. data/lib/active_merchant/billing/gateways/transnational.rb +9 -0
  245. data/lib/active_merchant/billing/gateways/trexle.rb +221 -0
  246. data/lib/active_merchant/billing/gateways/trust_commerce.rb +500 -0
  247. data/lib/active_merchant/billing/gateways/usa_epay.rb +24 -0
  248. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1612 -0
  249. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +367 -0
  250. data/lib/active_merchant/billing/gateways/vanco.rb +303 -0
  251. data/lib/active_merchant/billing/gateways/verifi.rb +224 -0
  252. data/lib/active_merchant/billing/gateways/viaklix.rb +171 -0
  253. data/lib/active_merchant/billing/gateways/visanet_peru.rb +250 -0
  254. data/lib/active_merchant/billing/gateways/vpos.rb +223 -0
  255. data/lib/active_merchant/billing/gateways/webpay.rb +97 -0
  256. data/lib/active_merchant/billing/gateways/wepay.rb +235 -0
  257. data/lib/active_merchant/billing/gateways/wirecard.rb +430 -0
  258. data/lib/active_merchant/billing/gateways/wompi.rb +197 -0
  259. data/lib/active_merchant/billing/gateways/world_net.rb +345 -0
  260. data/lib/active_merchant/billing/gateways/worldpay.rb +1050 -0
  261. data/lib/active_merchant/billing/gateways/worldpay_online_payments.rb +208 -0
  262. data/lib/active_merchant/billing/gateways/worldpay_us.rb +221 -0
  263. data/lib/active_merchant/billing/gateways.rb +14 -0
  264. data/lib/active_merchant/billing/model.rb +30 -0
  265. data/lib/active_merchant/billing/network_tokenization_credit_card.rb +39 -0
  266. data/lib/active_merchant/billing/payment_token.rb +21 -0
  267. data/lib/active_merchant/billing/rails.rb +3 -0
  268. data/lib/active_merchant/billing/response.rb +121 -0
  269. data/lib/active_merchant/billing/three_d_secure_eci_mapper.rb +27 -0
  270. data/lib/active_merchant/billing.rb +16 -0
  271. data/lib/active_merchant/connection.rb +194 -0
  272. data/lib/active_merchant/country.rb +338 -0
  273. data/lib/active_merchant/empty.rb +20 -0
  274. data/lib/active_merchant/errors.rb +38 -0
  275. data/lib/active_merchant/net_http_ssl_connection.rb +11 -0
  276. data/lib/active_merchant/network_connection_retries.rb +78 -0
  277. data/lib/active_merchant/post_data.rb +26 -0
  278. data/lib/active_merchant/posts_data.rb +92 -0
  279. data/lib/active_merchant/version.rb +3 -0
  280. data/lib/active_merchant.rb +63 -0
  281. data/lib/activemerchant.rb +1 -0
  282. data/lib/certs/cacert.pem +3214 -0
  283. data/lib/support/gateway_support.rb +69 -0
  284. data/lib/support/outbound_hosts.rb +28 -0
  285. data/lib/support/ssl_verify.rb +88 -0
  286. data/lib/support/ssl_version.rb +86 -0
  287. metadata +506 -0
@@ -0,0 +1,274 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ # ActiveMerchant Implementation for Quantum Gateway XML Requester Service
4
+ # Based on API Doc from 8/6/2009
5
+ #
6
+ # Important Notes
7
+ # * Support is included for a customer id via the :customer option, invoice number via :invoice option, invoice description via :merchant option and memo via :description option
8
+ # * You can force email of receipt with :email_receipt => true
9
+ # * You can force email of merchant receipt with :merchant_receipt => true
10
+ # * You can exclude CVV with :ignore_cvv => true
11
+ # * All transactions use dollar values.
12
+ class QuantumGateway < Gateway
13
+ self.live_url = self.test_url = 'https://secure.quantumgateway.com/cgi/xml_requester.php'
14
+
15
+ # visa, master, american_express, discover
16
+ self.supported_cardtypes = %i[visa master american_express discover]
17
+ self.supported_countries = ['US']
18
+ self.default_currency = 'USD'
19
+ self.money_format = :dollars
20
+ self.homepage_url = 'http://www.quantumgateway.com'
21
+ self.display_name = 'Quantum Gateway'
22
+
23
+ # These are the options that can be used when creating a new Quantum Gateway object.
24
+ #
25
+ # :login => Your Quantum Gateway Gateway ID
26
+ #
27
+ # :password => Your Quantum Gateway Vault Key or Restrict Key
28
+ #
29
+ # NOTE: For testing supply your test GatewayLogin and GatewayKey
30
+ #
31
+ # :email_receipt => true if you want a receipt sent to the customer (false be default)
32
+ #
33
+ # :merchant_receipt => true if you want to override receiving the merchant receipt
34
+ #
35
+ # :ignore_avs => true ignore both AVS and CVV verification
36
+ # :ignore_cvv => true don't want to use CVV so continue processing even if CVV would have failed
37
+ #
38
+ def initialize(options = {})
39
+ requires!(options, :login, :password)
40
+ super
41
+ end
42
+
43
+ # Request an authorization for an amount from CyberSource
44
+ #
45
+ def authorize(money, creditcard, options = {})
46
+ setup_address_hash(options)
47
+ commit(build_auth_request(money, creditcard, options), options)
48
+ end
49
+
50
+ # Capture an authorization that has previously been requested
51
+ def capture(money, authorization, options = {})
52
+ setup_address_hash(options)
53
+ commit(build_capture_request(money, authorization, options), options)
54
+ end
55
+
56
+ # Purchase is an auth followed by a capture
57
+ # You must supply an order_id in the options hash
58
+ def purchase(money, creditcard, options = {})
59
+ setup_address_hash(options)
60
+ commit(build_purchase_request(money, creditcard, options), options)
61
+ end
62
+
63
+ def void(identification, options = {})
64
+ commit(build_void_request(identification, options), options)
65
+ end
66
+
67
+ def refund(money, identification, options = {})
68
+ commit(build_credit_request(money, identification, options), options)
69
+ end
70
+
71
+ def credit(money, identification, options = {})
72
+ ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
73
+ refund(money, identification, options)
74
+ end
75
+
76
+ private
77
+
78
+ def setup_address_hash(options)
79
+ options[:billing_address] = options[:billing_address] || options[:address] || {}
80
+ end
81
+
82
+ def build_auth_request(money, creditcard, options)
83
+ xml = Builder::XmlMarkup.new
84
+ add_common_credit_card_info(xml, 'AUTH_ONLY')
85
+ add_purchase_data(xml, money)
86
+ add_creditcard(xml, creditcard)
87
+ add_address(xml, creditcard, options[:billing_address], options)
88
+ add_invoice_details(xml, options)
89
+ add_customer_details(xml, options)
90
+ add_memo(xml, options)
91
+ add_business_rules_data(xml)
92
+ xml.target!
93
+ end
94
+
95
+ def build_capture_request(money, authorization, options)
96
+ xml = Builder::XmlMarkup.new
97
+ add_common_credit_card_info(xml, 'PREVIOUS_SALE')
98
+ transaction_id, = authorization_parts_from(authorization)
99
+ add_transaction_id(xml, transaction_id)
100
+ xml.target!
101
+ end
102
+
103
+ def build_purchase_request(money, creditcard, options)
104
+ xml = Builder::XmlMarkup.new
105
+ add_common_credit_card_info(xml, @options[:ignore_avs] || @options[:ignore_cvv] ? 'SALES' : 'AUTH_CAPTURE')
106
+ add_address(xml, creditcard, options[:billing_address], options)
107
+ add_purchase_data(xml, money)
108
+ add_creditcard(xml, creditcard)
109
+ add_invoice_details(xml, options)
110
+ add_customer_details(xml, options)
111
+ add_memo(xml, options)
112
+ add_business_rules_data(xml)
113
+ xml.target!
114
+ end
115
+
116
+ def build_void_request(authorization, options)
117
+ xml = Builder::XmlMarkup.new
118
+ add_common_credit_card_info(xml, 'VOID')
119
+ transaction_id, = authorization_parts_from(authorization)
120
+ add_transaction_id(xml, transaction_id)
121
+ xml.target!
122
+ end
123
+
124
+ def build_credit_request(money, authorization, options)
125
+ xml = Builder::XmlMarkup.new
126
+ add_common_credit_card_info(xml, 'RETURN')
127
+ add_purchase_data(xml, money)
128
+ transaction_id, cc = authorization_parts_from(authorization)
129
+ add_transaction_id(xml, transaction_id)
130
+ xml.tag! 'CreditCardNumber', cc
131
+ xml.target!
132
+ end
133
+
134
+ def add_common_credit_card_info(xml, process_type)
135
+ xml.tag! 'RequestType', 'ProcessSingleTransaction'
136
+ xml.tag! 'TransactionType', 'CREDIT'
137
+ xml.tag! 'PaymentType', 'CC'
138
+ xml.tag! 'ProcessType', process_type
139
+ end
140
+
141
+ def add_business_rules_data(xml)
142
+ xml.tag!('CustomerEmail', @options[:email_receipt] ? 'Y' : 'N')
143
+ xml.tag!('MerchantEmail', @options[:merchant_receipt] ? 'Y' : 'N')
144
+ end
145
+
146
+ def add_invoice_details(xml, options)
147
+ xml.tag! 'InvoiceNumber', options[:invoice]
148
+ xml.tag! 'InvoiceDescription', options[:merchant]
149
+ end
150
+
151
+ def add_customer_details(xml, options)
152
+ xml.tag! 'CustomerID', options[:customer]
153
+ end
154
+
155
+ def add_transaction_id(xml, transaction_id)
156
+ xml.tag! 'TransactionID', transaction_id
157
+ end
158
+
159
+ def add_memo(xml, options)
160
+ xml.tag! 'Memo', options[:description]
161
+ end
162
+
163
+ def add_purchase_data(xml, money = 0)
164
+ xml.tag! 'Amount', amount(money)
165
+ xml.tag! 'TransactionDate', Time.now
166
+ end
167
+
168
+ def add_address(xml, creditcard, address, options, shipTo = false)
169
+ xml.tag! 'FirstName', creditcard.first_name
170
+ xml.tag! 'LastName', creditcard.last_name
171
+ xml.tag! 'Address', address[:address1] # => there is no support for address2 in quantum
172
+ xml.tag! 'City', address[:city]
173
+ xml.tag! 'State', address[:state]
174
+ xml.tag! 'ZipCode', address[:zip]
175
+ xml.tag! 'Country', address[:country]
176
+ xml.tag! 'EmailAddress', options[:email]
177
+ xml.tag! 'IPAddress', options[:ip]
178
+ end
179
+
180
+ def add_creditcard(xml, creditcard)
181
+ xml.tag! 'PaymentType', 'CC'
182
+ xml.tag! 'CreditCardNumber', creditcard.number
183
+ xml.tag! 'ExpireMonth', format(creditcard.month, :two_digits)
184
+ xml.tag! 'ExpireYear', format(creditcard.year, :four_digits)
185
+ xml.tag!('CVV2', creditcard.verification_value) unless @options[:ignore_cvv] || creditcard.verification_value.blank?
186
+ end
187
+
188
+ # Where we actually build the full SOAP request using builder
189
+ def build_request(body, options)
190
+ xml = Builder::XmlMarkup.new
191
+ xml.instruct!
192
+ xml.tag! 'QGWRequest' do
193
+ xml.tag! 'Authentication' do
194
+ xml.tag! 'GatewayLogin', @options[:login]
195
+ xml.tag! 'GatewayKey', @options[:password]
196
+ end
197
+ xml.tag! 'Request' do
198
+ xml << body
199
+ end
200
+ end
201
+ xml.target!
202
+ end
203
+
204
+ # Contact CyberSource, make the SOAP request, and parse the reply into a Response object
205
+ def commit(request, options)
206
+ headers = { 'Content-Type' => 'text/xml' }
207
+ response = parse(ssl_post(self.live_url, build_request(request, options), headers))
208
+
209
+ success = response[:request_status] == 'Success'
210
+ message = response[:request_message]
211
+
212
+ if success # => checking for connectivity success first
213
+ success = %w(APPROVED FORCED VOIDED).include?(response[:Status])
214
+ message = response[:StatusDescription]
215
+ authorization = success ? authorization_for(response) : nil
216
+ end
217
+
218
+ Response.new(success, message, response,
219
+ test: test?,
220
+ authorization: authorization,
221
+ avs_result: { code: response[:AVSResponseCode] },
222
+ cvv_result: response[:CVV2ResponseCode])
223
+ end
224
+
225
+ # Parse the SOAP response
226
+ # Technique inspired by the Paypal Gateway
227
+ def parse(xml)
228
+ reply = {}
229
+
230
+ begin
231
+ xml = REXML::Document.new(xml)
232
+
233
+ root = REXML::XPath.first(xml, '//QGWRequest/ResponseSummary')
234
+ parse_element(reply, root)
235
+ reply[:request_status] = reply[:Status]
236
+ reply[:request_message] = "#{reply[:Status]}: #{reply[:StatusDescription]}"
237
+
238
+ if root = REXML::XPath.first(xml, '//QGWRequest/Result')
239
+ root.elements.to_a.each do |node|
240
+ parse_element(reply, node)
241
+ end
242
+ end
243
+ rescue Exception
244
+ reply[:request_status] = 'Failure'
245
+ reply[:request_message] = 'Failure: There was a problem parsing the response XML'
246
+ end
247
+
248
+ return reply
249
+ end
250
+
251
+ def parse_element(reply, node)
252
+ if node.has_elements?
253
+ node.elements.each { |e| parse_element(reply, e) }
254
+ else
255
+ if /item/.match?(node.parent.name)
256
+ parent = node.parent.name + (node.parent.attributes['id'] ? '_' + node.parent.attributes['id'] : '')
257
+ reply[(parent + '_' + node.name).to_sym] = node.text
258
+ else
259
+ reply[node.name.to_sym] = node.text
260
+ end
261
+ end
262
+ return reply
263
+ end
264
+
265
+ def authorization_for(reply)
266
+ "#{reply[:TransactionID]};#{reply[:CreditCardNumber]}"
267
+ end
268
+
269
+ def authorization_parts_from(authorization)
270
+ authorization.split(/;/)
271
+ end
272
+ end
273
+ end
274
+ end
@@ -0,0 +1,377 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class QuickbooksGateway < Gateway
4
+ self.test_url = 'https://sandbox.api.intuit.com'
5
+ self.live_url = 'https://api.intuit.com'
6
+
7
+ self.supported_countries = ['US']
8
+ self.default_currency = 'USD'
9
+ self.supported_cardtypes = %i[visa master american_express discover diners]
10
+
11
+ self.homepage_url = 'http://payments.intuit.com'
12
+ self.display_name = 'QuickBooks Payments'
13
+ BASE = '/quickbooks/v4/payments'
14
+ ENDPOINT = "#{BASE}/charges"
15
+ VOID_ENDPOINT = "#{BASE}/txn-requests"
16
+ REFRESH_URI = 'https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer'
17
+
18
+ # https://developer.intuit.com/docs/0150_payments/0300_developer_guides/error_handling
19
+
20
+ STANDARD_ERROR_CODE_MAPPING = {
21
+ # Fraud Warnings
22
+ 'PMT-1000' => STANDARD_ERROR_CODE[:processing_error], # payment was accepted, but refund was unsuccessful
23
+ 'PMT-1001' => STANDARD_ERROR_CODE[:invalid_cvc], # payment processed, but cvc was invalid
24
+ 'PMT-1002' => STANDARD_ERROR_CODE[:incorrect_address], # payment processed, incorrect address info
25
+ 'PMT-1003' => STANDARD_ERROR_CODE[:processing_error], # payment processed, address info couldn't be validated
26
+
27
+ # Fraud Errors
28
+ 'PMT-2000' => STANDARD_ERROR_CODE[:incorrect_cvc], # Incorrect CVC
29
+ 'PMT-2001' => STANDARD_ERROR_CODE[:invalid_cvc], # CVC check unavaliable
30
+ 'PMT-2002' => STANDARD_ERROR_CODE[:incorrect_address], # Incorrect address
31
+ 'PMT-2003' => STANDARD_ERROR_CODE[:incorrect_address], # Address info unavailable
32
+
33
+ 'PMT-3000' => STANDARD_ERROR_CODE[:processing_error], # Merchant account could not be validated
34
+
35
+ # Invalid Request
36
+ 'PMT-4000' => STANDARD_ERROR_CODE[:processing_error], # Object is invalid
37
+ 'PMT-4001' => STANDARD_ERROR_CODE[:processing_error], # Object not found
38
+ 'PMT-4002' => STANDARD_ERROR_CODE[:processing_error], # Object is required
39
+
40
+ # Transaction Declined
41
+ 'PMT-5000' => STANDARD_ERROR_CODE[:card_declined], # Request was declined
42
+ 'PMT-5001' => STANDARD_ERROR_CODE[:card_declined], # Merchant does not support given payment method
43
+
44
+ # System Error
45
+ 'PMT-6000' => STANDARD_ERROR_CODE[:processing_error], # A temporary Issue prevented this request from being processed.
46
+ }
47
+
48
+ FRAUD_WARNING_CODES = ['PMT-1000', 'PMT-1001', 'PMT-1002', 'PMT-1003']
49
+
50
+ def initialize(options = {})
51
+ # Quickbooks is deprecating OAuth 1.0 on December 17, 2019.
52
+ # OAuth 2.0 requires a client_id, client_secret, access_token, and refresh_token
53
+ # To maintain backwards compatibility, check for the presence of a refresh_token (only specified for OAuth 2.0)
54
+ # When present, validate that all OAuth 2.0 options are present
55
+ if options[:refresh_token]
56
+ requires!(options, :client_id, :client_secret, :access_token, :refresh_token)
57
+ else
58
+ requires!(options, :consumer_key, :consumer_secret, :access_token, :token_secret, :realm)
59
+ end
60
+ @options = options
61
+ super
62
+ end
63
+
64
+ def purchase(money, payment, options = {})
65
+ post = {}
66
+ add_amount(post, money, options)
67
+ add_charge_data(post, payment, options)
68
+ post[:capture] = 'true'
69
+
70
+ response = commit(ENDPOINT, post)
71
+ check_token_response(response, ENDPOINT, post, options)
72
+ end
73
+
74
+ def authorize(money, payment, options = {})
75
+ post = {}
76
+ add_amount(post, money, options)
77
+ add_charge_data(post, payment, options)
78
+ post[:capture] = 'false'
79
+
80
+ response = commit(ENDPOINT, post)
81
+ check_token_response(response, ENDPOINT, post, options)
82
+ end
83
+
84
+ def capture(money, authorization, options = {})
85
+ post = {}
86
+ authorization, = split_authorization(authorization)
87
+ post[:amount] = localized_amount(money, currency(money))
88
+ add_context(post, options)
89
+
90
+ response = commit(capture_uri(authorization), post)
91
+ check_token_response(response, capture_uri(authorization), post, options)
92
+ end
93
+
94
+ def refund(money, authorization, options = {})
95
+ post = {}
96
+ post[:amount] = localized_amount(money, currency(money))
97
+ add_context(post, options)
98
+ authorization, = split_authorization(authorization)
99
+
100
+ response = commit(refund_uri(authorization), post)
101
+ check_token_response(response, refund_uri(authorization), post, options)
102
+ end
103
+
104
+ def void(authorization, options = {})
105
+ _, request_id = split_authorization(authorization)
106
+
107
+ response = commit(void_uri(request_id))
108
+ check_token_response(response, void_uri(request_id), {}, options)
109
+ end
110
+
111
+ def verify(credit_card, options = {})
112
+ authorize(1.00, credit_card, options)
113
+ end
114
+
115
+ def refresh
116
+ response = refresh_access_token
117
+ response_object(response)
118
+ end
119
+
120
+ def supports_scrubbing?
121
+ true
122
+ end
123
+
124
+ def scrub(transcript)
125
+ transcript.
126
+ gsub(%r((realm=\")\w+), '\1[FILTERED]').
127
+ gsub(%r((oauth_consumer_key=\")\w+), '\1[FILTERED]').
128
+ gsub(%r((oauth_nonce=\")\w+), '\1[FILTERED]').
129
+ gsub(%r((oauth_signature=\")[a-zA-Z%0-9]+), '\1[FILTERED]').
130
+ gsub(%r((oauth_token=\")\w+), '\1[FILTERED]').
131
+ gsub(%r((number\D+)\d{16}), '\1[FILTERED]').
132
+ gsub(%r((cvc\D+)\d{3}), '\1[FILTERED]').
133
+ gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]').
134
+ gsub(%r((access_token\\?":\\?")[\w\-\.]+)i, '\1[FILTERED]').
135
+ gsub(%r((refresh_token\\?":\\?")\w+), '\1[FILTERED]').
136
+ gsub(%r((refresh_token=)\w+), '\1[FILTERED]').
137
+ gsub(%r((Authorization: Bearer )[\w\-\.]+)i, '\1[FILTERED]\2')
138
+ end
139
+
140
+ private
141
+
142
+ def add_charge_data(post, payment, options = {})
143
+ add_payment(post, payment, options)
144
+ add_address(post, options)
145
+ end
146
+
147
+ def add_address(post, options)
148
+ return unless post[:card]&.kind_of?(Hash)
149
+
150
+ card_address = {}
151
+ if address = options[:billing_address] || options[:address]
152
+ card_address[:streetAddress] = address[:address1]
153
+ card_address[:city] = address[:city]
154
+ region = address[:state] || address[:region]
155
+ card_address[:region] = region if region.present?
156
+ card_address[:country] = address[:country] if address[:country].present?
157
+ card_address[:postalCode] = address[:zip] if address[:zip]
158
+ end
159
+ post[:card][:address] = card_address
160
+ end
161
+
162
+ def add_amount(post, money, options = {})
163
+ currency = options[:currency] || currency(money)
164
+ post[:amount] = localized_amount(money, currency)
165
+ post[:currency] = currency.upcase
166
+ end
167
+
168
+ def add_payment(post, payment, options = {})
169
+ add_creditcard(post, payment, options)
170
+ add_context(post, options)
171
+ end
172
+
173
+ def add_creditcard(post, creditcard, options = {})
174
+ card = {}
175
+ card[:number] = creditcard.number
176
+ card[:expMonth] = '%02d' % creditcard.month
177
+ card[:expYear] = creditcard.year
178
+ card[:cvc] = creditcard.verification_value if creditcard.verification_value?
179
+ card[:name] = creditcard.name if creditcard.name
180
+ card[:commercialCardCode] = options[:card_code] if options[:card_code]
181
+
182
+ post[:card] = card
183
+ end
184
+
185
+ def add_context(post, options = {})
186
+ post[:context] = {
187
+ mobile: options.fetch(:mobile, false),
188
+ isEcommerce: options.fetch(:ecommerce, true)
189
+ }
190
+ end
191
+
192
+ def parse(body)
193
+ JSON.parse(body)
194
+ end
195
+
196
+ def commit(uri, body = {}, method = :post)
197
+ endpoint = gateway_url + uri
198
+ # The QuickBooks API returns HTTP 4xx on failed transactions, which causes a
199
+ # ResponseError raise, so we have to inspect the response and discern between
200
+ # a legitimate HTTP error and an actual gateway transactional error.
201
+ headers = {}
202
+ response =
203
+ begin
204
+ headers = headers(method, endpoint)
205
+ method == :post ? ssl_post(endpoint, post_data(body), headers) : ssl_request(:get, endpoint, nil, headers)
206
+ rescue ResponseError => e
207
+ extract_response_body_or_raise(e)
208
+ end
209
+
210
+ response_object(response, headers)
211
+ end
212
+
213
+ def response_object(raw_response, headers = {})
214
+ parsed_response = parse(raw_response)
215
+
216
+ # Include access_token and refresh_token in params for OAuth 2.0
217
+ parsed_response['access_token'] = @options[:access_token] if @options[:refresh_token]
218
+ parsed_response['refresh_token'] = @options[:refresh_token] if @options[:refresh_token]
219
+
220
+ Response.new(
221
+ success?(parsed_response),
222
+ message_from(parsed_response),
223
+ parsed_response,
224
+ authorization: authorization_from(parsed_response, headers),
225
+ test: test?,
226
+ cvv_result: cvv_code_from(parsed_response),
227
+ error_code: errors_from(parsed_response),
228
+ fraud_review: fraud_review_status_from(parsed_response)
229
+ )
230
+ end
231
+
232
+ def gateway_url
233
+ test? ? test_url : live_url
234
+ end
235
+
236
+ def post_data(data = {})
237
+ data.to_json
238
+ end
239
+
240
+ def headers(method, uri)
241
+ return oauth_v2_headers if @options[:refresh_token]
242
+
243
+ raise ArgumentError, "Invalid HTTP method: #{method}. Valid methods are :post and :get" unless %i[post get].include?(method)
244
+
245
+ request_uri = URI.parse(uri)
246
+
247
+ # Following the guidelines from http://nouncer.com/oauth/authentication.html
248
+ oauth_parameters = {
249
+ oauth_nonce: generate_unique_id,
250
+ oauth_timestamp: Time.now.to_i.to_s,
251
+ oauth_signature_method: 'HMAC-SHA1',
252
+ oauth_version: '1.0',
253
+ oauth_consumer_key: @options[:consumer_key],
254
+ oauth_token: @options[:access_token]
255
+ }
256
+
257
+ # prepare components for signature
258
+ oauth_signature_base_string = [method.to_s.upcase, request_uri.to_s, oauth_parameters.to_param].map { |v| CGI.escape(v) }.join('&')
259
+ oauth_signing_key = [@options[:consumer_secret], @options[:token_secret]].map { |v| CGI.escape(v) }.join('&')
260
+ hmac_signature = OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha1'), oauth_signing_key, oauth_signature_base_string)
261
+
262
+ # append signature to required OAuth parameters
263
+ oauth_parameters[:oauth_signature] = CGI.escape(Base64.encode64(hmac_signature).chomp.delete("\n"))
264
+
265
+ # prepare Authorization header string
266
+ oauth_parameters = Hash[oauth_parameters.sort_by { |k, _| k }]
267
+ oauth_headers = ["OAuth realm=\"#{@options[:realm]}\""]
268
+ oauth_headers += oauth_parameters.map { |k, v| "#{k}=\"#{v}\"" }
269
+
270
+ {
271
+ 'Content-type' => 'application/json',
272
+ 'Request-Id' => generate_unique_id,
273
+ 'Authorization' => oauth_headers.join(', ')
274
+ }
275
+ end
276
+
277
+ def oauth_v2_headers
278
+ {
279
+ 'Content-Type' => 'application/json',
280
+ 'Request-Id' => generate_unique_id,
281
+ 'Accept' => 'application/json',
282
+ 'Authorization' => "Bearer #{@options[:access_token]}"
283
+ }
284
+ end
285
+
286
+ def check_token_response(response, endpoint, body = {}, options = {})
287
+ return response unless @options[:refresh_token]
288
+ return response unless options[:allow_refresh]
289
+ return response unless response.params['code'] == 'AuthenticationFailed'
290
+
291
+ refresh_access_token
292
+ commit(endpoint, body)
293
+ end
294
+
295
+ def refresh_access_token
296
+ post = {}
297
+ post[:grant_type] = 'refresh_token'
298
+ post[:refresh_token] = @options[:refresh_token]
299
+ data = post.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join('&')
300
+
301
+ basic_auth = Base64.strict_encode64("#{@options[:client_id]}:#{@options[:client_secret]}")
302
+ headers = {
303
+ 'Content-Type' => 'application/x-www-form-urlencoded',
304
+ 'Accept' => 'application/json',
305
+ 'Authorization' => "Basic #{basic_auth}"
306
+ }
307
+
308
+ response = ssl_post(REFRESH_URI, data, headers)
309
+ json_response = JSON.parse(response)
310
+
311
+ @options[:access_token] = json_response['access_token'] if json_response['access_token']
312
+ @options[:refresh_token] = json_response['refresh_token'] if json_response['refresh_token']
313
+ response
314
+ end
315
+
316
+ def cvv_code_from(response)
317
+ if response['errors'].present?
318
+ FRAUD_WARNING_CODES.include?(response['errors'].first['code']) ? 'I' : ''
319
+ else
320
+ success?(response) ? 'M' : ''
321
+ end
322
+ end
323
+
324
+ def success?(response)
325
+ return FRAUD_WARNING_CODES.concat(['0']).include?(response['errors'].first['code']) if response['errors']
326
+
327
+ !%w[DECLINED CANCELLED].include?(response['status']) && !%w[AuthenticationFailed AuthorizationFailed].include?(response['code'])
328
+ end
329
+
330
+ def message_from(response)
331
+ response['errors'].present? ? response['errors'].map { |error_hash| error_hash['message'] }.join(' ') : response['status']
332
+ end
333
+
334
+ def errors_from(response)
335
+ if %w[AuthenticationFailed AuthorizationFailed].include?(response['code'])
336
+ response['code']
337
+ else
338
+ response['errors'].present? ? STANDARD_ERROR_CODE_MAPPING[response['errors'].first['code']] : ''
339
+ end
340
+ end
341
+
342
+ def authorization_from(response, headers = {})
343
+ [response['id'], headers['Request-Id']].join('|')
344
+ end
345
+
346
+ def split_authorization(authorization)
347
+ authorization, request_id = authorization.split('|')
348
+ [authorization, request_id]
349
+ end
350
+
351
+ def fraud_review_status_from(response)
352
+ response['errors'] && FRAUD_WARNING_CODES.include?(response['errors'].first['code'])
353
+ end
354
+
355
+ def extract_response_body_or_raise(response_error)
356
+ begin
357
+ parse(response_error.response.body)
358
+ rescue JSON::ParserError
359
+ raise response_error
360
+ end
361
+ response_error.response.body
362
+ end
363
+
364
+ def refund_uri(authorization)
365
+ "#{ENDPOINT}/#{CGI.escape(authorization.to_s)}/refunds"
366
+ end
367
+
368
+ def capture_uri(authorization)
369
+ "#{ENDPOINT}/#{CGI.escape(authorization.to_s)}/capture"
370
+ end
371
+
372
+ def void_uri(request_id)
373
+ "#{VOID_ENDPOINT}/#{CGI.escape(request_id.to_s)}/void"
374
+ end
375
+ end
376
+ end
377
+ end