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,7 +1,7 @@
1
1
  require 'nokogiri'
2
2
 
3
- module ActiveMerchant #:nodoc:
4
- module Billing #:nodoc:
3
+ module ActiveMerchant # :nodoc:
4
+ module Billing # :nodoc:
5
5
  class WorldpayGateway < Gateway
6
6
  self.test_url = 'https://secure-test.worldpay.com/jsp/merchant/xml/paymentService.jsp'
7
7
  self.live_url = 'https://secure.worldpay.com/jsp/merchant/xml/paymentService.jsp'
@@ -16,7 +16,7 @@ module ActiveMerchant #:nodoc:
16
16
  OM PA PE PF PH PK PL PN PR PT PW PY QA RE RO RS RU RW SA SB SC SE SG SI SK SL SM SN ST SV
17
17
  SZ TC TD TF TG TH TJ TK TM TO TR TT TV TW TZ UA UG US UY UZ VA VC VE VI VN VU WF WS YE YT
18
18
  ZA ZM)
19
- self.supported_cardtypes = %i[visa master american_express discover jcb maestro elo naranja cabal unionpay]
19
+ self.supported_cardtypes = %i[visa master american_express discover jcb maestro elo naranja cabal unionpay patagonia_365 tarjeta_sol]
20
20
  self.currencies_without_fractions = %w(HUF IDR JPY KRW BEF XOF XAF XPF GRD GNF ITL LUF MGA MGF PYG PTE RWF ESP TRL VND KMF)
21
21
  self.currencies_with_three_decimal_places = %w(BHD KWD OMR TND LYD JOD IQD)
22
22
  self.homepage_url = 'http://www.worldpay.com/'
@@ -38,14 +38,14 @@ module ActiveMerchant #:nodoc:
38
38
  'G' => 'C', # Address does not match, postcode not checked
39
39
  'H' => 'I', # Address and postcode not provided
40
40
  'I' => 'C', # Address not checked postcode does not match
41
- 'J' => 'C', # Address and postcode does not match
41
+ 'J' => 'C' # Address and postcode does not match
42
42
  }
43
43
 
44
44
  CVC_CODE_MAP = {
45
45
  'A' => 'M', # CVV matches
46
46
  'B' => 'P', # Not provided
47
47
  'C' => 'P', # Not checked
48
- 'D' => 'N', # Does not match
48
+ 'D' => 'N' # Does not match
49
49
  }
50
50
 
51
51
  def initialize(options = {})
@@ -62,7 +62,7 @@ module ActiveMerchant #:nodoc:
62
62
 
63
63
  def authorize(money, payment_method, options = {})
64
64
  requires!(options, :order_id)
65
- payment_details = payment_details(payment_method)
65
+ payment_details = payment_details(payment_method, options)
66
66
  authorize_request(money, payment_method, payment_details.merge(options))
67
67
  end
68
68
 
@@ -108,9 +108,11 @@ module ActiveMerchant #:nodoc:
108
108
  # and other transactions should be performed on a normal eCom-flagged
109
109
  # merchant ID.
110
110
  def credit(money, payment_method, options = {})
111
- payment_details = payment_details(payment_method)
111
+ payment_details = payment_details(payment_method, options)
112
112
  if options[:fast_fund_credit]
113
113
  fast_fund_credit_request(money, payment_method, payment_details.merge(credit: true, **options))
114
+ elsif options[:account_funding_transaction]
115
+ aft_request(money, payment_method, payment_details.merge(**options))
114
116
  else
115
117
  credit_request(money, payment_method, payment_details.merge(credit: true, **options))
116
118
  end
@@ -131,7 +133,10 @@ module ActiveMerchant #:nodoc:
131
133
 
132
134
  def inquire(authorization, options = {})
133
135
  order_id = order_id_from_authorization(authorization.to_s) || options[:order_id]
134
- commit('direct_inquiry', build_order_inquiry_request(order_id, options), :ok, options)
136
+ failure_criteria = %w(REFUSED CANCELLED)
137
+ failure_criteria.delete('CANCELLED') if options[:original_request] == 'verification'
138
+
139
+ commit('direct_inquiry', build_order_inquiry_request(order_id, options), *failure_criteria, options)
135
140
  end
136
141
 
137
142
  def supports_scrubbing
@@ -148,13 +153,26 @@ module ActiveMerchant #:nodoc:
148
153
  gsub(%r((<cardNumber>)\d+(</cardNumber>)), '\1[FILTERED]\2').
149
154
  gsub(%r((<cvc>)[^<]+(</cvc>)), '\1[FILTERED]\2').
150
155
  gsub(%r((<tokenNumber>)\d+(</tokenNumber>)), '\1[FILTERED]\2').
