activemerchant 1.79.2 → 1.129.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (279) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG +1391 -0
  3. data/README.md +29 -14
  4. data/lib/active_merchant/billing/avs_result.rb +25 -28
  5. data/lib/active_merchant/billing/base.rb +0 -13
  6. data/lib/active_merchant/billing/check.rb +55 -22
  7. data/lib/active_merchant/billing/compatibility.rb +10 -12
  8. data/lib/active_merchant/billing/credit_card.rb +82 -62
  9. data/lib/active_merchant/billing/credit_card_formatting.rb +4 -4
  10. data/lib/active_merchant/billing/credit_card_methods.rb +328 -58
  11. data/lib/active_merchant/billing/cvv_result.rb +0 -1
  12. data/lib/active_merchant/billing/gateway.rb +61 -56
  13. data/lib/active_merchant/billing/gateways/adyen.rb +562 -87
  14. data/lib/active_merchant/billing/gateways/airwallex.rb +370 -0
  15. data/lib/active_merchant/billing/gateways/alelo.rb +256 -0
  16. data/lib/active_merchant/billing/gateways/allied_wallet.rb +35 -36
  17. data/lib/active_merchant/billing/gateways/authorize_net.rb +297 -196
  18. data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +31 -24
  19. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +94 -98
  20. data/lib/active_merchant/billing/gateways/axcessms.rb +64 -66
  21. data/lib/active_merchant/billing/gateways/balanced.rb +72 -65
  22. data/lib/active_merchant/billing/gateways/bambora_apac.rb +222 -0
  23. data/lib/active_merchant/billing/gateways/bank_frick.rb +16 -16
  24. data/lib/active_merchant/billing/gateways/banwire.rb +12 -12
  25. data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +140 -69
  26. data/lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb +7 -7
  27. data/lib/active_merchant/billing/gateways/be2bill.rb +7 -7
  28. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +115 -115
  29. data/lib/active_merchant/billing/gateways/beanstream.rb +39 -13
  30. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +1 -2
  31. data/lib/active_merchant/billing/gateways/blue_pay.rb +87 -58
  32. data/lib/active_merchant/billing/gateways/blue_snap.rb +405 -104
  33. data/lib/active_merchant/billing/gateways/bogus.rb +34 -30
  34. data/lib/active_merchant/billing/gateways/borgun.rb +97 -47
  35. data/lib/active_merchant/billing/gateways/bpoint.rb +20 -20
  36. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -3
  37. data/lib/active_merchant/billing/gateways/braintree/token_nonce.rb +113 -0
  38. data/lib/active_merchant/billing/gateways/braintree.rb +1 -1
  39. data/lib/active_merchant/billing/gateways/braintree_blue.rb +561 -259
  40. data/lib/active_merchant/billing/gateways/braintree_orange.rb +1 -1
  41. data/lib/active_merchant/billing/gateways/bridge_pay.rb +53 -54
  42. data/lib/active_merchant/billing/gateways/cams.rb +31 -31
  43. data/lib/active_merchant/billing/gateways/card_connect.rb +85 -33
  44. data/lib/active_merchant/billing/gateways/card_save.rb +7 -9
  45. data/lib/active_merchant/billing/gateways/card_stream.rb +187 -169
  46. data/lib/active_merchant/billing/gateways/cardknox.rb +24 -25
  47. data/lib/active_merchant/billing/gateways/cardprocess.rb +9 -7
  48. data/lib/active_merchant/billing/gateways/cashnet.rb +43 -27
  49. data/lib/active_merchant/billing/gateways/cc5.rb +14 -17
  50. data/lib/active_merchant/billing/gateways/cecabank.rb +62 -52
  51. data/lib/active_merchant/billing/gateways/cenpos.rb +63 -62
  52. data/lib/active_merchant/billing/gateways/checkout.rb +21 -23
  53. data/lib/active_merchant/billing/gateways/checkout_v2.rb +391 -113
  54. data/lib/active_merchant/billing/gateways/citrus_pay.rb +1 -3
  55. data/lib/active_merchant/billing/gateways/clearhaus.rb +40 -41
  56. data/lib/active_merchant/billing/gateways/commerce_hub.rb +361 -0
  57. data/lib/active_merchant/billing/gateways/commercegate.rb +11 -12
  58. data/lib/active_merchant/billing/gateways/conekta.rb +35 -30
  59. data/lib/active_merchant/billing/gateways/creditcall.rb +59 -59
  60. data/lib/active_merchant/billing/gateways/credorax.rb +326 -145
  61. data/lib/active_merchant/billing/gateways/ct_payment.rb +269 -0
  62. data/lib/active_merchant/billing/gateways/culqi.rb +53 -53
  63. data/lib/active_merchant/billing/gateways/cyber_source/cyber_source_common.rb +36 -0
  64. data/lib/active_merchant/billing/gateways/cyber_source.rb +566 -208
  65. data/lib/active_merchant/billing/gateways/cyber_source_rest.rb +456 -0
  66. data/lib/active_merchant/billing/gateways/d_local.rb +342 -0
  67. data/lib/active_merchant/billing/gateways/data_cash.rb +40 -56
  68. data/lib/active_merchant/billing/gateways/decidir.rb +358 -0
  69. data/lib/active_merchant/billing/gateways/decidir_plus.rb +344 -0
  70. data/lib/active_merchant/billing/gateways/dibs.rb +34 -40
  71. data/lib/active_merchant/billing/gateways/digitzs.rb +48 -45
  72. data/lib/active_merchant/billing/gateways/ebanx.rb +110 -60
  73. data/lib/active_merchant/billing/gateways/efsnet.rb +46 -50
  74. data/lib/active_merchant/billing/gateways/elavon.rb +351 -189
  75. data/lib/active_merchant/billing/gateways/element.rb +106 -56
  76. data/lib/active_merchant/billing/gateways/epay.rb +74 -64
  77. data/lib/active_merchant/billing/gateways/evo_ca.rb +13 -14
  78. data/lib/active_merchant/billing/gateways/eway.rb +74 -73
  79. data/lib/active_merchant/billing/gateways/eway_managed.rb +85 -87
  80. data/lib/active_merchant/billing/gateways/eway_rapid.rb +105 -60
  81. data/lib/active_merchant/billing/gateways/exact.rb +29 -37
  82. data/lib/active_merchant/billing/gateways/ezic.rb +21 -22
  83. data/lib/active_merchant/billing/gateways/fat_zebra.rb +70 -48
  84. data/lib/active_merchant/billing/gateways/federated_canada.rb +11 -13
  85. data/lib/active_merchant/billing/gateways/finansbank.rb +3 -4
  86. data/lib/active_merchant/billing/gateways/first_giving.rb +23 -23
  87. data/lib/active_merchant/billing/gateways/first_pay.rb +33 -13
  88. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +106 -105
  89. data/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb +505 -0
  90. data/lib/active_merchant/billing/gateways/flo2cash.rb +36 -36
  91. data/lib/active_merchant/billing/gateways/flo2cash_simple.rb +2 -2
  92. data/lib/active_merchant/billing/gateways/forte.rb +70 -40
  93. data/lib/active_merchant/billing/gateways/garanti.rb +24 -31
  94. data/lib/active_merchant/billing/gateways/global_collect.rb +378 -154
  95. data/lib/active_merchant/billing/gateways/global_transport.rb +12 -13
  96. data/lib/active_merchant/billing/gateways/hdfc.rb +55 -57
  97. data/lib/active_merchant/billing/gateways/hps.rb +236 -69
  98. data/lib/active_merchant/billing/gateways/iats_payments.rb +61 -39
  99. data/lib/active_merchant/billing/gateways/in_context_paypal_express.rb +1 -1
  100. data/lib/active_merchant/billing/gateways/inspire.rb +41 -47
  101. data/lib/active_merchant/billing/gateways/instapay.rb +10 -14
  102. data/lib/active_merchant/billing/gateways/ipg.rb +420 -0
  103. data/lib/active_merchant/billing/gateways/ipp.rb +25 -24
  104. data/lib/active_merchant/billing/gateways/iridium.rb +243 -244
  105. data/lib/active_merchant/billing/gateways/itransact.rb +14 -14
  106. data/lib/active_merchant/billing/gateways/iveri.rb +73 -34
  107. data/lib/active_merchant/billing/gateways/ixopay.rb +320 -0
  108. data/lib/active_merchant/billing/gateways/jetpay.rb +145 -152
  109. data/lib/active_merchant/billing/gateways/jetpay_v2.rb +154 -159
  110. data/lib/active_merchant/billing/gateways/komoju.rb +16 -16
  111. data/lib/active_merchant/billing/gateways/kushki.rb +127 -57
  112. data/lib/active_merchant/billing/gateways/latitude19.rb +111 -115
  113. data/lib/active_merchant/billing/gateways/linkpoint.rb +82 -85
  114. data/lib/active_merchant/billing/gateways/litle.rb +247 -53
  115. data/lib/active_merchant/billing/gateways/mastercard.rb +41 -23
  116. data/lib/active_merchant/billing/gateways/maxipago.rb +5 -5
  117. data/lib/active_merchant/billing/gateways/mercado_pago.rb +135 -49
  118. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +62 -29
  119. data/lib/active_merchant/billing/gateways/merchant_one.rb +16 -20
  120. data/lib/active_merchant/billing/gateways/merchant_partners.rb +40 -40
  121. data/lib/active_merchant/billing/gateways/merchant_ware.rb +54 -60
  122. data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +42 -44
  123. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +52 -14
  124. data/lib/active_merchant/billing/gateways/mercury.rb +47 -51
  125. data/lib/active_merchant/billing/gateways/metrics_global.rb +32 -42
  126. data/lib/active_merchant/billing/gateways/micropayment.rb +42 -45
  127. data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +7 -7
  128. data/lib/active_merchant/billing/gateways/migs.rb +45 -40
  129. data/lib/active_merchant/billing/gateways/mit.rb +260 -0
  130. data/lib/active_merchant/billing/gateways/modern_payments.rb +2 -2
  131. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +29 -31
  132. data/lib/active_merchant/billing/gateways/moka.rb +290 -0
  133. data/lib/active_merchant/billing/gateways/monei.rb +255 -138
  134. data/lib/active_merchant/billing/gateways/moneris.rb +226 -88
  135. data/lib/active_merchant/billing/gateways/money_movers.rb +11 -13
  136. data/lib/active_merchant/billing/gateways/mundipagg.rb +117 -43
  137. data/lib/active_merchant/billing/gateways/nab_transact.rb +28 -31
  138. data/lib/active_merchant/billing/gateways/ncr_secure_pay.rb +13 -15
  139. data/lib/active_merchant/billing/gateways/net_registry.rb +12 -12
  140. data/lib/active_merchant/billing/gateways/netaxept.rb +33 -34
  141. data/lib/active_merchant/billing/gateways/netbanx.rb +167 -80
  142. data/lib/active_merchant/billing/gateways/netbilling.rb +27 -30
  143. data/lib/active_merchant/billing/gateways/netpay.rb +10 -10
  144. data/lib/active_merchant/billing/gateways/network_merchants.rb +7 -11
  145. data/lib/active_merchant/billing/gateways/nmi.rb +134 -48
  146. data/lib/active_merchant/billing/gateways/ogone.rb +88 -58
  147. data/lib/active_merchant/billing/gateways/omise.rb +30 -31
  148. data/lib/active_merchant/billing/gateways/openpay.rb +45 -26
  149. data/lib/active_merchant/billing/gateways/opp.rb +166 -144
  150. data/lib/active_merchant/billing/gateways/optimal_payment.rb +67 -64
  151. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +5 -7
  152. data/lib/active_merchant/billing/gateways/orbital.rb +726 -382
  153. data/lib/active_merchant/billing/gateways/pac_net_raven.rb +26 -27
  154. data/lib/active_merchant/billing/gateways/pagarme.rb +47 -56
  155. data/lib/active_merchant/billing/gateways/pago_facil.rb +12 -14
  156. data/lib/active_merchant/billing/gateways/pay_arc.rb +392 -0
  157. data/lib/active_merchant/billing/gateways/pay_conex.rb +39 -40
  158. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +65 -65
  159. data/lib/active_merchant/billing/gateways/pay_hub.rb +39 -39
  160. data/lib/active_merchant/billing/gateways/pay_junction.rb +37 -37
  161. data/lib/active_merchant/billing/gateways/pay_junction_v2.rb +70 -54
  162. data/lib/active_merchant/billing/gateways/pay_secure.rb +15 -17
  163. data/lib/active_merchant/billing/gateways/pay_trace.rb +450 -0
  164. data/lib/active_merchant/billing/gateways/paybox_direct.rb +71 -47
  165. data/lib/active_merchant/billing/gateways/payeezy.rb +159 -32
  166. data/lib/active_merchant/billing/gateways/payex.rb +39 -42
  167. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +41 -36
  168. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +11 -8
  169. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +3 -3
  170. data/lib/active_merchant/billing/gateways/payflow.rb +178 -54
  171. data/lib/active_merchant/billing/gateways/payflow_express.rb +61 -65
  172. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +0 -1
  173. data/lib/active_merchant/billing/gateways/payflow_uk.rb +1 -2
  174. data/lib/active_merchant/billing/gateways/payment_express.rb +66 -58
  175. data/lib/active_merchant/billing/gateways/paymentez.rb +114 -25
  176. data/lib/active_merchant/billing/gateways/paymill.rb +134 -133
  177. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +2 -1
  178. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +4 -0
  179. data/lib/active_merchant/billing/gateways/paypal.rb +27 -14
  180. data/lib/active_merchant/billing/gateways/paypal_ca.rb +1 -1
  181. data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +2 -2
  182. data/lib/active_merchant/billing/gateways/paypal_express.rb +5 -2
  183. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +1 -1
  184. data/lib/active_merchant/billing/gateways/paysafe.rb +420 -0
  185. data/lib/active_merchant/billing/gateways/payscout.rb +10 -13
  186. data/lib/active_merchant/billing/gateways/paystation.rb +79 -82
  187. data/lib/active_merchant/billing/gateways/payu_in.rb +59 -58
  188. data/lib/active_merchant/billing/gateways/payu_latam.rb +139 -97
  189. data/lib/active_merchant/billing/gateways/payway.rb +27 -27
  190. data/lib/active_merchant/billing/gateways/payway_dot_com.rb +253 -0
  191. data/lib/active_merchant/billing/gateways/pin.rb +87 -34
  192. data/lib/active_merchant/billing/gateways/plexo.rb +308 -0
  193. data/lib/active_merchant/billing/gateways/plugnpay.rb +82 -82
  194. data/lib/active_merchant/billing/gateways/priority.rb +392 -0
  195. data/lib/active_merchant/billing/gateways/pro_pay.rb +139 -140
  196. data/lib/active_merchant/billing/gateways/psigate.rb +44 -44
  197. data/lib/active_merchant/billing/gateways/psl_card.rb +29 -37
  198. data/lib/active_merchant/billing/gateways/qbms.rb +75 -76
  199. data/lib/active_merchant/billing/gateways/quantum.rb +21 -23
  200. data/lib/active_merchant/billing/gateways/quickbooks.rb +142 -55
  201. data/lib/active_merchant/billing/gateways/quickpay/quickpay_common.rb +103 -107
  202. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +156 -158
  203. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb +7 -8
  204. data/lib/active_merchant/billing/gateways/quickpay.rb +1 -3
  205. data/lib/active_merchant/billing/gateways/qvalent.rb +137 -68
  206. data/lib/active_merchant/billing/gateways/rapyd.rb +319 -0
  207. data/lib/active_merchant/billing/gateways/reach.rb +277 -0
  208. data/lib/active_merchant/billing/gateways/realex.rb +132 -50
  209. data/lib/active_merchant/billing/gateways/redsys.rb +382 -186
  210. data/lib/active_merchant/billing/gateways/s5.rb +16 -16
  211. data/lib/active_merchant/billing/gateways/safe_charge.rb +83 -47
  212. data/lib/active_merchant/billing/gateways/sage.rb +49 -48
  213. data/lib/active_merchant/billing/gateways/sage_pay.rb +76 -83
  214. data/lib/active_merchant/billing/gateways/sallie_mae.rb +13 -15
  215. data/lib/active_merchant/billing/gateways/secure_net.rb +32 -40
  216. data/lib/active_merchant/billing/gateways/secure_pay.rb +30 -40
  217. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +23 -26
  218. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +14 -16
  219. data/lib/active_merchant/billing/gateways/securion_pay.rb +69 -31
  220. data/lib/active_merchant/billing/gateways/shift4.rb +342 -0
  221. data/lib/active_merchant/billing/gateways/simetrik.rb +368 -0
  222. data/lib/active_merchant/billing/gateways/skip_jack.rb +52 -53
  223. data/lib/active_merchant/billing/gateways/smart_ps.rb +51 -60
  224. data/lib/active_merchant/billing/gateways/so_easy_pay.rb +29 -29
  225. data/lib/active_merchant/billing/gateways/spreedly_core.rb +66 -47
  226. data/lib/active_merchant/billing/gateways/stripe.rb +309 -148
  227. data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +556 -0
  228. data/lib/active_merchant/billing/gateways/swipe_checkout.rb +18 -23
  229. data/lib/active_merchant/billing/gateways/telr.rb +46 -48
  230. data/lib/active_merchant/billing/gateways/tns.rb +8 -7
  231. data/lib/active_merchant/billing/gateways/trans_first.rb +37 -37
  232. data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +249 -245
  233. data/lib/active_merchant/billing/gateways/transact_pro.rb +25 -27
  234. data/lib/active_merchant/billing/gateways/transax.rb +6 -8
  235. data/lib/active_merchant/billing/gateways/transnational.rb +1 -2
  236. data/lib/active_merchant/billing/gateways/trexle.rb +22 -18
  237. data/lib/active_merchant/billing/gateways/trust_commerce.rb +161 -88
  238. data/lib/active_merchant/billing/gateways/usa_epay.rb +5 -6
  239. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +231 -238
  240. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +129 -55
  241. data/lib/active_merchant/billing/gateways/vanco.rb +42 -33
  242. data/lib/active_merchant/billing/gateways/verifi.rb +52 -53
  243. data/lib/active_merchant/billing/gateways/viaklix.rb +18 -22
  244. data/lib/active_merchant/billing/gateways/visanet_peru.rb +115 -74
  245. data/lib/active_merchant/billing/gateways/vpos.rb +223 -0
  246. data/lib/active_merchant/billing/gateways/webpay.rb +9 -9
  247. data/lib/active_merchant/billing/gateways/wepay.rb +38 -41
  248. data/lib/active_merchant/billing/gateways/wirecard.rb +36 -37
  249. data/lib/active_merchant/billing/gateways/wompi.rb +197 -0
  250. data/lib/active_merchant/billing/gateways/world_net.rb +39 -38
  251. data/lib/active_merchant/billing/gateways/worldpay.rb +756 -142
  252. data/lib/active_merchant/billing/gateways/worldpay_online_payments.rb +73 -83
  253. data/lib/active_merchant/billing/gateways/worldpay_us.rb +31 -31
  254. data/lib/active_merchant/billing/model.rb +2 -2
  255. data/lib/active_merchant/billing/network_tokenization_credit_card.rb +3 -3
  256. data/lib/active_merchant/billing/rails.rb +1 -1
  257. data/lib/active_merchant/billing/response.rb +32 -13
  258. data/lib/active_merchant/billing/three_d_secure_eci_mapper.rb +27 -0
  259. data/lib/active_merchant/billing.rb +1 -0
  260. data/lib/active_merchant/connection.rb +24 -38
  261. data/lib/active_merchant/country.rb +9 -5
  262. data/lib/active_merchant/errors.rb +4 -1
  263. data/lib/active_merchant/net_http_ssl_connection.rb +2 -0
  264. data/lib/active_merchant/network_connection_retries.rb +28 -31
  265. data/lib/active_merchant/post_data.rb +5 -3
  266. data/lib/active_merchant/posts_data.rb +5 -7
  267. data/lib/active_merchant/version.rb +1 -1
  268. data/lib/active_merchant.rb +3 -3
  269. data/lib/activemerchant.rb +1 -1
  270. data/lib/certs/cacert.pem +1592 -2329
  271. data/lib/support/gateway_support.rb +8 -10
  272. data/lib/support/ssl_verify.rb +9 -14
  273. data/lib/support/ssl_version.rb +9 -10
  274. metadata +98 -37
  275. data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +0 -246
  276. data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +0 -13
  277. data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +0 -29
  278. data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +0 -66
  279. data/lib/active_merchant/billing/gateways/moneris_us.rb +0 -309
