activemerchant 1.133.0 → 1.138.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +450 -0
  3. data/CONTRIBUTORS +1 -0
  4. data/lib/active_merchant/billing/apple_pay_payment_token.rb +2 -2
  5. data/lib/active_merchant/billing/base.rb +2 -2
  6. data/lib/active_merchant/billing/check.rb +16 -4
  7. data/lib/active_merchant/billing/compatibility.rb +4 -4
  8. data/lib/active_merchant/billing/credit_card.rb +35 -16
  9. data/lib/active_merchant/billing/credit_card_formatting.rb +13 -2
  10. data/lib/active_merchant/billing/credit_card_methods.rb +74 -19
  11. data/lib/active_merchant/billing/gateway.rb +22 -2
  12. data/lib/active_merchant/billing/gateways/adyen.rb +282 -87
  13. data/lib/active_merchant/billing/gateways/airwallex.rb +46 -25
  14. data/lib/active_merchant/billing/gateways/alelo.rb +29 -11
  15. data/lib/active_merchant/billing/gateways/allied_wallet.rb +2 -2
  16. data/lib/active_merchant/billing/gateways/authorize_net.rb +49 -41
  17. data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +14 -10
  18. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +3 -5
  19. data/lib/active_merchant/billing/gateways/axcessms.rb +9 -5
  20. data/lib/active_merchant/billing/gateways/balanced.rb +2 -2
  21. data/lib/active_merchant/billing/gateways/bambora_apac.rb +2 -2
  22. data/lib/active_merchant/billing/gateways/bank_frick.rb +2 -2
  23. data/lib/active_merchant/billing/gateways/banwire.rb +6 -4
  24. data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +8 -8
  25. data/lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb +2 -2
  26. data/lib/active_merchant/billing/gateways/be2bill.rb +2 -2
  27. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +12 -8
  28. data/lib/active_merchant/billing/gateways/beanstream.rb +2 -2
  29. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +2 -2
  30. data/lib/active_merchant/billing/gateways/blue_pay.rb +15 -7
  31. data/lib/active_merchant/billing/gateways/blue_snap.rb +5 -5
  32. data/lib/active_merchant/billing/gateways/bogus.rb +2 -2
  33. data/lib/active_merchant/billing/gateways/borgun.rb +2 -2
  34. data/lib/active_merchant/billing/gateways/bpoint.rb +2 -2
  35. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +3 -1
  36. data/lib/active_merchant/billing/gateways/braintree/token_nonce.rb +68 -23
  37. data/lib/active_merchant/billing/gateways/braintree.rb +2 -2
  38. data/lib/active_merchant/billing/gateways/braintree_blue.rb +266 -89
  39. data/lib/active_merchant/billing/gateways/braintree_orange.rb +3 -3
  40. data/lib/active_merchant/billing/gateways/bridge_pay.rb +2 -2
  41. data/lib/active_merchant/billing/gateways/cams.rb +2 -2
  42. data/lib/active_merchant/billing/gateways/card_connect.rb +7 -4
  43. data/lib/active_merchant/billing/gateways/card_save.rb +2 -2
  44. data/lib/active_merchant/billing/gateways/card_stream.rb +12 -13
  45. data/lib/active_merchant/billing/gateways/cardknox.rb +2 -2
  46. data/lib/active_merchant/billing/gateways/cardprocess.rb +2 -2
  47. data/lib/active_merchant/billing/gateways/cashnet.rb +4 -4
  48. data/lib/active_merchant/billing/gateways/cc5.rb +2 -2
  49. data/lib/active_merchant/billing/gateways/cecabank/cecabank_common.rb +36 -0
  50. data/lib/active_merchant/billing/gateways/cecabank/cecabank_json.rb +331 -0
  51. data/lib/active_merchant/billing/gateways/cecabank/cecabank_xml.rb +220 -0
  52. data/lib/active_merchant/billing/gateways/cecabank.rb +9 -242
  53. data/lib/active_merchant/billing/gateways/cenpos.rb +9 -3
  54. data/lib/active_merchant/billing/gateways/checkout.rb +5 -5
  55. data/lib/active_merchant/billing/gateways/checkout_v2.rb +362 -50
  56. data/lib/active_merchant/billing/gateways/clearhaus.rb +2 -2
  57. data/lib/active_merchant/billing/gateways/commerce_hub.rb +117 -35
  58. data/lib/active_merchant/billing/gateways/commercegate.rb +4 -4
  59. data/lib/active_merchant/billing/gateways/conekta.rb +2 -2
  60. data/lib/active_merchant/billing/gateways/creditcall.rb +2 -2
  61. data/lib/active_merchant/billing/gateways/credorax.rb +109 -20
  62. data/lib/active_merchant/billing/gateways/ct_payment.rb +6 -6
  63. data/lib/active_merchant/billing/gateways/culqi.rb +2 -2
  64. data/lib/active_merchant/billing/gateways/cyber_source/cyber_source_common.rb +2 -2
  65. data/lib/active_merchant/billing/gateways/cyber_source.rb +379 -100
  66. data/lib/active_merchant/billing/gateways/cyber_source_rest.rb +147 -76
  67. data/lib/active_merchant/billing/gateways/d_local.rb +45 -22
  68. data/lib/active_merchant/billing/gateways/data_cash.rb +22 -18
  69. data/lib/active_merchant/billing/gateways/datatrans.rb +284 -0
  70. data/lib/active_merchant/billing/gateways/decidir.rb +82 -46
  71. data/lib/active_merchant/billing/gateways/decidir_plus.rb +31 -35
  72. data/lib/active_merchant/billing/gateways/deepstack.rb +382 -0
  73. data/lib/active_merchant/billing/gateways/dibs.rb +3 -3
  74. data/lib/active_merchant/billing/gateways/digitzs.rb +2 -2
  75. data/lib/active_merchant/billing/gateways/ebanx.rb +116 -68
  76. data/lib/active_merchant/billing/gateways/efsnet.rb +13 -8
  77. data/lib/active_merchant/billing/gateways/elavon.rb +80 -47
  78. data/lib/active_merchant/billing/gateways/element.rb +39 -10
  79. data/lib/active_merchant/billing/gateways/epay.rb +8 -4
  80. data/lib/active_merchant/billing/gateways/evo_ca.rb +8 -4
  81. data/lib/active_merchant/billing/gateways/eway.rb +6 -4
  82. data/lib/active_merchant/billing/gateways/eway_managed.rb +8 -4
  83. data/lib/active_merchant/billing/gateways/eway_rapid.rb +3 -3
  84. data/lib/active_merchant/billing/gateways/exact.rb +8 -4
  85. data/lib/active_merchant/billing/gateways/fat_zebra.rb +37 -7
  86. data/lib/active_merchant/billing/gateways/federated_canada.rb +8 -4
  87. data/lib/active_merchant/billing/gateways/finansbank.rb +2 -2
  88. data/lib/active_merchant/billing/gateways/first_giving.rb +2 -2
  89. data/lib/active_merchant/billing/gateways/first_pay/first_pay_common.rb +15 -0
  90. data/lib/active_merchant/billing/gateways/first_pay/first_pay_json.rb +190 -0
  91. data/lib/active_merchant/billing/gateways/first_pay/first_pay_xml.rb +183 -0
  92. data/lib/active_merchant/billing/gateways/first_pay.rb +8 -174
  93. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +8 -4
  94. data/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb +9 -5
  95. data/lib/active_merchant/billing/gateways/flex_charge.rb +359 -0
  96. data/lib/active_merchant/billing/gateways/flo2cash.rb +4 -2
  97. data/lib/active_merchant/billing/gateways/flo2cash_simple.rb +2 -2
  98. data/lib/active_merchant/billing/gateways/forte.rb +6 -4
  99. data/lib/active_merchant/billing/gateways/fortis.rb +347 -0
  100. data/lib/active_merchant/billing/gateways/garanti.rb +6 -4
  101. data/lib/active_merchant/billing/gateways/global_collect.rb +69 -50
  102. data/lib/active_merchant/billing/gateways/global_transport.rb +2 -2
  103. data/lib/active_merchant/billing/gateways/hdfc.rb +2 -2
  104. data/lib/active_merchant/billing/gateways/hi_pay.rb +287 -0
  105. data/lib/active_merchant/billing/gateways/hps.rb +40 -47
  106. data/lib/active_merchant/billing/gateways/iats_payments.rb +9 -4
  107. data/lib/active_merchant/billing/gateways/in_context_paypal_express.rb +2 -2
  108. data/lib/active_merchant/billing/gateways/inspire.rb +8 -6
  109. data/lib/active_merchant/billing/gateways/instapay.rb +9 -6
  110. data/lib/active_merchant/billing/gateways/ipg.rb +14 -10
  111. data/lib/active_merchant/billing/gateways/ipp.rb +2 -2
  112. data/lib/active_merchant/billing/gateways/iridium.rb +18 -8
  113. data/lib/active_merchant/billing/gateways/itransact.rb +8 -4
  114. data/lib/active_merchant/billing/gateways/iveri.rb +12 -9
  115. data/lib/active_merchant/billing/gateways/ixopay.rb +4 -4
  116. data/lib/active_merchant/billing/gateways/jetpay.rb +6 -4
  117. data/lib/active_merchant/billing/gateways/jetpay_v2.rb +9 -6
  118. data/lib/active_merchant/billing/gateways/komoju.rb +2 -2
  119. data/lib/active_merchant/billing/gateways/kushki.rb +79 -16
  120. data/lib/active_merchant/billing/gateways/latitude19.rb +2 -2
  121. data/lib/active_merchant/billing/gateways/linkpoint.rb +8 -4
  122. data/lib/active_merchant/billing/gateways/litle.rb +37 -54
  123. data/lib/active_merchant/billing/gateways/loan_payment_pro.rb +267 -0
  124. data/lib/active_merchant/billing/gateways/loan_payment_pro_ach.rb +93 -0
  125. data/lib/active_merchant/billing/gateways/mastercard.rb +4 -4
  126. data/lib/active_merchant/billing/gateways/maxipago.rb +4 -4
  127. data/lib/active_merchant/billing/gateways/mercado_pago.rb +32 -11
  128. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +10 -7
  129. data/lib/active_merchant/billing/gateways/merchant_one.rb +2 -2
  130. data/lib/active_merchant/billing/gateways/merchant_partners.rb +2 -2
  131. data/lib/active_merchant/billing/gateways/merchant_ware.rb +13 -6
  132. data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +13 -6
  133. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +21 -5
  134. data/lib/active_merchant/billing/gateways/mercury.rb +11 -5
  135. data/lib/active_merchant/billing/gateways/metrics_global.rb +10 -8
  136. data/lib/active_merchant/billing/gateways/micropayment.rb +2 -2
  137. data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +7 -6
  138. data/lib/active_merchant/billing/gateways/migs.rb +8 -4
  139. data/lib/active_merchant/billing/gateways/mit.rb +10 -5
  140. data/lib/active_merchant/billing/gateways/modern_payments.rb +2 -2
  141. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +21 -13
  142. data/lib/active_merchant/billing/gateways/moka.rb +2 -2
  143. data/lib/active_merchant/billing/gateways/monei.rb +3 -3
  144. data/lib/active_merchant/billing/gateways/moneris.rb +11 -5
  145. data/lib/active_merchant/billing/gateways/money_movers.rb +8 -4
  146. data/lib/active_merchant/billing/gateways/multi_pay.rb +267 -0
  147. data/lib/active_merchant/billing/gateways/mundipagg.rb +5 -3
  148. data/lib/active_merchant/billing/gateways/nab_transact.rb +18 -10
  149. data/lib/active_merchant/billing/gateways/ncr_secure_pay.rb +2 -2
  150. data/lib/active_merchant/billing/gateways/net_registry.rb +6 -2
  151. data/lib/active_merchant/billing/gateways/netaxept.rb +4 -4
  152. data/lib/active_merchant/billing/gateways/netbanx.rb +4 -6
  153. data/lib/active_merchant/billing/gateways/netbilling.rb +8 -4
  154. data/lib/active_merchant/billing/gateways/netpay.rb +2 -2
  155. data/lib/active_merchant/billing/gateways/network_merchants.rb +9 -5
  156. data/lib/active_merchant/billing/gateways/nmi.rb +29 -8
  157. data/lib/active_merchant/billing/gateways/nuvei.rb +573 -0
  158. data/lib/active_merchant/billing/gateways/ogone.rb +8 -4
  159. data/lib/active_merchant/billing/gateways/omise.rb +2 -2
  160. data/lib/active_merchant/billing/gateways/openpay.rb +6 -4
  161. data/lib/active_merchant/billing/gateways/opp.rb +3 -4
  162. data/lib/active_merchant/billing/gateways/optimal_payment.rb +12 -6
  163. data/lib/active_merchant/billing/gateways/orbital/orbital_codes.rb +273 -0
  164. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +3 -5
  165. data/lib/active_merchant/billing/gateways/orbital.rb +114 -94
  166. data/lib/active_merchant/billing/gateways/pac_net_raven.rb +9 -6
  167. data/lib/active_merchant/billing/gateways/pagarme.rb +2 -2
  168. data/lib/active_merchant/billing/gateways/pago_facil.rb +2 -2
  169. data/lib/active_merchant/billing/gateways/pay_arc.rb +9 -7
  170. data/lib/active_merchant/billing/gateways/pay_conex.rb +6 -4
  171. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +8 -4
  172. data/lib/active_merchant/billing/gateways/pay_hub.rb +7 -5
  173. data/lib/active_merchant/billing/gateways/pay_junction.rb +8 -4
  174. data/lib/active_merchant/billing/gateways/pay_junction_v2.rb +2 -2
  175. data/lib/active_merchant/billing/gateways/pay_secure.rb +8 -4
  176. data/lib/active_merchant/billing/gateways/pay_trace.rb +36 -22
  177. data/lib/active_merchant/billing/gateways/paybox_direct.rb +14 -14
  178. data/lib/active_merchant/billing/gateways/payeezy.rb +26 -13
  179. data/lib/active_merchant/billing/gateways/payex.rb +8 -6
  180. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +3 -3
  181. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +2 -2
  182. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +2 -2
  183. data/lib/active_merchant/billing/gateways/payflow.rb +12 -11
  184. data/lib/active_merchant/billing/gateways/payflow_express.rb +2 -2
  185. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +2 -2
  186. data/lib/active_merchant/billing/gateways/payflow_uk.rb +2 -2
  187. data/lib/active_merchant/billing/gateways/payment_express.rb +10 -6
  188. data/lib/active_merchant/billing/gateways/paymentez.rb +30 -16
  189. data/lib/active_merchant/billing/gateways/paymill.rb +6 -4
  190. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +17 -12
  191. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +2 -2
  192. data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +2 -2
  193. data/lib/active_merchant/billing/gateways/paypal.rb +4 -2
  194. data/lib/active_merchant/billing/gateways/paypal_ca.rb +2 -2
  195. data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +2 -2
  196. data/lib/active_merchant/billing/gateways/paypal_express.rb +4 -2
  197. data/lib/active_merchant/billing/gateways/paysafe.rb +48 -24
  198. data/lib/active_merchant/billing/gateways/payscout.rb +9 -6
  199. data/lib/active_merchant/billing/gateways/paystation.rb +9 -5
  200. data/lib/active_merchant/billing/gateways/payu_in.rb +2 -2
  201. data/lib/active_merchant/billing/gateways/payu_latam.rb +7 -5
  202. data/lib/active_merchant/billing/gateways/payway.rb +6 -2
  203. data/lib/active_merchant/billing/gateways/payway_dot_com.rb +6 -6
  204. data/lib/active_merchant/billing/gateways/pin.rb +126 -41
  205. data/lib/active_merchant/billing/gateways/plexo.rb +71 -20
  206. data/lib/active_merchant/billing/gateways/plugnpay.rb +6 -2
  207. data/lib/active_merchant/billing/gateways/priority.rb +29 -24
  208. data/lib/active_merchant/billing/gateways/pro_pay.rb +2 -2
  209. data/lib/active_merchant/billing/gateways/psigate.rb +8 -4
  210. data/lib/active_merchant/billing/gateways/psl_card.rb +6 -2
  211. data/lib/active_merchant/billing/gateways/qbms.rb +9 -5
  212. data/lib/active_merchant/billing/gateways/quantum.rb +9 -5
  213. data/lib/active_merchant/billing/gateways/quickbooks.rb +27 -17
  214. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +7 -4
  215. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb +8 -4
  216. data/lib/active_merchant/billing/gateways/quickpay.rb +2 -2
  217. data/lib/active_merchant/billing/gateways/qvalent.rb +2 -2
  218. data/lib/active_merchant/billing/gateways/rapyd.rb +172 -53
  219. data/lib/active_merchant/billing/gateways/reach.rb +16 -9
  220. data/lib/active_merchant/billing/gateways/redsys.rb +7 -15
  221. data/lib/active_merchant/billing/gateways/redsys_rest.rb +545 -0
  222. data/lib/active_merchant/billing/gateways/s5.rb +5 -5
  223. data/lib/active_merchant/billing/gateways/safe_charge.rb +47 -24
  224. data/lib/active_merchant/billing/gateways/sage.rb +14 -6
  225. data/lib/active_merchant/billing/gateways/sage_pay.rb +81 -7
  226. data/lib/active_merchant/billing/gateways/sallie_mae.rb +8 -4
  227. data/lib/active_merchant/billing/gateways/secure_net.rb +9 -5
  228. data/lib/active_merchant/billing/gateways/secure_pay.rb +10 -8
  229. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +25 -15
  230. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +8 -4
  231. data/lib/active_merchant/billing/gateways/securion_pay.rb +26 -12
  232. data/lib/active_merchant/billing/gateways/shift4.rb +34 -26
  233. data/lib/active_merchant/billing/gateways/shift4_v2.rb +117 -0
  234. data/lib/active_merchant/billing/gateways/simetrik.rb +26 -17
  235. data/lib/active_merchant/billing/gateways/skip_jack.rb +8 -4
  236. data/lib/active_merchant/billing/gateways/smart_ps.rb +10 -7
  237. data/lib/active_merchant/billing/gateways/so_easy_pay.rb +6 -4
  238. data/lib/active_merchant/billing/gateways/spreedly_core.rb +4 -6
  239. data/lib/active_merchant/billing/gateways/stripe.rb +88 -84
  240. data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +388 -77
  241. data/lib/active_merchant/billing/gateways/sum_up.rb +224 -0
  242. data/lib/active_merchant/billing/gateways/swipe_checkout.rb +6 -4
  243. data/lib/active_merchant/billing/gateways/telr.rb +6 -7
  244. data/lib/active_merchant/billing/gateways/trans_first.rb +6 -4
  245. data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +10 -18
  246. data/lib/active_merchant/billing/gateways/transact_pro.rb +3 -3
  247. data/lib/active_merchant/billing/gateways/transax.rb +2 -2
  248. data/lib/active_merchant/billing/gateways/transnational.rb +2 -2
  249. data/lib/active_merchant/billing/gateways/trexle.rb +2 -2
  250. data/lib/active_merchant/billing/gateways/trust_commerce.rb +9 -5
  251. data/lib/active_merchant/billing/gateways/usa_epay.rb +2 -2
  252. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +32 -31
  253. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +8 -4
  254. data/lib/active_merchant/billing/gateways/vanco.rb +2 -4
  255. data/lib/active_merchant/billing/gateways/vantiv_express.rb +668 -0
  256. data/lib/active_merchant/billing/gateways/verifi.rb +12 -8
  257. data/lib/active_merchant/billing/gateways/versa_pay.rb +307 -0
  258. data/lib/active_merchant/billing/gateways/viaklix.rb +8 -4
  259. data/lib/active_merchant/billing/gateways/visanet_peru.rb +5 -5
  260. data/lib/active_merchant/billing/gateways/vpos.rb +25 -13
  261. data/lib/active_merchant/billing/gateways/webpay.rb +3 -3
  262. data/lib/active_merchant/billing/gateways/wepay.rb +6 -4
  263. data/lib/active_merchant/billing/gateways/wirecard.rb +10 -6
  264. data/lib/active_merchant/billing/gateways/wompi.rb +14 -7
  265. data/lib/active_merchant/billing/gateways/world_net.rb +2 -2
  266. data/lib/active_merchant/billing/gateways/worldpay.rb +297 -113
  267. data/lib/active_merchant/billing/gateways/worldpay_online_payments.rb +16 -13
  268. data/lib/active_merchant/billing/gateways/worldpay_us.rb +2 -2
  269. data/lib/active_merchant/billing/gateways/xpay.rb +244 -0
  270. data/lib/active_merchant/billing/network_tokenization_credit_card.rb +15 -3
  271. data/lib/active_merchant/billing/payment_token.rb +2 -2
  272. data/lib/active_merchant/billing/response.rb +7 -6
  273. data/lib/active_merchant/billing.rb +1 -0
  274. data/lib/active_merchant/connection.rb +8 -20
  275. data/lib/active_merchant/country.rb +3 -1
  276. data/lib/active_merchant/errors.rb +12 -2
  277. data/lib/active_merchant/net_http_ssl_connection.rb +35 -0
  278. data/lib/active_merchant/posts_data.rb +19 -4
  279. data/lib/active_merchant/version.rb +1 -1
  280. data/lib/active_merchant/versionable.rb +29 -0
  281. data/lib/certs/cacert.pem +1326 -1491
  282. data/lib/support/gateway_support.rb +3 -3
  283. data/lib/support/ssl_verify.rb +6 -6
  284. data/lib/support/ssl_version.rb +8 -8
  285. metadata +35 -9