151
- gsub(%r((<cryptogram>)[^<]+(</cryptogram>)), '\1[FILTERED]\2')
156
+ gsub(%r((<cryptogram>)[^<]+(</cryptogram>)), '\1[FILTERED]\2').
157
+ gsub(%r((<accountReference accountType="\w+">)\d+(<\/accountReference>)), '\1[FILTERED]\2')
152
158
  end
153
159
 
154
160
  private
155
161
 
162
+ def eci_value(payment_method, options)
163
+ eci = payment_method.respond_to?(:eci) ? format(payment_method.eci, :two_digits) : ''
164
+
165
+ return eci unless eci.empty?
166
+
167
+ options[:use_default_eci] ? '07' : eci
168
+ end
169
+
156
170
  def authorize_request(money, payment_method, options)
157
- commit('authorize', build_authorization_request(money, payment_method, options), 'AUTHORISED', 'CAPTURED', options)
171
+ if options[:account_funding_transaction]
172
+ aft_request(money, payment_method, options)
173
+ else
174
+ commit('authorize', build_authorization_request(money, payment_method, options), 'AUTHORISED', 'CAPTURED', options)
175
+ end
158
176
  end
159
177
 
160
178
  def capture_request(money, authorization, options)
@@ -181,6 +199,10 @@ module ActiveMerchant #:nodoc:
181
199
  commit('fast_credit', build_fast_fund_credit_request(money, payment_method, options), :ok, 'PUSH_APPROVED', options)
182
200
  end
183
201
 
202
+ def aft_request(money, payment_method, options)
203
+ commit('funding_transfer_transaction', build_aft_request(money, payment_method, options), :ok, 'AUTHORISED', options)
204
+ end
205
+
184
206
  def store_request(credit_card, options)
185
207
  commit('store', build_store_request(credit_card, options), options)
186
208
  end
@@ -222,6 +244,7 @@ module ActiveMerchant #:nodoc:
222
244
  add_order_content(xml, options)
223
245
  add_payment_method(xml, money, payment_method, options)
224
246
  add_shopper(xml, options)
247
+ add_fraud_sight_data(xml, options)
225
248
  add_statement_narrative(xml, options)
226
249
  add_risk_data(xml, options[:risk_data]) if options[:risk_data]
227
250
  add_sub_merchant_data(xml, options[:sub_merchant_data]) if options[:sub_merchant_data]
@@ -252,9 +275,8 @@ module ActiveMerchant #:nodoc:
252
275
  xml.invoiceReferenceNumber data[:invoice_reference_number] if data.include?(:invoice_reference_number)
253
276
  xml.customerReference data[:customer_reference] if data.include?(:customer_reference)
254
277
  xml.cardAcceptorTaxId data[:card_acceptor_tax_id] if data.include?(:card_acceptor_tax_id)
