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,866 @@
1
+ require 'active_support/core_ext/hash/slice'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ # This gateway uses an older version of the Stripe API.
6
+ # To utilize the updated {Payment Intents API}[https://stripe.com/docs/api/payment_intents], integrate with the StripePaymentIntents gateway
7
+ class StripeGateway < Gateway
8
+ self.live_url = 'https://api.stripe.com/v1/'
9
+
10
+ AVS_CODE_TRANSLATOR = {
11
+ 'line1: pass, zip: pass' => 'Y',
12
+ 'line1: pass, zip: fail' => 'A',
13
+ 'line1: pass, zip: unchecked' => 'B',
14
+ 'line1: fail, zip: pass' => 'Z',
15
+ 'line1: fail, zip: fail' => 'N',
16
+ 'line1: unchecked, zip: pass' => 'P',
17
+ 'line1: unchecked, zip: unchecked' => 'I'
18
+ }
19
+
20
+ CVC_CODE_TRANSLATOR = {
21
+ 'pass' => 'M',
22
+ 'fail' => 'N',
23
+ 'unchecked' => 'P'
24
+ }
25
+
26
+ DEFAULT_API_VERSION = '2020-08-27'
27
+
28
+ self.supported_countries = %w(AE AT AU BE BG BR CA CH CY CZ DE DK EE ES FI FR GB GR HK HU IE IN IT JP LT LU LV MT MX MY NL NO NZ PL PT RO SE SG SI SK US)
29
+ self.default_currency = 'USD'
30
+ self.money_format = :cents
31
+ self.supported_cardtypes = %i[visa master american_express discover jcb diners_club maestro unionpay]
32
+ self.currencies_without_fractions = %w(BIF CLP DJF GNF JPY KMF KRW MGA PYG RWF VND VUV XAF XOF XPF UGX)
33
+
34
+ self.homepage_url = 'https://stripe.com/'
35
+ self.display_name = 'Stripe'
36
+
37
+ STANDARD_ERROR_CODE_MAPPING = {
38
+ 'incorrect_number' => STANDARD_ERROR_CODE[:incorrect_number],
39
+ 'invalid_number' => STANDARD_ERROR_CODE[:invalid_number],
40
+ 'invalid_expiry_month' => STANDARD_ERROR_CODE[:invalid_expiry_date],
41
+ 'invalid_expiry_year' => STANDARD_ERROR_CODE[:invalid_expiry_date],
42
+ 'invalid_cvc' => STANDARD_ERROR_CODE[:invalid_cvc],
43
+ 'expired_card' => STANDARD_ERROR_CODE[:expired_card],
44
+ 'incorrect_cvc' => STANDARD_ERROR_CODE[:incorrect_cvc],
45
+ 'incorrect_zip' => STANDARD_ERROR_CODE[:incorrect_zip],
46
+ 'card_declined' => STANDARD_ERROR_CODE[:card_declined],
47
+ 'call_issuer' => STANDARD_ERROR_CODE[:call_issuer],
48
+ 'processing_error' => STANDARD_ERROR_CODE[:processing_error],
49
+ 'incorrect_pin' => STANDARD_ERROR_CODE[:incorrect_pin],
50
+ 'test_mode_live_card' => STANDARD_ERROR_CODE[:test_mode_live_card],
51
+ 'pickup_card' => STANDARD_ERROR_CODE[:pickup_card],
52
+ 'amount_too_small' => STANDARD_ERROR_CODE[:invalid_amount]
53
+ }
54
+
55
+ BANK_ACCOUNT_HOLDER_TYPE_MAPPING = {
56
+ 'personal' => 'individual',
57
+ 'business' => 'company'
58
+ }
59
+
60
+ MINIMUM_AUTHORIZE_AMOUNTS = {
61
+ 'USD' => 100,
62
+ 'CAD' => 100,
63
+ 'GBP' => 60,
64
+ 'EUR' => 100,
65
+ 'DKK' => 500,
66
+ 'NOK' => 600,
67
+ 'SEK' => 600,
68
+ 'CHF' => 100,
69
+ 'AUD' => 100,
70
+ 'JPY' => 100,
71
+ 'MXN' => 2000,
72
+ 'SGD' => 100,
73
+ 'HKD' => 800
74
+ }
75
+
76
+ SUCCESS_CODE = 200
77
+ SOFT_DECLINE_CODES = [402]
78
+
79
+ def initialize(options = {})
80
+ requires!(options, :login)
81
+ @api_key = options[:login]
82
+ @fee_refund_api_key = options[:fee_refund_login]
83
+ super
84
+ end
85
+
86
+ def authorize(money, payment, options = {})
87
+ if ach?(payment)
88
+ direct_bank_error = 'Direct bank account transactions are not supported for authorize.'
89
+ return Response.new(false, direct_bank_error)
90
+ end
91
+
92
+ MultiResponse.run do |r|
93
+ if payment.is_a?(ApplePayPaymentToken)
94
+ r.process { tokenize_apple_pay_token(payment) }
95
+ payment = StripePaymentToken.new(r.params['token']) if r.success?
96
+ end
97
+ r.process do
98
+ post = create_post_for_auth_or_purchase(money, payment, options)
99
+ add_application_fee(post, options) if emv_payment?(payment)
100
+ post[:capture] = 'false'
101
+ commit(:post, 'charges', post, options)
102
+ end
103
+ end.responses.last
104
+ end
105
+
106
+ # To create a charge on a card or a token, call
107
+ #
108
+ # purchase(money, card_hash_or_token, { ... })
109
+ #
110
+ # To create a charge on a customer, call
111
+ #
112
+ # purchase(money, nil, { :customer => id, ... })
113
+ def purchase(money, payment, options = {})
114
+ if ach?(payment)
115
+ direct_bank_error = 'Direct bank account transactions are not supported. Bank accounts must be stored and verified before use.'
116
+ return Response.new(false, direct_bank_error)
117
+ end
118
+
119
+ MultiResponse.run do |r|
120
+ if payment.is_a?(ApplePayPaymentToken)
121
+ r.process { tokenize_apple_pay_token(payment) }
122
+ payment = StripePaymentToken.new(r.params['token']) if r.success?
123
+ end
124
+ r.process do
125
+ post = create_post_for_auth_or_purchase(money, payment, options)
126
+ post[:card][:processing_method] = 'quick_chip' if quickchip_payment?(payment)
127
+ commit(:post, 'charges', post, options)
128
+ end
129
+ end.responses.last
130
+ end
131
+
132
+ def capture(money, authorization, options = {})
133
+ post = {}
134
+
135
+ if emv_tc_response = options.delete(:icc_data)
136
+ # update the charge with emv data if card present
137
+ update = {}
138
+ update[:card] = { emv_approval_data: emv_tc_response }
139
+ commit(:post, "charges/#{CGI.escape(authorization)}", update, options)
140
+ else
141
+ add_application_fee(post, options)
142
+ add_amount(post, money, options)
143
+ add_exchange_rate(post, options)
144
+ end
145
+
146
+ commit(:post, "charges/#{CGI.escape(authorization)}/capture", post, options)
147
+ end
148
+
149
+ def void(identification, options = {})
150
+ post = {}
151
+ post[:reverse_transfer] = options[:reverse_transfer] if options[:reverse_transfer]
152
+ post[:metadata] = options[:metadata] if options[:metadata]
153
+ post[:reason] = options[:reason] if options[:reason]
154
+ post[:expand] = [:charge]
155
+ commit(:post, "charges/#{CGI.escape(identification)}/refunds", post, options)
156
+ end
157
+
158
+ def refund(money, identification, options = {})
159
+ post = {}
160
+ add_amount(post, money, options)
161
+ post[:refund_application_fee] = true if options[:refund_application_fee]
162
+ post[:reverse_transfer] = options[:reverse_transfer] if options[:reverse_transfer]
163
+ post[:metadata] = options[:metadata] if options[:metadata]
164
+ post[:reason] = options[:reason] if options[:reason]
165
+ post[:expand] = [:charge]
166
+
167
+ response = commit(:post, "charges/#{CGI.escape(identification)}/refunds", post, options)
168
+
169
+ if response.success? && options[:refund_fee_amount] && options[:refund_fee_amount].to_s != '0'
170
+ charge = api_request(:get, "charges/#{CGI.escape(identification)}", nil, options)
171
+
172
+ if application_fee = charge['application_fee']
173
+ fee_refund_options = {
174
+ currency: options[:currency], # currency isn't used by Stripe here, but we need it for #add_amount
175
+ key: @fee_refund_api_key
176
+ }
177
+ refund_application_fee(options[:refund_fee_amount].to_i, application_fee, fee_refund_options)
178
+ end
179
+ end
180
+
181
+ response
182
+ end
183
+
184
+ def verify(payment, options = {})
185
+ MultiResponse.run(:use_first_response) do |r|
186
+ r.process { authorize(auth_minimum_amount(options), payment, options) }
187
+ options[:idempotency_key] = nil
188
+ r.process(:ignore_result) { void(r.authorization, options) }
189
+ end
190
+ end
191
+
192
+ def refund_application_fee(money, identification, options = {})
193
+ post = {}
194
+ add_amount(post, money, options)
195
+ commit(:post, "application_fees/#{CGI.escape(identification)}/refunds", post, options)
196
+ end
197
+
198
+ # Note: creating a new credit card will not change the customer's existing default credit card (use :set_default => true)
199
+ def store(payment, options = {})
200
+ params = {}
201
+ post = {}
202
+
203
+ if payment.is_a?(ApplePayPaymentToken)
204
+ token_exchange_response = tokenize_apple_pay_token(payment)
205
+ params = { card: token_exchange_response.params['token']['id'] } if token_exchange_response.success?
206
+ elsif payment.is_a?(StripePaymentToken)
207
+ add_payment_token(params, payment, options)
208
+ elsif payment.is_a?(Check)
209
+ bank_token_response = tokenize_bank_account(payment)
210
+ return bank_token_response unless bank_token_response.success?
211
+
212
+ params = { source: bank_token_response.params['token']['id'] }
213
+ else
214
+ add_creditcard(params, payment, options)
215
+ end
216
+
217
+ post[:validate] = options[:validate] unless options[:validate].nil?
218
+ post[:description] = options[:description] if options[:description]
219
+ post[:email] = options[:email] if options[:email]
220
+
221
+ if options[:account]
222
+ add_external_account(post, params, payment)
223
+ commit(:post, "accounts/#{CGI.escape(options[:account])}/external_accounts", post, options)
224
+ elsif options[:customer]
225
+ MultiResponse.run(:first) do |r|
226
+ # The /cards endpoint does not update other customer parameters.
227
+ r.process { commit(:post, "customers/#{CGI.escape(options[:customer])}/cards", params, options) }
228
+
229
+ post[:default_card] = r.params['id'] if options[:set_default] && r.success? && !r.params['id'].blank?
230
+
231
+ r.process { update_customer(options[:customer], post.merge(expand: [:sources])) } if post.count > 0
232
+ end
233
+ else
234
+ post[:expand] = [:sources]
235
+ commit(:post, 'customers', post.merge(params), options)
236
+ end
237
+ end
238
+
239
+ def update(customer_id, card_id, options = {})
240
+ commit(:post, "customers/#{CGI.escape(customer_id)}/cards/#{CGI.escape(card_id)}", options, options)
241
+ end
242
+
243
+ def update_customer(customer_id, options = {})
244
+ commit(:post, "customers/#{CGI.escape(customer_id)}", options, options)
245
+ end
246
+
247
+ def unstore(identification, options = {}, deprecated_options = {})
248
+ customer_id, card_id = identification.split('|')
249
+
250
+ if options.kind_of?(String)
251
+ ActiveMerchant.deprecated 'Passing the card_id as the 2nd parameter is deprecated. The response authorization includes both the customer_id and the card_id.'
252
+ card_id ||= options
253
+ options = deprecated_options
254
+ end
255
+
256
+ commit(:delete, "customers/#{CGI.escape(customer_id)}/cards/#{CGI.escape(card_id)}", nil, options)
257
+ end
258
+
259
+ def tokenize_apple_pay_token(apple_pay_payment_token, options = {})
260
+ token_response = api_request(:post, "tokens?pk_token=#{CGI.escape(apple_pay_payment_token.payment_data.to_json)}")
261
+ success = !token_response.key?('error')
262
+
263
+ if success && token_response.key?('id')
264
+ Response.new(success, nil, token: token_response)
265
+ else
266
+ Response.new(success, token_response['error']['message'])
267
+ end
268
+ end
269
+
270
+ def verify_credentials
271
+ begin
272
+ ssl_get(live_url + 'charges/nonexistent', headers)
273
+ rescue ResponseError => e
274
+ return false if e.response.code.to_i == 401
275
+ end
276
+
277
+ true
278
+ end
279
+
280
+ def supports_scrubbing?
281
+ true
282
+ end
283
+
284
+ def scrub(transcript)
285
+ transcript.
286
+ gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]').
287
+ gsub(%r((Authorization: Bearer )\w+), '\1[FILTERED]').
288
+ gsub(%r((&?three_d_secure\[cryptogram\]=)[\w=]*(&?)), '\1[FILTERED]\2').
289
+ gsub(%r(((\[card\]|card)\[cryptogram\]=)[^&]+(&?)), '\1[FILTERED]\3').
290
+ gsub(%r(((\[card\]|card)\[cvc\]=)\d+), '\1[FILTERED]').
291
+ gsub(%r(((\[card\]|card)\[emv_approval_data\]=)[^&]+(&?)), '\1[FILTERED]\3').
292
+ gsub(%r(((\[card\]|card)\[emv_auth_data\]=)[^&]+(&?)), '\1[FILTERED]\3').
293
+ gsub(%r(((\[card\]|card)\[encrypted_pin\]=)[^&]+(&?)), '\1[FILTERED]\3').
294
+ gsub(%r(((\[card\]|card)\[encrypted_pin_key_id\]=)[\w=]+(&?)), '\1[FILTERED]\3').
295
+ gsub(%r(((\[card\]|card)\[number\]=)\d+), '\1[FILTERED]').
296
+ gsub(%r(((\[card\]|card)\[swipe_data\]=)[^&]+(&?)), '\1[FILTERED]\3').
297
+ gsub(%r(((\[bank_account\]|bank_account)\[account_number\]=)\d+), '\1[FILTERED]').
298
+ gsub(%r(((\[payment_method_data\]|payment_method_data)\[card\]\[token\]=)[^&]+(&?)), '\1[FILTERED]\3')
299
+ end
300
+
301
+ def supports_network_tokenization?
302
+ true
303
+ end
304
+
305
+ # Helper method to prevent hitting the external_account limit from remote test runs
306
+ def delete_latest_test_external_account(account)
307
+ return unless test?
308
+
309
+ auth_header = { 'Authorization' => 'Basic ' + Base64.strict_encode64(options[:login].to_s + ':').strip }
310
+ url = "#{live_url}accounts/#{CGI.escape(account)}/external_accounts"
311
+ accounts_response = JSON.parse(ssl_get("#{url}?limit=100", auth_header))
312
+ to_delete = accounts_response['data'].reject { |ac| ac['default_for_currency'] }
313
+ ssl_request(:delete, "#{url}/#{to_delete.first['id']}", nil, auth_header)
314
+ end
315
+
316
+ private
317
+
318
+ class StripePaymentToken < PaymentToken
319
+ def type
320
+ 'stripe'
321
+ end
322
+ end
323
+
324
+ def create_source(money, payment, type, options = {})
325
+ post = {}
326
+ add_amount(post, money, options, true)
327
+ post[:type] = type
328
+ if type == 'card'
329
+ add_creditcard(post, payment, options, true)
330
+ add_source_owner(post, payment, options)
331
+ elsif type == 'three_d_secure'
332
+ post[:three_d_secure] = { card: payment }
333
+ post[:redirect] = { return_url: options[:redirect_url] }
334
+ end
335
+ commit(:post, 'sources', post, options)
336
+ end
337
+
338
+ def show_source(source_id, options)
339
+ commit(:get, "sources/#{source_id}", nil, options)
340
+ end
341
+
342
+ def create_webhook_endpoint(options, events)
343
+ post = {}
344
+ post[:url] = options[:callback_url]
345
+ post[:enabled_events] = events
346
+ post[:connect] = true if options[:stripe_account]
347
+ options.delete(:stripe_account)
348
+ commit(:post, 'webhook_endpoints', post, options)
349
+ end
350
+
351
+ def delete_webhook_endpoint(options)
352
+ commit(:delete, "webhook_endpoints/#{options[:webhook_id]}", {}, options)
353
+ end
354
+
355
+ def show_webhook_endpoint(options)
356
+ options.delete(:stripe_account)
357
+ commit(:get, "webhook_endpoints/#{options[:webhook_id]}", nil, options)
358
+ end
359
+
360
+ def list_webhook_endpoints(options)
361
+ params = {}
362
+ params[:limit] = options[:limit] if options[:limit]
363
+ options.delete(:stripe_account)
364
+ commit(:get, "webhook_endpoints?#{post_data(params)}", nil, options)
365
+ end
366
+
367
+ def create_post_for_auth_or_purchase(money, payment, options)
368
+ post = {}
369
+
370
+ if payment.is_a?(StripePaymentToken)
371
+ add_payment_token(post, payment, options)
372
+ else
373
+ add_creditcard(post, payment, options)
374
+ end
375
+
376
+ add_charge_details(post, money, payment, options)
377
+ post
378
+ end
379
+
380
+ # Used internally by Spreedly to populate the charge object for 3DS 1.0 transactions
381
+ def add_charge_details(post, money, payment, options)
382
+ if emv_payment?(payment)
383
+ add_statement_address(post, options)
384
+ add_emv_metadata(post, payment)
385
+ else
386
+ add_amount(post, money, options, true)
387
+ add_customer_data(post, options)
388
+ post[:description] = options[:description]
389
+ post[:statement_descriptor] = options[:statement_description]
390
+ post[:statement_descriptor_suffix] = options[:statement_descriptor_suffix] if options[:statement_descriptor_suffix]
391
+ post[:receipt_email] = options[:receipt_email] if options[:receipt_email]
392
+ add_customer(post, payment, options)
393
+ add_flags(post, options)
394
+ end
395
+
396
+ add_metadata(post, options)
397
+ add_shipping_address(post, payment, options)
398
+ add_application_fee(post, options)
399
+ add_exchange_rate(post, options)
400
+ add_destination(post, options)
401
+ add_level_three(post, options)
402
+ add_connected_account(post, options)
403
+ add_radar_data(post, options)
404
+ post
405
+ end
406
+
407
+ def add_amount(post, money, options, include_currency = false)
408
+ currency = options[:currency] || currency(money)
409
+ post[:amount] = localized_amount(money, currency)
410
+ post[:currency] = currency.downcase if include_currency
411
+ end
412
+
413
+ def add_application_fee(post, options)
414
+ post[:application_fee] = options[:application_fee] if options[:application_fee]
415
+ end
416
+
417
+ def add_exchange_rate(post, options)
418
+ post[:exchange_rate] = options[:exchange_rate] if options[:exchange_rate]
419
+ end
420
+
421
+ def add_destination(post, options)
422
+ if options[:destination]
423
+ post[:destination] = {}
424
+ post[:destination][:account] = options[:destination]
425
+ post[:destination][:amount] = options[:destination_amount] if options[:destination_amount]
426
+ end
427
+ end
428
+
429
+ def add_level_three(post, options)
430
+ level_three = {}
431
+
432
+ copy_when_present(level_three, [:merchant_reference], options)
433
+ copy_when_present(level_three, [:customer_reference], options)
434
+ copy_when_present(level_three, [:shipping_address_zip], options)
435
+ copy_when_present(level_three, [:shipping_from_zip], options)
436
+ copy_when_present(level_three, [:shipping_amount], options)
437
+ copy_when_present(level_three, [:line_items], options)
438
+
439
+ post[:level3] = level_three unless level_three.empty?
440
+ end
441
+
442
+ def add_expand_parameters(post, options)
443
+ post[:expand] ||= []
444
+ post[:expand].concat(Array.wrap(options[:expand]).map(&:to_sym)).uniq!
445
+ end
446
+
447
+ def add_external_account(post, card_params, payment)
448
+ external_account = {}
449
+ external_account[:object] = 'card'
450
+ external_account[:currency] = (options[:currency] || currency(payment)).downcase
451
+ post[:external_account] = external_account.merge(card_params[:card])
452
+ end
453
+
454
+ def add_customer_data(post, options)
455
+ metadata_options = %i[description ip user_agent referrer]
456
+ post.update(options.slice(*metadata_options))
457
+
458
+ post[:external_id] = options[:order_id]
459
+ post[:payment_user_agent] = "Stripe/v1 ActiveMerchantBindings/#{ActiveMerchant::VERSION}"
460
+ end
461
+
462
+ def add_address(post, options)
463
+ return unless post[:card]&.kind_of?(Hash)
464
+
465
+ if address = options[:billing_address] || options[:address]
466
+ post[:card][:address_line1] = address[:address1] if address[:address1]
467
+ post[:card][:address_line2] = address[:address2] if address[:address2]
468
+ post[:card][:address_country] = address[:country] if address[:country]
469
+ post[:card][:address_zip] = address[:zip] if address[:zip]
470
+ post[:card][:address_state] = address[:state] if address[:state]
471
+ post[:card][:address_city] = address[:city] if address[:city]
472
+ end
473
+ end
474
+
475
+ def add_statement_address(post, options)
476
+ return unless statement_address = options[:statement_address]
477
+ return unless %i[address1 city zip state].all? { |key| statement_address[key].present? }
478
+
479
+ post[:statement_address] = {}
480
+ post[:statement_address][:line1] = statement_address[:address1]
481
+ post[:statement_address][:line2] = statement_address[:address2] if statement_address[:address2].present?
482
+ post[:statement_address][:city] = statement_address[:city]
483
+ post[:statement_address][:postal_code] = statement_address[:zip]
484
+ post[:statement_address][:state] = statement_address[:state]
485
+ end
486
+
487
+ def add_creditcard(post, creditcard, options, use_sources = false)
488
+ card = {}
489
+ if emv_payment?(creditcard)
490
+ add_emv_creditcard(post, creditcard.icc_data)
491
+ post[:card][:read_method] = 'contactless' if creditcard.read_method == 'contactless'
492
+ post[:card][:read_method] = 'contactless_magstripe_mode' if creditcard.read_method == 'contactless_magstripe'
493
+ if creditcard.encrypted_pin_cryptogram.present? && creditcard.encrypted_pin_ksn.present?
494
+ post[:card][:encrypted_pin] = creditcard.encrypted_pin_cryptogram
495
+ post[:card][:encrypted_pin_key_id] = creditcard.encrypted_pin_ksn
496
+ end
497
+ elsif creditcard.respond_to?(:number)
498
+ if creditcard.respond_to?(:track_data) && creditcard.track_data.present?
499
+ card[:swipe_data] = creditcard.track_data
500
+ if creditcard.respond_to?(:read_method)
501
+ card[:fallback_reason] = 'no_chip' if creditcard.read_method == 'fallback_no_chip'
502
+ card[:fallback_reason] = 'chip_error' if creditcard.read_method == 'fallback_chip_error'
503
+ card[:read_method] = 'contactless_magstripe_mode' if creditcard.read_method == 'contactless_magstripe'
504
+ end
505
+ else
506
+ card[:number] = creditcard.number
507
+ card[:exp_month] = creditcard.month
508
+ card[:exp_year] = creditcard.year
509
+ card[:cvc] = creditcard.verification_value if creditcard.verification_value?
510
+ card[:name] = creditcard.name if creditcard.name && !use_sources
511
+ end
512
+
513
+ if creditcard.is_a?(NetworkTokenizationCreditCard)
514
+ card[:cryptogram] = creditcard.payment_cryptogram
515
+ card[:eci] = creditcard.eci.rjust(2, '0') if creditcard.eci =~ /^[0-9]+$/
516
+ card[:tokenization_method] = creditcard.source.to_s
517
+ end
518
+ post[:card] = card
519
+
520
+ add_address(post, options) unless use_sources
521
+ elsif creditcard.kind_of?(String)
522
+ if options[:track_data]
523
+ card[:swipe_data] = options[:track_data]
524
+ elsif creditcard.include?('|')
525
+ customer_id, card_id = creditcard.split('|')
526
+ card = card_id
527
+ post[:customer] = customer_id
528
+ else
529
+ card = creditcard
530
+ end
531
+ post[:card] = card
532
+ end
533
+ end
534
+
535
+ def add_emv_creditcard(post, icc_data, options = {})
536
+ post[:card] = { emv_auth_data: icc_data }
537
+ end
538
+
539
+ def add_payment_token(post, token, options = {})
540
+ post[:card] = token.payment_data['id']
541
+ end
542
+
543
+ def add_customer(post, payment, options)
544
+ post[:customer] = options[:customer] if options[:customer] && !payment.respond_to?(:number)
545
+ end
546
+
547
+ def add_flags(post, options)
548
+ post[:uncaptured] = true if options[:uncaptured]
549
+ post[:recurring] = true if options[:eci] == 'recurring' || options[:recurring]
550
+ end
551
+
552
+ def add_metadata(post, options = {})
553
+ post[:metadata] ||= {}
554
+ post[:metadata].merge!(options[:metadata]) if options[:metadata]
555
+ post[:metadata][:email] = options[:email] if options[:email]
556
+ post[:metadata][:order_id] = options[:order_id] if options[:order_id]
557
+ end
558
+
559
+ def add_emv_metadata(post, creditcard)
560
+ post[:metadata] ||= {}
561
+ post[:metadata][:card_read_method] = creditcard.read_method if creditcard.respond_to?(:read_method)
562
+ end
563
+
564
+ def add_shipping_address(post, payment, options = {})
565
+ return unless shipping = options[:shipping_address]
566
+ return unless shipping_name = shipping[:name]
567
+
568
+ post[:shipping] = {}
569
+
570
+ post[:shipping][:name] = shipping_name
571
+ post[:shipping][:address] = {}
572
+ post[:shipping][:address][:line1] = shipping[:address1]
573
+ post[:shipping][:address][:line2] = shipping[:address2] if shipping[:address2]
574
+ post[:shipping][:address][:city] = shipping[:city] if shipping[:city]
575
+ post[:shipping][:address][:country] = shipping[:country] if shipping[:country]
576
+ post[:shipping][:address][:state] = shipping[:state] if shipping[:state]
577
+ post[:shipping][:address][:postal_code] = shipping[:zip] if shipping[:zip]
578
+ post[:shipping][:phone] = shipping[:phone_number] if shipping[:phone_number]
579
+ end
580
+
581
+ def add_source_owner(post, creditcard, options)
582
+ post[:owner] = {}
583
+ post[:owner][:name] = creditcard.name if creditcard.name
584
+ post[:owner][:email] = options[:email] if options[:email]
585
+
586
+ if address = options[:billing_address] || options[:address]
587
+ owner_address = {}
588
+ owner_address[:line1] = address[:address1] if address[:address1]
589
+ owner_address[:line2] = address[:address2] if address[:address2]
590
+ owner_address[:country] = address[:country] if address[:country]
591
+ owner_address[:postal_code] = address[:zip] if address[:zip]
592
+ owner_address[:state] = address[:state] if address[:state]
593
+ owner_address[:city] = address[:city] if address[:city]
594
+
595
+ post[:owner][:phone] = address[:phone] if address[:phone]
596
+ post[:owner][:address] = owner_address
597
+ end
598
+ end
599
+
600
+ def add_connected_account(post, options = {})
601
+ post[:on_behalf_of] = options[:on_behalf_of] if options[:on_behalf_of]
602
+
603
+ return unless options[:transfer_destination]
604
+
605
+ post[:transfer_data] = { destination: options[:transfer_destination] }
606
+ post[:transfer_data][:amount] = options[:transfer_amount] if options[:transfer_amount]
607
+ post[:transfer_group] = options[:transfer_group] if options[:transfer_group]
608
+ post[:application_fee_amount] = options[:application_fee_amount] if options[:application_fee_amount]
609
+ end
610
+
611
+ def add_radar_data(post, options = {})
612
+ radar_options = {}
613
+ radar_options[:session] = options[:radar_session_id] if options[:radar_session_id]
614
+ radar_options[:skip_rules] = ['all'] if options[:skip_radar_rules]
615
+
616
+ post[:radar_options] = radar_options unless radar_options.empty?
617
+ end
618
+
619
+ def parse(body)
620
+ JSON.parse(body)
621
+ end
622
+
623
+ def post_data(params)
624
+ return nil unless params
625
+
626
+ flatten_params([], params).join('&')
627
+ end
628
+
629
+ def flatten_params(flattened, params, prefix = nil)
630
+ params.each do |key, value|
631
+ next if value != false && value.blank?
632
+
633
+ flattened_key = prefix.nil? ? key : "#{prefix}[#{key}]"
634
+ if value.is_a?(Hash)
635
+ flatten_params(flattened, value, flattened_key)
636
+ elsif value.is_a?(Array)
637
+ flatten_array(flattened, value, flattened_key)
638
+ else
639
+ flattened << "#{flattened_key}=#{CGI.escape(value.to_s)}"
640
+ end
641
+ end
642
+ flattened
643
+ end
644
+
645
+ def flatten_array(flattened, array, prefix)
646
+ array.each_with_index do |item, idx|
647
+ key = "#{prefix}[#{idx}]"
648
+ if item.is_a?(Hash)
649
+ flatten_params(flattened, item, key)
650
+ elsif item.is_a?(Array)
651
+ flatten_array(flattened, item, key)
652
+ else
653
+ flattened << "#{key}=#{CGI.escape(item.to_s)}"
654
+ end
655
+ end
656
+ end
657
+
658
+ def key(options = {})
659
+ options[:key] || @api_key
660
+ end
661
+
662
+ def headers(options = {})
663
+ headers = {
664
+ 'Authorization' => 'Basic ' + Base64.strict_encode64(key(options).to_s + ':').strip,
665
+ 'User-Agent' => "Stripe/v1 ActiveMerchantBindings/#{ActiveMerchant::VERSION}",
666
+ 'Stripe-Version' => api_version(options),
667
+ 'X-Stripe-Client-User-Agent' => stripe_client_user_agent(options),
668
+ 'X-Stripe-Client-User-Metadata' => { ip: options[:ip] }.to_json
669
+ }
670
+ headers['Idempotency-Key'] = options[:idempotency_key] if options[:idempotency_key]
671
+ headers['Stripe-Account'] = options[:stripe_account] if options[:stripe_account]
672
+ headers
673
+ end
674
+
675
+ def stripe_client_user_agent(options)
676
+ return user_agent unless options[:application]
677
+
678
+ JSON.dump(JSON.parse(user_agent).merge!({ application: options[:application] }))
679
+ end
680
+
681
+ def api_version(options)
682
+ options[:version] || @options[:version] || self.class::DEFAULT_API_VERSION
683
+ end
684
+
685
+ def api_request(method, endpoint, parameters = nil, options = {})
686
+ raw_response = response = nil
687
+ begin
688
+ raw_response = ssl_request(method, self.live_url + endpoint, post_data(parameters), headers(options))
689
+ response = parse(raw_response)
690
+ rescue ResponseError => e
691
+ raw_response = e.response.body
692
+ response = response_error(raw_response)
693
+ rescue JSON::ParserError
694
+ response = json_error(raw_response)
695
+ end
696
+ response
697
+ end
698
+
699
+ def commit(method, url, parameters = nil, options = {})
700
+ add_expand_parameters(parameters, options) if parameters
701
+
702
+ return Response.new(false, 'Invalid API Key provided') if test? && !key(options).start_with?('sk_test')
703
+
704
+ response = api_request(method, url, parameters, options)
705
+ response['webhook_id'] = options[:webhook_id] if options[:webhook_id]
706
+ success = success_from(response, options)
707
+
708
+ card = card_from_response(response)
709
+ avs_code = AVS_CODE_TRANSLATOR["line1: #{card['address_line1_check']}, zip: #{card['address_zip_check']}"]
710
+ cvc_code = CVC_CODE_TRANSLATOR[card['cvc_check']]
711
+ Response.new(success,
712
+ message_from(success, response),
713
+ response,
714
+ test: response_is_test?(response),
715
+ authorization: authorization_from(success, url, method, response),
716
+ avs_result: { code: avs_code },
717
+ cvv_result: cvc_code,
718
+ emv_authorization: emv_authorization_from_response(response),
719
+ error_code: success ? nil : error_code_from(response),
720
+ response_type: response_type(error_code_from(response))
721
+ )
722
+ end
723
+
724
+ def authorization_from(success, url, method, response)
725
+ return response.fetch('error', {})['charge'] unless success
726
+
727
+ if url == 'customers'
728
+ [response['id'], response.dig('sources', 'data').first&.dig('id')].join('|')
729
+ elsif method == :post && (url.match(/customers\/.*\/cards/) || url.match(/payment_methods\/.*\/attach/))
730
+ [response['customer'], response['id']].join('|')
731
+ else
732
+ response['id']
733
+ end
734
+ end
735
+
736
+ def message_from(success, response)
737
+ success ? 'Transaction approved' : response.fetch('error', { 'message' => 'No error details' })['message']
738
+ end
739
+
740
+ def success_from(response, options)
741
+ !response.key?('error') && response['status'] != 'failed'
742
+ end
743
+
744
+ def response_error(raw_response)
745
+ parse(raw_response)
746
+ rescue JSON::ParserError
747
+ json_error(raw_response)
748
+ end
749
+
750
+ def json_error(raw_response)
751
+ msg = 'Invalid response received from the Stripe API. Please contact support@stripe.com if you continue to receive this message.'
752
+ msg += " (The raw response returned by the API was #{raw_response.inspect})"
753
+ {
754
+ 'error' => {
755
+ 'message' => msg
756
+ }
757
+ }
758
+ end
759
+
760
+ def response_is_test?(response)
761
+ if response.has_key?('livemode')
762
+ !response['livemode']
763
+ elsif response['charge'].is_a?(Hash) && response['charge'].has_key?('livemode')
764
+ !response['charge']['livemode']
765
+ else
766
+ false
767
+ end
768
+ end
769
+
770
+ def emv_payment?(payment)
771
+ payment.respond_to?(:emv?) && payment.emv?
772
+ end
773
+
774
+ def quickchip_payment?(payment)
775
+ payment.respond_to?(:read_method) && payment.read_method == 'contact_quickchip'
776
+ end
777
+
778
+ def card_from_response(response)
779
+ response['card'] || response['active_card'] || response['source'] || {}
780
+ end
781
+
782
+ def emv_authorization_from_response(response)
783
+ return response['error']['emv_auth_data'] if response['error']
784
+
785
+ card_from_response(response)['emv_auth_data']
786
+ end
787
+
788
+ def error_code_from(response)
789
+ return STANDARD_ERROR_CODE_MAPPING['processing_error'] unless response['error']
790
+
791
+ code = response['error']['code']
792
+ decline_code = response['error']['decline_code'] if code == 'card_declined'
793
+
794
+ error_code = STANDARD_ERROR_CODE_MAPPING[decline_code]
795
+ error_code ||= STANDARD_ERROR_CODE_MAPPING[code]
796
+ error_code
797
+ end
798
+
799
+ def tokenize_bank_account(bank_account, options = {})
800
+ account_holder_type = BANK_ACCOUNT_HOLDER_TYPE_MAPPING[bank_account.account_holder_type]
801
+
802
+ post = {
803
+ bank_account: {
804
+ account_number: bank_account.account_number,
805
+ country: 'US',
806
+ currency: 'usd',
807
+ routing_number: bank_account.routing_number,
808
+ account_holder_name: bank_account.name,
809
+ account_holder_type: account_holder_type
810
+ }
811
+ }
812
+
813
+ token_response = api_request(:post, "tokens?#{post_data(post)}")
814
+ success = token_response['error'].nil?
815
+
816
+ if success && token_response['id']
817
+ Response.new(success, nil, token: token_response)
818
+ else
819
+ Response.new(success, token_response['error']['message'])
820
+ end
821
+ end
822
+
823
+ def ach?(payment_method)
824
+ case payment_method
825
+ when String, nil
826
+ false
827
+ else
828
+ card_brand(payment_method) == 'check'
829
+ end
830
+ end
831
+
832
+ def auth_minimum_amount(options)
833
+ return 100 unless options[:currency]
834
+
835
+ return MINIMUM_AUTHORIZE_AMOUNTS[options[:currency].upcase] || 100
836
+ end
837
+
838
+ def copy_when_present(dest, dest_path, source, source_path = nil)
839
+ source_path ||= dest_path
840
+ source_path.each do |key|
841
+ return nil unless source[key]
842
+
843
+ source = source[key]
844
+ end
845
+
846
+ if source
847
+ dest_path.first(dest_path.size - 1).each do |key|
848
+ dest[key] ||= {}
849
+ dest = dest[key]
850
+ end
851
+ dest[dest_path.last] = source
852
+ end
853
+ end
854
+
855
+ def response_type(code)
856
+ if code == SUCCESS_CODE
857
+ 0
858
+ elsif SOFT_DECLINE_CODES.include?(code)
859
+ 1
860
+ else
861
+ 2
862
+ end
863
+ end
864
+ end
865
+ end
866
+ end