@@ -1,20 +1,26 @@
1
1
  require 'active_support/core_ext/hash/slice'
2
2
 
3
- module ActiveMerchant #:nodoc:
4
- module Billing #:nodoc:
3
+ module ActiveMerchant # :nodoc:
4
+ module Billing # :nodoc:
5
5
  # This gateway uses the current Stripe {Payment Intents API}[https://stripe.com/docs/api/payment_intents].
6
6
  # For the legacy API, see the Stripe gateway
7
7
  class StripePaymentIntentsGateway < StripeGateway
8
+ version '2022-11-15'
9
+
8
10
  ALLOWED_METHOD_STATES = %w[automatic manual].freeze
9
11
  ALLOWED_CANCELLATION_REASONS = %w[duplicate fraudulent requested_by_customer abandoned].freeze
10
12
  CREATE_INTENT_ATTRIBUTES = %i[description statement_descriptor_suffix statement_descriptor receipt_email save_payment_method]
11
13
  CONFIRM_INTENT_ATTRIBUTES = %i[receipt_email return_url save_payment_method setup_future_usage off_session]
12
14
  UPDATE_INTENT_ATTRIBUTES = %i[description statement_descriptor_suffix statement_descriptor receipt_email setup_future_usage]
13
- DEFAULT_API_VERSION = '2020-08-27'
15
+ ALLOWED_MULTICAPTURE_OPTIONS = %w[if_available never].freeze
16
+ DIGITAL_WALLETS = {
17
+ apple_pay: 'apple_pay',
18
+ google_pay: 'google_pay_dpan'
19
+ }
14
20
 