255
-
256
278
  {
257
- sales_tax: 'salesTax',
279
+ tax_amount: 'salesTax',
258
280
  discount_amount: 'discountAmount',
259
281
  shipping_amount: 'shippingAmount',
260
282
  duty_amount: 'dutyAmount'
@@ -262,53 +284,37 @@ module ActiveMerchant #:nodoc:
262
284
  next unless data.include?(key)
263
285
 
264
286
  xml.tag! tag do
265
- data_amount = data[key].symbolize_keys
266
- add_amount(xml, data_amount[:amount].to_i, data_amount)
287
+ add_amount(xml, data[key].to_i, data)
267
288
  end
268
289
  end
269
290
 
270
- xml.discountName data[:discount_name] if data.include?(:discount_name)
271
- xml.discountCode data[:discount_code] if data.include?(:discount_code)
272
-
273
- add_date_element(xml, 'shippingDate', data[:shipping_date]) if data.include?(:shipping_date)
274
-
275
- if data.include?(:shipping_courier)
276
- xml.shippingCourier(
277
- data[:shipping_courier][:priority],
278
- data[:shipping_courier][:tracking_number],
279
- data[:shipping_courier][:name]
280
- )
281
- end
282
-
283
291
  add_optional_data_level_two_and_three(xml, data)
284
292
 
285
- if data.include?(:item) && data[:item].kind_of?(Array)
286
- data[:item].each { |item| add_items_into_level_three_data(xml, item.symbolize_keys) }
287
- elsif data.include?(:item)
288
- add_items_into_level_three_data(xml, data[:item].symbolize_keys)
289
- end
293
+ data[:line_items].each { |item| add_line_items_into_level_three_data(xml, item.symbolize_keys, data) } if data.include?(:line_items)
290
294
  end
291
295
 
292
- def add_items_into_level_three_data(xml, item)
296
+ def add_line_items_into_level_three_data(xml, item, data)
293
297
  xml.item do
294
298
  xml.description item[:description] if item[:description]
295
299
  xml.productCode item[:product_code] if item[:product_code]
296
300
  xml.commodityCode item[:commodity_code] if item[:commodity_code]
297
301
  xml.quantity item[:quantity] if item[:quantity]
298
-
299
- {
300
- unit_cost: 'unitCost',
301
- item_total: 'itemTotal',
302
- item_total_with_tax: 'itemTotalWithTax',
303
- item_discount_amount: 'itemDiscountAmount',
304
- tax_amount: 'taxAmount'
305
- }.each do |key, tag|
306
- next unless item.include?(key)
307
-
308
- xml.tag! tag do
309
- data_amount = item[key].symbolize_keys
310
- add_amount(xml, data_amount[:amount].to_i, data_amount)
311
- end
302
+ xml.unitCost do
303
+ add_amount(xml, item[:unit_cost], data)
304
+ end
305
+ xml.unitOfMeasure item[:unit_of_measure] || 'each'
306
+ xml.itemTotal do
307
+ sub_total_amount = item[:quantity].to_i * (item[:unit_cost].to_i - item[:discount_amount].to_i)
308
+ add_amount(xml, sub_total_amount, data)
309
+ end
310
+ xml.itemTotalWithTax do
311
+ add_amount(xml, item[:total_amount], data)
312
+ end
313
+ xml.itemDiscountAmount do
314
+ add_amount(xml, item[:discount_amount], data)
315
+ end
316
+ xml.taxAmount do
317
+ add_amount(xml, item[:tax_amount], data)
312
318
  end
313
319
  end
314
320
  end
@@ -318,7 +324,7 @@ module ActiveMerchant #:nodoc:
318
324
  xml.destinationPostalCode data[:destination_postal_code] if data.include?(:destination_postal_code)
319
325
  xml.destinationCountryCode data[:destination_country_code] if data.include?(:destination_country_code)
320
326
  add_date_element(xml, 'orderDate', data[:order_date].symbolize_keys) if data.include?(:order_date)
321
- xml.taxExempt data[:tax_exempt] if data.include?(:tax_exempt)
327
+ xml.taxExempt data[:tax_amount].to_i > 0 ? 'false' : 'true'
322
328
  end
323
329
 
324
330
  def order_tag_attributes(options)
@@ -360,6 +366,10 @@ module ActiveMerchant #:nodoc:
360
366
  if options[:cancel_or_refund]
361
367
  # Worldpay docs claim amount must be passed. This causes an error.
362
368
  xml.cancelOrRefund # { add_amount(xml, money, options.merge(debit_credit_indicator: 'credit')) }
369
+ elsif options[:refund_reference]
370
+ xml.refund 'reference' => options[:refund_reference] do
371
+ add_amount(xml, money, options.merge(debit_credit_indicator: 'credit'))
372
+ end
363
373
  else
364
374
  xml.refund do
365
375
  add_amount(xml, money, options.merge(debit_credit_indicator: 'credit'))
@@ -403,7 +413,74 @@ module ActiveMerchant #:nodoc:
403
413
  add_amount(xml, money, options)
404
414
  add_order_content(xml, options)
405
415
  add_payment_details_for_ff_credit(xml, payment_method, options)
406
- add_shopper_id(xml, options)
416
+
417
+ if options[:email]
418
+ xml.shopper do
419
+ xml.shopperEmailAddress options[:email]
420
+ end
421
+ end
422
+ end
423
+ end
424
+ end
425
+ end
426
+
427
+ def build_aft_request(money, payment_method, options)
428
+ build_request do |xml|
429
+ xml.submit do
430
+ xml.order order_tag_attributes(options) do
431
+ xml.description(options[:description].blank? ? 'Account Funding Transaction' : options[:description])
432
+ add_amount(xml, money, options)
433
+ add_order_content(xml, options)
434
+ add_payment_method(xml, money, payment_method, options)
435
+ add_shopper(xml, options)
436
+ add_sub_merchant_data(xml, options[:sub_merchant_data]) if options[:sub_merchant_data]
437
+ add_additional_3ds_data(xml, options) if options[:execute_threed] && options[:three_ds_version] && options[:three_ds_version] =~ /^2/
438
+ add_3ds_exemption(xml, options) if options[:exemption_type]
439
+ add_aft_data(xml, payment_method, options)
440
+ end
441
+ end
442
+ end
443
+ end
444
+
445
+ def add_aft_data(xml, payment_method, options)
446
+ xml.fundingTransfer 'type' => options[:aft_type], 'category' => 'PULL_FROM_CARD' do
447
+ xml.paymentPurpose options[:aft_payment_purpose] # Must be included for the recipient for following countries, otherwise optional: Argentina, Bangladesh, Chile, Columbia, Jordan, Mexico, Thailand, UAE, India cross-border
448
+ xml.fundingParty 'type' => 'sender' do
449
+ xml.accountReference options[:aft_sender_account_reference], 'accountType' => options[:aft_sender_account_type]
450
+ xml.fullName do
451
+ xml.first options.dig(:aft_sender_full_name, :first)
452
+ xml.middle options.dig(:aft_sender_full_name, :middle) if options.dig(:aft_sender_full_name, :middle)
453
+ xml.last options.dig(:aft_sender_full_name, :last)
454
+ end
455
+ xml.fundingAddress do
456
+ xml.address1 options.dig(:aft_sender_funding_address, :address1) if options.dig(:aft_sender_funding_address, :address1)
457
+ xml.address2 options.dig(:aft_sender_funding_address, :address2) if options.dig(:aft_sender_funding_address, :address2)
458
+ xml.postalCode options.dig(:aft_sender_funding_address, :postal_code) if options.dig(:aft_sender_funding_address, :postal_code)
459
+ xml.city options.dig(:aft_sender_funding_address, :city) if options.dig(:aft_sender_funding_address, :city)
460
+ xml.state options.dig(:aft_sender_funding_address, :state) if options.dig(:aft_sender_funding_address, :state)
461
+ xml.countryCode options.dig(:aft_sender_funding_address, :country_code) if options.dig(:aft_sender_funding_address, :country_code)
462
+ end
463
+ end
464
+ xml.fundingParty 'type' => 'recipient' do
465
+ xml.accountReference options[:aft_recipient_account_reference], 'accountType' => options[:aft_recipient_account_type]
466
+ xml.fullName do
467
+ xml.first options.dig(:aft_recipient_full_name, :first)
468
+ xml.middle options.dig(:aft_recipient_full_name, :middle) if options.dig(:aft_recipient_full_name, :middle)
469
+ xml.last options.dig(:aft_recipient_full_name, :last)
470
+ end
471
+ xml.fundingAddress do
472
+ xml.address1 options.dig(:aft_recipient_funding_address, :address1) if options.dig(:aft_recipient_funding_address, :address1)
473
+ xml.address2 options.dig(:aft_recipient_funding_address, :address2) if options.dig(:aft_recipient_funding_address, :address2)
474
+ xml.postalCode options.dig(:aft_recipient_funding_address, :postal_code) if options.dig(:aft_recipient_funding_address, :postal_code)
475
+ xml.city options.dig(:aft_recipient_funding_address, :city) if options.dig(:aft_recipient_funding_address, :city)
476
+ xml.state options.dig(:aft_recipient_funding_address, :state) if options.dig(:aft_recipient_funding_address, :state)
477
+ xml.countryCode options.dig(:aft_recipient_funding_address, :country_code) if options.dig(:aft_recipient_funding_address, :country_code)
478
+ end
479
+ if options[:aft_recipient_funding_data]
480
+ xml.fundingData do
481
+ add_date_element(xml, 'birthDate', options[:aft_recipient_funding_data][:birth_date]) if options[:aft_recipient_funding_data][:birth_date]
482
+ xml.telephoneNumber options.dig(:aft_recipient_funding_data, :telephone_number) if options.dig(:aft_recipient_funding_data, :telephone_number)
483
+ end
407
484
  end
408
485
  end
409
486
  end
@@ -418,6 +495,7 @@ module ActiveMerchant #:nodoc:
418
495
  add_token_for_ff_credit(xml, payment_method, options)
419
496
  end
420
497
  end
498
+ add_shopper_id(xml, options)
421
499
  end
422
500
  end
423
501
 
@@ -443,7 +521,7 @@ module ActiveMerchant #:nodoc:
443
521
  end
444
522
 
445
523
  def add_additional_3ds_data(xml, options)
446
- additional_data = { 'dfReferenceId' => options[:session_id] }
524
+ additional_data = { 'dfReferenceId' => options[:df_reference_id] }
447
525
  additional_data['challengeWindowSize'] = options[:browser_size] if options[:browser_size]
448
526
 
449
527
  xml.additional3DSData additional_data
@@ -554,10 +632,10 @@ module ActiveMerchant #:nodoc:
554
632
  end
555
633
 
556
634
  def add_amount(xml, money, options)
557
- currency = options[:currency] || currency(money)
635
+ currency = options[:currency] || currency(money.to_i)
558
636
 
559
637
  amount_hash = {
560
- :value => localized_amount(money, currency),
638
+ :value => localized_amount(money.to_i, currency),
561
639
  'currencyCode' => currency,
562
640
  'exponent' => currency_exponent(currency)
563
641
  }
@@ -571,8 +649,10 @@ module ActiveMerchant #:nodoc:
571
649
  case options[:payment_type]
572
650
  when :pay_as_order
573
651
  add_amount_for_pay_as_order(xml, amount, payment_method, options)
652
+ when :encrypted_wallet
653
+ add_encrypted_wallet(xml, payment_method)
574
654
  when :network_token
575
- add_network_tokenization_card(xml, payment_method)
655
+ add_network_tokenization_card(xml, payment_method, options)
576
656
  else
577
657
  add_card_or_token(xml, payment_method, options)
578
658
  end
@@ -590,8 +670,9 @@ module ActiveMerchant #:nodoc:
590
670
  end
591
671
  end
592
672
 
593
- def add_network_tokenization_card(xml, payment_method)
594
- token_type = NETWORK_TOKEN_TYPE.fetch(payment_method.source, 'NETWORKTOKEN')
673
+ def add_network_tokenization_card(xml, payment_method, options)
674
+ source = payment_method.respond_to?(:source) ? payment_method.source : options[:wallet_type]
675
+ token_type = NETWORK_TOKEN_TYPE.fetch(source, 'NETWORKTOKEN')
595
676
 
596
677
  xml.paymentDetails do
597
678
  xml.tag! 'EMVCO_TOKEN-SSL', 'type' => token_type do
@@ -603,14 +684,58 @@ module ActiveMerchant #:nodoc:
603
684
  )
