swiss-crm-activemerchant 1.0.12

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 (287) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +4033 -0
  3. data/CONTRIBUTORS +568 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +252 -0
  6. data/lib/active_merchant/billing/apple_pay_payment_token.rb +22 -0
  7. data/lib/active_merchant/billing/avs_result.rb +95 -0
  8. data/lib/active_merchant/billing/base.rb +48 -0
  9. data/lib/active_merchant/billing/check.rb +112 -0
  10. data/lib/active_merchant/billing/compatibility.rb +118 -0
  11. data/lib/active_merchant/billing/credit_card.rb +451 -0
  12. data/lib/active_merchant/billing/credit_card_formatting.rb +24 -0
  13. data/lib/active_merchant/billing/credit_card_methods.rb +512 -0
  14. data/lib/active_merchant/billing/cvv_result.rb +37 -0
  15. data/lib/active_merchant/billing/gateway.rb +332 -0
  16. data/lib/active_merchant/billing/gateways/adyen.rb +774 -0
  17. data/lib/active_merchant/billing/gateways/airwallex.rb +370 -0
  18. data/lib/active_merchant/billing/gateways/alelo.rb +256 -0
  19. data/lib/active_merchant/billing/gateways/allied_wallet.rb +205 -0
  20. data/lib/active_merchant/billing/gateways/authorize_net.rb +1125 -0
  21. data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +424 -0
  22. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +977 -0
  23. data/lib/active_merchant/billing/gateways/axcessms.rb +242 -0
  24. data/lib/active_merchant/billing/gateways/balanced.rb +263 -0
  25. data/lib/active_merchant/billing/gateways/bambora_apac.rb +222 -0
  26. data/lib/active_merchant/billing/gateways/bank_frick.rb +225 -0
  27. data/lib/active_merchant/billing/gateways/banwire.rb +116 -0
  28. data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +397 -0
  29. data/lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb +15 -0
  30. data/lib/active_merchant/billing/gateways/be2bill.rb +131 -0
  31. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +474 -0
  32. data/lib/active_merchant/billing/gateways/beanstream.rb +238 -0
  33. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +57 -0
  34. data/lib/active_merchant/billing/gateways/blue_pay.rb +549 -0
  35. data/lib/active_merchant/billing/gateways/blue_snap.rb +644 -0
  36. data/lib/active_merchant/billing/gateways/bogus.rb +190 -0
  37. data/lib/active_merchant/billing/gateways/borgun.rb +272 -0
  38. data/lib/active_merchant/billing/gateways/bpoint.rb +277 -0
  39. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +28 -0
  40. data/lib/active_merchant/billing/gateways/braintree/token_nonce.rb +113 -0
  41. data/lib/active_merchant/billing/gateways/braintree.rb +19 -0
  42. data/lib/active_merchant/billing/gateways/braintree_blue.rb +952 -0
  43. data/lib/active_merchant/billing/gateways/braintree_orange.rb +19 -0
  44. data/lib/active_merchant/billing/gateways/bridge_pay.rb +244 -0
  45. data/lib/active_merchant/billing/gateways/cams.rb +230 -0
  46. data/lib/active_merchant/billing/gateways/card_connect.rb +338 -0
  47. data/lib/active_merchant/billing/gateways/card_save.rb +21 -0
  48. data/lib/active_merchant/billing/gateways/card_stream.rb +394 -0
  49. data/lib/active_merchant/billing/gateways/cardknox.rb +327 -0
  50. data/lib/active_merchant/billing/gateways/cardprocess.rb +256 -0
  51. data/lib/active_merchant/billing/gateways/cashnet.rb +235 -0
  52. data/lib/active_merchant/billing/gateways/cc5.rb +198 -0
  53. data/lib/active_merchant/billing/gateways/cecabank.rb +249 -0
  54. data/lib/active_merchant/billing/gateways/cenpos.rb +328 -0
  55. data/lib/active_merchant/billing/gateways/checkout.rb +212 -0
  56. data/lib/active_merchant/billing/gateways/checkout_v2.rb +587 -0
  57. data/lib/active_merchant/billing/gateways/citrus_pay.rb +21 -0
  58. data/lib/active_merchant/billing/gateways/clearhaus.rb +219 -0
  59. data/lib/active_merchant/billing/gateways/commerce_hub.rb +366 -0
  60. data/lib/active_merchant/billing/gateways/commercegate.rb +142 -0
  61. data/lib/active_merchant/billing/gateways/conekta.rb +230 -0
  62. data/lib/active_merchant/billing/gateways/creditcall.rb +272 -0
  63. data/lib/active_merchant/billing/gateways/credorax.rb +526 -0
  64. data/lib/active_merchant/billing/gateways/ct_payment.rb +269 -0
  65. data/lib/active_merchant/billing/gateways/culqi.rb +279 -0
  66. data/lib/active_merchant/billing/gateways/cyber_source/cyber_source_common.rb +36 -0
  67. data/lib/active_merchant/billing/gateways/cyber_source.rb +1148 -0
  68. data/lib/active_merchant/billing/gateways/cyber_source_rest.rb +454 -0
  69. data/lib/active_merchant/billing/gateways/d_local.rb +343 -0
  70. data/lib/active_merchant/billing/gateways/data_cash.rb +302 -0
  71. data/lib/active_merchant/billing/gateways/decidir.rb +358 -0
  72. data/lib/active_merchant/billing/gateways/decidir_plus.rb +344 -0
  73. data/lib/active_merchant/billing/gateways/dibs.rb +199 -0
  74. data/lib/active_merchant/billing/gateways/digitzs.rb +295 -0
  75. data/lib/active_merchant/billing/gateways/ebanx.rb +346 -0
  76. data/lib/active_merchant/billing/gateways/efsnet.rb +215 -0
  77. data/lib/active_merchant/billing/gateways/elavon.rb +475 -0
  78. data/lib/active_merchant/billing/gateways/element.rb +406 -0
  79. data/lib/active_merchant/billing/gateways/epay.rb +296 -0
  80. data/lib/active_merchant/billing/gateways/evo_ca.rb +307 -0
  81. data/lib/active_merchant/billing/gateways/eway.rb +226 -0
  82. data/lib/active_merchant/billing/gateways/eway_managed.rb +289 -0
  83. data/lib/active_merchant/billing/gateways/eway_rapid.rb +578 -0
  84. data/lib/active_merchant/billing/gateways/exact.rb +219 -0
  85. data/lib/active_merchant/billing/gateways/ezic.rb +195 -0
  86. data/lib/active_merchant/billing/gateways/fat_zebra.rb +223 -0
  87. data/lib/active_merchant/billing/gateways/federated_canada.rb +158 -0
  88. data/lib/active_merchant/billing/gateways/finansbank.rb +22 -0
  89. data/lib/active_merchant/billing/gateways/first_giving.rb +143 -0
  90. data/lib/active_merchant/billing/gateways/first_pay.rb +182 -0
  91. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +452 -0
  92. data/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb +505 -0
  93. data/lib/active_merchant/billing/gateways/flo2cash.rb +215 -0
  94. data/lib/active_merchant/billing/gateways/flo2cash_simple.rb +20 -0
  95. data/lib/active_merchant/billing/gateways/fluidpay.rb +275 -0
  96. data/lib/active_merchant/billing/gateways/forte.rb +286 -0
  97. data/lib/active_merchant/billing/gateways/garanti.rb +256 -0
  98. data/lib/active_merchant/billing/gateways/global_collect.rb +580 -0
  99. data/lib/active_merchant/billing/gateways/global_transport.rb +193 -0
  100. data/lib/active_merchant/billing/gateways/hdfc.rb +205 -0
  101. data/lib/active_merchant/billing/gateways/hps.rb +472 -0
  102. data/lib/active_merchant/billing/gateways/iats_payments.rb +312 -0
  103. data/lib/active_merchant/billing/gateways/in_context_paypal_express.rb +15 -0
  104. data/lib/active_merchant/billing/gateways/inspire.rb +213 -0
  105. data/lib/active_merchant/billing/gateways/instapay.rb +159 -0
  106. data/lib/active_merchant/billing/gateways/ipg.rb +420 -0
  107. data/lib/active_merchant/billing/gateways/ipp.rb +176 -0
  108. data/lib/active_merchant/billing/gateways/iridium.rb +467 -0
  109. data/lib/active_merchant/billing/gateways/itransact.rb +448 -0
  110. data/lib/active_merchant/billing/gateways/iveri.rb +290 -0
  111. data/lib/active_merchant/billing/gateways/ixopay.rb +320 -0
  112. data/lib/active_merchant/billing/gateways/jetpay.rb +395 -0
  113. data/lib/active_merchant/billing/gateways/jetpay_v2.rb +432 -0
  114. data/lib/active_merchant/billing/gateways/klarna.rb +317 -0
  115. data/lib/active_merchant/billing/gateways/komoju.rb +115 -0
  116. data/lib/active_merchant/billing/gateways/kushki.rb +297 -0
  117. data/lib/active_merchant/billing/gateways/latitude19.rb +412 -0
  118. data/lib/active_merchant/billing/gateways/linkpoint.rb +448 -0
  119. data/lib/active_merchant/billing/gateways/litle.rb +643 -0
  120. data/lib/active_merchant/billing/gateways/mastercard.rb +286 -0
  121. data/lib/active_merchant/billing/gateways/maxipago.rb +220 -0
  122. data/lib/active_merchant/billing/gateways/mercado_pago.rb +348 -0
  123. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +228 -0
  124. data/lib/active_merchant/billing/gateways/merchant_one.rb +110 -0
  125. data/lib/active_merchant/billing/gateways/merchant_partners.rb +245 -0
  126. data/lib/active_merchant/billing/gateways/merchant_ware.rb +313 -0
  127. data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +284 -0
  128. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +248 -0
  129. data/lib/active_merchant/billing/gateways/mercury.rb +352 -0
  130. data/lib/active_merchant/billing/gateways/metrics_global.rb +293 -0
  131. data/lib/active_merchant/billing/gateways/micropayment.rb +182 -0
  132. data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +100 -0
  133. data/lib/active_merchant/billing/gateways/migs.rb +329 -0
  134. data/lib/active_merchant/billing/gateways/mit.rb +260 -0
  135. data/lib/active_merchant/billing/gateways/modern_payments.rb +37 -0
  136. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +215 -0
  137. data/lib/active_merchant/billing/gateways/moka.rb +290 -0
  138. data/lib/active_merchant/billing/gateways/monei.rb +424 -0
  139. data/lib/active_merchant/billing/gateways/moneris.rb +488 -0
  140. data/lib/active_merchant/billing/gateways/money_movers.rb +150 -0
  141. data/lib/active_merchant/billing/gateways/mundipagg.rb +366 -0
  142. data/lib/active_merchant/billing/gateways/nab_transact.rb +299 -0
  143. data/lib/active_merchant/billing/gateways/ncr_secure_pay.rb +163 -0
  144. data/lib/active_merchant/billing/gateways/net_registry.rb +198 -0
  145. data/lib/active_merchant/billing/gateways/netaxept.rb +180 -0
  146. data/lib/active_merchant/billing/gateways/netbanx.rb +376 -0
  147. data/lib/active_merchant/billing/gateways/netbilling.rb +229 -0
  148. data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
  149. data/lib/active_merchant/billing/gateways/network_merchants.rb +238 -0
  150. data/lib/active_merchant/billing/gateways/nmi.rb +396 -0
  151. data/lib/active_merchant/billing/gateways/ogone.rb +509 -0
  152. data/lib/active_merchant/billing/gateways/omise.rb +323 -0
  153. data/lib/active_merchant/billing/gateways/openpay.rb +246 -0
  154. data/lib/active_merchant/billing/gateways/opp.rb +394 -0
  155. data/lib/active_merchant/billing/gateways/optimal_payment.rb +331 -0
  156. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +45 -0
  157. data/lib/active_merchant/billing/gateways/orbital.rb +1267 -0
  158. data/lib/active_merchant/billing/gateways/pac_net_raven.rb +206 -0
  159. data/lib/active_merchant/billing/gateways/pagarme.rb +239 -0
  160. data/lib/active_merchant/billing/gateways/pago_facil.rb +120 -0
  161. data/lib/active_merchant/billing/gateways/pay_arc.rb +392 -0
  162. data/lib/active_merchant/billing/gateways/pay_conex.rb +245 -0
  163. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +277 -0
  164. data/lib/active_merchant/billing/gateways/pay_hub.rb +213 -0
  165. data/lib/active_merchant/billing/gateways/pay_junction.rb +390 -0
  166. data/lib/active_merchant/billing/gateways/pay_junction_v2.rb +206 -0
  167. data/lib/active_merchant/billing/gateways/pay_secure.rb +110 -0
  168. data/lib/active_merchant/billing/gateways/pay_trace.rb +450 -0
  169. data/lib/active_merchant/billing/gateways/paybox_direct.rb +224 -0
  170. data/lib/active_merchant/billing/gateways/payeezy.rb +513 -0
  171. data/lib/active_merchant/billing/gateways/payex.rb +409 -0
  172. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +235 -0
  173. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +42 -0
  174. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  175. data/lib/active_merchant/billing/gateways/payflow.rb +473 -0
  176. data/lib/active_merchant/billing/gateways/payflow_express.rb +220 -0
  177. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +14 -0
  178. data/lib/active_merchant/billing/gateways/payflow_uk.rb +20 -0
  179. data/lib/active_merchant/billing/gateways/payment_express.rb +373 -0
  180. data/lib/active_merchant/billing/gateways/paymentez.rb +365 -0
  181. data/lib/active_merchant/billing/gateways/paymill.rb +369 -0
  182. data/lib/active_merchant/billing/gateways/paynetworx.rb +228 -0
  183. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +718 -0
  184. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +69 -0
  185. data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +262 -0
  186. data/lib/active_merchant/billing/gateways/paypal.rb +136 -0
  187. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  188. data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +44 -0
  189. data/lib/active_merchant/billing/gateways/paypal_express.rb +272 -0
  190. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +30 -0
  191. data/lib/active_merchant/billing/gateways/paypal_standard.rb +281 -0
  192. data/lib/active_merchant/billing/gateways/paysafe.rb +420 -0
  193. data/lib/active_merchant/billing/gateways/payscout.rb +159 -0
  194. data/lib/active_merchant/billing/gateways/paystation.rb +204 -0
  195. data/lib/active_merchant/billing/gateways/payu_in.rb +249 -0
  196. data/lib/active_merchant/billing/gateways/payu_latam.rb +482 -0
  197. data/lib/active_merchant/billing/gateways/payway.rb +207 -0
  198. data/lib/active_merchant/billing/gateways/payway_dot_com.rb +253 -0
  199. data/lib/active_merchant/billing/gateways/pin.rb +273 -0
  200. data/lib/active_merchant/billing/gateways/pixxels.rb +263 -0
  201. data/lib/active_merchant/billing/gateways/plexo.rb +308 -0
  202. data/lib/active_merchant/billing/gateways/plugnpay.rb +283 -0
  203. data/lib/active_merchant/billing/gateways/priority.rb +392 -0
  204. data/lib/active_merchant/billing/gateways/pro_pay.rb +325 -0
  205. data/lib/active_merchant/billing/gateways/psigate.rb +227 -0
  206. data/lib/active_merchant/billing/gateways/psl_card.rb +295 -0
  207. data/lib/active_merchant/billing/gateways/qbms.rb +302 -0
  208. data/lib/active_merchant/billing/gateways/quantum.rb +274 -0
  209. data/lib/active_merchant/billing/gateways/quickbooks.rb +377 -0
  210. data/lib/active_merchant/billing/gateways/quickpay/quickpay_common.rb +184 -0
  211. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +297 -0
  212. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb +226 -0
  213. data/lib/active_merchant/billing/gateways/quickpay.rb +24 -0
  214. data/lib/active_merchant/billing/gateways/qvalent.rb +305 -0
  215. data/lib/active_merchant/billing/gateways/rapyd.rb +319 -0
  216. data/lib/active_merchant/billing/gateways/reach.rb +277 -0
  217. data/lib/active_merchant/billing/gateways/realex.rb +400 -0
  218. data/lib/active_merchant/billing/gateways/redsys.rb +723 -0
  219. data/lib/active_merchant/billing/gateways/s5.rb +247 -0
  220. data/lib/active_merchant/billing/gateways/safe_charge.rb +298 -0
  221. data/lib/active_merchant/billing/gateways/sage.rb +446 -0
  222. data/lib/active_merchant/billing/gateways/sage_pay.rb +434 -0
  223. data/lib/active_merchant/billing/gateways/sallie_mae.rb +141 -0
  224. data/lib/active_merchant/billing/gateways/secure_net.rb +260 -0
  225. data/lib/active_merchant/billing/gateways/secure_pay.rb +191 -0
  226. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +290 -0
  227. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +103 -0
  228. data/lib/active_merchant/billing/gateways/securion_pay.rb +305 -0
  229. data/lib/active_merchant/billing/gateways/shift4.rb +345 -0
  230. data/lib/active_merchant/billing/gateways/simetrik.rb +368 -0
  231. data/lib/active_merchant/billing/gateways/skip_jack.rb +450 -0
  232. data/lib/active_merchant/billing/gateways/smart_ps.rb +274 -0
  233. data/lib/active_merchant/billing/gateways/so_easy_pay.rb +194 -0
  234. data/lib/active_merchant/billing/gateways/spreedly_core.rb +354 -0
  235. data/lib/active_merchant/billing/gateways/stripe.rb +866 -0
  236. data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +602 -0
  237. data/lib/active_merchant/billing/gateways/swipe_checkout.rb +151 -0
  238. data/lib/active_merchant/billing/gateways/telr.rb +273 -0
  239. data/lib/active_merchant/billing/gateways/tns.rb +23 -0
  240. data/lib/active_merchant/billing/gateways/trans_first.rb +240 -0
  241. data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +612 -0
  242. data/lib/active_merchant/billing/gateways/transact_pro.rb +222 -0
  243. data/lib/active_merchant/billing/gateways/transax.rb +21 -0
  244. data/lib/active_merchant/billing/gateways/transnational.rb +9 -0
  245. data/lib/active_merchant/billing/gateways/trexle.rb +221 -0
  246. data/lib/active_merchant/billing/gateways/trust_commerce.rb +500 -0
  247. data/lib/active_merchant/billing/gateways/usa_epay.rb +24 -0
  248. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1612 -0
  249. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +367 -0
  250. data/lib/active_merchant/billing/gateways/vanco.rb +303 -0
  251. data/lib/active_merchant/billing/gateways/verifi.rb +224 -0
  252. data/lib/active_merchant/billing/gateways/viaklix.rb +171 -0
  253. data/lib/active_merchant/billing/gateways/visanet_peru.rb +250 -0
  254. data/lib/active_merchant/billing/gateways/vpos.rb +223 -0
  255. data/lib/active_merchant/billing/gateways/webpay.rb +97 -0
  256. data/lib/active_merchant/billing/gateways/wepay.rb +235 -0
  257. data/lib/active_merchant/billing/gateways/wirecard.rb +430 -0
  258. data/lib/active_merchant/billing/gateways/wompi.rb +197 -0
  259. data/lib/active_merchant/billing/gateways/world_net.rb +345 -0
  260. data/lib/active_merchant/billing/gateways/worldpay.rb +1050 -0
  261. data/lib/active_merchant/billing/gateways/worldpay_online_payments.rb +208 -0
  262. data/lib/active_merchant/billing/gateways/worldpay_us.rb +221 -0
  263. data/lib/active_merchant/billing/gateways.rb +14 -0
  264. data/lib/active_merchant/billing/model.rb +30 -0
  265. data/lib/active_merchant/billing/network_tokenization_credit_card.rb +39 -0
  266. data/lib/active_merchant/billing/payment_token.rb +21 -0
  267. data/lib/active_merchant/billing/rails.rb +3 -0
  268. data/lib/active_merchant/billing/response.rb +121 -0
  269. data/lib/active_merchant/billing/three_d_secure_eci_mapper.rb +27 -0
  270. data/lib/active_merchant/billing.rb +16 -0
  271. data/lib/active_merchant/connection.rb +194 -0
  272. data/lib/active_merchant/country.rb +338 -0
  273. data/lib/active_merchant/empty.rb +20 -0
  274. data/lib/active_merchant/errors.rb +38 -0
  275. data/lib/active_merchant/net_http_ssl_connection.rb +11 -0
  276. data/lib/active_merchant/network_connection_retries.rb +78 -0
  277. data/lib/active_merchant/post_data.rb +26 -0
  278. data/lib/active_merchant/posts_data.rb +92 -0
  279. data/lib/active_merchant/version.rb +3 -0
  280. data/lib/active_merchant.rb +63 -0
  281. data/lib/activemerchant.rb +1 -0
  282. data/lib/certs/cacert.pem +3214 -0
  283. data/lib/support/gateway_support.rb +69 -0
  284. data/lib/support/outbound_hosts.rb +28 -0
  285. data/lib/support/ssl_verify.rb +88 -0
  286. data/lib/support/ssl_version.rb +86 -0
  287. metadata +506 -0