@@ -1,4 +1,5 @@
1
1
  # coding: utf-8
2
+
2
3
  require 'nokogiri'
3
4
 
4
5
  module ActiveMerchant #:nodoc:
@@ -35,140 +36,145 @@ module ActiveMerchant #:nodoc:
35
36
  #
36
37
  #
37
38
  class RedsysGateway < Gateway
38
- self.live_url = "https://sis.sermepa.es/sis/operaciones"
39
- self.test_url = "https://sis-t.redsys.es:25443/sis/operaciones"
39
+ self.live_url = 'https://sis.redsys.es/sis/operaciones'
40
+ self.test_url = 'https://sis-t.redsys.es:25443/sis/operaciones'
40
41
 
41
42
  self.supported_countries = ['ES']
42
43
  self.default_currency = 'EUR'
43
44
  self.money_format = :cents
44
45
 
45
46
  # Not all card types may be activated by the bank!
46
- self.supported_cardtypes = [:visa, :master, :american_express, :jcb, :diners_club]
47
- self.homepage_url = "http://www.redsys.es/"
48
- self.display_name = "Redsys"
47
+ self.supported_cardtypes = %i[visa master american_express jcb diners_club unionpay]
48
+ self.homepage_url = 'http://www.redsys.es/'
49
+ self.display_name = 'Redsys'
49
50
 