604
685
  end
605
686
  name = card_holder_name(payment_method, options)
606
- eci = format(payment_method.eci, :two_digits)
607
687
  xml.cardHolderName name if name.present?
608
- xml.cryptogram payment_method.payment_cryptogram
609
- xml.eciIndicator eci.empty? ? '07' : eci
688
+ xml.cryptogram payment_method.payment_cryptogram unless should_send_payment_cryptogram?(options, payment_method)
689
+ eci = eci_value(payment_method, options)
690
+ xml.eciIndicator eci if eci.present?
691
+ end
692
+ add_stored_credential_options(xml, options)
693
+ add_shopper_id(xml, options, false)
694
+ add_three_d_secure(xml, options)
695
+ end
696
+ end
697
+
698
+ def should_send_payment_cryptogram?(options, payment_method)
699
+ wallet_type_google_pay?(options) ||
700
+ (payment_method_apple_pay?(payment_method) &&
701
+ merchant_initiated?(options))
702
+ end
703
+
704
+ def merchant_initiated?(options)
705
+ options.dig(:stored_credential, :initiator) == 'merchant'
706
+ end
707
+
708
+ def add_encrypted_wallet(xml, payment_method)
709
+ source = encrypted_wallet_source(payment_method.source)
710
+
711
+ xml.paymentDetails do
712
+ xml.tag! "#{source}-SSL" do
713
+ if source == 'APPLEPAY'
714
+ add_encrypted_apple_pay(xml, payment_method)
715
+ else
716
+ add_encrypted_google_pay(xml, payment_method)
717
+ end
610
718
  end