@@ -0,0 +1,370 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class AirwallexGateway < Gateway
4
+ self.test_url = 'https://api-demo.airwallex.com/api/v1'
5
+ self.live_url = 'https://pci-api.airwallex.com/api/v1'
6
+
7
+ # per https://www.airwallex.com/docs/online-payments__overview, cards are accepted in all EU countries
8
+ self.supported_countries = %w[AT AU BE BG CY CZ DE DK EE GR ES FI FR GB HK HR HU IE IT LT LU LV MT NL PL PT RO SE SG SI SK]
9
+ self.default_currency = 'AUD'
10
+ self.supported_cardtypes = %i[visa master]
11
+
12
+ self.homepage_url = 'https://airwallex.com/'
13
+ self.display_name = 'Airwallex'
14
+
15
+ ENDPOINTS = {
16
+ login: '/authentication/login',
17
+ setup: '/pa/payment_intents/create',
18
+ sale: '/pa/payment_intents/%{id}/confirm',
19
+ capture: '/pa/payment_intents/%{id}/capture',
20
+ refund: '/pa/refunds/create',
21
+ void: '/pa/payment_intents/%{id}/cancel'
22
+ }
23
+
24
+ # Provided by Airwallex for testing purposes
25
+ TEST_NETWORK_TRANSACTION_IDS = {
26
+ visa: '123456789012345',
27
+ master: 'MCC123ABC0101'
28
+ }
29
+
30
+ def initialize(options = {})
31
+ requires!(options, :client_id, :client_api_key)
32
+ @client_id = options[:client_id]
33
+ @client_api_key = options[:client_api_key]
34
+ super
35
+ @access_token = setup_access_token
36
+ end
37
+
38
+ def purchase(money, card, options = {})
39
+ payment_intent_id = create_payment_intent(money, options)
40
+ post = {
41
+ 'request_id' => request_id(options),
42
+ 'merchant_order_id' => merchant_order_id(options)
43
+ }
44
+ add_card(post, card, options)
45
+ add_descriptor(post, options)
46
+ add_stored_credential(post, options)
47
+ add_return_url(post, options)
48
+ post['payment_method_options'] = { 'card' => { 'auto_capture' => false } } if authorization_only?(options)
49
+
50
+ add_three_ds(post, options)
51
+ commit(:sale, post, payment_intent_id)
52
+ end
53
+
54
+ def authorize(money, payment, options = {})
55
+ # authorize is just a purchase w/o an auto capture
56
+ purchase(money, payment, options.merge({ auto_capture: false }))
57
+ end
58
+
59
+ def capture(money, authorization, options = {})
60
+ raise ArgumentError, 'An authorization value must be provided.' if authorization.blank?
61
+
62
+ post = {
63
+ 'request_id' => request_id(options),
64
+ 'merchant_order_id' => merchant_order_id(options),
65
+ 'amount' => amount(money)
66
+ }
67
+ add_descriptor(post, options)
68
+
69
+ commit(:capture, post, authorization)
70
+ end
71
+
72
+ def refund(money, authorization, options = {})
73
+ raise ArgumentError, 'An authorization value must be provided.' if authorization.blank?
74
+
75
+ post = {}
76
+ post[:amount] = amount(money)
77
+ post[:payment_intent_id] = authorization
78
+ post[:request_id] = request_id(options)
79
+ post[:merchant_order_id] = merchant_order_id(options)
80
+
81
+ commit(:refund, post)
82
+ end
83
+
84
+ def void(authorization, options = {})
85
+ raise ArgumentError, 'An authorization value must be provided.' if authorization.blank?
86
+
87
+ post = {}
88
+ post[:request_id] = request_id(options)
89
+ post[:merchant_order_id] = merchant_order_id(options)
90
+ add_descriptor(post, options)
91
+
92
+ commit(:void, post, authorization)
93
+ end
94
+
95
+ def verify(credit_card, options = {})
96
+ MultiResponse.run(:use_first_response) do |r|
97
+ r.process { authorize(100, credit_card, options) }
98
+ r.process(:ignore_result) { void(r.authorization, options) }
99
+ end
100
+ end
101
+
102
+ def supports_scrubbing?
103
+ true
104
+ end
105
+
106
+ def scrub(transcript)
107
+ transcript.
108
+ gsub(/(\\\"number\\\":\\\")\d+/, '\1[REDACTED]').
109
+ gsub(/(\\\"cvc\\\":\\\")\d+/, '\1[REDACTED]')
110
+ end
111
+
112
+ private
113
+
114
+ def request_id(options)
115
+ options[:request_id] || generate_uuid
116
+ end
117
+
118
+ def merchant_order_id(options)
119
+ options[:merchant_order_id] || options[:order_id] || generate_uuid
120
+ end
121
+
122
+ def add_return_url(post, options)
123
+ post[:return_url] = options[:return_url] if options[:return_url]
124
+ end
125
+
126
+ def generate_uuid
127
+ SecureRandom.uuid
128
+ end
129
+
130
+ def setup_access_token
131
+ token_headers = {
132
+ 'Content-Type' => 'application/json',
133
+ 'x-client-id' => @client_id,
134
+ 'x-api-key' => @client_api_key
135
+ }
136
+ response = ssl_post(build_request_url(:login), nil, token_headers)
137
+ JSON.parse(response)['token']
138
+ end
139
+
140
+ def build_request_url(action, id = nil)
141
+ base_url = (test? ? test_url : live_url)
142
+ base_url + ENDPOINTS[action].to_s % { id: id }
143
+ end
144
+
145
+ def add_referrer_data(post)
146
+ post[:referrer_data] = { type: 'spreedly' }
147
+ end
148
+
149
+ def create_payment_intent(money, options = {})
150
+ post = {}
151
+ add_invoice(post, money, options)
152
+ add_order(post, options)
153
+ post[:request_id] = "#{request_id(options)}_setup"
154
+ post[:merchant_order_id] = merchant_order_id(options)
155
+ add_referrer_data(post)
156
+ add_descriptor(post, options)
157
+ post['payment_method_options'] = { 'card' => { 'risk_control' => { 'three_ds_action' => 'SKIP_3DS' } } } if options[:skip_3ds]
158
+
159
+ response = commit(:setup, post)
160
+ raise ArgumentError.new(response.message) unless response.success?
161
+
162
+ response.params['id']
163
+ end
164
+
165
+ def add_billing(post, card, options = {})
166
+ return unless has_name_info?(card)
167
+
168
+ billing = post['payment_method']['card']['billing'] || {}
169
+ billing['email'] = options[:email] if options[:email]
170
+ billing['phone'] = options[:phone] if options[:phone]
171
+ billing['first_name'] = card.first_name
172
+ billing['last_name'] = card.last_name
173
+ billing_address = options[:billing_address]
174
+ billing['address'] = build_address(billing_address) if has_required_address_info?(billing_address)
175
+
176
+ post['payment_method']['card']['billing'] = billing
177
+ end
178
+
179
+ def has_name_info?(card)
180
+ # These fields are required if billing data is sent.
181
+ card.first_name && card.last_name
182
+ end
183
+
184
+ def has_required_address_info?(address)
185
+ # These fields are required if address data is sent.
186
+ return unless address
187
+
188
+ address[:address1] && address[:country]
189
+ end
190
+
191
+ def build_address(address)
192
+ return unless address
193
+
194
+ address_data = {} # names r hard
195
+ address_data[:country_code] = address[:country]
196
+ address_data[:street] = address[:address1]
197
+ address_data[:city] = address[:city] if address[:city] # required per doc, not in practice
198
+ address_data[:postcode] = address[:zip] if address[:zip]
199
+ address_data[:state] = address[:state] if address[:state]
200
+ address_data
201
+ end
202
+
203
+ def add_invoice(post, money, options)
204
+ post[:amount] = amount(money)
205
+ post[:currency] = (options[:currency] || currency(money))
206
+ end
207
+
208
+ def add_card(post, card, options = {})
209
+ post['payment_method'] = {
210
+ 'type' => 'card',
211
+ 'card' => {
212
+ 'expiry_month' => format(card.month, :two_digits),
213
+ 'expiry_year' => card.year.to_s,
214
+ 'number' => card.number.to_s,
215
+ 'name' => card.name,
216
+ 'cvc' => card.verification_value,
217
+ 'brand' => card.brand
218
+ }
219
+ }
220
+ add_billing(post, card, options)
221
+ end
222
+
223
+ def add_order(post, options)
224
+ return unless shipping_address = options[:shipping_address]
225
+
226
+ physical_address = build_shipping_address(shipping_address)
227
+ first_name, last_name = split_names(shipping_address[:name])
228
+ shipping = {}
229
+ shipping[:first_name] = first_name if first_name
230
+ shipping[:last_name] = last_name if last_name
231
+ shipping[:phone_number] = shipping_address[:phone_number] if shipping_address[:phone_number]
232
+ shipping[:address] = physical_address
233
+ post[:order] = { shipping: shipping }
234
+ end
235
+
236
+ def build_shipping_address(shipping_address)
237
+ address = {}
238
+ address[:city] = shipping_address[:city]
239
+ address[:country_code] = shipping_address[:country]
240
+ address[:postcode] = shipping_address[:zip]
241
+ address[:state] = shipping_address[:state]
242
+ address[:street] = shipping_address[:address1]
243
+ address
244
+ end
245
+
246
+ def add_stored_credential(post, options)
247
+ return unless stored_credential = options[:stored_credential]
248
+
249
+ external_recurring_data = post[:external_recurring_data] = {}
250
+
251
+ case stored_credential.dig(:reason_type)
252
+ when 'recurring', 'installment'
253
+ external_recurring_data[:merchant_trigger_reason] = 'scheduled'
254
+ when 'unscheduled'
255
+ external_recurring_data[:merchant_trigger_reason] = 'unscheduled'
256
+ end
257
+
258
+ external_recurring_data[:original_transaction_id] = test_mit?(options) ? test_network_transaction_id(post) : stored_credential.dig(:network_transaction_id)
259
+ external_recurring_data[:triggered_by] = stored_credential.dig(:initiator) == 'cardholder' ? 'customer' : 'merchant'
260
+ end
261
+
262
+ def test_network_transaction_id(post)
263
+ case post['payment_method']['card']['brand']
264
+ when 'visa'
265
+ TEST_NETWORK_TRANSACTION_IDS[:visa]
266
+ when 'master'
267
+ TEST_NETWORK_TRANSACTION_IDS[:master]
268
+ end
269
+ end
270
+
271
+ def test_mit?(options)
272
+ test? && options.dig(:stored_credential, :initiator) == 'merchant'
273
+ end
274
+
275
+ def add_three_ds(post, options)
276
+ return unless three_d_secure = options[:three_d_secure]
277
+
278
+ pm_options = post.dig('payment_method_options', 'card')
279
+
280
+ external_three_ds = {
281
+ 'version': format_three_ds_version(three_d_secure),
282
+ 'eci': three_d_secure[:eci]
283
+ }.merge(three_ds_version_specific_fields(three_d_secure))
284
+
285
+ pm_options ? pm_options.merge!('external_three_ds': external_three_ds) : post['payment_method_options'] = { 'card': { 'external_three_ds': external_three_ds } }
286
+ end
287
+
288
+ def format_three_ds_version(three_d_secure)
289
+ version = three_d_secure[:version].split('.')
290
+
291
+ version.push('0') until version.length == 3
292
+ version.join('.')
293
+ end
294
+
295
+ def three_ds_version_specific_fields(three_d_secure)
296
+ if three_d_secure[:version].to_f >= 2
297
+ {
298
+ 'authentication_value': three_d_secure[:cavv],
299
+ 'ds_transaction_id': three_d_secure[:ds_transaction_id],
300
+ 'three_ds_server_transaction_id': three_d_secure[:three_ds_server_trans_id]
301
+ }
302
+ else
303
+ {
304
+ 'cavv': three_d_secure[:cavv],
305
+ 'xid': three_d_secure[:xid]
306
+ }
307
+ end
308
+ end
309
+
310
+ def authorization_only?(options = {})
311
+ options.include?(:auto_capture) && options[:auto_capture] == false
312
+ end
313
+
314
+ def add_descriptor(post, options)
315
+ post[:descriptor] = options[:description] if options[:description]
316
+ end
317
+
318
+ def parse(body)
319
+ JSON.parse(body)
320
+ end
321
+
322
+ def commit(action, post, id = nil)
323
+ url = build_request_url(action, id)
324
+
325
+ post_headers = { 'Authorization' => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
326
+ response = parse(ssl_post(url, post_data(post), post_headers))
327
+
328
+ Response.new(
329
+ success_from(response),
330
+ message_from(response),
331
+ response,
332
+ authorization: authorization_from(response),
333
+ avs_result: AVSResult.new(code: response.dig('latest_payment_attempt', 'authentication_data', 'avs_result')),
334
+ cvv_result: CVVResult.new(response.dig('latest_payment_attempt', 'authentication_data', 'cvc_code')),
335
+ test: test?,
336
+ error_code: error_code_from(response)
337
+ )
338
+ end
339
+
340
+ def handle_response(response)
341
+ case response.code.to_i
342
+ when 200...300, 400, 404
343
+ response.body
344
+ else
345
+ raise ResponseError.new(response)
346
+ end
347
+ end
348
+
349
+ def post_data(post)
350
+ post.to_json
351
+ end
352
+
353
+ def success_from(response)
354
+ %w(REQUIRES_PAYMENT_METHOD SUCCEEDED RECEIVED REQUIRES_CAPTURE CANCELLED).include?(response['status'])
355
+ end
356
+
357
+ def message_from(response)
358
+ response.dig('latest_payment_attempt', 'status') || response['status'] || response['message']
359
+ end
360
+
361
+ def authorization_from(response)
362
+ response.dig('latest_payment_attempt', 'payment_intent_id')
363
+ end
364
+
365
+ def error_code_from(response)
366
+ response['provider_original_response_code'] || response['code'] unless success_from(response)
367
+ end
368
+ end
369
+ end
370
+ end
@@ -0,0 +1,256 @@
1
+ require 'jose'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class AleloGateway < Gateway
6
+ class_attribute :prelive_url
7
+
8
+ self.test_url = 'https://sandbox-api.alelo.com.br/alelo/sandbox/'
9
+ self.live_url = 'https://api.alelo.com.br/alelo/prd/'
10
+ self.prelive_url = 'https://api.homologacaoalelo.com.br/alelo/uat/'
11
+
12
+ self.supported_countries = ['BR']
13
+ self.default_currency = 'BRL'
14
+ self.supported_cardtypes = %i[visa master american_express discover]
15
+
16
+ self.homepage_url = 'https://www.alelo.com.br'
17
+ self.display_name = 'Alelo'
18
+
19
+ def initialize(options = {})
20
+ requires!(options, :client_id, :client_secret)
21
+ super
22
+ end
23
+
24
+ def purchase(money, payment, options = {})
25
+ post = {}
26
+ add_order(post, options)
27
+ add_amount(post, money)
28
+ add_payment(post, payment)
29
+ add_geolocation(post, options)
30
+ add_extra_data(post, options)
31
+
32
+ commit('capture/transaction', post, options)
33
+ end
34
+
35
+ def refund(money, authorization, options = {})
36
+ request_id = authorization.split('#').first
37
+ options[:http] = { method: :put, prevent_encrypt: true }
38
+ commit('capture/transaction/refund', { requestId: request_id }, options, :put)
39
+ end
40
+
41
+ def supports_scrubbing?
42
+ true
43
+ end
44
+
45
+ def scrub(transcript)
46
+ force_utf8(transcript.encode).
47
+ gsub(%r((Authorization: Bearer )[\w -]+), '\1[FILTERED]').
48
+ gsub(%r((client_id=|Client-Id:)[\w -]+), '\1[FILTERED]\2').
49
+ gsub(%r((client_secret=|Client-Secret:)[\w -]+), '\1[FILTERED]\2').
50
+ gsub(%r((access_token\":\")[^\"]*), '\1[FILTERED]').
51
+ gsub(%r((publicKey\":\")[^\"]*), '\1[FILTERED]')
52
+ end
53
+
54
+ private
55
+
56
+ def force_utf8(string)
57
+ return nil unless string
58
+
59
+ # binary = string.encode('BINARY', invalid: :replace, undef: :replace, replace: '?')
60
+ string.encode('UTF-8', invalid: :replace, undef: :replace, replace: '?')
61
+ end
62
+
63
+ def add_amount(post, money)
64
+ post[:amount] = amount(money).to_f
65
+ end
66
+
67
+ def add_order(post, options)
68
+ post[:requestId] = options[:order_id]
69
+ end
70
+
71
+ def add_extra_data(post, options)
72
+ post.merge!({
73
+ establishmentCode: options[:establishment_code],
74
+ playerIdentification: options[:player_identification],
75
+ captureType: '3', # send fixed value 3 to ecommerce
76
+ subMerchantCode: options[:sub_merchant_mcc],
77
+ externalTraceNumber: options[:external_trace_number]
78
+ }.compact)
79
+ end
80
+
81
+ def add_geolocation(post, options)
82
+ return if options[:geo_latitude].blank? || options[:geo_longitude].blank?
83
+
84
+ post.merge!(geolocation: {
85
+ latitude: options[:geo_latitude],
86
+ longitude: options[:geo_longitude]
87
+ })
88
+ end
89
+
90
+ def add_payment(post, payment)
91
+ post.merge!({
92
+ cardNumber: payment.number,
93
+ cardholderName: payment.name,
94
+ expirationMonth: payment.month,
95
+ expirationYear: format(payment.year, :two_digits).to_i,
96
+ securityCode: payment.verification_value
97
+ })
98
+ end
99
+
100
+ def fetch_access_token
101
+ params = {
102
+ grant_type: 'client_credentials',
103
+ client_id: @options[:client_id],
104
+ client_secret: @options[:client_secret],
105
+ scope: '/capture'
106
+ }
107
+
108
+ headers = {
109
+ 'Accept' => 'application/json',
110
+ 'Content-Type' => 'application/x-www-form-urlencoded'
111
+ }
112
+
113
+ parsed = parse(ssl_post(url('captura-oauth-provider/oauth/token'), post_data(params), headers))
114
+ Response.new(true, parsed[:access_token], parsed)
115
+ end
116
+
117
+ def remote_encryption_key(access_token)
118
+ response = parse(ssl_get(url('capture/key'), request_headers(access_token)))
119
+ Response.new(true, response[:publicKey], response)
120
+ end
121
+
122
+ def ensure_credentials(try_again = true)
123
+ multiresp = MultiResponse.new
124
+ access_token = @options[:access_token]
125
+ key = @options[:encryption_key]
126
+ uuid = @options[:encryption_uuid]
127
+
128
+ if access_token.blank?
129
+ multiresp.process { fetch_access_token }
130
+ access_token = multiresp.message
131
+ key = nil
132
+ uuid = nil
133
+ end
134
+
135
+ if key.blank?
136
+ multiresp.process { remote_encryption_key(access_token) }
137
+ key = multiresp.message
138
+ uuid = multiresp.params['uuid']
139
+ end
140
+
141
+ {
142
+ key: key,
143
+ uuid: uuid,
144
+ access_token: access_token,
145
+ multiresp: multiresp.responses.present? ? multiresp : nil
146
+ }
147
+ rescue ResponseError => error
148
+ # retry to generate a new access_token when the provided one is expired
149
+ raise error unless try_again && %w(401 404).include?(error.response.code) && @options[:access_token].present?
150
+
151
+ @options.delete(:access_token)
152
+ @options.delete(:encryption_key)
153
+ ensure_credentials false
154
+ end
155
+
156
+ def encrypt_payload(body, credentials, options)
157
+ key = OpenSSL::PKey::RSA.new(Base64.decode64(credentials[:key]))
158
+ jwk = JOSE::JWK.from_key(key)
159
+ alg_enc = { 'alg' => 'RSA-OAEP-256', 'enc' => 'A128CBC-HS256' }
160
+
161
+ token = JOSE::JWE.block_encrypt(jwk, body.to_json, alg_enc).compact
162
+
163
+ encrypted_body = {
164
+ token: token,
165
+ uuid: credentials[:uuid]
166
+ }
167
+
168
+ encrypted_body.to_json
169
+ end
170
+
171
+ def parse(body)
172
+ JSON.parse(body, symbolize_names: true)
173
+ end
174
+
175
+ def post_data(params)
176
+ params.map { |k, v| "#{k}=#{CGI.escape(v.to_s)}" }.join('&')
177
+ end
178
+
179
+ def commit(action, body, options, try_again = true)
180
+ credentials = ensure_credentials
181
+ payload = encrypt_payload(body, credentials, options)
182
+
183
+ if options.dig :http, :method
184
+ payload = body.to_json if options.dig :http, :prevent_encrypt
185
+ response = parse ssl_request(options[:http][:method], url(action), payload, request_headers(credentials[:access_token]))
186
+ else
187
+ response = parse ssl_post(url(action), payload, request_headers(credentials[:access_token]))
188
+ end
189
+
190
+ resp = Response.new(
191
+ success_from(action, response),
192
+ message_from(response),
193
+ response,
194
+ authorization: authorization_from(response, options),
195
+ test: test?
196
+ )
197
+
198
+ return resp unless credentials[:multiresp].present?
199
+
200
+ multiresp = credentials[:multiresp]
201
+ resp.params.merge!({
202
+ 'access_token' => credentials[:access_token],
203
+ 'encryption_key' => credentials[:key],
204
+ 'encryption_uuid' => credentials[:uuid]
205
+ })
206
+ multiresp.process { resp }
207
+
208
+ multiresp
209
+ rescue ActiveMerchant::ResponseError => e
210
+ # Retry on a possible expired encryption key
211
+ if try_again && %w(401 404).include?(e.response.code) && @options[:encryption_key].present?
212
+ @options.delete(:encryption_key)
213
+ commit(action, body, options, false)
214
+ else
215
+ res = parse(e.response.body)
216
+ Response.new(false, res[:messageUser] || res[:error], res, test: test?)
217
+ end
218
+ end
219
+
220
+ def success_from(action, response)
221
+ case action
222
+ when 'capture/transaction/refund'
223
+ response[:status] == 'ESTORNADA'
224
+ when 'capture/transaction'
225
+ response[:status] == 'CONFIRMADA'
226
+ else
227
+ false
228
+ end
229
+ end
230
+
231
+ def message_from(response)
232
+ response[:messages] || response[:messageUser]
233
+ end
234
+
235
+ def authorization_from(response, options)
236
+ [response[:requestId]].join('#')
237
+ end
238
+
239
+ def url(action)
240
+ return prelive_url if @options[:url_override] == 'prelive'
241
+
242
+ "#{test? ? test_url : live_url}#{action}"
243
+ end
244
+
245
+ def request_headers(access_token)
246
+ {
247
+ 'Accept' => 'application/json',
248
+ 'X-IBM-Client-Id' => @options[:client_id],
249
+ 'X-IBM-Client-Secret' => @options[:client_secret],
250
+ 'Content-Type' => 'application/json',
251
+ 'Authorization' => "Bearer #{access_token}"
252
+ }
253
+ end
254
+ end
255
+ end
256
+ end