50
51
  CURRENCY_CODES = {
51
- "AED" => '784',
52
- "ARS" => '32',
53
- "AUD" => '36',
54
- "BRL" => '986',
55
- "BOB" => '68',
56
- "CAD" => '124',
57
- "CHF" => '756',
58
- "CLP" => '152',
59
- "CNY" => '156',
60
- "COP" => '170',
61
- "CRC" => '188',
62
- "CZK" => '203',
63
- "DKK" => '208',
64
- "DOP" => '214',
65
- "EUR" => '978',
66
- "GBP" => '826',
67
- "GTQ" => '320',
68
- "HUF" => '348',
69
- "IDR" => '360',
70
- "INR" => '356',
71
- "JPY" => '392',
72
- "KRW" => '410',
73
- "MYR" => '458',
74
- "MXN" => '484',
75
- "NOK" => '578',
76
- "NZD" => '554',
77
- "PEN" => '604',
78
- "PLN" => '985',
79
- "RUB" => '643',
80
- "SAR" => '682',
81
- "SEK" => '752',
82
- "SGD" => '702',
83
- "THB" => '764',
84
- "TWD" => '901',
85
- "USD" => '840',
86
- "UYU" => '858'
52
+ 'AED' => '784',
53
+ 'ARS' => '32',
54
+ 'AUD' => '36',
55
+ 'BRL' => '986',
56
+ 'BOB' => '68',
57
+ 'CAD' => '124',
58
+ 'CHF' => '756',
59
+ 'CLP' => '152',
60
+ 'CNY' => '156',
61
+ 'COP' => '170',
62
+ 'CRC' => '188',
63
+ 'CZK' => '203',
64
+ 'DKK' => '208',
65
+ 'DOP' => '214',
66
+ 'EUR' => '978',
67
+ 'GBP' => '826',
68
+ 'GTQ' => '320',
69
+ 'HUF' => '348',
70
+ 'IDR' => '360',
71
+ 'INR' => '356',
72
+ 'JPY' => '392',
73
+ 'KRW' => '410',
74
+ 'MYR' => '458',
75
+ 'MXN' => '484',
76
+ 'NOK' => '578',
77
+ 'NZD' => '554',
78
+ 'PEN' => '604',
79
+ 'PLN' => '985',
80
+ 'RUB' => '643',
81
+ 'SAR' => '682',
82
+ 'SEK' => '752',
83
+ 'SGD' => '702',
84
+ 'THB' => '764',
85
+ 'TWD' => '901',
86
+ 'USD' => '840',
87
+ 'UYU' => '858'
87
88
  }