611
719
  end
612
720
  end
613
721
 
722
+ def add_encrypted_apple_pay(xml, payment_method)
723
+ xml.header do
724
+ xml.ephemeralPublicKey payment_method.payment_data.dig(:header, :ephemeralPublicKey)
725
+ xml.publicKeyHash payment_method.payment_data.dig(:header, :publicKeyHash)
726
+ xml.transactionId payment_method.payment_data.dig(:header, :transactionId)
727
+ end
728
+ xml.signature payment_method.payment_data[:signature]
729
+ xml.version payment_method.payment_data[:version]
730
+ xml.data payment_method.payment_data[:data]
731
+ end
732
+
733
+ def add_encrypted_google_pay(xml, payment_method)
734
+ xml.protocolVersion payment_method.payment_data[:version]
735
+ xml.signature payment_method.payment_data[:signature]
736
+ xml.signedMessage payment_method.payment_data[:signed_message]
737
+ end
738
+
614
739
  def add_card_or_token(xml, payment_method, options)
615
740
  xml.paymentDetails credit_fund_transfer_attribute(options) do
616
741
  if options[:payment_type] == :token
@@ -636,13 +761,13 @@ module ActiveMerchant #:nodoc:
636
761
  end
637
762
  end
638
763
 
639
- def add_shopper_id(xml, options)
640
- if options[:ip] && options[:session_id]
641
- xml.session 'shopperIPAddress' => options[:ip], 'id' => options[:session_id]
642
- else
643
- xml.session 'shopperIPAddress' => options[:ip] if options[:ip]
644
- xml.session 'id' => options[:session_id] if options[:session_id]
645
- end
764
+ def add_shopper_id(xml, options, with_session_id = true)
765
+ session_params = {
766
+ 'shopperIPAddress' => options[:ip],
767
+ 'id' => with_session_id ? options[:session_id] : nil
768
+ }.compact
769
+
770
+ xml.session session_params if session_params.present?
646
771
  end
