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,8 +1,10 @@
1
- module ActiveMerchant #:nodoc:
2
- module Billing #:nodoc:
1
+ module ActiveMerchant # :nodoc:
2
+ module Billing # :nodoc:
3
3
  class CommerceHubGateway < Gateway
4
- self.test_url = 'https://cert.api.fiservapps.com/ch'
5
- self.live_url = 'https://prod.api.fiservapps.com/ch'
4
+ version 'v1'
5
+
6
+ self.test_url = 'https://connect-cert.fiservapps.com/ch'
7
+ self.live_url = 'https://connect.fiservapis.com/ch'
6
8
 
7
9
  self.supported_countries = ['US']
8
10
  self.default_currency = 'USD'
@@ -15,11 +17,11 @@ module ActiveMerchant #:nodoc:
15
17
 
16
18
  SCHEDULED_REASON_TYPES = %w(recurring installment)
17
19
  ENDPOINTS = {
18
- 'sale' => '/payments/v1/charges',
19
- 'void' => '/payments/v1/cancels',
20
- 'refund' => '/payments/v1/refunds',
21
- 'vault' => '/payments-vas/v1/tokens',
22
- 'verify' => '/payments-vas/v1/accounts/verification'
20
+ 'sale' => "/payments/#{fetch_version}/charges",
21
+ 'void' => "/payments/#{fetch_version}/cancels",
22
+ 'refund' => "/payments/#{fetch_version}/refunds",
23
+ 'vault' => "/payments-vas/#{fetch_version}/tokens",
24
+ 'verify' => "/payments-vas/#{fetch_version}/accounts/verification"
23
25
  }
24
26
 
25
27
  def initialize(options = {})
@@ -55,6 +57,7 @@ module ActiveMerchant #:nodoc:
55
57
  add_invoice(post, money, options)
56
58
  add_transaction_details(post, options, 'capture')
57
59
  add_reference_transaction_details(post, authorization, options, :capture)
60
+ add_dynamic_descriptors(post, options)
58
61
 
59
62
  commit('sale', post, options)
60
63
  end
@@ -68,6 +71,16 @@ module ActiveMerchant #:nodoc:
68
71
  commit('refund', post, options)
69
72
  end
70
73
 
74
+ def credit(money, payment_method, options = {})
75
+ post = {}
76
+ add_invoice(post, money, options)
77
+ add_transaction_details(post, options)
78
+ add_transaction_interaction(post, options)
79
+ add_payment(post, payment_method, options)
80
+
81
+ commit('refund', post, options)
82
+ end
83
+
71
84
  def void(authorization, options = {})
72
85
  post = {}
73
86
  add_transaction_details(post, options)
@@ -90,6 +103,7 @@ module ActiveMerchant #:nodoc:
90
103
  post = {}
91
104
  add_payment(post, credit_card, options)
92
105
  add_billing_address(post, credit_card, options)
106
+ add_transaction_details(post, options, 'verify')
93
107
 
94
108
  commit('verify', post, options)
95
109
  end
@@ -102,6 +116,7 @@ module ActiveMerchant #:nodoc:
102
116
  transcript.
103
117
  gsub(%r((Authorization: )[a-zA-Z0-9+./=]+), '\1[FILTERED]').
104
118
  gsub(%r((Api-Key: )\w+), '\1[FILTERED]').