88
89
 
89
90
  # The set of supported transactions for this gateway.
90
91
  # More operations are supported by the gateway itself, but
91
92
  # are not supported in this library.
92
93
  SUPPORTED_TRANSACTIONS = {
93
- :purchase => 'A',
94
- :authorize => '1',
95
- :capture => '2',
96
- :refund => '3',
97
- :cancel => '9'
94
+ purchase: '0',
95
+ authorize: '1',
96
+ capture: '2',
97
+ refund: '3',
98
+ cancel: '9'
98
99
  }
99
100
 
100
101
  # These are the text meanings sent back by the acquirer when
101
102
  # a card has been rejected. Syntax or general request errors
102
103
  # are not covered here.
103
104
  RESPONSE_TEXTS = {
104
- 0 => "Transaction Approved",
105
- 400 => "Cancellation Accepted",
106
- 481 => "Cancellation Accepted",
107
- 500 => "Reconciliation Accepted",
108
- 900 => "Refund / Confirmation approved",
109
-
110
- 101 => "Card expired",
111
- 102 => "Card blocked temporarily or under susciption of fraud",
112
- 104 => "Transaction not permitted",
113
- 107 => "Contact the card issuer",
114
- 109 => "Invalid identification by merchant or POS terminal",
115
- 110 => "Invalid amount",
116
- 114 => "Card cannot be used to the requested transaction",
117
- 116 => "Insufficient credit",
118
- 118 => "Non-registered card",
119
- 125 => "Card not effective",
120
- 129 => "CVV2/CVC2 Error",
121
- 167 => "Contact the card issuer: suspected fraud",
122
- 180 => "Card out of service",
123
- 181 => "Card with credit or debit restrictions",
124
- 182 => "Card with credit or debit restrictions",
125
- 184 => "Authentication error",
126
- 190 => "Refusal with no specific reason",
127
- 191 => "Expiry date incorrect",
128
-
129
- 201 => "Card expired",
130
- 202 => "Card blocked temporarily or under suspicion of fraud",
131
- 204 => "Transaction not permitted",
132
- 207 => "Contact the card issuer",
133
- 208 => "Lost or stolen card",
134
- 209 => "Lost or stolen card",
135
- 280 => "CVV2/CVC2 Error",
136
- 290 => "Declined with no specific reason",
137
-
138
- 480 => "Original transaction not located, or time-out exceeded",
139
- 501 => "Original transaction not located, or time-out exceeded",
140
- 502 => "Original transaction not located, or time-out exceeded",
141
- 503 => "Original transaction not located, or time-out exceeded",
142
-
143
- 904 => "Merchant not registered at FUC",
144
- 909 => "System error",
145
- 912 => "Issuer not available",
146
- 913 => "Duplicate transmission",
147
- 916 => "Amount too low",
148
- 928 => "Time-out exceeded",
149
- 940 => "Transaction cancelled previously",
150
- 941 => "Authorization operation already cancelled",
151
- 942 => "Original authorization declined",
152
- 943 => "Different details from origin transaction",
153
- 944 => "Session error",
154
- 945 => "Duplicate transmission",
155
- 946 => "Cancellation of transaction while in progress",
156
- 947 => "Duplicate tranmission while in progress",
157
- 949 => "POS Inoperative",
158
- 950 => "Refund not possible",
159
- 9064 => "Card number incorrect",
160
- 9078 => "No payment method available",
161
- 9093 => "Non-existent card",
162
- 9218 => "Recursive transaction in bad gateway",
163
- 9253 => "Check-digit incorrect",
164
- 9256 => "Preauth not allowed for merchant",
165
- 9257 => "Preauth not allowed for card",
166
- 9261 => "Operating limit exceeded",
167
- 9912 => "Issuer not available",
168
- 9913 => "Confirmation error",
169
- 9914 => "KO Confirmation"
105
+ 0 => 'Transaction Approved',
106
+ 400 => 'Cancellation Accepted',
107
+ 481 => 'Cancellation Accepted',
108
+ 500 => 'Reconciliation Accepted',
109
+ 900 => 'Refund / Confirmation approved',
110
+
111
+ 101 => 'Card expired',
112
+ 102 => 'Card blocked temporarily or under susciption of fraud',
113
+ 104 => 'Transaction not permitted',
114
+ 107 => 'Contact the card issuer',
115
+ 109 => 'Invalid identification by merchant or POS terminal',
116
+ 110 => 'Invalid amount',
117
+ 114 => 'Card cannot be used to the requested transaction',
118
+ 116 => 'Insufficient credit',
119
+ 118 => 'Non-registered card',
120
+ 125 => 'Card not effective',
121
+ 129 => 'CVV2/CVC2 Error',
122
+ 167 => 'Contact the card issuer: suspected fraud',
123
+ 180 => 'Card out of service',
124
+ 181 => 'Card with credit or debit restrictions',
125
+ 182 => 'Card with credit or debit restrictions',
126
+ 184 => 'Authentication error',
127
+ 190 => 'Refusal with no specific reason',
128
+ 191 => 'Expiry date incorrect',
129
+ 195 => 'Requires SCA authentication',
130
+
131
+ 201 => 'Card expired',
132
+ 202 => 'Card blocked temporarily or under suspicion of fraud',
133
+ 204 => 'Transaction not permitted',
134
+ 207 => 'Contact the card issuer',
135
+ 208 => 'Lost or stolen card',
136
+ 209 => 'Lost or stolen card',
137
+ 280 => 'CVV2/CVC2 Error',
138
+ 290 => 'Declined with no specific reason',
139
+
140
+ 480 => 'Original transaction not located, or time-out exceeded',
141
+ 501 => 'Original transaction not located, or time-out exceeded',
142
+ 502 => 'Original transaction not located, or time-out exceeded',
143
+ 503 => 'Original transaction not located, or time-out exceeded',
144
+
145
+ 904 => 'Merchant not registered at FUC',
146
+ 909 => 'System error',
147
+ 912 => 'Issuer not available',
148
+ 913 => 'Duplicate transmission',
149
+ 916 => 'Amount too low',
150
+ 928 => 'Time-out exceeded',
151
+ 940 => 'Transaction cancelled previously',
152
+ 941 => 'Authorization operation already cancelled',
153
+ 942 => 'Original authorization declined',
154
+ 943 => 'Different details from origin transaction',
155
+ 944 => 'Session error',
156
+ 945 => 'Duplicate transmission',
157
+ 946 => 'Cancellation of transaction while in progress',
158
+ 947 => 'Duplicate tranmission while in progress',
159
+ 949 => 'POS Inoperative',
160
+ 950 => 'Refund not possible',
161
+ 9064 => 'Card number incorrect',
162
+ 9078 => 'No payment method available',
163
+ 9093 => 'Non-existent card',
164
+ 9218 => 'Recursive transaction in bad gateway',
165
+ 9253 => 'Check-digit incorrect',
166
+ 9256 => 'Preauth not allowed for merchant',
167
+ 9257 => 'Preauth not allowed for card',
168
+ 9261 => 'Operating limit exceeded',
169
+ 9912 => 'Issuer not available',
170
+ 9913 => 'Confirmation error',
171
+ 9914 => 'KO Confirmation'
170
172
  }