647
772
 
648
773
  def add_three_d_secure(xml, options)
@@ -678,39 +803,38 @@ module ActiveMerchant #:nodoc:
678
803
  def add_stored_credential_options(xml, options = {})
679
804
  if options[:stored_credential]
680
805
  add_stored_credential_using_normalized_fields(xml, options)
681
- else
806
+ elsif options[:stored_credential_usage]
682
807
  add_stored_credential_using_gateway_specific_fields(xml, options)
683
808
  end
684
809
  end
685
810
 
686
811
  def add_stored_credential_using_normalized_fields(xml, options)
687
- if options[:stored_credential][:initial_transaction]
688
- xml.storedCredentials 'usage' => 'FIRST'
689
- else
690
- reason = case options[:stored_credential][:reason_type]
691
- when 'installment' then 'INSTALMENT'
692
- when 'recurring' then 'RECURRING'
693
- when 'unscheduled' then 'UNSCHEDULED'
694
- end
695
-
696
- xml.storedCredentials 'usage' => 'USED', 'merchantInitiatedReason' => reason do
697
- xml.schemeTransactionIdentifier options[:stored_credential][:network_transaction_id] if options[:stored_credential][:network_transaction_id]
698
- end
812
+ reason = case options[:stored_credential][:reason_type]
813
+ when 'installment' then 'INSTALMENT'
814
+ when 'recurring' then 'RECURRING'
815
+ when 'unscheduled' then 'UNSCHEDULED'
816
+ end
817
+ is_initial_transaction = options[:stored_credential][:initial_transaction]
818
+ stored_credential_params = generate_stored_credential_params(is_initial_transaction, reason, options[:stored_credential][:initiator])
819
+
820
+ xml.storedCredentials stored_credential_params do
821
+ xml.schemeTransactionIdentifier network_transaction_id(options) if send_network_transaction_id?(options)
699
822
  end
700
823
  end
701
824
 
702
825
  def add_stored_credential_using_gateway_specific_fields(xml, options)
703
- return unless options[:stored_credential_usage]
826
+ is_initial_transaction = options[:stored_credential_usage] == 'FIRST'
827
+ stored_credential_params = generate_stored_credential_params(is_initial_transaction, options[:stored_credential_initiated_reason])
704
828
 
705
- if options[:stored_credential_initiated_reason]
706
- xml.storedCredentials 'usage' => options[:stored_credential_usage], 'merchantInitiatedReason' => options[:stored_credential_initiated_reason] do
707
- xml.schemeTransactionIdentifier options[:stored_credential_transaction_id] if options[:stored_credential_transaction_id]
708
- end
709
- else
710
- xml.storedCredentials 'usage' => options[:stored_credential_usage]
829
+ xml.storedCredentials stored_credential_params do
830
+ xml.schemeTransactionIdentifier options[:stored_credential_transaction_id] if options[:stored_credential_transaction_id] && !is_initial_transaction
711
831
  end
712
832
  end
713
833
 
834
+ def send_network_transaction_id?(options)
835
+ network_transaction_id(options) && !options.dig(:stored_credential, :initial_transaction) && options.dig(:stored_credential, :initiator) != 'cardholder'
836
+ end
837
+
714
838
  def add_shopper(xml, options)
715
839
  return unless options[:execute_threed] || options[:email] || options[:customer]
716
840
 
@@ -724,6 +848,20 @@ module ActiveMerchant #:nodoc:
724
848
  end
725
849
  end
726
850
 
851
+ def add_fraud_sight_data(xml, options)
852
+ return unless options[:custom_string_fields].is_a?(Hash)
853
+
854
+ xml.tag! 'FraudSightData' do
855
+ xml.tag! 'customStringFields' do
856
+ options[:custom_string_fields].each do |key, value|
857
+ # transform custom_string_field_1 into customStringField1, etc.
858
+ formatted_key = key.to_s.camelize(:lower).to_sym
859
+ xml.tag! formatted_key, value
860
+ end
861
+ end
862
+ end
863
+ end
864
+
727
865
  def add_statement_narrative(xml, options)
