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,5 +1,5 @@
1
- module ActiveMerchant #:nodoc:
2
- module Billing #:nodoc:
1
+ module ActiveMerchant # :nodoc:
2
+ module Billing # :nodoc:
3
3
  class AdyenGateway < Gateway
4
4
  # we recommend setting up merchant-specific endpoints.
5
5
  # https://docs.adyen.com/developers/api-manual#apiendpoints
@@ -10,15 +10,16 @@ module ActiveMerchant #:nodoc:
10
10
  self.default_currency = 'USD'
11
11
  self.currencies_without_fractions = %w(CVE DJF GNF IDR JPY KMF KRW PYG RWF UGX VND VUV XAF XOF XPF)
12
12
  self.currencies_with_three_decimal_places = %w(BHD IQD JOD KWD LYD OMR TND)
13
- self.supported_cardtypes = %i[visa master american_express diners_club jcb dankort maestro discover elo naranja cabal unionpay]
13
+ self.supported_cardtypes = %i[visa master american_express diners_club jcb dankort maestro discover elo naranja cabal unionpay patagonia_365 tarjeta_sol]
14
14
 
15
15
  self.money_format = :cents
16
16
 
17
17
  self.homepage_url = 'https://www.adyen.com/'
18
18
  self.display_name = 'Adyen'
19
19
 
20
- PAYMENT_API_VERSION = 'v68'
21
- RECURRING_API_VERSION = 'v68'
20
+ version 'v68', :payment_api
21
+ version 'v68', :payout_api
22
+ version 'v68', :recurring_api
22
23
 