119
+ gsub(%r(("apiKey\\?":\\?")\w+), '\1[FILTERED]').
105
120
  gsub(%r(("cardData\\?":\\?")\d+), '\1[FILTERED]').
106
121
  gsub(%r(("securityCode\\?":\\?")\d+), '\1[FILTERED]').
107
122
  gsub(%r(("cavv\\?":\\?")\w+), '\1[FILTERED]')
@@ -109,10 +124,27 @@ module ActiveMerchant #:nodoc:
109
124
 
110
125
  private
111
126
 
127
+ def add_three_d_secure(post, options)
128
+ return unless three_d_secure = options[:three_d_secure]
129
+
130
+ post[:additionalData3DS] = {
131
+ dsTransactionId: three_d_secure[:ds_transaction_id],
132
+ authenticationStatus: three_d_secure[:authentication_response_status],
133
+ serverTransactionId: three_d_secure[:three_ds_server_trans_id],
134
+ acsTransactionId: three_d_secure[:acs_transaction_id],
135
+ mpiData: {
136
+ cavv: three_d_secure[:cavv],
137
+ eci: three_d_secure[:eci],
138
+ xid: three_d_secure[:xid]
139
+ }.compact,
140
+ versionData: { recommendedVersion: three_d_secure[:version] }
141
+ }.compact
142
+ end
143
+
112
144
  def add_transaction_interaction(post, options)
113
145
  post[:transactionInteraction] = {}
114
146
  post[:transactionInteraction][:origin] = options[:origin] || 'ECOM'
115
- post[:transactionInteraction][:eciIndicator] = options[:eci_indicator] || 'CHANNEL_ENCRYPTED'
147
+ post[:transactionInteraction][:eciIndicator] = map_ecommerce_indicator(options)
116
148
  post[:transactionInteraction][:posConditionCode] = options[:pos_condition_code] || 'CARD_NOT_PRESENT_ECOM'
117
149
  post[:transactionInteraction][:posEntryMode] = (options[:pos_entry_mode] || 'MANUAL') unless options[:encryption_data].present?
118
150
  post[:transactionInteraction][:additionalPosInformation] = {}
@@ -126,16 +158,12 @@ module ActiveMerchant #:nodoc:
126
158
  physicalGoodsIndicator: [true, 'true'].include?(options[:physical_goods_indicator])
127
159
  }
128
160
 
129
- if options[:order_id].present? && action == 'sale'
161
+ if %w(sale verify).include?(action)
130
162
  details[:merchantOrderId] = options[:order_id]
131
- details[:merchantTransactionId] = options[:order_id]
163
+ details[:merchantTransactionId] = rand.to_s[2..13]
132
164
  end
133
165
 
134
- if action != 'capture'
135
- details[:merchantInvoiceNumber] = options[:merchant_invoice_number] || rand.to_s[2..13]
136
- details[:primaryTransactionType] = options[:primary_transaction_type]
137
- details[:accountVerification] = options[:account_verification]
138
- end
166
+ details[:merchantInvoiceNumber] = options[:order_id] if action != 'capture'
139
167
 
140
168
  post[:transactionDetails] = details.compact
141
169
  end
@@ -144,10 +172,7 @@ module ActiveMerchant #:nodoc:
144
172
  return unless billing = options[:billing_address]
145
173
 
146
174
  billing_address = {}
147
- if payment.is_a?(CreditCard)
148
- billing_address[:firstName] = payment.first_name if payment.first_name
149
- billing_address[:lastName] = payment.last_name if payment.last_name
150
- end
175
+ name_from_address(billing_address, billing) || name_from_payment(billing_address, payment)
151
176
  address = {}
152
177
  address[:street] = billing[:address1] if billing[:address1]
153
178
  address[:houseNumberOrName] = billing[:address2] if billing[:address2]
@@ -165,6 +190,22 @@ module ActiveMerchant #:nodoc:
165
190
  post[:billingAddress] = billing_address
166
191
  end
167
192
 
193
+ def name_from_payment(billing_address, payment)
194
+ return unless payment.respond_to?(:first_name) && payment.respond_to?(:last_name)
195
+
196
+ billing_address[:firstName] = payment.first_name if payment.first_name
197
+ billing_address[:lastName] = payment.last_name if payment.last_name
198
+ end
199
+
200
+ def name_from_address(billing_address, billing)
201
+ return unless address = billing
202
+
203
+ first_name, last_name = split_names(address[:name]) if address[:name]
204
+
205
+ billing_address[:firstName] = first_name if first_name
206
+ billing_address[:lastName] = last_name if last_name
207
+ end
208
+
168
209
  def add_shipping_address(post, options)
169
210
  return unless shipping = options[:shipping_address]
170
211
 
@@ -187,12 +228,28 @@ module ActiveMerchant #:nodoc:
187
228
  end
188
229
 
189
230
  def build_purchase_and_auth_request(post, money, payment, options)
231
+ add_three_d_secure(post, options)
190
232
  add_invoice(post, money, options)
191
233
  add_payment(post, payment, options)
192
234
  add_stored_credentials(post, options)
193
235
  add_transaction_interaction(post, options)
194
236
  add_billing_address(post, payment, options)
195
237
  add_shipping_address(post, options)
238
+ add_dynamic_descriptors(post, options)
239
+ end
240
+
241
+ def add_dynamic_descriptors(post, options)
242
+ dynamic_descriptors_fields = %i[mcc merchant_name customer_service_number service_entitlement dynamic_descriptors_address]
243
+ return unless dynamic_descriptors_fields.any? { |key| options.include?(key) }
244
+
245
+ dynamic_descriptors = {}
246
+ dynamic_descriptors[:mcc] = options[:mcc] if options[:mcc]
247
+ dynamic_descriptors[:merchantName] = options[:merchant_name] if options[:merchant_name]
248
+ dynamic_descriptors[:customerServiceNumber] = options[:customer_service_number] if options[:customer_service_number]
249
+ dynamic_descriptors[:serviceEntitlement] = options[:service_entitlement] if options[:service_entitlement]
250
+ dynamic_descriptors[:address] = options[:dynamic_descriptors_address] if options[:dynamic_descriptors_address]
251
+
252
+ post[:dynamicDescriptors] = dynamic_descriptors
196
253
  end
197
254
 
198
255
  def add_reference_transaction_details(post, authorization, options, action = nil)
@@ -254,20 +311,31 @@ module ActiveMerchant #:nodoc:
254
311
  source[:walletType] = payment.source.to_s.upcase
255
312
  end
256
313
 
314
+ def add_network_token(source, payment, options)
315
+ source[:sourceType] = 'PaymentToken'
316
+ source[:tokenData] = payment.number
317
+ source[:tokenSource] = 'NETWORK_TOKEN'
318
+ source[:cryptogram] = payment.payment_cryptogram
319
+ source[:card] = {
320
+ expirationMonth: format(payment.month, :two_digits),
321
+ expirationYear: format(payment.year, :four_digits)
322
+ }
323
+ end
324
+
257
325
  def add_payment(post, payment, options = {})
258
326
  source = {}
259
- case payment
260
- when NetworkTokenizationCreditCard
261
- add_decrypted_wallet(source, payment, options)
262
- when CreditCard
263
- if options[:encryption_data].present?
264
- source[:sourceType] = 'PaymentCard'
265
- source[:encryptionData] = options[:encryption_data]
266
- else
267
- add_credit_card(source, payment, options)
268
- end
269
- when String
327
+
328
+ if payment.is_a?(String)
270
329
  add_payment_token(source, payment, options)
330
+ elsif payment.mobile_wallet?
331
+ add_decrypted_wallet(source, payment, options)
332
+ elsif payment.network_token?
333
+ add_network_token(source, payment, options)
334
+ elsif options[:encryption_data].present?
335
+ source[:sourceType] = 'PaymentCard'
336
+ source[:encryptionData] = options[:encryption_data]
337
+ elsif payment.is_a?(CreditCard)
338
+ add_credit_card(source, payment, options)
271
339
  end
272
340
  post[:source] = source
273
341
  end
@@ -278,11 +346,11 @@ module ActiveMerchant #:nodoc:
278
346
 
279
347
  def headers(request, options)
280
348
  time = DateTime.now.strftime('%Q').to_s
281
- client_request_id = options[:client_request_id] || rand.to_s[2..8]
349
+ client_request_id = options[:client_request_id] || SecureRandom.uuid
282
350
  raw_signature = @options[:api_key] + client_request_id.to_s + time + request
283
351
  hmac = OpenSSL::HMAC.digest('sha256', @options[:api_secret], raw_signature)
284
352
  signature = Base64.strict_encode64(hmac.to_s).to_s
285
-
353
+ custom_headers = options.fetch(:headers_identifiers, {})
286
354
  {
287
355
  'Client-Request-Id' => client_request_id,
288
356
  'Api-Key' => @options[:api_key],
@@ -292,7 +360,7 @@ module ActiveMerchant #:nodoc:
292
360
  'Content-Type' => 'application/json',
293
361
  'Accept' => 'application/json',
294
362
  'Authorization' => signature
295
- }
363
+ }.merge!(custom_headers)
296
364
  end
297
365
 
298
366
  def add_merchant_details(post)
@@ -365,6 +433,20 @@ module ActiveMerchant #:nodoc:
365
433
  def error_code_from(response, action)
366
434
  response.dig('error', 0, 'code') unless success_from(response, action)
367
435
  end
436
+
437
+ def map_ecommerce_indicator(options)
438
+ return options[:eci_indicator] if options[:eci_indicator]
439
+ return 'CHANNEL_ENCRYPTED' unless options[:three_d_secure]
440
+
441
+ case options[:three_d_secure][:eci]
442
+ when '2', '02', '5', '05'
443
+ 'SECURE_ECOM'
444
+ when '01', '1', '06', '6'
445
+ 'NON_AUTH_ECOM'
446
+ else
447
+ 'CHANNEL_ENCRYPTED'
448
+ end
449
+ end
368
450
  end
369
451
  end
370
452
  end
@@ -1,5 +1,5 @@
1
- module ActiveMerchant #:nodoc:
2
- module Billing #:nodoc:
1
+ module ActiveMerchant # :nodoc:
2
+ module Billing # :nodoc:
3
3
  class CommercegateGateway < Gateway
4
4
  self.test_url = self.live_url = 'https://secure.commercegate.com/gateway/nvp'
5
5
 
@@ -127,8 +127,8 @@ module ActiveMerchant #:nodoc:
127
127
  response['returnText']
128
128
  else
129
129
  'Invalid response received from the CommerceGate API. ' \
130
- 'Please contact CommerceGate support if you continue to receive this message. ' \
131
- "(The raw response returned by the API was #{response.inspect})"
130
+ 'Please contact CommerceGate support if you continue to receive this message. ' \
131
+ "(The raw response returned by the API was #{response.inspect})"
132
132
  end
133
133
  end
134
134
 
@@ -1,5 +1,5 @@
1
- module ActiveMerchant #:nodoc:
2
- module Billing #:nodoc:
1
+ module ActiveMerchant # :nodoc:
2
+ module Billing # :nodoc:
3
3
  class ConektaGateway < Gateway
4
4
  self.live_url = 'https://api.conekta.io/'
5
5
 
@@ -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 CreditcallGateway < Gateway
6
6
  include Empty
7
7
 
@@ -1,5 +1,5 @@
1
- module ActiveMerchant #:nodoc:
2
- module Billing #:nodoc:
1
+ module ActiveMerchant # :nodoc:
2
+ module Billing # :nodoc:
3
3
  class CredoraxGateway < Gateway
4
4
  class_attribute :test_url, :live_na_url, :live_eu_url
5
5
 
@@ -150,6 +150,12 @@ module ActiveMerchant #:nodoc:
150
150
  add_submerchant_id(post, options)
151
151
  add_stored_credential(post, options)
152
152
  add_processor(post, options)
153
+ add_crypto_currency_type(post, options)
154
+
155
+ if options[:aft]
156
+ add_recipient(post, options)
157
+ add_sender(post, options)
158
+ end
153
159
 
154
160
  commit(:purchase, post)
155
161
  end
@@ -165,8 +171,15 @@ module ActiveMerchant #:nodoc:
165
171
  add_echo(post, options)
166
172
  add_submerchant_id(post, options)
167
173
  add_stored_credential(post, options)
174
+ add_account_name_inquiry(post, options)
168
175
  add_processor(post, options)
169
176
  add_authorization_details(post, options)
177
+ add_crypto_currency_type(post, options)
178
+
179
+ if options[:aft]
180
+ add_recipient(post, options)
181
+ add_sender(post, options)
182
+ end
170
183
 
171
184
  commit(:authorize, post)
172
185
  end
@@ -179,6 +192,8 @@ module ActiveMerchant #:nodoc:
179
192
  add_echo(post, options)
180
193
  add_submerchant_id(post, options)
181
194
  add_processor(post, options)
195
+ add_crypto_currency_type(post, options)
196
+ add_transaction_type(post, options)
182
197
 
183
198
  commit(:capture, post)
184
199
  end
@@ -191,6 +206,8 @@ module ActiveMerchant #:nodoc:
191
206
  add_submerchant_id(post, options)
192
207
  post[:a1] = generate_unique_id
193
208
  add_processor(post, options)
209
+ add_crypto_currency_type(post, options)
210
+ add_transaction_type(post, options)
194
211
 
195
212
  commit(:void, post, reference_action)
196
213
  end
@@ -205,6 +222,8 @@ module ActiveMerchant #:nodoc:
205
222
  add_processor(post, options)
206
223
  add_email(post, options)
207
224
  add_recipient(post, options)
225
+ add_crypto_currency_type(post, options)
226
+ add_transaction_type(post, options)
208
227
 
209
228
  if options[:referral_cft]
210
229
  add_customer_name(post, options)
@@ -225,14 +244,16 @@ module ActiveMerchant #:nodoc:
225
244
  add_transaction_type(post, options)
226
245
  add_processor(post, options)
227
246
  add_customer_name(post, options)
247
+ add_crypto_currency_type(post, options)
228
248
 
229
249
  commit(:credit, post)
230
250
  end
231
251
 
232
- def verify(credit_card, options = {})
252
+ def verify(payment_method, options = {})
253
+ amount = eligible_for_0_auth?(payment_method, options) ? 0 : 100
233
254
  MultiResponse.run(:use_first_response) do |r|
234
- r.process { authorize(100, credit_card, options) }
235
- r.process(:ignore_result) { void(r.authorization, options) }
255
+ r.process { authorize(amount, payment_method, options) }
256
+ r.process(:ignore_result) { void(r.authorization, options) } unless eligible_for_0_auth?(payment_method, options)
236
257
  end
237
258
  end
238
259
 
@@ -254,9 +275,7 @@ module ActiveMerchant #:nodoc:
254
275
  normalized_value = normalize(value)
255
276
  next if normalized_value.nil?
256
277
 
257
- if key == :'3ds_homephonecountry'
258
- next unless options[:billing_address] && options[:billing_address][:phone]
259
- end
278
+ next if key == :'3ds_homephonecountry' && !(options[:billing_address] && options[:billing_address][:phone])
260
279
 
261
280
  post[key] = normalized_value unless post[key]
262
281
  end
@@ -284,7 +303,7 @@ module ActiveMerchant #:nodoc:
284
303
  }
285
304
 
286
305
  def add_payment_method(post, payment_method, options)
287
- post[:c1] = payment_method&.name || ''
306
+ post[:c1] = payment_method&.name || '' unless options[:account_name_inquiry].to_s == 'true'
288
307
  add_network_tokenization_card(post, payment_method, options) if payment_method.is_a? NetworkTokenizationCreditCard
289
308
  post[:b2] = CARD_TYPES[payment_method.brand] || ''
290
309
  post[:b1] = payment_method.number
@@ -293,6 +312,10 @@ module ActiveMerchant #:nodoc:
293
312
  post[:b3] = format(payment_method.month, :two_digits)
294
313
  end
295
314
 
315
+ def eligible_for_0_auth?(payment_method, options = {})
316
+ payment_method.is_a?(CreditCard) && %w(visa master).include?(payment_method.brand) && options[:zero_dollar_auth]
317
+ end
318
+
296
319
  def add_network_tokenization_card(post, payment_method, options)
297
320
  post[:b21] = NETWORK_TOKENIZATION_CARD_SOURCE[payment_method.source.to_s]
298
321
  post[:token_eci] = post[:b21] == 'vts_mdes_token' ? '07' : nil
@@ -321,12 +344,12 @@ module ActiveMerchant #:nodoc:
321
344
  def add_customer_data(post, options)
322
345
  post[:d1] = options[:ip] || '127.0.0.1'
323
346
  if (billing_address = options[:billing_address])
324
- post[:c5] = billing_address[:address1] if billing_address[:address1]
325
- post[:c7] = billing_address[:city] if billing_address[:city]
326
- post[:c10] = billing_address[:zip] if billing_address[:zip]
327
- post[:c8] = billing_address[:state] if billing_address[:state]
328
- post[:c9] = billing_address[:country] if billing_address[:country]
329
- post[:c2] = billing_address[:phone] if billing_address[:phone]
347
+ post[:c5] = billing_address[:address1] if billing_address[:address1]
348
+ post[:c7] = billing_address[:city] if billing_address[:city]
349
+ post[:c10] = billing_address[:zip] if billing_address[:zip]
350
+ post[:c8] = billing_address[:state] if billing_address[:state]
351
+ post[:c9] = billing_address[:country] if billing_address[:country]
352
+ post[:c2] = billing_address[:phone] if billing_address[:phone]
330
353
  end
331
354
  end
332
355
 
@@ -342,14 +365,35 @@ module ActiveMerchant #:nodoc:
342
365
  post[:c3] = options[:email] || 'unspecified@example.com'
343
366
  end
344
367
 
368
+ def add_sender(post, options)
369
+ return unless options[:sender_ref_number] || options[:sender_fund_source] || options[:sender_country_code] || options[:sender_street_address] || options[:sender_city] || options[:sender_state] || options[:sender_first_name] || options[:sender_last_name] || options[:sender_birth_date]
370
+
371
+ sender_country_code = options[:sender_country_code]&.length == 3 ? options[:sender_country_code] : Country.find(options[:sender_country_code]).code(:alpha3).value if options[:sender_country_code]
372
+ post[:s15] = sender_country_code
373
+ post[:s17] = options[:sender_ref_number] if options[:sender_ref_number]
374
+ post[:s18] = options[:sender_fund_source] if options[:sender_fund_source]
375
+ post[:s10] = options[:sender_first_name] if options[:sender_first_name]
376
+ post[:s11] = options[:sender_last_name] if options[:sender_last_name]
377
+ post[:s12] = options[:sender_street_address] if options[:sender_street_address]
378
+ post[:s13] = options[:sender_city] if options[:sender_city]
379
+ post[:s14] = options[:sender_state] if options[:sender_state]
380
+ post[:s19] = options[:sender_birth_date] if options[:sender_birth_date]
381
+ end
382
+
345
383
  def add_recipient(post, options)
346
- return unless options[:recipient_street_address] || options[:recipient_city] || options[:recipient_province_code] || options[:recipient_country_code]
384
+ return unless options[:recipient_street_address] || options[:recipient_city] || options[:recipient_province_code] || options[:recipient_country_code] || options[:recipient_first_name] || options[:recipient_last_name] || options[:recipient_postal_code]
347
385
 
348
386
  recipient_country_code = options[:recipient_country_code]&.length == 3 ? options[:recipient_country_code] : Country.find(options[:recipient_country_code]).code(:alpha3).value if options[:recipient_country_code]
349
387
  post[:j6] = options[:recipient_street_address] if options[:recipient_street_address]
350
388
  post[:j7] = options[:recipient_city] if options[:recipient_city]
351
389
  post[:j8] = options[:recipient_province_code] if options[:recipient_province_code]
390
+ post[:j12] = options[:recipient_postal_code] if options[:recipient_postal_code]
352
391
  post[:j9] = recipient_country_code
392
+
393
+ if options[:aft]
394
+ post[:j5] = options[:recipient_first_name] if options[:recipient_first_name]
395
+ post[:j13] = options[:recipient_last_name] if options[:recipient_last_name]
396
+ end
353
397
  end
354
398
 
355
399
  def add_customer_name(post, options)
@@ -357,6 +401,14 @@ module ActiveMerchant #:nodoc:
357
401
  post[:j13] = options[:last_name] if options[:last_name]
358
402
  end
359
403
 
404
+ def add_account_name_inquiry(post, options)
405
+ return unless options[:account_name_inquiry].to_s == 'true'
406
+
407
+ post[:c22] = options[:first_name] if options[:first_name]
408
+ post[:c23] = options[:last_name] if options[:last_name]
409
+ post[:a9] = '5'
410
+ end
411
+
360
412
  def add_3d_secure(post, options)
361
413
  if (options[:eci] && options[:xid]) || (options[:three_d_secure] && options[:three_d_secure][:version]&.start_with?('1'))
362
414
  add_3d_secure_1_data(post, options)
@@ -417,7 +469,7 @@ module ActiveMerchant #:nodoc:
417
469
  three_d_secure_options[:eci],
418
470
  three_d_secure_options[:cavv]
419
471
  )
420
- post[:'3ds_version'] = three_d_secure_options[:version]&.start_with?('2') ? '2.0' : three_d_secure_options[:version]
472
+ post[:'3ds_version'] = three_d_secure_options[:version] == '2' ? '2.0' : three_d_secure_options[:version]
421
473
  post[:'3ds_dstrxid'] = three_d_secure_options[:ds_transaction_id]
422
474
  end
423
475
 
@@ -436,7 +488,9 @@ module ActiveMerchant #:nodoc:
436
488
  end
437
489
 
438
490
  def add_transaction_type(post, options)
439
- post[:a9] = options[:transaction_type] if options[:transaction_type]
491
+ a9 = options[:zero_dollar_auth] ? '5' : options[:transaction_type]
492
+
493
+ post[:a9] = a9 if a9
440
494
  post[:a2] = '3' if options.dig(:metadata, :manual_entry)
441
495
  end
442
496
 
@@ -450,6 +504,10 @@ module ActiveMerchant #:nodoc:
450
504
  post[:a11] = options[:multiple_capture_count] if options[:multiple_capture_count]
451
505
  end
452
506
 
507
+ def add_crypto_currency_type(post, options)
508
+ post[:crypto_currency_type] = options[:crypto_currency_type] if options[:crypto_currency_type]
509
+ end
510
+
453
511
  ACTIONS = {
454
512
  purchase: '1',
455
513
  authorize: '2',
@@ -488,11 +546,16 @@ module ActiveMerchant #:nodoc:
488
546
  Digest::MD5.hexdigest(values.join + @options[:cipher_key])
489
547
  end
490
548
 
549
+ def sign_request_with_sha256(params)
550
+ sorted_params = sort_parameters(params)
551
+ Digest::SHA256.hexdigest(sorted_params.values.join + @options[:cipher_key])
552
+ end
553
+
491
554
  def post_data(action, params, reference_action)
492
555
  params.keys.each { |key| params[key] = params[key].to_s }
493
556
  params[:M] = @options[:merchant_id]
494
557
  params[:O] = request_action(action, reference_action)
495
- params[:K] = sign_request(params)
558
+ params[:K] = @options[:use_sha256_signing] ? sign_request_with_sha256(params) : sign_request(params)
496
559
  params.map { |k, v| "#{k}=#{CGI.escape(v.to_s)}" }.join('&')
497
560
  end
498
561
 
@@ -507,7 +570,7 @@ module ActiveMerchant #:nodoc:
507
570
  end
508
571
 
509
572
  def parse(body)
510
- Hash[CGI::parse(body).map { |k, v| [k.upcase, v.first] }]
573
+ CGI::parse(body).map { |k, v| [k.upcase, v.first] }.to_h
511
574
  end
512
575
 
513
576
  def success_from(response)
@@ -521,6 +584,32 @@ module ActiveMerchant #:nodoc:
521
584
  RESPONSE_MESSAGES[response['Z6']] || response['Z3'] || 'Unable to read error message'
522
585
  end
523
586
  end
587
+
588
+ def sort_parameters(parameters)
589
+ # Character type lookup hash for faster classification
590
+ char_type_lookup = {}.tap do |lookup|
591
+ ('0'..'9').each { |c| lookup[c] = 0 } # Digits
592
+ ('A'..'Z').each { |c| lookup[c] = 1 } # Uppercase letters
593
+ # All other chars default to 2
594
+ end
595
+
596
+ # Memoize sort keys to avoid recalculating for the same string
597
+ sort_key_cache = {}
598
+ generate_sort_key = lambda do |str|
599
+ str = str.to_s
600
+ sort_key_cache[str] ||= str.chars.map { |char| [char_type_lookup[char] || 2, char] }
601
+ end
602
+
603
+ sanitize_regex = /[<>"'()\\]/
604
+
605
+ # Sort keys and build output in one pass
606
+ parameters.keys.
607
+ sort_by(&generate_sort_key).
608
+ each_with_object({}) do |key, sorted_params|
609
+ value = parameters[key]
610
+ sorted_params[key] = value.is_a?(String) ? value.gsub(sanitize_regex, ' ').strip : value
611
+ end
612
+ end
524
613
  end
525
614
  end
526
615
  end
@@ -1,5 +1,5 @@
1
- module ActiveMerchant #:nodoc:
2
- module Billing #:nodoc:
1
+ module ActiveMerchant # :nodoc:
2
+ module Billing # :nodoc:
3
3
  class CtPaymentGateway < Gateway
4
4
  self.test_url = 'https://test.ctpaiement.ca/v1/'
5
5
  self.live_url = 'https://www.ctpaiement.com/v1/'
@@ -155,7 +155,7 @@ module ActiveMerchant #:nodoc:
155
155
  private
156
156
 
157
157
  def add_terminal_number(post, options)
158
- post[:MerchantTerminalNumber] = options[:merchant_terminal_number] || ' ' * 5
158
+ post[:MerchantTerminalNumber] = options[:merchant_terminal_number] || (' ' * 5)
159
159
  end
160
160
 
161
161
  def add_money(post, money)
@@ -163,11 +163,11 @@ module ActiveMerchant #:nodoc:
163
163
  end
164
164
 
165
165
  def add_operator_id(post, options)
166
- post[:OperatorID] = options[:operator_id] || '0' * 8
166
+ post[:OperatorID] = options[:operator_id] || ('0' * 8)
167
167
  end
168
168
 
169
169
  def add_customer_data(post, options)
170
- post[:CustomerNumber] = options[:customer_number] || '0' * 8
170
+ post[:CustomerNumber] = options[:customer_number] || ('0' * 8)
171
171
  end
172
172
 
173
173
  def add_address(post, creditcard, options)
@@ -248,7 +248,7 @@ module ActiveMerchant #:nodoc:
248
248
 
249
249
  def authorization_from(response)
250
250
  "#{response['transactionNumber']};#{response['authorizationNumber']};"\
251
- "#{response['invoiceNumber']};#{response['token']};#{response['id']}"
251
+ "#{response['invoiceNumber']};#{response['token']};#{response['id']}"
252
252
  end
253
253
 
254
254
  def post_data(action, parameters = {})
@@ -1,7 +1,7 @@
1
1
  require 'digest/md5'
2
2
 
3
- module ActiveMerchant #:nodoc:
4
- module Billing #:nodoc:
3
+ module ActiveMerchant # :nodoc:
4
+ module Billing # :nodoc:
5
5
  # Important note:
6
6
  # ===
7
7
  # Culqi merchant accounts are configured for either purchase or auth/capture
@@ -1,5 +1,5 @@
1
- module ActiveMerchant #:nodoc:
2
- module Billing #:nodoc:
1
+ module ActiveMerchant # :nodoc:
2
+ module Billing # :nodoc:
3
3
  module CyberSourceCommon
4
4
  def check_billing_field_value(default, submitted)
5
5
  if submitted.nil?