15
21
  def create_intent(money, payment_method, options = {})
16
22
  MultiResponse.run do |r|
17
- if payment_method.is_a?(NetworkTokenizationCreditCard)
23
+ if payment_method.is_a?(NetworkTokenizationCreditCard) && digital_wallet_payment_method?(payment_method) && options[:new_ap_gp_route] != true
18
24
  r.process { tokenize_apple_google(payment_method, options) }
19
25
  payment_method = (r.params['token']['id']) if r.success?
20
26
  end
@@ -25,9 +31,15 @@ module ActiveMerchant #:nodoc:
25
31
  add_confirmation_method(post, options)
26
32
  add_customer(post, options)
27
33
 
28
- result = add_payment_method_token(post, payment_method, options)
29
- return result if result.is_a?(ActiveMerchant::Billing::Response)
34
+ if new_apple_google_pay_flow(payment_method, options)
35
+ add_digital_wallet(post, payment_method, options)
36
+ add_billing_address(post, payment_method, options)
37
+ else
38
+ result = add_payment_method_token(post, payment_method, options)
39
+ return result if result.is_a?(ActiveMerchant::Billing::Response)
40
+ end
30
41
 
42
+ add_network_token_info(post, payment_method, options)
31
43
  add_external_three_d_secure_auth_data(post, options)