728
866
  xml.statementNarrative truncate(options[:statement_narrative], 50) if options[:statement_narrative]
729
867
  end
@@ -792,7 +930,7 @@ module ActiveMerchant #:nodoc:
792
930
  xml = xml.strip.gsub(/\&/, '&amp;')
793
931
  doc = Nokogiri::XML(xml, &:strict)
794
932
  doc.remove_namespaces!
795
- resp_params = { action: action }
933
+ resp_params = { action: }
796
934
 
797
935
  parse_elements(doc.root, resp_params)
798
936
  extract_issuer_response(doc.root, resp_params)
@@ -823,7 +961,7 @@ module ActiveMerchant #:nodoc:
823
961
  end
824
962
 
825
963
  def headers(options)
826
- idempotency_key = options[:idempotency_key]
964
+ @idempotency_key ||= options[:idempotency_key]
827
965
 
828
966
  headers = {
829
967
  'Content-Type' => 'text/xml',
@@ -832,14 +970,20 @@ module ActiveMerchant #:nodoc:
832
970
 
833
971
  # ensure cookie included on follow-up '3ds' and 'capture_request' calls, using the cookie saved from the preceding response
834
972
  # cookie should be present in options on the 3ds and capture calls, but also still saved in the instance var in case
835
- cookie = options[:cookie] || @cookie || nil
973
+ cookie = defined?(@cookie) ? @cookie : nil
974
+ cookie = options[:cookie] || cookie
836
975
  headers['Cookie'] = cookie if cookie
837
976
 
838
- headers['Idempotency-Key'] = idempotency_key if idempotency_key
977
+ # Required because Worldpay does not accept duplicate idempotency keys
978
+ # for different transactions, such as in the case of an authorize => capture flow.
979
+ if @idempotency_key
980
+ headers['Idempotency-Key'] = @idempotency_key
981
+ @idempotency_key = SecureRandom.uuid
982
+ end
839
983
  headers
840
984
  end
841
985
 
842
- def commit(action, request, *success_criteria, options)
986
+ def commit(action, request, *success_or_failure_criteria, options)
843
987
  xml = ssl_post(url, request, headers(options))
844
988
  raw = parse(action, xml)
845
989
 
@@ -848,8 +992,9 @@ module ActiveMerchant #:nodoc:
848
992
  raw[:session_id] = options[:session_id]
849
993
  raw[:is3DSOrder] = true
850
994
  end
851
- success = success_from(action, raw, success_criteria)
852
- message = message_from(success, raw, success_criteria, action)
995
+
996
+ success = success_from(action, raw, success_or_failure_criteria)
997
+ message = message_from(success, raw, success_or_failure_criteria, action)
853
998
 
854
999
  Response.new(
855
1000
  success,
@@ -894,32 +1039,37 @@ module ActiveMerchant #:nodoc:
894
1039
  end
895
1040
  end
896
1041
 
897
- def success_from(action, raw, success_criteria)
898
- success_criteria_success?(raw, success_criteria) || action_success?(action, raw)
1042
+ def success_from(action, raw, success_or_failure_criteria)
1043
+ if action == 'direct_inquiry'
1044
+ return if raw[:error]
1045
+
1046
+ # for direct_inquiry we are looking for failed last_event
1047
+ !success_or_failure_criteria.include?(raw[:last_event])
1048
+ else
1049
+ success_criteria_success?(raw, success_or_failure_criteria) || action_success?(action, raw)
1050
+ end
899
1051
  end
900
1052
 
901
- def message_from(success, raw, success_criteria, action)
1053
+ def message_from(success, raw, success_or_failure_criteria, action)
902
1054
  return 'SUCCESS' if success
903
1055
 
904
- raw[:iso8583_return_code_description] || raw[:error] || required_status_message(raw, success_criteria, action) || raw[:issuer_response_description]
1056
+ raw[:iso8583_return_code_description] || raw[:error] || required_status_message(raw, success_or_failure_criteria, action) || raw[:issuer_response_description]
905
1057
  end
906
1058
 
907
- # success_criteria can be:
1059
+ # success_or_failure_criteria can be:
908
1060
  # - a string or an array of strings (if one of many responses)
909
1061
  # - An array of strings if one of many responses could be considered a
910
1062
  # success.
911
- def success_criteria_success?(raw, success_criteria)
1063
+ def success_criteria_success?(raw, success_or_failure_criteria)
912
1064
  return if raw[:error]
913
1065
 
914
- raw[:ok].present? || (success_criteria.include?(raw[:last_event]) if raw[:last_event])
1066
+ raw[:ok].present? || (success_or_failure_criteria.include?(raw[:last_event]) if raw[:last_event])
915
1067
  end
916
1068
 
917
1069
  def action_success?(action, raw)
918
1070
  case action
919
1071
  when 'store'
920
1072
  raw[:token].present?
921
- when 'direct_inquiry'
922
- raw[:last_event].present?
923
1073
  else
924
1074
  false
925
1075
  end
@@ -929,11 +1079,11 @@ module ActiveMerchant #:nodoc:
929
1079
  raw[:iso8583_return_code_code] || raw[:error_code] || nil unless success == 'SUCCESS'
930
1080
  end
931
1081
 
932
- def required_status_message(raw, success_criteria, action)
933
- return if success_criteria.include?(raw[:last_event])
1082
+ def required_status_message(raw, success_or_failure_criteria, action)
1083
+ return if success_or_failure_criteria.include?(raw[:last_event])
934
1084
  return unless %w[cancel refund inquiry credit fast_credit].include?(action)
935
1085
 
936
- "A transaction status of #{success_criteria.collect { |c| "'#{c}'" }.join(' or ')} is required."
1086
+ "A transaction status of #{success_or_failure_criteria.collect { |c| "'#{c}'" }.join(' or ')} is required."
937
1087
  end
938
1088
 
939
1089
  def authorization_from(action, raw, options)
@@ -942,7 +1092,7 @@ module ActiveMerchant #:nodoc:
942
1092
  case action
943
1093
  when 'store'
944
1094
  authorization_from_token_details(
945
- order_id: order_id,
1095
+ order_id:,
946
1096
  token_id: raw[:payment_token_id],
947
1097
  token_scope: 'shopper',
948
1098
  customer: options[:customer]
@@ -977,21 +1127,32 @@ module ActiveMerchant #:nodoc:
977
1127
  token_details
978
1128
  end
979
1129
 
980
- def payment_details(payment_method)
1130
+ def payment_details(payment_method, options = {})
981
1131
  case payment_method
982
1132
  when String
983
1133
  token_type_and_details(payment_method)
984
1134
  else
985
- type = network_token?(payment_method) ? :network_token : :credit
986
-
987
- { payment_type: type }
1135
+ payment_method_type(payment_method, options)
988
1136
  end
989
1137
  end
990
1138
 
991
- def network_token?(payment_method)
992
- payment_method.respond_to?(:source) &&
993
- payment_method.respond_to?(:payment_cryptogram) &&
994
- payment_method.respond_to?(:eci)
1139
+ def payment_method_type(payment_method, options)
1140
+ type = if payment_method.is_a?(NetworkTokenizationCreditCard)
1141
+ payment_method.encrypted_wallet? ? :encrypted_wallet : :network_token
1142
+ else
1143
+ wallet_type_google_pay?(options) ? :network_token : :credit
1144
+ end
1145
+ { payment_type: type }
1146
+ end
1147
+
1148
+ def payment_method_apple_pay?(payment_method)
1149
+ return false unless payment_method.is_a?(NetworkTokenizationCreditCard)
1150
+
1151
+ payment_method.source == :apple_pay
1152
+ end
1153
+
1154
+ def wallet_type_google_pay?(options)
1155
+ options[:wallet_type] == :google_pay
995
1156
  end
996
1157
 
997
1158
  def token_type_and_details(token)
@@ -1026,6 +1187,29 @@ module ActiveMerchant #:nodoc:
1026
1187
  def card_holder_name(payment_method, options)
1027
1188
  test? && options[:execute_threed] && !options[:three_ds_version]&.start_with?('2') ? '3D' : payment_method.name
1028
1189
  end
1190
+
1191
+ def generate_stored_credential_params(is_initial_transaction, reason = nil, initiator = nil)
1192
+ customer_or_merchant = initiator == 'cardholder' ? 'customerInitiatedReason' : 'merchantInitiatedReason'
1193
+
1194
+ stored_credential_params = {}
1195
+ stored_credential_params['usage'] = is_initial_transaction ? 'FIRST' : 'USED'
1196
+
1197
+ return stored_credential_params if customer_or_merchant == 'customerInitiatedReason' && stored_credential_params['usage'] == 'USED'
1198
+
1199
+ stored_credential_params[customer_or_merchant] = reason if reason
1200
+ stored_credential_params
1201
+ end
1202
+
1203
+ def encrypted_wallet_source(source)
1204
+ case source
1205
+ when :apple_pay
1206
+ 'APPLEPAY'
1207
+ when :google_pay
1208
+ 'PAYWITHGOOGLE'
1209
+ else
1210
+ raise ArgumentError, 'Invalid encrypted wallet source'
1211
+ end
1212
+ end
1029
1213
  end
1030
1214
  end
1031
1215
  end