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,602 @@
1
+ require 'active_support/core_ext/hash/slice'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ # This gateway uses the current Stripe {Payment Intents API}[https://stripe.com/docs/api/payment_intents].
6
+ # For the legacy API, see the Stripe gateway
7
+ class StripePaymentIntentsGateway < StripeGateway
8
+ ALLOWED_METHOD_STATES = %w[automatic manual].freeze
9
+ ALLOWED_CANCELLATION_REASONS = %w[duplicate fraudulent requested_by_customer abandoned].freeze
10
+ CREATE_INTENT_ATTRIBUTES = %i[description statement_descriptor_suffix statement_descriptor receipt_email save_payment_method]
11
+ CONFIRM_INTENT_ATTRIBUTES = %i[receipt_email return_url save_payment_method setup_future_usage off_session]
12
+ UPDATE_INTENT_ATTRIBUTES = %i[description statement_descriptor_suffix statement_descriptor receipt_email setup_future_usage]
13
+ DEFAULT_API_VERSION = '2020-08-27'
14
+
15
+ def create_intent(money, payment_method, options = {})
16
+ MultiResponse.run do |r|
17
+ if payment_method.is_a?(NetworkTokenizationCreditCard)
18
+ r.process { tokenize_apple_google(payment_method, options) }
19
+ payment_method = (r.params['token']['id']) if r.success?
20
+ end
21
+ r.process do
22
+ post = {}
23
+ add_amount(post, money, options, true)
24
+ add_capture_method(post, options)
25
+ add_confirmation_method(post, options)
26
+ add_customer(post, options)
27
+
28
+ result = add_payment_method_token(post, payment_method, options)
29
+ return result if result.is_a?(ActiveMerchant::Billing::Response)
30
+
31
+ add_external_three_d_secure_auth_data(post, options)
32
+ add_metadata(post, options)
33
+ add_return_url(post, options)
34
+ add_connected_account(post, options)
35
+ add_radar_data(post, options)
36
+ add_shipping_address(post, options)
37
+ add_stored_credentials(post, options)
38
+ setup_future_usage(post, options)
39
+ add_exemption(post, options)
40
+ add_ntid(post, options)
41
+ add_claim_without_transaction_id(post, options)
42
+ add_error_on_requires_action(post, options)
43
+ add_fulfillment_date(post, options)
44
+ request_three_d_secure(post, options)
45
+ add_level_three(post, options)
46
+
47
+ CREATE_INTENT_ATTRIBUTES.each do |attribute|
48
+ add_whitelisted_attribute(post, options, attribute)
49
+ end
50
+ commit(:post, 'payment_intents', post, options)
51
+ end
52
+ end
53
+ end
54
+
55
+ def show_intent(intent_id, options)
56
+ commit(:get, "payment_intents/#{intent_id}", nil, options)
57
+ end
58
+
59
+ def create_test_customer
60
+ response = api_request(:post, 'customers')
61
+ response['id']
62
+ end
63
+
64
+ def confirm_intent(intent_id, payment_method, options = {})
65
+ post = {}
66
+ result = add_payment_method_token(post, payment_method, options)
67
+ return result if result.is_a?(ActiveMerchant::Billing::Response)
68
+
69
+ add_payment_method_types(post, options)
70
+ CONFIRM_INTENT_ATTRIBUTES.each do |attribute|
71
+ add_whitelisted_attribute(post, options, attribute)
72
+ end
73
+
74
+ commit(:post, "payment_intents/#{intent_id}/confirm", post, options)
75
+ end
76
+
77
+ def create_payment_method(payment_method, options = {})
78
+ post_data = add_payment_method_data(payment_method, options)
79
+
80
+ options = format_idempotency_key(options, 'pm')
81
+ commit(:post, 'payment_methods', post_data, options)
82
+ end
83
+
84
+ def add_payment_method_data(payment_method, options = {})
85
+ post_data = {}
86
+ post_data[:type] = 'card'
87
+ post_data[:card] = {}
88
+ post_data[:card][:number] = payment_method.number
89
+ post_data[:card][:exp_month] = payment_method.month
90
+ post_data[:card][:exp_year] = payment_method.year
91
+ post_data[:card][:cvc] = payment_method.verification_value if payment_method.verification_value
92
+ add_billing_address(post_data, options)
93
+ add_name_only(post_data, payment_method) if post_data[:billing_details].nil?
94
+ post_data
95
+ end
96
+
97
+ def add_payment_method_card_data_token(post_data, payment_method)
98
+ post_data.merge!({
99
+ payment_method_types: ['card'],
100
+ payment_method_data: { type: 'card', card: { token: payment_method } }
101
+ })
102
+ end
103
+
104
+ def update_intent(money, intent_id, payment_method, options = {})
105
+ post = {}
106
+ add_amount(post, money, options)
107
+
108
+ result = add_payment_method_token(post, payment_method, options)
109
+ return result if result.is_a?(ActiveMerchant::Billing::Response)
110
+
111
+ add_payment_method_types(post, options)
112
+ add_customer(post, options)
113
+ add_metadata(post, options)
114
+ add_shipping_address(post, options)
115
+ add_connected_account(post, options)
116
+ add_fulfillment_date(post, options)
117
+
118
+ UPDATE_INTENT_ATTRIBUTES.each do |attribute|
119
+ add_whitelisted_attribute(post, options, attribute)
120
+ end
121
+ commit(:post, "payment_intents/#{intent_id}", post, options)
122
+ end
123
+
124
+ def create_setup_intent(payment_method, options = {})
125
+ MultiResponse.run do |r|
126
+ r.process do
127
+ post = {}
128
+ add_customer(post, options)
129
+ result = add_payment_method_token(post, payment_method, options, r)
130
+ return result if result.is_a?(ActiveMerchant::Billing::Response)
131
+
132
+ add_metadata(post, options)
133
+ add_return_url(post, options)
134
+ add_fulfillment_date(post, options)
135
+ request_three_d_secure(post, options)
136
+ post[:on_behalf_of] = options[:on_behalf_of] if options[:on_behalf_of]
137
+ post[:usage] = options[:usage] if %w(on_session off_session).include?(options[:usage])
138
+ post[:description] = options[:description] if options[:description]
139
+
140
+ commit(:post, 'setup_intents', post, options)
141
+ end
142
+ end
143
+ end
144
+
145
+ def retrieve_setup_intent(setup_intent_id, options = {})
146
+ # Retrieving a setup_intent passing 'expand[]=latest_attempt' allows the caller to
147
+ # check for a network_transaction_id and ds_transaction_id
148
+ # eg (latest_attempt -> payment_method_details -> card -> network_transaction_id)
149
+ #
150
+ # Being able to retrieve these fields enables payment flows that rely on MIT exemptions, e.g: off_session
151
+ commit(:post, "setup_intents/#{setup_intent_id}", {
152
+ 'expand[]': 'latest_attempt'
153
+ }, options)
154
+ end
155
+
156
+ def authorize(money, payment_method, options = {})
157
+ create_intent(money, payment_method, options.merge!(confirm: true, capture_method: 'manual'))
158
+ end
159
+
160
+ def purchase(money, payment_method, options = {})
161
+ create_intent(money, payment_method, options.merge!(confirm: true, capture_method: 'automatic'))
162
+ end
163
+
164
+ def capture(money, intent_id, options = {})
165
+ post = {}
166
+ currency = options[:currency] || currency(money)
167
+ post[:amount_to_capture] = localized_amount(money, currency)
168
+ if options[:transfer_amount]
169
+ post[:transfer_data] = {}
170
+ post[:transfer_data][:amount] = options[:transfer_amount]
171
+ end
172
+ post[:application_fee_amount] = options[:application_fee] if options[:application_fee]
173
+ options = format_idempotency_key(options, 'capture')
174
+ commit(:post, "payment_intents/#{intent_id}/capture", post, options)
175
+ end
176
+
177
+ def void(intent_id, options = {})
178
+ post = {}
179
+ post[:cancellation_reason] = options[:cancellation_reason] if ALLOWED_CANCELLATION_REASONS.include?(options[:cancellation_reason])
180
+ commit(:post, "payment_intents/#{intent_id}/cancel", post, options)
181
+ end
182
+
183
+ def refund(money, intent_id, options = {})
184
+ if intent_id.include?('pi_')
185
+ intent = api_request(:get, "payment_intents/#{intent_id}", nil, options)
186
+
187
+ return Response.new(false, intent['error']['message'], intent) if intent['error']
188
+
189
+ charge_id = intent.try(:[], 'charges').try(:[], 'data').try(:[], 0).try(:[], 'id')
190
+
191
+ if charge_id.nil?
192
+ error_message = "No associated charge for #{intent['id']}"
193
+ error_message << "; payment_intent has a status of #{intent['status']}" if intent.try(:[], 'status') && intent.try(:[], 'status') != 'succeeded'
194
+ return Response.new(false, error_message, intent)
195
+ end
196
+ else
197
+ charge_id = intent_id
198
+ end
199
+
200
+ super(money, charge_id, options)
201
+ end
202
+
203
+ # Note: Not all payment methods are currently supported by the {Payment Methods API}[https://stripe.com/docs/payments/payment-methods]
204
+ # Current implementation will create a PaymentMethod object if the method is a token or credit card
205
+ # All other types will default to legacy Stripe store
206
+ def store(payment_method, options = {})
207
+ params = {}
208
+ post = {}
209
+ # If customer option is provided, create a payment method and attach to customer id
210
+ # Otherwise, create a customer, then attach
211
+ if payment_method.is_a?(StripePaymentToken) || payment_method.is_a?(ActiveMerchant::Billing::CreditCard)
212
+ result = add_payment_method_token(params, payment_method, options)
213
+ return result if result.is_a?(ActiveMerchant::Billing::Response)
214
+
215
+ if options[:customer]
216
+ customer_id = options[:customer]
217
+ else
218
+ post[:description] = options[:description] if options[:description]
219
+ post[:email] = options[:email] if options[:email]
220
+ options = format_idempotency_key(options, 'customer')
221
+ post[:expand] = [:sources]
222
+ customer = commit(:post, 'customers', post, options)
223
+ customer_id = customer.params['id']
224
+ end
225
+ options = format_idempotency_key(options, 'attach')
226
+ attach_parameters = { customer: customer_id }
227
+ attach_parameters[:validate] = options[:validate] unless options[:validate].nil?
228
+ commit(:post, "payment_methods/#{params[:payment_method]}/attach", attach_parameters, options)
229
+ else
230
+ super(payment_method, options)
231
+ end
232
+ end
233
+
234
+ def unstore(identification, options = {}, deprecated_options = {})
235
+ if identification.include?('pm_')
236
+ _, payment_method = identification.split('|')
237
+ commit(:post, "payment_methods/#{payment_method}/detach", nil, options)
238
+ else
239
+ super(identification, options, deprecated_options)
240
+ end
241
+ end
242
+
243
+ def verify(payment_method, options = {})
244
+ create_setup_intent(payment_method, options.merge!({ confirm: true, verify: true }))
245
+ end
246
+
247
+ def setup_purchase(money, options = {})
248
+ requires!(options, :payment_method_types)
249
+ post = {}
250
+ add_currency(post, options, money)
251
+ add_amount(post, money, options)
252
+ add_payment_method_types(post, options)
253
+ add_metadata(post, options)
254
+ commit(:post, 'payment_intents', post, options)
255
+ end
256
+
257
+ private
258
+
259
+ def off_session_request?(options = {})
260
+ (options[:off_session] || options[:setup_future_usage]) && options[:confirm] == true
261
+ end
262
+
263
+ def add_connected_account(post, options = {})
264
+ super(post, options)
265
+ post[:application_fee_amount] = options[:application_fee] if options[:application_fee]
266
+ end
267
+
268
+ def add_whitelisted_attribute(post, options, attribute)
269
+ post[attribute] = options[attribute] if options[attribute]
270
+ end
271
+
272
+ def add_capture_method(post, options)
273
+ capture_method = options[:capture_method].to_s
274
+ post[:capture_method] = capture_method if ALLOWED_METHOD_STATES.include?(capture_method)
275
+ end
276
+
277
+ def add_confirmation_method(post, options)
278
+ confirmation_method = options[:confirmation_method].to_s
279
+ post[:confirmation_method] = confirmation_method if ALLOWED_METHOD_STATES.include?(confirmation_method)
280
+ end
281
+
282
+ def add_customer(post, options)
283
+ customer = options[:customer].to_s
284
+ post[:customer] = customer if customer.start_with?('cus_')
285
+ end
286
+
287
+ def add_fulfillment_date(post, options)
288
+ post[:fulfillment_date] = options[:fulfillment_date].to_i if options[:fulfillment_date]
289
+ end
290
+
291
+ def add_metadata(post, options = {})
292
+ super
293
+
294
+ post[:metadata][:event_type] = options[:event_type] if options[:event_type]
295
+ end
296
+
297
+ def add_level_three(post, options = {})
298
+ level_three = {}
299
+
300
+ level_three[:merchant_reference] = options[:merchant_reference] if options[:merchant_reference]
301
+ level_three[:customer_reference] = options[:customer_reference] if options[:customer_reference]
302
+ level_three[:shipping_address_zip] = options[:shipping_address_zip] if options[:shipping_address_zip]
303
+ level_three[:shipping_from_zip] = options[:shipping_from_zip] if options[:shipping_from_zip]
304
+ level_three[:shipping_amount] = options[:shipping_amount] if options[:shipping_amount]
305
+ level_three[:line_items] = options[:line_items] if options[:line_items]
306
+
307
+ post[:level3] = level_three unless level_three.empty?
308
+ end
309
+
310
+ def add_return_url(post, options)
311
+ return unless options[:confirm]
312
+
313
+ post[:confirm] = options[:confirm]
314
+ post[:return_url] = options[:return_url] if options[:return_url]
315
+ end
316
+
317
+ def add_payment_method_token(post, payment_method, options, responses = [])
318
+ case payment_method
319
+ when StripePaymentToken
320
+ post[:payment_method_data] = {
321
+ type: 'card',
322
+ card: {
323
+ token: payment_method.payment_data['id'] || payment_method.payment_data
324
+ }
325
+ }
326
+ post[:payment_method] = payment_method.payment_data['id'] || payment_method.payment_data
327
+ when String
328
+ extract_token_from_string_and_maybe_add_customer_id(post, payment_method)
329
+ when ActiveMerchant::Billing::CreditCard
330
+ return create_payment_method_and_extract_token(post, payment_method, options, responses) if options[:verify]
331
+
332
+ get_payment_method_data_from_card(post, payment_method, options, responses)
333
+ end
334
+ end
335
+
336
+ def extract_token_from_string_and_maybe_add_customer_id(post, payment_method)
337
+ if payment_method.include?('|')
338
+ customer_id, payment_method = payment_method.split('|')
339
+ post[:customer] = customer_id
340
+ end
341
+
342
+ if payment_method.include?('tok_')
343
+ add_payment_method_card_data_token(post, payment_method)
344
+ else
345
+ post[:payment_method] = payment_method
346
+ end
347
+ end
348
+
349
+ def tokenize_apple_google(payment, options = {})
350
+ tokenization_method = payment.source == :google_pay ? :android_pay : payment.source
351
+ post = {
352
+ card: {
353
+ number: payment.number,
354
+ exp_month: payment.month,
355
+ exp_year: payment.year,
356
+ tokenization_method: tokenization_method,
357
+ eci: payment.eci,
358
+ cryptogram: payment.payment_cryptogram
359
+ }
360
+ }
361
+ add_billing_address_for_card_tokenization(post, options) if %i(apple_pay android_pay).include?(tokenization_method)
362
+ token_response = api_request(:post, 'tokens', post, options)
363
+ success = token_response['error'].nil?
364
+ if success && token_response['id']
365
+ Response.new(success, nil, token: token_response)
366
+ elsif token_response['error']['message']
367
+ Response.new(false, "The tokenization process fails. #{token_response['error']['message']}")
368
+ else
369
+ Response.new(false, "The tokenization process fails. #{token_response}")
370
+ end
371
+ end
372
+
373
+ def get_payment_method_data_from_card(post, payment_method, options, responses)
374
+ return create_payment_method_and_extract_token(post, payment_method, options, responses) unless off_session_request?(options)
375
+
376
+ post[:payment_method_data] = add_payment_method_data(payment_method, options)
377
+ end
378
+
379
+ def create_payment_method_and_extract_token(post, payment_method, options, responses)
380
+ payment_method_response = create_payment_method(payment_method, options)
381
+ return payment_method_response if payment_method_response.failure?
382
+
383
+ responses << payment_method_response
384
+ add_payment_method_token(post, payment_method_response.params['id'], options)
385
+ end
386
+
387
+ def add_payment_method_types(post, options)
388
+ payment_method_types = options[:payment_method_types] if options[:payment_method_types]
389
+ return if payment_method_types.nil?
390
+
391
+ post[:payment_method_types] = Array(payment_method_types)
392
+ end
393
+
394
+ def add_exemption(post, options = {})
395
+ return unless options[:confirm]
396
+
397
+ post[:payment_method_options] ||= {}
398
+ post[:payment_method_options][:card] ||= {}
399
+ post[:payment_method_options][:card][:moto] = true if options[:moto]
400
+ end
401
+
402
+ # Stripe Payment Intents now supports specifying on a transaction level basis stored credential information.
403
+ # The feature is currently gated but is listed as `stored_credential_transaction_type` inside the
404
+ # `post[:payment_method_options][:card]` hash. Since this is a beta field adding an extra check to use
405
+ # the existing logic by default. To be able to utilize this field, you must reach out to Stripe.
406
+
407
+ def add_stored_credentials(post, options = {})
408
+ return unless options[:stored_credential] && !options[:stored_credential].values.all?(&:nil?)
409
+
410
+ post[:payment_method_options] ||= {}
411
+ post[:payment_method_options][:card] ||= {}
412
+ add_stored_credential_transaction_type(post, options) if options[:stored_credential_transaction_type]
413
+
414
+ stored_credential = options[:stored_credential]
415
+ post[:payment_method_options][:card][:mit_exemption] = {}
416
+
417
+ # Stripe PI accepts network_transaction_id and ds_transaction_id via mit field under card.
418
+ # The network_transaction_id can be sent in nested under stored credentials OR as its own field (add_ntid handles when it is sent in on its own)
419
+ # If it is sent is as its own field AND under stored credentials, the value sent under its own field is what will send.
420
+ post[:payment_method_options][:card][:mit_exemption][:ds_transaction_id] = stored_credential[:ds_transaction_id] if stored_credential[:ds_transaction_id]
421
+ post[:payment_method_options][:card][:mit_exemption][:network_transaction_id] = stored_credential[:network_transaction_id] if stored_credential[:network_transaction_id]
422
+ end
423
+
424
+ def add_stored_credential_transaction_type(post, options = {})
425
+ stored_credential = options[:stored_credential]
426
+ # Do not add anything unless these are present.
427
+ return unless stored_credential[:reason_type] && stored_credential[:initiator]
428
+
429
+ # Not compatible with off_session parameter.
430
+ options.delete(:off_session)
431
+ if stored_credential[:initial_transaction]
432
+ # Initial transactions must by CIT
433
+ return unless stored_credential[:initiator] == 'cardholder'
434
+
435
+ initial_transaction_stored_credential(post, stored_credential[:reason_type])
436
+ else
437
+ # Subsequent transaction
438
+ subsequent_transaction_stored_credential(post, stored_credential[:initiator], stored_credential[:reason_type])
439
+ end
440
+ end
441
+
442
+ def initial_transaction_stored_credential(post, reason_type)
443
+ if reason_type == 'unscheduled'
444
+ # Charge on-session and store card for future one-off payment use
445
+ post[:payment_method_options][:card][:stored_credential_transaction_type] = 'setup_off_session_unscheduled'
446
+ elsif reason_type == 'recurring'
447
+ # Charge on-session and store card for future recurring payment use
448
+ post[:payment_method_options][:card][:stored_credential_transaction_type] = 'setup_off_session_recurring'
449
+ else
450
+ # Charge on-session and store card for future on-session payment use.
451
+ post[:payment_method_options][:card][:stored_credential_transaction_type] = 'setup_on_session'
452
+ end
453
+ end
454
+
455
+ def subsequent_transaction_stored_credential(post, initiator, reason_type)
456
+ if initiator == 'cardholder'
457
+ # Charge on-session customer using previously stored card.
458
+ post[:payment_method_options][:card][:stored_credential_transaction_type] = 'stored_on_session'
459
+ elsif reason_type == 'recurring'
460
+ # Charge off-session customer using previously stored card for recurring transaction
461
+ post[:payment_method_options][:card][:stored_credential_transaction_type] = 'stored_off_session_recurring'
462
+ else
463
+ # Charge off-session customer using previously stored card for one-off transaction
464
+ post[:payment_method_options][:card][:stored_credential_transaction_type] = 'stored_off_session_unscheduled'
465
+ end
466
+ end
467
+
468
+ def add_ntid(post, options = {})
469
+ return unless options[:network_transaction_id]
470
+
471
+ post[:payment_method_options] ||= {}
472
+ post[:payment_method_options][:card] ||= {}
473
+ post[:payment_method_options][:card][:mit_exemption] = {}
474
+
475
+ post[:payment_method_options][:card][:mit_exemption][:network_transaction_id] = options[:network_transaction_id] if options[:network_transaction_id]
476
+ end
477
+
478
+ def add_claim_without_transaction_id(post, options = {})
479
+ return if options[:stored_credential] || options[:network_transaction_id] || options[:ds_transaction_id]
480
+ return unless options[:claim_without_transaction_id]
481
+
482
+ post[:payment_method_options] ||= {}
483
+ post[:payment_method_options][:card] ||= {}
484
+ post[:payment_method_options][:card][:mit_exemption] = {}
485
+
486
+ # Stripe PI accepts claim_without_transaction_id for transactions without transaction ids.
487
+ # Gateway validation for this field occurs through a different service, before the transaction request is sent to the gateway.
488
+ post[:payment_method_options][:card][:mit_exemption][:claim_without_transaction_id] = options[:claim_without_transaction_id]
489
+ end
490
+
491
+ def add_error_on_requires_action(post, options = {})
492
+ return unless options[:confirm]
493
+
494
+ post[:error_on_requires_action] = true if options[:error_on_requires_action]
495
+ end
496
+
497
+ def request_three_d_secure(post, options = {})
498
+ return unless options[:request_three_d_secure] && %w(any automatic).include?(options[:request_three_d_secure])
499
+
500
+ post[:payment_method_options] ||= {}
501
+ post[:payment_method_options][:card] ||= {}
502
+ post[:payment_method_options][:card][:request_three_d_secure] = options[:request_three_d_secure]
503
+ end
504
+
505
+ def add_external_three_d_secure_auth_data(post, options = {})
506
+ return unless options[:three_d_secure]&.is_a?(Hash)
507
+
508
+ three_d_secure = options[:three_d_secure]
509
+ post[:payment_method_options] ||= {}
510
+ post[:payment_method_options][:card] ||= {}
511
+ post[:payment_method_options][:card][:three_d_secure] ||= {}
512
+ post[:payment_method_options][:card][:three_d_secure][:version] = three_d_secure[:version] || (three_d_secure[:ds_transaction_id] ? '2.2.0' : '1.0.2')
513
+ post[:payment_method_options][:card][:three_d_secure][:electronic_commerce_indicator] = three_d_secure[:eci] if three_d_secure[:eci]
514
+ post[:payment_method_options][:card][:three_d_secure][:cryptogram] = three_d_secure[:cavv] if three_d_secure[:cavv]
515
+ post[:payment_method_options][:card][:three_d_secure][:transaction_id] = three_d_secure[:ds_transaction_id] || three_d_secure[:xid]
516
+ end
517
+
518
+ def setup_future_usage(post, options = {})
519
+ post[:setup_future_usage] = options[:setup_future_usage] if %w(on_session off_session).include?(options[:setup_future_usage])
520
+ post[:off_session] = options[:off_session] if off_session_request?(options)
521
+ post
522
+ end
523
+
524
+ def add_billing_address_for_card_tokenization(post, options = {})
525
+ return unless (billing = options[:billing_address] || options[:address])
526
+
527
+ post[:card][:address_city] = billing[:city] if billing[:city]
528
+ post[:card][:address_country] = billing[:country] if billing[:country]
529
+ post[:card][:address_line1] = billing[:address1] if billing[:address1]
530
+ post[:card][:address_line2] = billing[:address2] if billing[:address2]
531
+ post[:card][:address_zip] = billing[:zip] if billing[:zip]
532
+ post[:card][:address_state] = billing[:state] if billing[:state]
533
+ end
534
+
535
+ def add_billing_address(post, options = {})
536
+ return unless billing = options[:billing_address] || options[:address]
537
+
538
+ email = billing[:email] || options[:email]
539
+
540
+ post[:billing_details] = {}
541
+ post[:billing_details][:address] = {}
542
+ post[:billing_details][:address][:city] = billing[:city] if billing[:city]
543
+ post[:billing_details][:address][:country] = billing[:country] if billing[:country]
544
+ post[:billing_details][:address][:line1] = billing[:address1] if billing[:address1]
545
+ post[:billing_details][:address][:line2] = billing[:address2] if billing[:address2]
546
+ post[:billing_details][:address][:postal_code] = billing[:zip] if billing[:zip]
547
+ post[:billing_details][:address][:state] = billing[:state] if billing[:state]
548
+ post[:billing_details][:email] = email if email
549
+ post[:billing_details][:name] = billing[:name] if billing[:name]
550
+ post[:billing_details][:phone] = billing[:phone] if billing[:phone]
551
+ end
552
+
553
+ def add_name_only(post, payment_method)
554
+ post[:billing_details] = {} unless post[:billing_details]
555
+
556
+ name = [payment_method.first_name, payment_method.last_name].compact.join(' ')
557
+ post[:billing_details][:name] = name
558
+ end
559
+
560
+ def add_shipping_address(post, options = {})
561
+ return unless shipping = options[:shipping_address]
562
+
563
+ post[:shipping] = {}
564
+
565
+ # fields required by Stripe PI
566
+ post[:shipping][:address] = {}
567
+ post[:shipping][:address][:line1] = shipping[:address1]
568
+ post[:shipping][:name] = shipping[:name]
569
+
570
+ # fields considered optional by Stripe PI
571
+ post[:shipping][:address][:city] = shipping[:city] if shipping[:city]
572
+ post[:shipping][:address][:country] = shipping[:country] if shipping[:country]
573
+ post[:shipping][:address][:line2] = shipping[:address2] if shipping[:address2]
574
+ post[:shipping][:address][:postal_code] = shipping[:zip] if shipping[:zip]
575
+ post[:shipping][:address][:state] = shipping[:state] if shipping[:state]
576
+ post[:shipping][:phone] = shipping[:phone_number] if shipping[:phone_number]
577
+ post[:shipping][:carrier] = (shipping[:carrier] || options[:shipping_carrier]) if shipping[:carrier] || options[:shipping_carrier]
578
+ post[:shipping][:tracking_number] = (shipping[:tracking_number] || options[:shipping_tracking_number]) if shipping[:tracking_number] || options[:shipping_tracking_number]
579
+ end
580
+
581
+ def format_idempotency_key(options, suffix)
582
+ return options unless options[:idempotency_key]
583
+
584
+ options.merge(idempotency_key: "#{options[:idempotency_key]}-#{suffix}")
585
+ end
586
+
587
+ def success_from(response, options)
588
+ if response['status'] == 'requires_action' && !options[:execute_threed]
589
+ response['error'] = {}
590
+ response['error']['message'] = 'Received unexpected 3DS authentication response, but a 3DS initiation flag was not included in the request.'
591
+ return false
592
+ end
593
+
594
+ super(response, options)
595
+ end
596
+
597
+ def add_currency(post, options, money)
598
+ post[:currency] = options[:currency] || currency(money)
599
+ end
600
+ end
601
+ end
602
+ end