32
44
  add_metadata(post, options)
33
45
  add_return_url(post, options)
@@ -43,6 +55,12 @@ module ActiveMerchant #:nodoc:
43
55
  add_fulfillment_date(post, options)
44
56
  request_three_d_secure(post, options)
45
57
  add_level_three(post, options)
58
+ add_card_brand(post, options)
59
+ add_aft_recipient_details(post, options)
60
+ add_aft_sender_details(post, options)
61
+ add_request_extended_authorization(post, options)
62
+ add_statement_descriptor_suffix_kanji_kana(post, options)
63
+ add_request_multicapture(post, options)
46
64
 
47
65
  CREATE_INTENT_ATTRIBUTES.each do |attribute|
48
66
  add_whitelisted_attribute(post, options, attribute)
@@ -53,7 +71,7 @@ module ActiveMerchant #:nodoc:
53
71
  end
54
72
 
55
73
  def show_intent(intent_id, options)
56
- commit(:get, "payment_intents/#{intent_id}", nil, options)
74
+ commit(:get, "payment_intents/#{intent_id}?expand[]=latest_charge.balance_transaction", nil, options)
57
75
  end
58
76
 
59
77
  def create_test_customer
@@ -63,9 +81,14 @@ module ActiveMerchant #:nodoc:
63
81
 
64
82
  def confirm_intent(intent_id, payment_method, options = {})
65
83
  post = {}
66
- result = add_payment_method_token(post, payment_method, options)
67
- return result if result.is_a?(ActiveMerchant::Billing::Response)
84
+ if new_apple_google_pay_flow(payment_method, options)
85
+ add_digital_wallet(post, payment_method, options)
86
+ else
87
+ result = add_payment_method_token(post, payment_method, options)
88
+ return result if result.is_a?(ActiveMerchant::Billing::Response)
89
+ end
68
90
 
91
+ add_network_token_info(post, payment_method, options)
69
92
  add_payment_method_types(post, options)
70
93
  CONFIRM_INTENT_ATTRIBUTES.each do |attribute|
71
94
  add_whitelisted_attribute(post, options, attribute)
@@ -80,22 +103,33 @@ module ActiveMerchant #:nodoc:
80
103
  commit(:post, 'payment_methods', post_data, options)
81
104
  end
82
105
 
106
+ def new_apple_google_pay_flow(payment_method, options)
107
+ return false unless options[:new_ap_gp_route]
108
+
109
+ payment_method.is_a?(NetworkTokenizationCreditCard) && digital_wallet_payment_method?(payment_method)
110
+ end
111
+
83
112
  def add_payment_method_data(payment_method, options = {})
84
113
  post = {
85
114
  type: 'card',
86
115
  card: {
87
- number: payment_method.number,
88
116
  exp_month: payment_method.month,
89
117
  exp_year: payment_method.year
90
118
  }
91
119
  }
92
-
120
+ post[:card][:number] = payment_method.number unless adding_network_token_card_data?(payment_method)
93
121
  post[:card][:cvc] = payment_method.verification_value if payment_method.verification_value
94
122
  if billing = options[:billing_address] || options[:address]
95
123
  post[:billing_details] = add_address(billing, options)
96
124
  end
97
125
 
126
+ # wallet_type is only passed for non-tokenized GooglePay which acts as a CreditCard
127
+ if options[:wallet_type]
128
+ post[:metadata] ||= {}
129
+ post[:metadata][:input_method] = 'GooglePay'
130
+ end
98
131
  add_name_only(post, payment_method) if post[:billing_details].nil?
132
+ add_network_token_data(post, payment_method, options)
99
133
  post
100
134
  end
101
135
 
@@ -110,15 +144,21 @@ module ActiveMerchant #:nodoc:
110
144
  post = {}
111
145
  add_amount(post, money, options)
112
146
 
113
- result = add_payment_method_token(post, payment_method, options)
114
- return result if result.is_a?(ActiveMerchant::Billing::Response)
147
+ if new_apple_google_pay_flow(payment_method, options)
148
+ add_digital_wallet(post, payment_method, options)
149
+ else
150
+ result = add_payment_method_token(post, payment_method, options)
151
+ return result if result.is_a?(ActiveMerchant::Billing::Response)
152
+ end
115
153
 
154
+ add_network_token_info(post, payment_method, options)
116
155
  add_payment_method_types(post, options)
117
156
  add_customer(post, options)
118
157
  add_metadata(post, options)
119
158
  add_shipping_address(post, options)
120
159
  add_connected_account(post, options)
121
160
  add_fulfillment_date(post, options)
161
+ add_statement_descriptor_suffix_kanji_kana(post, options)
122
162
 
123
163
  UPDATE_INTENT_ATTRIBUTES.each do |attribute|
124
164
  add_whitelisted_attribute(post, options, attribute)
@@ -131,13 +171,22 @@ module ActiveMerchant #:nodoc:
131
171
  r.process do
132
172
  post = {}
133
173
  add_customer(post, options)
134
- result = add_payment_method_token(post, payment_method, options, r)
135
- return result if result.is_a?(ActiveMerchant::Billing::Response)
136
174
 
175
+ if new_apple_google_pay_flow(payment_method, options)
176
+ add_digital_wallet(post, payment_method, options)
177
+ add_billing_address(post, payment_method, options)
178
+ else
179
+ result = add_payment_method_token(post, payment_method, options, r)
180
+ return result if result.is_a?(ActiveMerchant::Billing::Response)
181
+ end
182
+
183
+ add_network_token_info(post, payment_method, options)
137
184
  add_metadata(post, options)
138
185
  add_return_url(post, options)
139
186
  add_fulfillment_date(post, options)
140
187
  request_three_d_secure(post, options)
188
+ add_card_brand(post, options)
189
+ add_exemption(post, options)
141
190
  post[:on_behalf_of] = options[:on_behalf_of] if options[:on_behalf_of]
142
191
  post[:usage] = options[:usage] if %w(on_session off_session).include?(options[:usage])