171
173
 
174
+ # Expected values as per documentation
175
+ THREE_DS_V1 = '1.0.2'
176
+ THREE_DS_V2 = '2.1.0'
177
+
172
178
  # Creates a new instance
173
179
  #
174
180
  # Redsys requires a login and secret_key, and optionally also accepts a
@@ -184,7 +190,7 @@ module ActiveMerchant #:nodoc:
184
190
  def initialize(options = {})
185
191
  requires!(options, :login, :secret_key)
186
192
  options[:terminal] ||= 1
187
- options[:signature_algorithm] ||= "sha1"
193
+ options[:signature_algorithm] ||= 'sha1'
188
194
  super
189
195
  end
190
196
 
@@ -192,67 +198,81 @@ module ActiveMerchant #:nodoc:
192
198
  requires!(options, :order_id)
193
199
 
194
200
  data = {}
195
- add_action(data, :purchase)
201
+ add_action(data, :purchase, options)
196
202
  add_amount(data, money, options)
197
203
  add_order(data, options[:order_id])
198
204
  add_payment(data, payment)
205
+ add_external_mpi_fields(data, options)
206
+ add_three_ds_data(data, options) if options[:execute_threed]
207
+ add_stored_credential_options(data, options)
199
208
  data[:description] = options[:description]
200
209
  data[:store_in_vault] = options[:store]
210
+ data[:sca_exemption] = options[:sca_exemption]
211
+ data[:sca_exemption_direct_payment_enabled] = options[:sca_exemption_direct_payment_enabled]
201
212
 
202
- commit data
213
+ commit data, options
203
214
  end
204
215
 
205
216
  def authorize(money, payment, options = {})
206
217
  requires!(options, :order_id)
207
218
 
208
219
  data = {}
209
- add_action(data, :authorize)
220
+ add_action(data, :authorize, options)
210
221
  add_amount(data, money, options)
211
222
  add_order(data, options[:order_id])
212
223
  add_payment(data, payment)
224
+ add_external_mpi_fields(data, options)
225
+ add_three_ds_data(data, options) if options[:execute_threed]
226
+ add_stored_credential_options(data, options)
213
227
  data[:description] = options[:description]
214
228
  data[:store_in_vault] = options[:store]
229
+ data[:sca_exemption] = options[:sca_exemption]
230
+ data[:sca_exemption_direct_payment_enabled] = options[:sca_exemption_direct_payment_enabled]
215
231
 
216
- commit data
232
+ commit data, options
217
233
  end
218
234
 
219
235
  def capture(money, authorization, options = {})
220
236
  data = {}
221
237
  add_action(data, :capture)
222
238
  add_amount(data, money, options)
223
- order_id, _, _ = split_authorization(authorization)
239
+ order_id, = split_authorization(authorization)
224
240
  add_order(data, order_id)
225
241
  data[:description] = options[:description]
226
242
 
227
- commit data
243
+ commit data, options
228
244
  end
229
245
 
230
246
  def void(authorization, options = {})
231
247
  data = {}
232
248
  add_action(data, :cancel)
233
249
  order_id, amount, currency = split_authorization(authorization)
234
- add_amount(data, amount, :currency => currency)
250
+ add_amount(data, amount, currency: currency)
235
251
  add_order(data, order_id)
236
252
  data[:description] = options[:description]
237
253
 
238
- commit data
254
+ commit data, options
239
255
  end
240
256
 
241
257
  def refund(money, authorization, options = {})
242
258
  data = {}
243
259
  add_action(data, :refund)
244
260
  add_amount(data, money, options)
245
- order_id, _, _ = split_authorization(authorization)
261
+ order_id, = split_authorization(authorization)
246
262
  add_order(data, order_id)
247
263
  data[:description] = options[:description]
248
264
 
249
- commit data
265
+ commit data, options
250
266
  end
251
267
 
252
268
  def verify(creditcard, options = {})
253
- MultiResponse.run(:use_first_response) do |r|
254
- r.process { authorize(100, creditcard, options) }
255
- r.process(:ignore_result) { void(r.authorization, options) }
269
+ if options[:sca_exemption_behavior_override] == 'endpoint_and_ntid'
270
+ purchase(0, creditcard, options)
271
+ else
272
+ MultiResponse.run(:use_first_response) do |r|
273
+ r.process { authorize(100, creditcard, options) }
274
+ r.process(:ignore_result) { void(r.authorization, options) }
275
+ end
256
276
  end
257
277
  end
258
278
 
@@ -265,8 +285,10 @@ module ActiveMerchant #:nodoc:
265
285
  gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]').
266
286
  gsub(%r((%3CDS_MERCHANT_PAN%3E)\d+(%3C%2FDS_MERCHANT_PAN%3E))i, '\1[FILTERED]\2').
267
287
  gsub(%r((%3CDS_MERCHANT_CVV2%3E)\d+(%3C%2FDS_MERCHANT_CVV2%3E))i, '\1[FILTERED]\2').
288
+ gsub(%r((&lt;DS_MERCHANT_PAN&gt;)\d+(&lt;/DS_MERCHANT_PAN&gt;))i, '\1[FILTERED]\2').
268
289
  gsub(%r((<DS_MERCHANT_PAN>)\d+(</DS_MERCHANT_PAN>))i, '\1[FILTERED]\2').
269
290
  gsub(%r((<DS_MERCHANT_CVV2>)\d+(</DS_MERCHANT_CVV2>))i, '\1[FILTERED]\2').
291
+ gsub(%r((&lt;DS_MERCHANT_CVV2&gt;)\d+(&lt;/DS_MERCHANT_CVV2&gt;))i, '\1[FILTERED]\2').
270
292
  gsub(%r((DS_MERCHANT_CVV2)%2F%3E%0A%3C%2F)i, '\1[BLANK]').