23
24
  STANDARD_ERROR_CODE_MAPPING = {
24
25
  '0' => STANDARD_ERROR_CODE[:processing_error],
@@ -63,13 +64,18 @@ module ActiveMerchant #:nodoc:
63
64
  add_3ds(post, options)
64
65
  add_3ds_authenticated_data(post, options)
65
66
  add_splits(post, options)
66
- add_recurring_contract(post, options)
67
+ add_recurring_contract(post, options, payment)
67
68
  add_network_transaction_reference(post, options)
68
69
  add_application_info(post, options)
69
70
  add_level_2_data(post, options)
70
71
  add_level_3_data(post, options)
71
72
  add_data_airline(post, options)
72
73
  add_data_lodging(post, options)
74
+ add_metadata(post, options)
75
+ add_recurring_detail_reference(post, options)
76
+ add_fund_source(post, options)
77
+ add_fund_destination(post, options)
78
+ post[:localizedShopperStatement] = options[:localized_shopper_statement] if options[:localized_shopper_statement]
73
79
  commit('authorise', post, options)
74
80
  end
75
81
 
@@ -89,16 +95,33 @@ module ActiveMerchant #:nodoc:
89
95
  add_reference(post, authorization, options)
90
96
  add_splits(post, options)
91
97
  add_network_transaction_reference(post, options)
98
+ add_shopper_statement(post, options)
92
99
  commit('refund', post, options)
93
100
  end
94
101
 
95
102
  def credit(money, payment, options = {})
96
- action = 'refundWithData'
103
+ action = options[:payout] ? 'payout' : 'refundWithData'
97
104
  post = init_post(options)
98
105
  add_invoice(post, money, options)
99
106
  add_payment(post, payment, options, action)
100
107
  add_shopper_reference(post, options)
101
108
  add_network_transaction_reference(post, options)
109
+
110
+ if action == 'payout'
111
+ add_shopper_interaction(post, payment, options)
112
+ add_fraud_offset(post, options)
113
+ add_fund_source(post, options)
114
+ add_recurring_contract(post, options)
115
+ add_shopper_data(post, payment, options)
116
+
117
+ if (address = options[:billing_address] || options[:address]) && address[:country]
118
+ add_billing_address(post, options, address)
119
+ end
120
+
121
+ post[:dateOfBirth] = options[:date_of_birth] if options[:date_of_birth]
122
+ post[:nationality] = options[:nationality] if options[:nationality]
123
+ end
124
+ add_recurring_detail_reference(post, options)
102
125
  commit(action, post, options)
103
126
  end
104
127
 
@@ -115,6 +138,7 @@ module ActiveMerchant #:nodoc:
115
138
  add_invoice_for_modification(post, money, options)
116
139
  add_reference(post, authorization, options)
117
140
  add_extra_data(post, nil, options)
141
+ add_recurring_detail_reference(post, options)
118
142
  commit('adjustAuthorisation', post, options)
119
143
  end
120
144
 
@@ -230,25 +254,38 @@ module ActiveMerchant #:nodoc:
230
254
 
231
255
  def add_extra_data(post, payment, options)
232
256
  post[:telephoneNumber] = (options[:billing_address][:phone_number] if options.dig(:billing_address, :phone_number)) || (options[:billing_address][:phone] if options.dig(:billing_address, :phone)) || ''
233
- post[:fraudOffset] = options[:fraud_offset] if options[:fraud_offset]
234
- post[:selectedBrand] = options[:selected_brand] if options[:selected_brand]
235
- post[:selectedBrand] ||= NETWORK_TOKENIZATION_CARD_SOURCE[payment.source.to_s] if payment.is_a?(NetworkTokenizationCreditCard)
257
+ post[:selectedBrand] = options[:selected_brand] if options[:selected_brand] && !post[:selectedBrand]
236
258
  post[:deliveryDate] = options[:delivery_date] if options[:delivery_date]
237
259
  post[:merchantOrderReference] = options[:merchant_order_reference] if options[:merchant_order_reference]
238
260
  post[:captureDelayHours] = options[:capture_delay_hours] if options[:capture_delay_hours]
261
+ post[:deviceFingerprint] = options[:device_fingerprint] if options[:device_fingerprint]
262
+ post[:shopperIP] = options[:shopper_ip] || options[:ip] if options[:shopper_ip] || options[:ip]
263
+ post[:shopperStatement] = options[:shopper_statement] if options[:shopper_statement]
264
+ post[:store] = options[:store] if options[:store]
265
+ post[:mcc] = options[:mcc] if options[:mcc]
266
+
267
+ add_shopper_data(post, payment, options)
268
+ add_additional_data(post, payment, options)
269
+ add_risk_data(post, options)
270
+ add_shopper_reference(post, options)
271
+ add_merchant_data(post, options)
272
+ add_fraud_offset(post, options)
273
+ end
274
+
275
+ def add_fraud_offset(post, options)
276
+ post[:fraudOffset] = options[:fraud_offset] if options[:fraud_offset]
277
+ end
278
+
279
+ def add_additional_data(post, payment, options)
239
280
  post[:additionalData] ||= {}
240
281
  post[:additionalData][:overwriteBrand] = normalize(options[:overwrite_brand]) if options[:overwrite_brand]
241
282
  post[:additionalData][:customRoutingFlag] = options[:custom_routing_flag] if options[:custom_routing_flag]
242
- post[:additionalData]['paymentdatasource.type'] = NETWORK_TOKENIZATION_CARD_SOURCE[payment.source.to_s] if payment.is_a?(NetworkTokenizationCreditCard)
243
283
  post[:additionalData][:authorisationType] = options[:authorisation_type] if options[:authorisation_type]
244
284
  post[:additionalData][:adjustAuthorisationData] = options[:adjust_authorisation_data] if options[:adjust_authorisation_data]
245
285
  post[:additionalData][:industryUsage] = options[:industry_usage] if options[:industry_usage]
246
286
  post[:additionalData][:RequestedTestAcquirerResponseCode] = options[:requested_test_acquirer_response_code] if options[:requested_test_acquirer_response_code] && test?
247
- post[:deviceFingerprint] = options[:device_fingerprint] if options[:device_fingerprint]
248
- add_shopper_data(post, options)
249
- add_risk_data(post, options)
250
- add_shopper_reference(post, options)
251
- add_merchant_data(post, options)
287
+ post[:additionalData][:updateShopperStatement] = options[:update_shopper_statement] if options[:update_shopper_statement]
288
+ post[:additionalData][:manualCapture] = options[:manual_capture] if options[:manual_capture]
252
289
  end
253
290
 
254
291
  def extract_and_transform(mapper, from)
@@ -262,8 +299,8 @@ module ActiveMerchant #:nodoc:
262
299
  return unless options[:level_2_data].present?
263
300
 
264
301
  mapper = {
265
- "enhancedSchemeData.totalTaxAmount": 'total_tax_amount',
266
- "enhancedSchemeData.customerReference": 'customer_reference'
302
+ 'enhancedSchemeData.totalTaxAmount': 'total_tax_amount',
303
+ 'enhancedSchemeData.customerReference': 'customer_reference'
267
304
  }
268
305
  post[:additionalData].merge!(extract_and_transform(mapper, options[:level_2_data]))
269
306
  end
@@ -271,13 +308,13 @@ module ActiveMerchant #:nodoc:
271
308
  def add_level_3_data(post, options)
272
309
  return unless options[:level_3_data].present?
273
310
 
274
- mapper = { "enhancedSchemeData.freightAmount": 'freight_amount',
275
- "enhancedSchemeData.destinationStateProvinceCode": 'destination_state_province_code',
276
- "enhancedSchemeData.shipFromPostalCode": 'ship_from_postal_code',
277
- "enhancedSchemeData.orderDate": 'order_date',
278
- "enhancedSchemeData.destinationPostalCode": 'destination_postal_code',
279
- "enhancedSchemeData.destinationCountryCode": 'destination_country_code',
280
- "enhancedSchemeData.dutyAmount": 'duty_amount' }
311
+ mapper = { 'enhancedSchemeData.freightAmount': 'freight_amount',
312
+ 'enhancedSchemeData.destinationStateProvinceCode': 'destination_state_province_code',
313
+ 'enhancedSchemeData.shipFromPostalCode': 'ship_from_postal_code',
314
+ 'enhancedSchemeData.orderDate': 'order_date',
315
+ 'enhancedSchemeData.destinationPostalCode': 'destination_postal_code',
316
+ 'enhancedSchemeData.destinationCountryCode': 'destination_country_code',
317
+ 'enhancedSchemeData.dutyAmount': 'duty_amount' }
281
318
 
282
319
  post[:additionalData].merge!(extract_and_transform(mapper, options[:level_3_data]))
283
320
 
@@ -331,6 +368,26 @@ module ActiveMerchant #:nodoc:
331
368
  post[:additionalData].merge!(extract_and_transform(leg_data, options[:additional_data_airline][:leg]))
332
369
  end
333
370
 
371
+ # temporary duplication with minor modification (:legs array with nested hashes instead of a single :leg hash)
372
+ # this should preserve backward-compatibility with :leg logic above until it is deprecated/removed
373
+ if options[:additional_data_airline][:legs].present?
374
+ options[:additional_data_airline][:legs].each_with_index do |leg, number|
375
+ leg_data = %w[
376
+ carrier_code
377
+ class_of_travel
378
+ date_of_travel
379
+ depart_airport
380
+ depart_tax
381
+ destination_code
382
+ fare_base_code
383
+ flight_number
384
+ stop_over_code
385
+ ].each_with_object({}) { |value, hash| hash["airline.leg#{number + 1}.#{value}"] = value }
386
+
387
+ post[:additionalData].merge!(extract_and_transform(leg_data, leg))
388
+ end
389
+ end
390
+
334
391
  if options[:additional_data_airline][:passenger].present?
335
392
  passenger_data = %w[
336
393
  date_of_birth
@@ -371,21 +428,10 @@ module ActiveMerchant #:nodoc:
371
428
  post[:additionalData].compact!
372
429
  end
373
430
 
374
- def add_shopper_data(post, options)
375
- post[:shopperEmail] = options[:email] if options[:email]
376
- post[:shopperEmail] = options[:shopper_email] if options[:shopper_email]
377
- post[:shopperIP] = options[:ip] if options[:ip]
378
- post[:shopperIP] = options[:shopper_ip] if options[:shopper_ip]
379
- post[:shopperStatement] = options[:shopper_statement] if options[:shopper_statement]
380
- post[:additionalData][:updateShopperStatement] = options[:update_shopper_statement] if options[:update_shopper_statement]
381
- end
382
-
383
431
  def add_shopper_statement(post, options)
384
- return unless options[:shopper_statement]
385
-
386
- post[:additionalData] = {
387
- shopperStatement: options[:shopper_statement]
388
- }
432
+ post[:additionalData] ||= {}
433
+ post[:additionalData][:shopperStatement] = options[:shopper_statement] if options[:shopper_statement]
434
+ post[:additionalData][:localizedShopperStatement] = options[:localized_shopper_statement] if options[:localized_shopper_statement]
389
435
  end
390
436
 
391
437
  def add_merchant_data(post, options)
@@ -403,7 +449,7 @@ module ActiveMerchant #:nodoc:
403
449
 
404
450
  def add_risk_data(post, options)
405
451
  if (risk_data = options[:risk_data])
406
- risk_data = Hash[risk_data.map { |k, v| ["riskdata.#{k}", v] }]
452
+ risk_data = risk_data.map { |k, v| ["riskdata.#{k}", v] }.to_h
407
453
  post[:additionalData].merge!(risk_data)
408
454
  end
409
455
  end
@@ -413,16 +459,17 @@ module ActiveMerchant #:nodoc:
413
459
 
414
460
  splits = []
415
461
  split_data.each do |split|
416
- amount = {
417
- value: split['amount']['value']
418
- }
419
- amount[:currency] = split['amount']['currency'] if split['amount']['currency']
462
+ if split['amount']
463
+ amount = {}
464
+ amount[:value] = split['amount']['value'] if split['amount']['value']
465
+ amount[:currency] = split['amount']['currency'] if split['amount']['currency']
466
+ end
420
467
 
421
468
  split_hash = {
422
- amount: amount,
423
469
  type: split['type'],
424
470
  reference: split['reference']
425
471
  }
472
+ split_hash[:amount] = amount unless amount.nil?
426
473
  split_hash['account'] = split['account'] if split['account']
427
474
  splits.push(split_hash)
428
475
  end
@@ -443,9 +490,7 @@ module ActiveMerchant #:nodoc:
443
490
  end
444
491
 
445
492
  def add_shopper_interaction(post, payment, options = {})
446
- if (options.dig(:stored_credential, :initial_transaction) && options.dig(:stored_credential, :initiator) == 'cardholder') ||
447
- (payment.respond_to?(:verification_value) && payment.verification_value && options.dig(:stored_credential, :initial_transaction).nil?) ||
448
- payment.is_a?(NetworkTokenizationCreditCard)
493
+ if ecommerce_shopper_interaction?(payment, options)
449
494
  shopper_interaction = 'Ecommerce'
450
495
  else
451
496
  shopper_interaction = 'ContAuth'
@@ -473,35 +518,47 @@ module ActiveMerchant #:nodoc:
473
518
  def add_address(post, options)
474
519
  if address = options[:shipping_address]
475
520
  post[:deliveryAddress] = {}
476
- post[:deliveryAddress][:street] = address[:address1] || 'NA'
477
- post[:deliveryAddress][:houseNumberOrName] = address[:address2] || 'NA'
521
+ post[:deliveryAddress][:street] = options[:address_override] == true ? address[:address2] : address[:address1] || 'NA'
522
+ post[:deliveryAddress][:houseNumberOrName] = options[:address_override] == true ? address[:address1] : address[:address2] || 'NA'
478
523
  post[:deliveryAddress][:postalCode] = address[:zip] if address[:zip]
479
524
  post[:deliveryAddress][:city] = address[:city] || 'NA'
480
525
  post[:deliveryAddress][:stateOrProvince] = get_state(address)
481
- post[:deliveryAddress][:country] = address[:country] if address[:country]
526
+ post[:deliveryAddress][:country] = get_country(address)
482
527
  end
483
528
  return unless post[:bankAccount]&.kind_of?(Hash) || post[:card]&.kind_of?(Hash)
484
529
 
485
530
  if (address = options[:billing_address] || options[:address]) && address[:country]
486
- post[:billingAddress] = {}
487
- post[:billingAddress][:street] = address[:address1] || 'NA'
488
- post[:billingAddress][:houseNumberOrName] = address[:address2] || 'NA'
489
- post[:billingAddress][:postalCode] = address[:zip] if address[:zip]
490
- post[:billingAddress][:city] = address[:city] || 'NA'
491
- post[:billingAddress][:stateOrProvince] = get_state(address)
492
- post[:billingAddress][:country] = address[:country] if address[:country]
531
+ add_billing_address(post, options, address)
493
532
  end
494
533
  end
495
534
 
535
+ def add_billing_address(post, options, address)
536
+ address[:address1] = 'NA' if address[:address1].blank?
537
+ address[:address2] = 'NA' if address[:address2].blank?
538
+
539
+ post[:billingAddress] = {}
540
+ post[:billingAddress][:street] = options[:address_override] == true ? address[:address2] : address[:address1]
541
+ post[:billingAddress][:houseNumberOrName] = options[:address_override] == true ? address[:address1] : address[:address2]
542
+ post[:billingAddress][:postalCode] = address[:zip] if address[:zip]
543
+ post[:billingAddress][:city] = address[:city] || 'NA'
544
+ post[:billingAddress][:stateOrProvince] = get_state(address)
545
+ post[:billingAddress][:country] = get_country(address)
546
+ post[:telephoneNumber] = address[:phone_number] || address[:phone] || ''
547
+ end
548
+
496
549
  def get_state(address)
497
550
  address[:state] && !address[:state].blank? ? address[:state] : 'NA'
498
551
  end
499
552
 
553
+ def get_country(address)
554
+ address[:country].present? ? address[:country] : 'ZZ'
555
+ end
556
+
500
557
  def add_invoice(post, money, options)
501
558
  currency = options[:currency] || currency(money)
502
559
  amount = {
503
560
  value: localized_amount(money, currency),
504
- currency: currency
561
+ currency:
505
562
  }
506
563
 
507
564
  post[:amount] = amount
@@ -511,24 +568,33 @@ module ActiveMerchant #:nodoc:
511
568
  currency = options[:currency] || currency(money)
512
569
  amount = {
513
570
  value: localized_amount(money, currency),
514
- currency: currency
571
+ currency:
515
572
  }
516
573
  post[:modificationAmount] = amount
517
574
  end
518
575
 
519
576
  def add_payment(post, payment, options, action = nil)
520
- if payment.is_a?(String)
577
+ case payment
578
+ when String
521
579
  _, _, recurring_detail_reference = payment.split('#')
522
580
  post[:selectedRecurringDetailReference] = recurring_detail_reference
523
581
  options[:recurring_contract_type] ||= 'RECURRING'
524
- elsif payment.is_a?(Check)
582
+ when Check
525
583
  add_bank_account(post, payment, options, action)
526
584
  else
527
- add_mpi_data_for_network_tokenization_card(post, payment, options) if payment.is_a?(NetworkTokenizationCreditCard)
585
+ add_network_tokenization_card(post, payment, options) if network_tokenization_payment?(payment, options)
528
586
  add_card(post, payment)
529
587
  end
530
588
  end
531
589
 
590
+ def network_tokenization_payment?(payment, options)
591
+ payment.is_a?(NetworkTokenizationCreditCard) || options[:wallet_type] == :google_pay
592
+ end
593
+
594
+ def add_recurring_detail_reference(post, options)
595
+ post[:selectedRecurringDetailReference] = options[:recurring_detail_reference] if options[:recurring_detail_reference].present?
596
+ end
597
+
532
598
  def add_bank_account(post, bank_account, options, action)
533
599
  bank = {
534
600
  bankAccountNumber: bank_account.account_number,
@@ -557,6 +623,17 @@ module ActiveMerchant #:nodoc:
557
623
  post[:card] = card
558
624
  end
559
625
 
626
+ def add_shopper_data(post, payment, options)
627
+ if payment && !payment.is_a?(String)
628
+ post[:shopperName] = {}
629
+ post[:shopperName][:firstName] = payment.first_name
630
+ post[:shopperName][:lastName] = payment.last_name
631
+ end
632
+
633
+ post[:shopperEmail] = options[:email] if options[:email]
634
+ post[:shopperEmail] = options[:shopper_email] if options[:shopper_email]
635
+ end
636
+
560
637
  def capture_options(options)
561
638
  return options.merge(idempotency_key: "#{options[:idempotency_key]}-cap") if options[:idempotency_key]
562
639
 
@@ -575,24 +652,44 @@ module ActiveMerchant #:nodoc:
575
652
  post[:originalReference] = original_reference
576
653
  end
577
654
 
578
- def add_mpi_data_for_network_tokenization_card(post, payment, options)
579
- return if options[:skip_mpi_data] == 'Y'
655
+ def add_network_tokenization_card(post, payment, options)
656
+ selected_brand = NETWORK_TOKENIZATION_CARD_SOURCE[options[:wallet_type]&.to_s || payment.source.to_s]
657
+ if selected_brand
658
+ post[:selectedBrand] = selected_brand
659
+ post[:additionalData] = {} unless post[:additionalData]
660
+ post[:additionalData]['paymentdatasource.type'] = selected_brand
661
+ post[:additionalData]['paymentdatasource.tokenized'] = options[:wallet_type] ? 'false' : 'true' if selected_brand == 'googlepay'
662
+ end
663
+
664
+ return if skip_mpi_data?(payment, options)
580
665
 
581
- post[:mpiData] = {}
582
- post[:mpiData][:authenticationResponse] = 'Y'
583
- post[:mpiData][:cavv] = payment.payment_cryptogram
584
- post[:mpiData][:directoryResponse] = 'Y'
585
- post[:mpiData][:eci] = payment.eci || '07'
666
+ post[:mpiData] = {
667
+ authenticationResponse: 'Y',
668
+ directoryResponse: 'Y',
669
+ eci: payment.eci || '07'
670
+ }
671
+
672
+ cryptogram_field = payment.try(:network_token?) ? :tokenAuthenticationVerificationValue : :cavv
673
+ post[:mpiData][cryptogram_field] = payment.payment_cryptogram
586
674
  end
587
675
 
588
- def add_recurring_contract(post, options = {})
589
- return unless options[:recurring_contract_type]
676
+ def add_recurring_contract(post, options = {}, payment = nil)
677
+ return unless options[:recurring_contract_type] || payment.try(:network_token?)
590
678
 
591
- recurring = {
592
- contract: options[:recurring_contract_type]
593
- }
679
+ post[:recurring] ||= {}
680
+ post[:recurring][:contract] = options[:recurring_contract_type] if options[:recurring_contract_type]
681
+ post[:recurring][:recurringDetailName] = options[:recurring_detail_name] if options[:recurring_detail_name]
682
+ post[:recurring][:recurringExpiry] = options[:recurring_expiry] if options[:recurring_expiry]
683
+ post[:recurring][:recurringFrequency] = options[:recurring_frequency] if options[:recurring_frequency]
684
+ post[:recurring][:tokenService] = options[:token_service] if options[:token_service]
594
685
 
595
- post[:recurring] = recurring
686
+ if payment.try(:network_token?)
687
+ post[:recurring][:contract] = 'EXTERNAL'
688
+ post[:recurring][:tokenService] = case payment.brand
689
+ when 'visa' then 'VISATOKENSERVICE'
690
+ else 'MCTOKENSERVICE'
691
+ end
692
+ end
596
693
  end
597
694
 
598
695
  def add_application_info(post, options)
@@ -688,10 +785,66 @@ module ActiveMerchant #:nodoc:
688
785
  }
689
786
  end
690
787
 
788
+ def add_fund_source(post, options)
789
+ return unless fund_source = options[:fund_source]
790
+
791
+ post[:fundSource] = {}
792
+ post[:fundSource][:additionalData] = fund_source[:additional_data] if fund_source[:additional_data]
793
+ post[:fundSource][:shopperEmail] = fund_source[:shopper_email] if fund_source[:shopper_email]
794
+
795
+ if fund_source[:first_name] && fund_source[:last_name]
796
+ post[:fundSource][:shopperName] = {}
797
+ post[:fundSource][:shopperName][:firstName] = fund_source[:first_name]
798
+ post[:fundSource][:shopperName][:lastName] = fund_source[:last_name]
799
+ end
800
+
801
+ if (address = fund_source[:billing_address])
802
+ add_billing_address(post[:fundSource], options, address)
803
+ end
804
+ end
805
+
806
+ def add_fund_destination(post, options)
807
+ return unless fund_destination = options[:fund_destination]
808
+
809
+ post[:fundDestination] = {}
810
+ post[:fundDestination][:additionalData] = fund_destination[:additional_data] if fund_destination[:additional_data]
811
+ end
812
+
813
+ def add_metadata(post, options = {})
814
+ return unless options[:metadata]
815
+
816
+ post[:metadata] ||= {}
817
+ post[:metadata].merge!(options[:metadata]) if options[:metadata]
818
+ end
819
+
820
+ def add_header_fields(response)
821
+ return unless @response_headers.present?
822
+
823
+ headers = {}
824
+ headers['response_headers'] = {}
825
+ headers['response_headers']['transient_error'] = @response_headers['transient-error'] if @response_headers['transient-error']
826
+
827
+ response.merge!(headers)
828
+ end
829
+
691
830
  def parse(body)
692
831
  return {} if body.blank?
693
832
 
694
- JSON.parse(body)
833
+ response = JSON.parse(body)
834
+ add_header_fields(response)
835
+ response
836
+ end
837
+
838
+ # Override the regular handle response so we can access the headers
839
+ # set header fields and values so we can add them to the response body
840
+ def handle_response(response)
841
+ @response_headers = response.each_header.to_h if response.respond_to?(:header)
842
+ case response.code.to_i
843
+ when 200...300
844
+ response.body
845
+ else
846
+ raise ResponseError.new(response)
847
+ end
695
848
  end
696
849
 
697
850
  def commit(action, parameters, options)
@@ -706,7 +859,7 @@ module ActiveMerchant #:nodoc:
706
859
  success = success_from(action, response, options)
707
860
  Response.new(
708
861
  success,
709
- message_from(action, response),
862
+ message_from(action, response, options),
710
863
  response,
711
864
  authorization: authorization_from(action, parameters, response),
712
865
  test: test?,
@@ -726,8 +879,14 @@ module ActiveMerchant #:nodoc:
726
879
  end
727
880
 
728
881
  def endpoint(action)
729
- recurring = %w(disable storeToken).include?(action)
730
- recurring ? "Recurring/#{RECURRING_API_VERSION}/#{action}" : "Payment/#{PAYMENT_API_VERSION}/#{action}"
882
+ case action
883
+ when 'disable', 'storeToken'
884
+ "Recurring/#{fetch_version(:recurring_api)}/#{action}"
885
+ when 'payout'
886
+ "Payout/#{fetch_version(:payout_api)}/#{action}"
887
+ else
888
+ "Payment/#{fetch_version(:payment_api)}/#{action}"
889
+ end
731
890
  end
732
891
 
733
892
  def url(action)
@@ -754,7 +913,7 @@ module ActiveMerchant #:nodoc:
754
913
  end
755
914
 
756
915
  def success_from(action, response, options)
757
- if %w[RedirectShopper ChallengeShopper].include?(response.dig('resultCode')) && !options[:execute_threed] && !options[:threed_dynamic]
916
+ if %w[RedirectShopper ChallengeShopper].include?(response.dig('resultCode')) && !options[:execute_threed] && (!options[:threed_dynamic] || options[:ignore_threed_dynamic])
758
917
  response['refusalReason'] = 'Received unexpected 3DS authentication response, but a 3DS initiation flag was not included in the request.'
759
918
  return false
760
919
  end
@@ -771,18 +930,27 @@ module ActiveMerchant #:nodoc:
771
930
  response['response'] == '[detail-successfully-disabled]'
772
931
  when 'refundWithData'
773
932
  response['resultCode'] == 'Received'
933
+ when 'payout'
934
+ return false unless response['resultCode'] && response['authCode']
935
+
936
+ %[AuthenticationFinished Authorised Received].include?(response['resultCode'])
774
937
  else
775
938
  false
776
939
  end
777
940
  end
778
941
 
779
- def message_from(action, response)
780
- return authorize_message_from(response) if %w(authorise authorise3d authorise3ds2).include?(action.to_s)
781
-
782
- response['response'] || response['message'] || response['result'] || response['resultCode']
942
+ def message_from(action, response, options = {})
943
+ case action.to_s
944
+ when 'authorise', 'authorise3d', 'authorise3ds2'
945
+ authorize_message_from(response, options)
946
+ when 'payout'
947
+ response['refusalReason'] || response['resultCode'] || response['message']
948
+ else
949
+ response['response'] || response['message'] || response['result'] || response['resultCode']
950
+ end
783
951
  end
784
952
 
785
- def authorize_message_from(response)
953
+ def authorize_message_from(response, options = {})
786
954
  if response['refusalReason'] && response['additionalData'] && (response['additionalData']['merchantAdviceCode'] || response['additionalData']['refusalReasonRaw'])
787
955
  "#{response['refusalReason']} | #{response['additionalData']['merchantAdviceCode'] || response['additionalData']['refusalReasonRaw']}"
788
956
  else
@@ -811,7 +979,10 @@ module ActiveMerchant #:nodoc:
811
979
  end
812
980
 
813
981
  def error_code_from(response)
814
- STANDARD_ERROR_CODE_MAPPING[response['errorCode']] || response['errorCode']
982
+ response.dig('additionalData', 'refusalReasonRaw').try(:match, /^([a-zA-Z0-9 ]{1,5})(?=:)/).try(:[], 1).try(:strip) ||
983
+ STANDARD_ERROR_CODE_MAPPING[response['errorCode']] ||
984
+ response['errorCode'] ||
985
+ response['refusalReason']
815
986
  end
816
987
 
817
988
  def network_transaction_id_from(response)
@@ -849,6 +1020,30 @@ module ActiveMerchant #:nodoc:
849
1020
  def card_not_stored?(response)
850
1021
  response.authorization ? response.authorization.split('#')[2].nil? : true
851
1022
  end
1023
+
1024
+ def skip_mpi_data?(payment, options = {})
1025
+ return true if options[:shopper_interaction] == 'ContAuth' && options[:recurring_processing_model] == 'Subscription'
1026
+ return true if options.dig(:stored_credential, :initiator) == 'merchant' && payment.is_a?(NetworkTokenizationCreditCard)
1027
+
1028
+ # Skips adding the NT mpi data if it is explicitly skipped in options, or if it is MIT and not the initial transaction.
1029
+ options[:wallet_type] || (!options.dig(:stored_credential, :initial_transaction) && options.dig(:stored_credential, :initiator) == 'merchant')
1030
+ end
1031
+
1032
+ def ecommerce_shopper_interaction?(payment, options)
1033
+ return true if payment.is_a?(NetworkTokenizationCreditCard) && options.dig(:stored_credential, :initiator) != 'merchant'
1034
+ return true unless (stored_credential = options[:stored_credential])
1035
+
1036
+ cardholder_shopper_interaction?(stored_credential) ||
1037
+ (payment.respond_to?(:verification_value) && payment.verification_value && stored_credential[:initial_transaction])
1038
+ end
1039
+
1040
+ def cardholder_shopper_interaction?(stored_credential)
1041
+ if stored_credential[:reason_type] == 'unscheduled'
1042
+ stored_credential[:initial_transaction] && stored_credential[:initiator] == 'cardholder'
1043
+ else
1044
+ stored_credential[:initiator] == 'cardholder'
1045
+ end
1046
+ end
852
1047
  end
853
1048
  end
854
1049
  end