143
192
  post[:description] = options[:description] if options[:description]
@@ -148,14 +197,7 @@ module ActiveMerchant #:nodoc:
148
197
  end
149
198
 
150
199
  def retrieve_setup_intent(setup_intent_id, options = {})
151
- # Retrieving a setup_intent passing 'expand[]=latest_attempt' allows the caller to
152
- # check for a network_transaction_id and ds_transaction_id
153
- # eg (latest_attempt -> payment_method_details -> card -> network_transaction_id)
154
- #
155
- # Being able to retrieve these fields enables payment flows that rely on MIT exemptions, e.g: off_session
156
- commit(:post, "setup_intents/#{setup_intent_id}", {
157
- 'expand[]': 'latest_attempt'
158
- }, options)
200
+ commit(:get, "setup_intents/#{setup_intent_id}?expand[]=latest_attempt", nil, options)
159
201
  end
160
202
 
161
203
  def authorize(money, payment_method, options = {})
@@ -167,6 +209,8 @@ module ActiveMerchant #:nodoc:
167
209
  end
168
210
 
169
211
  def capture(money, intent_id, options = {})
212
+ return Response.new(false, 'Only Authorizations performed via the Payment Intent API are capturable') unless intent_id.include?('pi_')
213
+
170
214
  post = {}
171
215
  currency = options[:currency] || currency(money)
172
216
  post[:amount_to_capture] = localized_amount(money, currency)
@@ -175,6 +219,7 @@ module ActiveMerchant #:nodoc:
175
219
  post[:transfer_data][:amount] = options[:transfer_amount]
176
220
  end
177
221
  post[:application_fee_amount] = options[:application_fee] if options[:application_fee]
222
+ post[:final_capture] = normalize(options[:final_capture]) unless options[:final_capture].nil?
178
223
  options = format_idempotency_key(options, 'capture')
179
224
  commit(:post, "payment_intents/#{intent_id}/capture", post, options)
180
225
  end
@@ -187,11 +232,11 @@ module ActiveMerchant #:nodoc:
187
232
 
188
233
  def refund(money, intent_id, options = {})
189
234
  if intent_id.include?('pi_')
190
- intent = api_request(:get, "payment_intents/#{intent_id}", nil, options)
235
+ intent = api_request(:get, "payment_intents/#{intent_id}?expand[]=latest_charge.balance_transaction", nil, options)
191
236
 
192
237
  return Response.new(false, intent['error']['message'], intent) if intent['error']
193
238
 
194
- charge_id = intent.try(:[], 'charges').try(:[], 'data').try(:[], 0).try(:[], 'id')
239
+ charge_id = intent.try(:[], 'latest_charge').try(:[], 'id')
195
240
 
196
241
  if charge_id.nil?
197
242
  error_message = "No associated charge for #{intent['id']}"
@@ -210,14 +255,16 @@ module ActiveMerchant #:nodoc:
210
255
  # All other types will default to legacy Stripe store
211
256
  def store(payment_method, options = {})
212
257
  params = {}
213
- post = {}
214
258
  # If customer option is provided, create a payment method and attach to customer id
215
259
  # Otherwise, create a customer, then attach
216
- if payment_method.is_a?(StripePaymentToken) || payment_method.is_a?(ActiveMerchant::Billing::CreditCard)
260
+ if new_apple_google_pay_flow(payment_method, options)
261
+ options[:customer] = customer(payment_method, options).params['id'] unless options[:customer]
262
+ verify(payment_method, options.merge!(action: :store))
263
+ elsif payment_method.is_a?(ActiveMerchant::Billing::CreditCard)
217
264
  result = add_payment_method_token(params, payment_method, options)
218
265
  return result if result.is_a?(ActiveMerchant::Billing::Response)
219
266
 
220
- customer_id = options[:customer] || customer(post, payment_method, options).params['id']
267
+ customer_id = options[:customer] || customer(payment_method, options).params['id']
221
268
  options = format_idempotency_key(options, 'attach')
222
269
  attach_parameters = { customer: customer_id }
223
270
  attach_parameters[:validate] = options[:validate] unless options[:validate].nil?
@@ -227,7 +274,8 @@ module ActiveMerchant #:nodoc:
227
274
  end
228
275
  end
229
276
 
230
- def customer(post, payment, options)
277
+ def customer(payment, options)
278
+ post = {}
231
279
  post[:description] = options[:description] if options[:description]
232
280
  post[:expand] = [:sources]
233
281
  post[:email] = options[:email]
@@ -267,8 +315,68 @@ module ActiveMerchant #:nodoc:
267
315
  commit(:post, 'payment_intents', post, options)
268
316
  end
269
317
 
318
+ def inquire(authorization, options = {})
319
+ options.merge!({ request_type: :inquire })
320
+ if authorization&.start_with?('pi_')
321
+ show_intent(authorization, options)
322
+ else
323
+ retrieve_setup_intent(authorization, options)
324
+ end
325
+ end
326
+
327
+ def supports_network_tokenization?
328
+ true
329
+ end
330
+
270
331
  private
271
332
 
333
+ def card_from_response(response)
334
+ extract_payment_intent_details(response) || extract_setup_intent_details(response) || super
335
+ end
336
+
337
+ def extract_payment_intent_details(response)
338
+ return nil if response['latest_charge'].nil? || response['latest_charge']&.is_a?(String)
339
+
340
+ response.dig('latest_charge', 'payment_method_details', 'card', 'checks')
341
+ end
342
+
343
+ def extract_setup_intent_details(response)
344
+ return nil if response['latest_attempt'].nil? || response['latest_attempt']&.is_a?(String)
345
+
346
+ response.dig('latest_attempt', 'payment_method_details', 'card', 'checks')
347
+ end
348
+
349
+ def add_expand_parameters(post, options, method, url)
350
+ post[:expand] ||= []
351
+ post[:expand].concat(Array.wrap(options[:expand]).map(&:to_sym)).uniq!
352
+
353
+ return if method == :get
354
+
355
+ if url.include?('payment_intents')
356
+ post[:expand].concat(['latest_charge', 'latest_charge.balance_transaction'])
357
+ elsif url.include?('setup_intents')
358
+ post[:expand] << 'latest_attempt'
359
+ end
360
+ end
361
+
362
+ def error_id(response, url)
363
+ if url.end_with?('payment_intents')
364
+ response.dig('error', 'payment_intent', 'id') || super
365
+ else
366
+ super
367
+ end
368
+ end
369
+
370
+ def digital_wallet_payment_method?(payment_method)
371
+ payment_method.source == :google_pay || payment_method.source == :apple_pay
372
+ end
373
+
374
+ def adding_network_token_card_data?(payment_method)
375
+ return true if payment_method.is_a?(ActiveMerchant::Billing::NetworkTokenizationCreditCard) && payment_method.source == :network_token
376
+
377
+ false
378
+ end
379
+
272
380
  def off_session_request?(options = {})
273
381
  (options[:off_session] || options[:setup_future_usage]) && options[:confirm] == true
274
382
  end
@@ -307,6 +415,40 @@ module ActiveMerchant #:nodoc:
307
415
  post[:metadata][:event_type] = options[:event_type] if options[:event_type]
308
416
  end
309
417
 