271
293
  gsub(%r((DS_MERCHANT_CVV2)%2F%3E%3C)i, '\1[BLANK]').
272
294
  gsub(%r((DS_MERCHANT_CVV2%3E)(%3C%2FDS_MERCHANT_CVV2))i, '\1[BLANK]\2').
@@ -277,8 +299,8 @@ module ActiveMerchant #:nodoc:
277
299
 
278
300
  private
279
301
 
280
- def add_action(data, action)
281
- data[:action] = transaction_code(action)
302
+ def add_action(data, action, options = {})
303
+ data[:action] = options[:execute_threed].present? ? '0' : transaction_code(action)
282
304
  end
283
305
 
284
306
  def add_amount(data, money, options)
@@ -294,45 +316,132 @@ module ActiveMerchant #:nodoc:
294
316
  test? ? test_url : live_url
295
317
  end
296
318
 
319
+ def webservice_url
320
+ test? ? 'https://sis-t.redsys.es:25443/sis/services/SerClsWSEntradaV2' : 'https://sis.redsys.es/sis/services/SerClsWSEntradaV2'
321
+ end
322
+
297
323
  def add_payment(data, card)
298
324
  if card.is_a?(String)
299
325
  data[:credit_card_token] = card
300
326
  else
301
327
  name = [card.first_name, card.last_name].join(' ').slice(0, 60)
302
- year = sprintf("%.4i", card.year)
303
- month = sprintf("%.2i", card.month)
328
+ year = sprintf('%.4i', card.year)
329
+ month = sprintf('%.2i', card.month)
304
330
  data[:card] = {
305
- :name => name,
306
- :pan => card.number,
307
- :date => "#{year[2..3]}#{month}",
308
- :cvv => card.verification_value
331
+ name: name,
332
+ pan: card.number,
333
+ date: "#{year[2..3]}#{month}",
334
+ cvv: card.verification_value
309
335
  }
310
336
  end
311
337
  end
312
338
 
313
- def commit(data)
314
- parse(ssl_post(url, "entrada=#{CGI.escape(xml_request_from(data))}", headers))
339
+ def add_external_mpi_fields(data, options)
340
+ return unless options[:three_d_secure]
341
+
342
+ if options[:three_d_secure][:version] == THREE_DS_V2
343
+ data[:threeDSServerTransID] = options[:three_d_secure][:three_ds_server_trans_id] if options[:three_d_secure][:three_ds_server_trans_id]
344
+ data[:dsTransID] = options[:three_d_secure][:ds_transaction_id] if options[:three_d_secure][:ds_transaction_id]
345
+ data[:authenticacionValue] = options[:three_d_secure][:cavv] if options[:three_d_secure][:cavv]
346
+ data[:protocolVersion] = options[:three_d_secure][:version] if options[:three_d_secure][:version]
347
+ data[:authenticacionMethod] = options[:authentication_method] if options[:authentication_method]
348
+ data[:authenticacionType] = options[:authentication_type] if options[:authentication_type]
349
+ data[:authenticacionFlow] = options[:authentication_flow] if options[:authentication_flow]
350
+ data[:eci_v2] = options[:three_d_secure][:eci] if options[:three_d_secure][:eci]
351
+ elsif options[:three_d_secure][:version] == THREE_DS_V1
352
+ data[:txid] = options[:three_d_secure][:xid] if options[:three_d_secure][:xid]
353
+ data[:cavv] = options[:three_d_secure][:cavv] if options[:three_d_secure][:cavv]
354
+ data[:eci_v1] = options[:three_d_secure][:eci] if options[:three_d_secure][:eci]
355
+ end
356
+ end
357
+
358
+ def add_stored_credential_options(data, options)
359
+ return unless options[:stored_credential]
360
+
361
+ case options[:stored_credential][:initial_transaction]
362
+ when true
363
+ data[:DS_MERCHANT_COF_INI] = 'S'
364
+ when false
365
+ data[:DS_MERCHANT_COF_INI] = 'N'
366
+ data[:DS_MERCHANT_COF_TXNID] = options[:stored_credential][:network_transaction_id] if options[:stored_credential][:network_transaction_id]
367
+ end
368
+
369
+ case options[:stored_credential][:reason_type]
370
+ when 'recurring'
371
+ data[:DS_MERCHANT_COF_TYPE] = 'R'
372
+ when 'installment'
373
+ data[:DS_MERCHANT_COF_TYPE] = 'I'
374
+ when 'unscheduled'
375
+ return
376
+ end
377
+ end
378
+
379
+ def add_three_ds_data(data, options)
380
+ data[:three_ds_data] = { threeDSInfo: 'CardData' } if options[:execute_threed] == true
315
381
  end
316
382
 
317
- def headers
318
- {
319
- 'Content-Type' => 'application/x-www-form-urlencoded'
320
- }
383
+ def determine_peticion_type(data)
384
+ three_ds_info = data.dig(:three_ds_data, :threeDSInfo)
385
+ return 'iniciaPeticion' if three_ds_info == 'CardData'
386
+ return 'trataPeticion' if three_ds_info == 'AuthenticationData' ||
387
+ three_ds_info == 'ChallengeResponse' ||
388
+ data[:sca_exemption] == 'MIT'
321
389
  end
322
390
 