418
+ def add_card_brand(post, options)
419
+ return unless options[:card_brand]
420
+
421
+ post[:payment_method_options] ||= {}
422
+ post[:payment_method_options][:card] ||= {}
423
+ post[:payment_method_options][:card][:network] = options[:card_brand] if options[:card_brand]
424
+ end
425
+
426
+ def add_request_extended_authorization(post, options)
427
+ return unless options[:request_extended_authorization]
428
+
429
+ post[:payment_method_options] ||= {}
430
+ post[:payment_method_options][:card] ||= {}
431
+ post[:payment_method_options][:card][:request_extended_authorization] = options[:request_extended_authorization] if options[:request_extended_authorization]
432
+ end
433
+
434
+ def add_statement_descriptor_suffix_kanji_kana(post, options)
435
+ return unless options[:statement_descriptor_suffix_kanji] || options[:statement_descriptor_suffix_kana]
436
+
437
+ post[:payment_method_options] ||= {}
438
+ post[:payment_method_options][:card] ||= {}
439
+ post[:payment_method_options][:card][:statement_descriptor_suffix_kanji] = options[:statement_descriptor_suffix_kanji] if options[:statement_descriptor_suffix_kanji]
440
+ post[:payment_method_options][:card][:statement_descriptor_suffix_kana] = options[:statement_descriptor_suffix_kana] if options[:statement_descriptor_suffix_kana]
441
+ end
442
+
443
+ def add_request_multicapture(post, options)
444
+ request_multicapture = options[:request_multicapture]
445
+ return unless ALLOWED_MULTICAPTURE_OPTIONS.include?(request_multicapture)
446
+
447
+ post[:payment_method_options] ||= {}
448
+ post[:payment_method_options][:card] ||= {}
449
+ post[:payment_method_options][:card][:request_multicapture] = request_multicapture
450
+ end
451
+
310
452
  def add_level_three(post, options = {})
311
453
  level_three = {}
312
454
 
@@ -320,6 +462,82 @@ module ActiveMerchant #:nodoc:
320
462
  post[:level3] = level_three unless level_three.empty?
321
463
  end
322
464
 
465
+ def add_aft_recipient_details(post, options)
466
+ return unless options[:recipient_details]&.is_a?(Hash)
467
+
468
+ recipient_details = options[:recipient_details]
469
+ post[:payment_method_options] ||= {}
470
+ post[:payment_method_options][:card] ||= {}
471
+ post[:payment_method_options][:card][:recipient_details] = {}
472
+ post[:payment_method_options][:card][:recipient_details][:first_name] = recipient_details[:first_name] if recipient_details[:first_name]
473
+ post[:payment_method_options][:card][:recipient_details][:last_name] = recipient_details[:last_name] if recipient_details[:last_name]
474
+ post[:payment_method_options][:card][:recipient_details][:email] = recipient_details[:email] if recipient_details[:email]
475
+ post[:payment_method_options][:card][:recipient_details][:phone] = recipient_details[:phone] if recipient_details[:phone]
476
+
477
+ if recipient_details[:address].is_a?(Hash)
478
+ address = recipient_details[:address]
479
+ post[:payment_method_options][:card][:recipient_details][:address] = {}
480
+ post[:payment_method_options][:card][:recipient_details][:address][:country] = address[:country] if address[:country]
481
+ post[:payment_method_options][:card][:recipient_details][:address][:line1] = address[:line1] if address[:line1]
482
+ post[:payment_method_options][:card][:recipient_details][:address][:line2] = address[:line2] if address[:line2]
483
+ post[:payment_method_options][:card][:recipient_details][:address][:postal_code] = address[:postal_code] if address[:postal_code]
484
+ post[:payment_method_options][:card][:recipient_details][:address][:state] = address[:state] if address[:state]
485
+ post[:payment_method_options][:card][:recipient_details][:address][:city] = address[:city] if address[:city]
486
+ end
487
+
488
+ if recipient_details[:account_details].is_a?(Hash)
489
+ account_details = recipient_details[:account_details]
490
+ post[:payment_method_options][:card][:recipient_details][:account_details] = {}
491
+
492
+ if account_details[:card].is_a?(Hash)
493
+ card = account_details[:card]
494
+ post[:payment_method_options][:card][:recipient_details][:account_details][:card] = {}
495
+ post[:payment_method_options][:card][:recipient_details][:account_details][:card][:first6] = card[:first6] if card[:first6]
496
+ post[:payment_method_options][:card][:recipient_details][:account_details][:card][:last4] = card[:last4] if card[:last4]
497
+ end
498
+
499
+ if account_details[:unique_identifier].is_a?(Hash)
500
+ unique_identifier = account_details[:unique_identifier]
501
+ post[:payment_method_options][:card][:recipient_details][:account_details][:unique_identifier] = {}
502
+ post[:payment_method_options][:card][:recipient_details][:account_details][:unique_identifier][:identifier] = unique_identifier[:identifier] if unique_identifier[:identifier]
503
+ end
504
+ end
505
+ end
506
+
507
+ def add_aft_sender_details(post, options)
508
+ return unless options[:sender_details]&.is_a?(Hash)
509
+
510
+ sender_details = options[:sender_details]
511
+ post[:payment_method_options] ||= {}
512
+ post[:payment_method_options][:card] ||= {}
513
+ post[:payment_method_options][:card][:sender_details] = {}
514
+ post[:payment_method_options][:card][:sender_details][:first_name] = sender_details[:first_name] if sender_details[:first_name]
515
+ post[:payment_method_options][:card][:sender_details][:last_name] = sender_details[:last_name] if sender_details[:last_name]
516
+ post[:payment_method_options][:card][:sender_details][:email] = sender_details[:email] if sender_details[:email]
517
+ post[:payment_method_options][:card][:sender_details][:occupation] = sender_details[:occupation] if sender_details[:occupation]
518
+ post[:payment_method_options][:card][:sender_details][:nationality] = sender_details[:nationality] if sender_details[:nationality]
519
+ post[:payment_method_options][:card][:sender_details][:birth_country] = sender_details[:birth_country] if sender_details[:birth_country]
520
+
521
+ if sender_details[:address].is_a?(Hash)
522
+ address = sender_details[:address]
523
+ post[:payment_method_options][:card][:sender_details][:address] = {}
524
+ post[:payment_method_options][:card][:sender_details][:address][:country] = address[:country] if address[:country]
525
+ post[:payment_method_options][:card][:sender_details][:address][:line1] = address[:line1] if address[:line1]
526
+ post[:payment_method_options][:card][:sender_details][:address][:line2] = address[:line2] if address[:line2]
527
+ post[:payment_method_options][:card][:sender_details][:address][:postal_code] = address[:postal_code] if address[:postal_code]
528
+ post[:payment_method_options][:card][:sender_details][:address][:state] = address[:state] if address[:state]
529
+ post[:payment_method_options][:card][:sender_details][:address][:city] = address[:city] if address[:city]
530
+ end
531
+
532
+ if sender_details[:dob].is_a?(Hash)
533
+ dob = sender_details[:dob]
534
+ post[:payment_method_options][:card][:sender_details][:dob] = {}
535
+ post[:payment_method_options][:card][:sender_details][:dob][:day] = dob[:day] if dob[:day]
536
+ post[:payment_method_options][:card][:sender_details][:dob][:month] = dob[:month] if dob[:month]
537
+ post[:payment_method_options][:card][:sender_details][:dob][:year] = dob[:year] if dob[:year]
538
+ end
539
+ end
540
+
323
541
  def add_return_url(post, options)
324
542
  return unless options[:confirm]
325
543
 
@@ -329,20 +547,74 @@ module ActiveMerchant #:nodoc:
329
547
 
330
548
  def add_payment_method_token(post, payment_method, options, responses = [])
331
549
  case payment_method
332
- when StripePaymentToken
333
- post[:payment_method_data] = {
334
- type: 'card',
335
- card: {
336
- token: payment_method.payment_data['id'] || payment_method.payment_data
337
- }
338
- }
339
- post[:payment_method] = payment_method.payment_data['id'] || payment_method.payment_data
340
550
  when String
341
551
  extract_token_from_string_and_maybe_add_customer_id(post, payment_method)
342
552
  when ActiveMerchant::Billing::CreditCard
343
553
  return create_payment_method_and_extract_token(post, payment_method, options, responses) if options[:verify]
344
554
 
345
555
  get_payment_method_data_from_card(post, payment_method, options, responses)
556
+ when ActiveMerchant::Billing::NetworkTokenizationCreditCard
557
+ get_payment_method_data_from_card(post, payment_method, options, responses)
558
+ end
559
+ end
560
+
561
+ def add_network_token_data(post_data, payment_method, options)
562
+ return unless adding_network_token_card_data?(payment_method)
563
+
564
+ post_data[:card] ||= {}
565
+ post_data[:card][:last4] = options[:last_4] || payment_method.number[-4..]
566
+ post_data[:card][:network_token] = {}
567
+ post_data[:card][:network_token][:number] = payment_method.number
568
+ post_data[:card][:network_token][:exp_month] = payment_method.month
569
+ post_data[:card][:network_token][:exp_year] = payment_method.year
570
+ post_data[:card][:network_token][:payment_account_reference] = options[:payment_account_reference] if options[:payment_account_reference]
571
+
572
+ post_data
573
+ end
574
+
575
+ def add_network_token_info(post, payment_method, options)
576
+ # wallet_type is only passed for non-tokenized GooglePay which acts as a CreditCard
577
+ if options[:wallet_type]
578
+ post[:metadata] ||= {}
579
+ post[:metadata][:input_method] = 'GooglePay'
580
+ end
581
+
582
+ return unless payment_method.is_a?(NetworkTokenizationCreditCard) && options.dig(:stored_credential, :initiator) != 'merchant'
583
+ return if digital_wallet_payment_method?(payment_method) && options[:new_ap_gp_route] != true
584
+
585
+ post[:payment_method_options] ||= {}
586
+ post[:payment_method_options][:card] ||= {}
587
+ post[:payment_method_options][:card][:network_token] ||= {}
588
+ post[:payment_method_options][:card][:network_token].merge!({
589
+ cryptogram: payment_method.respond_to?(:payment_cryptogram) ? payment_method.payment_cryptogram : options[:cryptogram],
590
+ electronic_commerce_indicator: format_eci(payment_method, options)
591
+ }.compact)
592
+ end
593
+
594
+ def add_digital_wallet(post, payment_method, options)
595
+ post[:payment_method_data] = {
596
+ type: 'card',
597
+ card: {
598
+ last4: options[:last_4] || payment_method.number[-4..],
599
+ exp_month: payment_method.month,
600
+ exp_year: payment_method.year,
601
+ network_token: {
602
+ number: payment_method.number,
603
+ exp_month: payment_method.month,
604
+ exp_year: payment_method.year,
605
+ tokenization_method: DIGITAL_WALLETS[payment_method.source]
606
+ }
607
+ }
608
+ }
609
+ end
610
+
611
+ def format_eci(payment_method, options)
612
+ eci_value = payment_method.respond_to?(:eci) ? payment_method.eci : options[:eci]
613
+
614
+ if eci_value&.length == 1
615
+ "0#{eci_value}"
616
+ else
617
+ eci_value
346
618
  end
347
619
  end
348
620
 
@@ -366,7 +638,7 @@ module ActiveMerchant #:nodoc:
366
638
  number: payment.number,
367
639
  exp_month: payment.month,
368
640
  exp_year: payment.year,
369
- tokenization_method: tokenization_method,
641
+ tokenization_method:,
370
642
  eci: payment.eci,
371
643
  cryptogram: payment.payment_cryptogram
372
644
  }
@@ -384,7 +656,7 @@ module ActiveMerchant #:nodoc:
384
656
  end
385
657
 
386
658
  def get_payment_method_data_from_card(post, payment_method, options, responses)
387
- return create_payment_method_and_extract_token(post, payment_method, options, responses) unless off_session_request?(options)
659
+ return create_payment_method_and_extract_token(post, payment_method, options, responses) unless off_session_request?(options) || adding_network_token_card_data?(payment_method)
388
660
 
389
661
  post[:payment_method_data] = add_payment_method_data(payment_method, options)
390
662
  end
@@ -393,6 +665,8 @@ module ActiveMerchant #:nodoc:
393
665
  payment_method_response = create_payment_method(payment_method, options)
394
666
  return payment_method_response if payment_method_response.failure?
395
667
 
668
+ add_card_3d_secure_usage_supported(payment_method_response)
669
+
396
670
  responses << payment_method_response
397
671
  add_payment_method_token(post, payment_method_response.params['id'], options)
398
672
  end
@@ -405,7 +679,7 @@ module ActiveMerchant #:nodoc:
405
679
  end
406
680
 
407
681
  def add_exemption(post, options = {})
408
- return unless options[:confirm]
682
+ return unless options[:confirm] && options[:moto]
409
683
 
410
684
  post[:payment_method_options] ||= {}
411
685
  post[:payment_method_options][:card] ||= {}
@@ -418,63 +692,71 @@ module ActiveMerchant #:nodoc:
418
692
  # the existing logic by default. To be able to utilize this field, you must reach out to Stripe.
419
693
 
420
694
  def add_stored_credentials(post, options = {})
421
- return unless options[:stored_credential] && !options[:stored_credential].values.all?(&:nil?)
695
+ stored_credential = options[:stored_credential]
696
+ return unless stored_credential && !stored_credential.values.all?(&:nil?)
422
697
 
423
698
  post[:payment_method_options] ||= {}
424
699
  post[:payment_method_options][:card] ||= {}
425
- add_stored_credential_transaction_type(post, options) if options[:stored_credential_transaction_type]
426
700
 
427
- stored_credential = options[:stored_credential]
428
- post[:payment_method_options][:card][:mit_exemption] = {}
701
+ card_options = post[:payment_method_options][:card]
702
+ card_options[:mit_exemption] = {}
429
703
 
430
704
  # Stripe PI accepts network_transaction_id and ds_transaction_id via mit field under card.
431
705
  # 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)
432
706
  # If it is sent is as its own field AND under stored credentials, the value sent under its own field is what will send.
433
- post[:payment_method_options][:card][:mit_exemption][:ds_transaction_id] = stored_credential[:ds_transaction_id] if stored_credential[:ds_transaction_id]
434
- post[:payment_method_options][:card][:mit_exemption][:network_transaction_id] = stored_credential[:network_transaction_id] if stored_credential[:network_transaction_id]
707
+ card_options[:mit_exemption][:ds_transaction_id] = stored_credential[:ds_transaction_id] if stored_credential[:ds_transaction_id]
708
+ card_options[:mit_exemption][:network_transaction_id] = stored_credential[:network_transaction_id] if !(options[:setup_future_usage] == 'off_session') && (stored_credential[:network_transaction_id])
709
+
710
+ add_stored_credential_transaction_type(post, options)
435
711
  end
436
712
 
437
713
  def add_stored_credential_transaction_type(post, options = {})
714
+ return unless options[:stored_credential_transaction_type]
715
+
438
716
  stored_credential = options[:stored_credential]
439
717
  # Do not add anything unless these are present.
440
718
  return unless stored_credential[:reason_type] && stored_credential[:initiator]
441
719
 
442
720
  # Not compatible with off_session parameter.
443
721
  options.delete(:off_session)
444
- if stored_credential[:initial_transaction]
445
- # Initial transactions must by CIT
446
- return unless stored_credential[:initiator] == 'cardholder'
447
722
 