323
- def xml_request_from(data)
391
+ def use_webservice_endpoint?(data, options)
392
+ options[:use_webservice_endpoint].to_s == 'true' || data[:three_ds_data] || data[:sca_exemption] == 'MIT'
393
+ end
394
+
395
+ def commit(data, options = {})
396
+ xmlreq = xml_request_from(data, options)
397
+
398
+ if use_webservice_endpoint?(data, options)
399
+ peticion_type = determine_peticion_type(data)
400
+
401
+ request = <<-REQUEST
402
+ <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://webservice.sis.sermepa.es" xmlns:intf="http://webservice.sis.sermepa.es" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
403
+ <soapenv:Header/>
404
+ <soapenv:Body>
405
+ <intf:#{peticion_type} xmlns:intf="http://webservice.sis.sermepa.es">
406
+ <intf:datoEntrada>
407
+ <![CDATA[#{xmlreq}]]>
408
+ </intf:datoEntrada>
409
+ </intf:#{peticion_type}>
410
+ </soapenv:Body>
411
+ </soapenv:Envelope>
412
+ REQUEST
413
+ parse(ssl_post(webservice_url, request, headers(peticion_type)), peticion_type)
414
+ else
415
+ parse(ssl_post(url, "entrada=#{CGI.escape(xmlreq)}", headers), peticion_type)
416
+ end
417
+ end
418
+
419
+ def headers(peticion_type = nil)
420
+ if peticion_type
421
+ {
422
+ 'Content-Type' => 'text/xml',
423
+ 'SOAPAction' => peticion_type
424
+ }
425
+ else
426
+ {
427
+ 'Content-Type' => 'application/x-www-form-urlencoded'
428
+ }
429
+ end
430
+ end
431
+
432
+ def xml_request_from(data, options = {})
324
433
  if sha256_authentication?
325
- build_sha256_xml_request(data)
434
+ build_sha256_xml_request(data, options)
326
435
  else
327
- build_sha1_xml_request(data)
436
+ build_sha1_xml_request(data, options)
328
437
  end
329
438
  end
330
439
 
331
440
  def build_signature(data)
332
441
  str = data[:amount] +
333
- data[:order_id].to_s +
334
- @options[:login].to_s +
335
- data[:currency]
442
+ data[:order_id].to_s +
443
+ @options[:login].to_s +
444
+ data[:currency]
336
445
 
337
446
  if card = data[:card]
338
447
  str << card[:pan]
@@ -350,30 +459,32 @@ module ActiveMerchant #:nodoc:
350
459
  Digest::SHA1.hexdigest(str)
351
460
  end
352
461
 
353
- def build_sha256_xml_request(data)
462
+ def build_sha256_xml_request(data, options = {})
354
463
  xml = Builder::XmlMarkup.new
355
464
  xml.instruct!
356
465
  xml.REQUEST do
357
- build_merchant_data(xml, data)
466
+ build_merchant_data(xml, data, options)
358
467
  xml.DS_SIGNATUREVERSION 'HMAC_SHA256_V1'
359
- xml.DS_SIGNATURE sign_request(merchant_data_xml(data), data[:order_id])
468
+ xml.DS_SIGNATURE sign_request(merchant_data_xml(data, options), data[:order_id])
360
469
  end
361
470
  xml.target!
362
471
  end
363
472
 
364
- def build_sha1_xml_request(data)
365
- xml = Builder::XmlMarkup.new :indent => 2
366
- build_merchant_data(xml, data)
473
+ def build_sha1_xml_request(data, options = {})
474
+ xml = Builder::XmlMarkup.new indent: 2
475
+ build_merchant_data(xml, data, options)
367
476
  xml.target!
368
477
  end
369
478
 
370
- def merchant_data_xml(data)
479
+ def merchant_data_xml(data, options = {})
371
480
  xml = Builder::XmlMarkup.new
372
- build_merchant_data(xml, data)
481
+ build_merchant_data(xml, data, options)
373
482
  xml.target!
374
483
  end
375
484
 
376
- def build_merchant_data(xml, data)
485
+ def build_merchant_data(xml, data, options = {})
486
+ # See https://sis-t.redsys.es:25443/sis/services/SerClsWSEntradaV2/wsdl/SerClsWSEntradaV2.wsdl
487
+ # (which results from calling #webservice_url + '?WSDL', https://sis-t.redsys.es:25443/sis/services/SerClsWSEntradaV2?WSDL)
377
488
  xml.DATOSENTRADA do
378
489
  # Basic elements
379
490
  xml.DS_Version 0.1
@@ -381,44 +492,108 @@ module ActiveMerchant #:nodoc:
381
492
  xml.DS_MERCHANT_AMOUNT data[:amount]
382
493
  xml.DS_MERCHANT_ORDER data[:order_id]
383
494
  xml.DS_MERCHANT_TRANSACTIONTYPE data[:action]
384
- xml.DS_MERCHANT_PRODUCTDESCRIPTION data[:description]
385
- xml.DS_MERCHANT_TERMINAL @options[:terminal]
495
+ if data[:description] && use_webservice_endpoint?(data, options)
496
+ xml.DS_MERCHANT_PRODUCTDESCRIPTION CGI.escape(data[:description])
497
+ else
498
+ xml.DS_MERCHANT_PRODUCTDESCRIPTION data[:description]
499
+ end
500
+ xml.DS_MERCHANT_TERMINAL options[:terminal] || @options[:terminal]
386
501
  xml.DS_MERCHANT_MERCHANTCODE @options[:login]
387
502
  xml.DS_MERCHANT_MERCHANTSIGNATURE build_signature(data) unless sha256_authentication?
388
503
 
504
+ peticion_type = determine_peticion_type(data) if data[:three_ds_data]
505
+ if peticion_type == 'iniciaPeticion' && data[:sca_exemption]
506
+ xml.DS_MERCHANT_EXCEP_SCA 'Y'
507
+ else
508
+ xml.DS_MERCHANT_EXCEP_SCA data[:sca_exemption] if data[:sca_exemption]
509
+ xml.DS_MERCHANT_DIRECTPAYMENT data[:sca_exemption_direct_payment_enabled] || 'true' if data[:sca_exemption] == 'MIT'
510
+ end
511
+
389
512
  # Only when card is present
390
513
  if data[:card]
391
- xml.DS_MERCHANT_TITULAR data[:card][:name]
514
+ if data[:card][:name] && use_webservice_endpoint?(data, options)
515
+ xml.DS_MERCHANT_TITULAR CGI.escape(data[:card][:name])
516
+ else
517
+ xml.DS_MERCHANT_TITULAR data[:card][:name]
518
+ end
392
519
  xml.DS_MERCHANT_PAN data[:card][:pan]
393
520
  xml.DS_MERCHANT_EXPIRYDATE data[:card][:date]
394
521
  xml.DS_MERCHANT_CVV2 data[:card][:cvv]
395
522
  xml.DS_MERCHANT_IDENTIFIER 'REQUIRED' if data[:store_in_vault]
523
+
524
+ build_merchant_mpi_external(xml, data)
525
+
396
526
  elsif data[:credit_card_token]
397
527
  xml.DS_MERCHANT_IDENTIFIER data[:credit_card_token]
528
+ xml.DS_MERCHANT_DIRECTPAYMENT 'true'
529
+ end
530
+
531
+ # Set moto flag only if explicitly requested via moto field
532
+ # Requires account configuration to be able to use
533
+ xml.DS_MERCHANT_DIRECTPAYMENT 'moto' if options.dig(:moto) && options.dig(:metadata, :manual_entry)
534
+
535
+ xml.DS_MERCHANT_EMV3DS data[:three_ds_data].to_json if data[:three_ds_data]
536
+
537
+ if options[:stored_credential]
538
+ xml.DS_MERCHANT_COF_INI data[:DS_MERCHANT_COF_INI]
539
+ xml.DS_MERCHANT_COF_TYPE data[:DS_MERCHANT_COF_TYPE]
540
+ xml.DS_MERCHANT_COF_TXNID data[:DS_MERCHANT_COF_TXNID] if data[:DS_MERCHANT_COF_TXNID]
398
541
  end
399
542
  end
400
543
  end
401
544
 
402
- def parse(data)
545
+ def build_merchant_mpi_external(xml, data)
546
+ return unless data[:txid] || data[:threeDSServerTransID]
547
+
548
+ ds_merchant_mpi_external = {}
549
+ ds_merchant_mpi_external[:TXID] = data[:txid] if data[:txid]
550
+ ds_merchant_mpi_external[:CAVV] = data[:cavv] if data[:cavv]
551
+ ds_merchant_mpi_external[:ECI] = data[:eci_v1] if data[:eci_v1]
552
+
553
+ ds_merchant_mpi_external[:threeDSServerTransID] = data[:threeDSServerTransID] if data[:threeDSServerTransID]
554
+ ds_merchant_mpi_external[:dsTransID] = data[:dsTransID] if data[:dsTransID]
555
+ ds_merchant_mpi_external[:authenticacionValue] = data[:authenticacionValue] if data[:authenticacionValue]
556
+ ds_merchant_mpi_external[:protocolVersion] = data[:protocolVersion] if data[:protocolVersion]
557
+ ds_merchant_mpi_external[:Eci] = data[:eci_v2] if data[:eci_v2]
558
+ ds_merchant_mpi_external[:authenticacionMethod] = data[:authenticacionMethod] if data[:authenticacionMethod]
559
+ ds_merchant_mpi_external[:authenticacionType] = data[:authenticacionType] if data[:authenticacionType]
560
+ ds_merchant_mpi_external[:authenticacionFlow] = data[:authenticacionFlow] if data[:authenticacionFlow]
561
+
562
+ xml.DS_MERCHANT_MPIEXTERNAL ds_merchant_mpi_external.to_json unless ds_merchant_mpi_external.empty?
563
+ xml.target!
564
+ end
565
+
566
+ def parse(data, action)
403
567
  params = {}
404
568
  success = false
405
- message = ""
406
- options = @options.merge(:test => test?)
569
+ message = ''
570
+ options = @options.merge(test: test?)
407
571
  xml = Nokogiri::XML(data)
408
- code = xml.xpath("//RETORNOXML/CODIGO").text
409
- if code == "0"
410
- op = xml.xpath("//RETORNOXML/OPERACION")
572
+ code = xml.xpath('//RETORNOXML/CODIGO').text
573
+
574
+ if code == '0' && xml.xpath('//RETORNOXML/OPERACION').present?
575
+ op = xml.xpath('//RETORNOXML/OPERACION')
411
576
  op.children.each do |element|
412
577
  params[element.name.downcase.to_sym] = element.text
413
578
  end
414
-
415
579
  if validate_signature(params)
416
580
  message = response_text(params[:ds_response])
417
581
  options[:authorization] = build_authorization(params)
418
- success = is_success_response?(params[:ds_response])
582
+ success = success_response?(params[:ds_response])
419
583
  else
420
- message = "Response failed validation check"
584
+ message = 'Response failed validation check'
421
585
  end
586
+ elsif %w[iniciaPeticion trataPeticion].include?(action)
587
+ vxml = Nokogiri::XML(data).remove_namespaces!.xpath("//Envelope/Body/#{action}Response/#{action}Return").inner_text
588
+ xml = Nokogiri::XML(vxml)
589
+ node = (action == 'iniciaPeticion' ? 'INFOTARJETA' : 'OPERACION')
590
+ op = xml.xpath("//RETORNOXML/#{node}")
591
+ op.children.each do |element|
592
+ params[element.name.downcase.to_sym] = element.text
593
+ end
594
+ message = response_text_3ds(xml, params)
595
+ options[:authorization] = build_authorization(params)
596
+ success = params.size > 0 && success_response?(params[:ds_response])
422
597
  else
423
598
  # Some kind of programmer error with the request!
424
599
  message = "#{code} ERROR"
@@ -430,17 +605,17 @@ module ActiveMerchant #:nodoc:
430
605
  def validate_signature(data)
431
606
  if sha256_authentication?
432
607
  sig = Base64.strict_encode64(mac256(get_key(data[:ds_order].to_s), xml_signed_fields(data)))
433
- sig.upcase == data[:ds_signature].to_s.upcase
608
+ sig.casecmp(data[:ds_signature].to_s).zero?
434
609
  else
435
610
  str = data[:ds_amount] +
436
- data[:ds_order].to_s +
437
- data[:ds_merchantcode] +
438
- data[:ds_currency] +
439
- data[:ds_response] +
440
- data[:ds_cardnumber].to_s +
441
- data[:ds_transactiontype].to_s +
442
- data[:ds_securepayment].to_s +
443
- @options[:secret_key]
611
+ data[:ds_order].to_s +
612
+ data[:ds_merchantcode] +
613
+ data[:ds_currency] +
614
+ data[:ds_response] +
615
+ data[:ds_cardnumber].to_s +
616
+ data[:ds_transactiontype].to_s +
617
+ data[:ds_securepayment].to_s +
618
+ @options[:secret_key]
444
619
 
445
620
  sig = Digest::SHA1.hexdigest(str)
446
621
  data[:ds_signature].to_s.downcase == sig
@@ -448,17 +623,18 @@ module ActiveMerchant #:nodoc:
448
623
  end
449
624
 
450
625
  def build_authorization(params)
451
- [params[:ds_order], params[:ds_amount], params[:ds_currency]].join("|")
626
+ [params[:ds_order], params[:ds_amount], params[:ds_currency]].join('|')
452
627
  end
453
628
 
454
629
  def split_authorization(authorization)
455
- order_id, amount, currency = authorization.split("|")
630
+ order_id, amount, currency = authorization.split('|')
456
631
  [order_id, amount.to_i, currency]
457
632
  end
458
633
 
459
634
  def currency_code(currency)
460
635
  return currency if currency =~ /^\d+$/
461
636
  raise ArgumentError, "Unknown currency #{currency}" unless CURRENCY_CODES[currency]
637
+
462
638
  CURRENCY_CODES[currency]
463
639
  end
464
640
 
@@ -469,24 +645,38 @@ module ActiveMerchant #:nodoc:
469
645
  def response_text(code)
470
646
  code = code.to_i
471
647
  code = 0 if code < 100
472
- RESPONSE_TEXTS[code] || "Unkown code, please check in manual"
648
+ RESPONSE_TEXTS[code] || 'Unknown code, please check in manual'
473
649
  end
474
650
 
475
- def is_success_response?(code)
651
+ def response_text_3ds(xml, params)
652
+ code = xml.xpath('//RETORNOXML/CODIGO').text
653
+ message = ''
654
+ if code != '0'
655
+ message = "#{code} ERROR"
656
+ elsif params[:ds_emv3ds]
657
+ three_ds_data = JSON.parse(params[:ds_emv3ds])
658
+ message = three_ds_data['threeDSInfo']
659
+ elsif params[:ds_response]
660
+ message = response_text(params[:ds_response])
661
+ end
662
+ message
663
+ end
664
+
665
+ def success_response?(code)
476
666
  (code.to_i < 100) || [400, 481, 500, 900].include?(code.to_i)
477
667
  end
478
668
 
479
669
  def clean_order_id(order_id)
480
670
  cleansed = order_id.gsub(/[^\da-zA-Z]/, '')
481
- if cleansed =~ /^\d{4}/
671
+ if /^\d{4}/.match?(cleansed)
482
672
  cleansed[0..11]
483
673
  else
484
- "%04d%s" % [rand(0..9999), cleansed[0...8]]
674
+ '%04d%s' % [rand(0..9999), cleansed[0...8]]
485
675
  end
486
676
  end
487
677
 
488
678
  def sha256_authentication?
489
- @options[:signature_algorithm] == "sha256"
679
+ @options[:signature_algorithm] == 'sha256'
490
680
  end
491
681
 
492
682
  def sign_request(xml_request_string, order_id)
@@ -499,7 +689,7 @@ module ActiveMerchant #:nodoc:
499
689
  cipher = OpenSSL::Cipher.new('DES3')
500
690
  cipher.encrypt
501
691
 
502
- cipher.key = Base64.strict_decode64(key)
692
+ cipher.key = Base64.urlsafe_decode64(key)
503
693
  # The OpenSSL default of an all-zeroes ("\\0") IV is used.
504
694
  cipher.padding = 0
505
695
 
@@ -514,8 +704,14 @@ module ActiveMerchant #:nodoc:
514
704
  end
515
705
 
516
706
  def xml_signed_fields(data)
517
- data[:ds_amount] + data[:ds_order] + data[:ds_merchantcode] + data[:ds_currency] +
518
- data[:ds_response] + data[:ds_transactiontype] + data[:ds_securepayment]
707
+ xml_signed_fields = data[:ds_amount] + data[:ds_order] + data[:ds_merchantcode] +
708
+ data[:ds_currency] + data[:ds_response]
709
+
710
+ xml_signed_fields += data[:ds_cardnumber] if data[:ds_cardnumber]
711
+
712
+ xml_signed_fields += data[:ds_emv3ds] if data[:ds_emv3ds]
713
+
714
+ xml_signed_fields + data[:ds_transactiontype] + data[:ds_securepayment]
519
715
  end
520
716
 
521
717
  def get_key(order_id)