448
- initial_transaction_stored_credential(post, stored_credential[:reason_type])
449
- else
450
- # Subsequent transaction
451
- subsequent_transaction_stored_credential(post, stored_credential[:initiator], stored_credential[:reason_type])
452
- end
723
+ stored_credential_type = if stored_credential[:initial_transaction]
724
+ return unless stored_credential[:initiator] == 'cardholder'
725
+
726
+ initial_transaction_stored_credential(post, stored_credential)
727
+ else
728
+ subsequent_transaction_stored_credential(post, stored_credential)
729
+ end
730
+
731
+ card_options = post[:payment_method_options][:card]
732
+ card_options[:stored_credential_transaction_type] = stored_credential_type
733
+ card_options[:mit_exemption].delete(:network_transaction_id) if %w(setup_on_session stored_on_session).include?(stored_credential_type)
453
734
  end
454
735
 
455
- def initial_transaction_stored_credential(post, reason_type)
456
- if reason_type == 'unscheduled'
736
+ def initial_transaction_stored_credential(post, stored_credential)
737
+ case stored_credential[:reason_type]
738
+ when 'unscheduled'
457
739
  # Charge on-session and store card for future one-off payment use
458
- post[:payment_method_options][:card][:stored_credential_transaction_type] = 'setup_off_session_unscheduled'
459
- elsif reason_type == 'recurring'
740
+ 'setup_off_session_unscheduled'
741
+ when 'recurring'
460
742
  # Charge on-session and store card for future recurring payment use
461
- post[:payment_method_options][:card][:stored_credential_transaction_type] = 'setup_off_session_recurring'
743
+ 'setup_off_session_recurring'
462
744
  else
463
745
  # Charge on-session and store card for future on-session payment use.
464
- post[:payment_method_options][:card][:stored_credential_transaction_type] = 'setup_on_session'
746
+ 'setup_on_session'
465
747
  end
466
748
  end
467
749
 
468
- def subsequent_transaction_stored_credential(post, initiator, reason_type)
469
- if initiator == 'cardholder'
750
+ def subsequent_transaction_stored_credential(post, stored_credential)
751
+ if stored_credential[:initiator] == 'cardholder'
470
752
  # Charge on-session customer using previously stored card.
471
- post[:payment_method_options][:card][:stored_credential_transaction_type] = 'stored_on_session'
472
- elsif reason_type == 'recurring'
753
+ 'stored_on_session'
754
+ elsif stored_credential[:reason_type] == 'recurring'
473
755
  # Charge off-session customer using previously stored card for recurring transaction
474
- post[:payment_method_options][:card][:stored_credential_transaction_type] = 'stored_off_session_recurring'
756
+ 'stored_off_session_recurring'
475
757
  else
476
758
  # Charge off-session customer using previously stored card for one-off transaction
477
- post[:payment_method_options][:card][:stored_credential_transaction_type] = 'stored_off_session_unscheduled'
759
+ 'stored_off_session_unscheduled'
478
760
  end
479
761
  end
480
762
 
@@ -485,7 +767,7 @@ module ActiveMerchant #:nodoc:
485
767
  post[:payment_method_options][:card] ||= {}
486
768
  post[:payment_method_options][:card][:mit_exemption] = {}
487
769
 
488
- post[:payment_method_options][:card][:mit_exemption][:network_transaction_id] = options[:network_transaction_id] if options[:network_transaction_id]
770
+ post[:payment_method_options][:card][:mit_exemption][:network_transaction_id] = options[:network_transaction_id]
489
771
  end
490
772
 
491
773
  def add_claim_without_transaction_id(post, options = {})
@@ -501,6 +783,16 @@ module ActiveMerchant #:nodoc:
501
783
  post[:payment_method_options][:card][:mit_exemption][:claim_without_transaction_id] = options[:claim_without_transaction_id]
502
784
  end
503
785
 
786
+ def add_billing_address_for_card_tokenization(post, options = {})
787
+ return unless (billing = options[:billing_address] || options[:address])
788
+
789
+ billing = add_address(billing, options)
790
+ billing[:address].transform_keys! { |k| k == :postal_code ? :address_zip : k.to_s.prepend('address_').to_sym }
791
+
792
+ post[:card][:name] = billing[:name]
793
+ post[:card].merge!(billing[:address])
794
+ end
795
+
504
796
  def add_error_on_requires_action(post, options = {})
505
797
  return unless options[:confirm]
506
798
 
@@ -508,7 +800,7 @@ module ActiveMerchant #:nodoc:
508
800
  end
509
801
 
510
802
  def request_three_d_secure(post, options = {})
511
- return unless options[:request_three_d_secure] && %w(any automatic).include?(options[:request_three_d_secure])
803
+ return unless options[:request_three_d_secure] && %w(any automatic challenge).include?(options[:request_three_d_secure])
512
804
 
513
805
  post[:payment_method_options] ||= {}
514
806
  post[:payment_method_options][:card] ||= {}
@@ -534,14 +826,18 @@ module ActiveMerchant #:nodoc:
534
826
  post
535
827
  end
536
828
 
537
- def add_billing_address_for_card_tokenization(post, options = {})
538
- return unless (billing = options[:billing_address] || options[:address])
829
+ def add_billing_address(post, payment_method, options = {})
830
+ return if payment_method.nil? || payment_method.is_a?(String)
539
831
 
540
- billing = add_address(billing, options)
541
- billing[:address].transform_keys! { |k| k == :postal_code ? :address_zip : k.to_s.prepend('address_').to_sym }
832
+ post[:payment_method_data] ||= {}
833
+ if billing = options[:billing_address] || options[:address]
834
+ post[:payment_method_data][:billing_details] = add_address(billing, options)
835
+ end
542
836
 
543
- post[:card][:name] = billing[:name]
544
- post[:card].merge!(billing[:address])
837
+ unless post[:payment_method_data][:billing_details]
838
+ name = [payment_method.first_name, payment_method.last_name].compact.join(' ')
839
+ post[:payment_method_data][:billing_details] = { name: }
840
+ end
545
841
  end
546
842
 
547
843
  def add_shipping_address(post, options = {})
@@ -575,6 +871,13 @@ module ActiveMerchant #:nodoc:
575
871
  post[:billing_details][:name] = name
576
872
  end
577
873
 
874
+ # This surfaces the three_d_secure_usage.supported field and saves it as an instance variable so that we can access it later on in the response
875
+ def add_card_3d_secure_usage_supported(response)
876
+ return unless response.params['card'] && response.params['card']['three_d_secure_usage']
877
+
878
+ @card_3d_supported = response.params['card']['three_d_secure_usage']['supported']
879
+ end
880
+
578
881
  def format_idempotency_key(options, suffix)
579
882
  return options unless options[:idempotency_key]
580
883
 
@@ -582,9 +885,13 @@ module ActiveMerchant #:nodoc:
582
885
  end
583
886
 
584
887
  def success_from(response, options)
585
- if response['status'] == 'requires_action' && !options[:execute_threed]
586
- response['error'] = {}
587
- response['error']['message'] = 'Received unexpected 3DS authentication response, but a 3DS initiation flag was not included in the request.'
888
+ if options[:request_type] != :inquire && response['status'] == 'requires_action' && !options[:execute_threed]
889
+ response['error'] = { 'message' => 'Received unexpected 3DS authentication response, but a 3DS initiation flag was not included in the request.' }
890
+ return false
891
+ end
892
+
893
+ if options[:request_type] == :inquire && (error = response['last_setup_error'] || response['last_payment_error'])
894
+ response['error'] = error
588
895
  return false
589
896
  end
590
897
 
@@ -594,6 +901,10 @@ module ActiveMerchant #:nodoc:
594
901
  def add_currency(post, options, money)
595
902
  post[:currency] = options[:currency] || currency(money)
596
903
  end
904
+
905
+ def api_version(options)
906
+ options[:version] || @options[:version] || fetch_version
907
+ end
597
908
  end
598
909
  end
599
910
  end