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
@@ -2,6 +2,8 @@ require 'active_support/core_ext/hash/slice'
2
2
 
3
3
  module ActiveMerchant #:nodoc:
4
4
  module Billing #:nodoc:
5
+ # This gateway uses an older version of the Stripe API.
6
+ # To utilize the updated {Payment Intents API}[https://stripe.com/docs/api/payment_intents], integrate with the StripePaymentIntents gateway
5
7
  class StripeGateway < Gateway
6
8
  self.live_url = 'https://api.stripe.com/v1/'
7
9
 
@@ -21,10 +23,12 @@ module ActiveMerchant #:nodoc:
21
23
  'unchecked' => 'P'
22
24
  }
23
25
 
24
- self.supported_countries = %w(AT AU BE BR CA CH DE DK ES FI FR GB HK IE IT JP LU MX NL NO NZ PT SE SG US)
26
+ DEFAULT_API_VERSION = '2020-08-27'
27
+
28
+ self.supported_countries = %w(AE AT AU BE BG BR CA CH CY CZ DE DK EE ES FI FR GB GR HK HU IE IN IT JP LT LU LV MT MX MY NL NO NZ PL PT RO SE SG SI SK US)
25
29
  self.default_currency = 'USD'
26
30
  self.money_format = :cents
27
- self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club, :maestro]
31
+ self.supported_cardtypes = %i[visa master american_express discover jcb diners_club maestro unionpay]
28
32
  self.currencies_without_fractions = %w(BIF CLP DJF GNF JPY KMF KRW MGA PYG RWF VND VUV XAF XOF XPF UGX)
29
33
 
30
34
  self.homepage_url = 'https://stripe.com/'
@@ -44,28 +48,29 @@ module ActiveMerchant #:nodoc:
44
48
  'processing_error' => STANDARD_ERROR_CODE[:processing_error],
45
49
  'incorrect_pin' => STANDARD_ERROR_CODE[:incorrect_pin],
46
50
  'test_mode_live_card' => STANDARD_ERROR_CODE[:test_mode_live_card],
47
- 'pickup_card' => STANDARD_ERROR_CODE[:pickup_card]
51
+ 'pickup_card' => STANDARD_ERROR_CODE[:pickup_card],
52
+ 'amount_too_small' => STANDARD_ERROR_CODE[:invalid_amount]
48
53
  }
49
54
 
50
55
  BANK_ACCOUNT_HOLDER_TYPE_MAPPING = {
51
- "personal" => "individual",
52
- "business" => "company",
56
+ 'personal' => 'individual',
57
+ 'business' => 'company'
53
58
  }
54
59
 
55
60
  MINIMUM_AUTHORIZE_AMOUNTS = {
56
- "USD" => 100,
57
- "CAD" => 100,
58
- "GBP" => 60,
59
- "EUR" => 100,
60
- "DKK" => 500,
61
- "NOK" => 600,
62
- "SEK" => 600,
63
- "CHF" => 100,
64
- "AUD" => 100,
65
- "JPY" => 100,
66
- "MXN" => 2000,
67
- "SGD" => 100,
68
- "HKD" => 800
61
+ 'USD' => 100,
62
+ 'CAD' => 100,
63
+ 'GBP' => 60,
64
+ 'EUR' => 100,
65
+ 'DKK' => 500,
66
+ 'NOK' => 600,
67
+ 'SEK' => 600,
68
+ 'CHF' => 100,
69
+ 'AUD' => 100,
70
+ 'JPY' => 100,
71
+ 'MXN' => 2000,
72
+ 'SGD' => 100,
73
+ 'HKD' => 800
69
74
  }
70
75
 
71
76
  def initialize(options = {})
@@ -76,18 +81,20 @@ module ActiveMerchant #:nodoc:
76
81
  end
77
82
 
78
83
  def authorize(money, payment, options = {})
84
+ if ach?(payment)
85
+ direct_bank_error = 'Direct bank account transactions are not supported for authorize.'
86
+ return Response.new(false, direct_bank_error)
87
+ end
88
+
79
89
  MultiResponse.run do |r|
80
90
  if payment.is_a?(ApplePayPaymentToken)
81
91
  r.process { tokenize_apple_pay_token(payment) }
82
- payment = StripePaymentToken.new(r.params["token"]) if r.success?
92
+ payment = StripePaymentToken.new(r.params['token']) if r.success?
83
93
  end
84
94
  r.process do
85
95
  post = create_post_for_auth_or_purchase(money, payment, options)
86
- if emv_payment?(payment)
87
- add_application_fee(post, options)
88
- else
89
- post[:capture] = "false"
90
- end
96
+ add_application_fee(post, options) if emv_payment?(payment)
97
+ post[:capture] = 'false'
91
98
  commit(:post, 'charges', post, options)
92
99
  end
93
100
  end.responses.last
@@ -102,14 +109,14 @@ module ActiveMerchant #:nodoc:
102
109
  # purchase(money, nil, { :customer => id, ... })
103
110
  def purchase(money, payment, options = {})
104
111
  if ach?(payment)
105
- direct_bank_error = "Direct bank account transactions are not supported. Bank accounts must be stored and verified before use."
112
+ direct_bank_error = 'Direct bank account transactions are not supported. Bank accounts must be stored and verified before use.'
106
113
  return Response.new(false, direct_bank_error)
107
114
  end
108
115
 
109
116
  MultiResponse.run do |r|
110
117
  if payment.is_a?(ApplePayPaymentToken)
111
118
  r.process { tokenize_apple_pay_token(payment) }
112
- payment = StripePaymentToken.new(r.params["token"]) if r.success?
119
+ payment = StripePaymentToken.new(r.params['token']) if r.success?
113
120
  end
114
121
  r.process do
115
122
  post = create_post_for_auth_or_purchase(money, payment, options)
@@ -123,19 +130,24 @@ module ActiveMerchant #:nodoc:
123
130
  post = {}
124
131
 
125
132
  if emv_tc_response = options.delete(:icc_data)
126
- post[:card] = { emv_approval_data: emv_tc_response }
127
- commit(:post, "charges/#{CGI.escape(authorization)}", post, options)
133
+ # update the charge with emv data if card present
134
+ update = {}
135
+ update[:card] = { emv_approval_data: emv_tc_response }
136
+ commit(:post, "charges/#{CGI.escape(authorization)}", update, options)
128
137
  else
129
138
  add_application_fee(post, options)
130
139
  add_amount(post, money, options)
131
140
  add_exchange_rate(post, options)
132
- commit(:post, "charges/#{CGI.escape(authorization)}/capture", post, options)
133
141
  end
142
+
143
+ commit(:post, "charges/#{CGI.escape(authorization)}/capture", post, options)
134
144
  end
135
145
 
136
146
  def void(identification, options = {})
137
147
  post = {}
148
+ post[:reverse_transfer] = options[:reverse_transfer] if options[:reverse_transfer]
138
149
  post[:metadata] = options[:metadata] if options[:metadata]
150
+ post[:reason] = options[:reason] if options[:reason]
139
151
  post[:expand] = [:charge]
140
152
  commit(:post, "charges/#{CGI.escape(identification)}/refunds", post, options)
141
153
  end
@@ -146,16 +158,24 @@ module ActiveMerchant #:nodoc:
146
158
  post[:refund_application_fee] = true if options[:refund_application_fee]
147
159
  post[:reverse_transfer] = options[:reverse_transfer] if options[:reverse_transfer]
148
160
  post[:metadata] = options[:metadata] if options[:metadata]
161
+ post[:reason] = options[:reason] if options[:reason]
149
162
  post[:expand] = [:charge]
150
163
 
151
- MultiResponse.run(:first) do |r|
152
- r.process { commit(:post, "charges/#{CGI.escape(identification)}/refunds", post, options) }
164
+ response = commit(:post, "charges/#{CGI.escape(identification)}/refunds", post, options)
165
+
166
+ if response.success? && options[:refund_fee_amount] && options[:refund_fee_amount].to_s != '0'
167
+ charge = api_request(:get, "charges/#{CGI.escape(identification)}", nil, options)
153
168
 
154
- if options[:refund_fee_amount] && options[:refund_fee_amount].to_s != '0'
155
- r.process { fetch_application_fee(identification, options) }
156
- r.process { refund_application_fee(options[:refund_fee_amount].to_i, application_fee_from_response(r.responses.last), options) }
169
+ if application_fee = charge['application_fee']
170
+ fee_refund_options = {
171
+ currency: options[:currency], # currency isn't used by Stripe here, but we need it for #add_amount
172
+ key: @fee_refund_api_key
173
+ }
174
+ refund_application_fee(options[:refund_fee_amount].to_i, application_fee, fee_refund_options)
157
175
  end
158
176
  end
177
+
178
+ response
159
179
  end
160
180
 
161
181
  def verify(payment, options = {})
@@ -166,21 +186,10 @@ module ActiveMerchant #:nodoc:
166
186
  end
167
187
  end
168
188
 
169
- def application_fee_from_response(response)
170
- return unless response.success?
171
- response.params["application_fee"] unless response.params["application_fee"].empty?
172
- end
173
-
174
189
  def refund_application_fee(money, identification, options = {})
175
- return Response.new(false, "Application fee id could not be found") unless identification
176
-
177
190
  post = {}
178
191
  add_amount(post, money, options)
179
- options.merge!(:key => @fee_refund_api_key) if @fee_refund_api_key
180
- options.delete(:stripe_account)
181
-
182
- refund_fee = commit(:post, "application_fees/#{CGI.escape(identification)}/refunds", post, options)
183
- application_fee_response!(refund_fee, "Application fee could not be refunded: #{refund_fee.message}")
192
+ commit(:post, "application_fees/#{CGI.escape(identification)}/refunds", post, options)
184
193
  end
185
194
 
186
195
  # Note: creating a new credit card will not change the customer's existing default credit card (use :set_default => true)
@@ -190,13 +199,14 @@ module ActiveMerchant #:nodoc:
190
199
 
191
200
  if payment.is_a?(ApplePayPaymentToken)
192
201
  token_exchange_response = tokenize_apple_pay_token(payment)
193
- params = { card: token_exchange_response.params["token"]["id"] } if token_exchange_response.success?
202
+ params = { card: token_exchange_response.params['token']['id'] } if token_exchange_response.success?
194
203
  elsif payment.is_a?(StripePaymentToken)
195
204
  add_payment_token(params, payment, options)
196
205
  elsif payment.is_a?(Check)
197
206
  bank_token_response = tokenize_bank_account(payment)
198
207
  return bank_token_response unless bank_token_response.success?
199
- params = { source: bank_token_response.params["token"]["id"] }
208
+
209
+ params = { source: bank_token_response.params['token']['id'] }
200
210
  else
201
211
  add_creditcard(params, payment, options)
202
212
  end
@@ -213,15 +223,12 @@ module ActiveMerchant #:nodoc:
213
223
  # The /cards endpoint does not update other customer parameters.
214
224
  r.process { commit(:post, "customers/#{CGI.escape(options[:customer])}/cards", params, options) }
215
225
 
216
- if options[:set_default] and r.success? and !r.params['id'].blank?
217
- post[:default_card] = r.params['id']
218
- end
226
+ post[:default_card] = r.params['id'] if options[:set_default] && r.success? && !r.params['id'].blank?
219
227
 
220
- if post.count > 0
221
- r.process { update_customer(options[:customer], post) }
222
- end
228
+ r.process { update_customer(options[:customer], post.merge(expand: [:sources])) } if post.count > 0
223
229
  end
224
230
  else
231
+ post[:expand] = [:sources]
225
232
  commit(:post, 'customers', post.merge(params), options)
226
233
  end
227
234
  end
@@ -235,10 +242,10 @@ module ActiveMerchant #:nodoc:
235
242
  end
236
243
 
237
244
  def unstore(identification, options = {}, deprecated_options = {})
238
- customer_id, card_id = identification.split("|")
245
+ customer_id, card_id = identification.split('|')
239
246
 
240
247
  if options.kind_of?(String)
241
- ActiveMerchant.deprecated "Passing the card_id as the 2nd parameter is deprecated. The response authorization includes both the customer_id and the card_id."
248
+ ActiveMerchant.deprecated 'Passing the card_id as the 2nd parameter is deprecated. The response authorization includes both the customer_id and the card_id.'
242
249
  card_id ||= options
243
250
  options = deprecated_options
244
251
  end
@@ -248,18 +255,18 @@ module ActiveMerchant #:nodoc:
248
255
 
249
256
  def tokenize_apple_pay_token(apple_pay_payment_token, options = {})
250
257
  token_response = api_request(:post, "tokens?pk_token=#{CGI.escape(apple_pay_payment_token.payment_data.to_json)}")
251
- success = !token_response.key?("error")
258
+ success = !token_response.key?('error')
252
259
 
253
- if success && token_response.key?("id")
260
+ if success && token_response.key?('id')
254
261
  Response.new(success, nil, token: token_response)
255
262
  else
256
- Response.new(success, token_response["error"]["message"])
263
+ Response.new(success, token_response['error']['message'])
257
264
  end
258
265
  end
259
266
 
260
267
  def verify_credentials
261
268
  begin
262
- ssl_get(live_url + "charges/nonexistent", headers)
269
+ ssl_get(live_url + 'charges/nonexistent', headers)
263
270
  rescue ResponseError => e
264
271
  return false if e.response.code.to_i == 401
265
272
  end
@@ -274,21 +281,35 @@ module ActiveMerchant #:nodoc:
274
281
  def scrub(transcript)
275
282
  transcript.
276
283
  gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]').
284
+ gsub(%r((Authorization: Bearer )\w+), '\1[FILTERED]').
277
285
  gsub(%r((&?three_d_secure\[cryptogram\]=)[\w=]*(&?)), '\1[FILTERED]\2').
278
- gsub(%r((card\[cryptogram\]=)[^&]+(&?)), '\1[FILTERED]\2').
279
- gsub(%r((card\[cvc\]=)\d+), '\1[FILTERED]').
280
- gsub(%r((card\[emv_approval_data\]=)[^&]+(&?)), '\1[FILTERED]\2').
281
- gsub(%r((card\[emv_auth_data\]=)[^&]+(&?)), '\1[FILTERED]\2').
282
- gsub(%r((card\[encrypted_pin\]=)[^&]+(&?)), '\1[FILTERED]\2').
283
- gsub(%r((card\[encrypted_pin_key_id\]=)[\w=]+(&?)), '\1[FILTERED]\2').
284
- gsub(%r((card\[number\]=)\d+), '\1[FILTERED]').
285
- gsub(%r((card\[swipe_data\]=)[^&]+(&?)), '\1[FILTERED]\2')
286
+ gsub(%r(((\[card\]|card)\[cryptogram\]=)[^&]+(&?)), '\1[FILTERED]\3').
287
+ gsub(%r(((\[card\]|card)\[cvc\]=)\d+), '\1[FILTERED]').
288
+ gsub(%r(((\[card\]|card)\[emv_approval_data\]=)[^&]+(&?)), '\1[FILTERED]\3').
289
+ gsub(%r(((\[card\]|card)\[emv_auth_data\]=)[^&]+(&?)), '\1[FILTERED]\3').
290
+ gsub(%r(((\[card\]|card)\[encrypted_pin\]=)[^&]+(&?)), '\1[FILTERED]\3').
291
+ gsub(%r(((\[card\]|card)\[encrypted_pin_key_id\]=)[\w=]+(&?)), '\1[FILTERED]\3').
292
+ gsub(%r(((\[card\]|card)\[number\]=)\d+), '\1[FILTERED]').
293
+ gsub(%r(((\[card\]|card)\[swipe_data\]=)[^&]+(&?)), '\1[FILTERED]\3').
294
+ gsub(%r(((\[bank_account\]|bank_account)\[account_number\]=)\d+), '\1[FILTERED]').
295
+ gsub(%r(((\[payment_method_data\]|payment_method_data)\[card\]\[token\]=)[^&]+(&?)), '\1[FILTERED]\3')
286
296
  end
287
297
 
288
298
  def supports_network_tokenization?
289
299
  true
290
300
  end
291
301
 
302
+ # Helper method to prevent hitting the external_account limit from remote test runs
303
+ def delete_latest_test_external_account(account)
304
+ return unless test?
305
+
306
+ auth_header = { 'Authorization' => 'Basic ' + Base64.strict_encode64(options[:login].to_s + ':').strip }
307
+ url = "#{live_url}accounts/#{CGI.escape(account)}/external_accounts"
308
+ accounts_response = JSON.parse(ssl_get("#{url}?limit=100", auth_header))
309
+ to_delete = accounts_response['data'].reject { |ac| ac['default_for_currency'] }
310
+ ssl_request(:delete, "#{url}/#{to_delete.first['id']}", nil, auth_header)
311
+ end
312
+
292
313
  private
293
314
 
294
315
  class StripePaymentToken < PaymentToken
@@ -297,6 +318,49 @@ module ActiveMerchant #:nodoc:
297
318
  end
298
319
  end
299
320
 
321
+ def create_source(money, payment, type, options = {})
322
+ post = {}
323
+ add_amount(post, money, options, true)
324
+ post[:type] = type
325
+ if type == 'card'
326
+ add_creditcard(post, payment, options, true)
327
+ add_source_owner(post, payment, options)
328
+ elsif type == 'three_d_secure'
329
+ post[:three_d_secure] = { card: payment }
330
+ post[:redirect] = { return_url: options[:redirect_url] }
331
+ end
332
+ commit(:post, 'sources', post, options)
333
+ end
334
+
335
+ def show_source(source_id, options)
336
+ commit(:get, "sources/#{source_id}", nil, options)
337
+ end
338
+
339
+ def create_webhook_endpoint(options, events)
340
+ post = {}
341
+ post[:url] = options[:callback_url]
342
+ post[:enabled_events] = events
343
+ post[:connect] = true if options[:stripe_account]
344
+ options.delete(:stripe_account)
345
+ commit(:post, 'webhook_endpoints', post, options)
346
+ end
347
+
348
+ def delete_webhook_endpoint(options)
349
+ commit(:delete, "webhook_endpoints/#{options[:webhook_id]}", {}, options)
350
+ end
351
+
352
+ def show_webhook_endpoint(options)
353
+ options.delete(:stripe_account)
354
+ commit(:get, "webhook_endpoints/#{options[:webhook_id]}", nil, options)
355
+ end
356
+
357
+ def list_webhook_endpoints(options)
358
+ params = {}
359
+ params[:limit] = options[:limit] if options[:limit]
360
+ options.delete(:stripe_account)
361
+ commit(:get, "webhook_endpoints?#{post_data(params)}", nil, options)
362
+ end
363
+
300
364
  def create_post_for_auth_or_purchase(money, payment, options)
301
365
  post = {}
302
366
 
@@ -306,6 +370,12 @@ module ActiveMerchant #:nodoc:
306
370
  add_creditcard(post, payment, options)
307
371
  end
308
372
 
373
+ add_charge_details(post, money, payment, options)
374
+ post
375
+ end
376
+
377
+ # Used internally by Spreedly to populate the charge object for 3DS 1.0 transactions
378
+ def add_charge_details(post, money, payment, options)
309
379
  if emv_payment?(payment)
310
380
  add_statement_address(post, options)
311
381
  add_emv_metadata(post, payment)
@@ -314,15 +384,20 @@ module ActiveMerchant #:nodoc:
314
384
  add_customer_data(post, options)
315
385
  post[:description] = options[:description]
316
386
  post[:statement_descriptor] = options[:statement_description]
387
+ post[:statement_descriptor_suffix] = options[:statement_descriptor_suffix] if options[:statement_descriptor_suffix]
317
388
  post[:receipt_email] = options[:receipt_email] if options[:receipt_email]
318
389
  add_customer(post, payment, options)
319
390
  add_flags(post, options)
320
391
  end
321
392
 
322
393
  add_metadata(post, options)
394
+ add_shipping_address(post, payment, options)
323
395
  add_application_fee(post, options)
324
396
  add_exchange_rate(post, options)
325
397
  add_destination(post, options)
398
+ add_level_three(post, options)
399
+ add_connected_account(post, options)
400
+ add_radar_data(post, options)
326
401
  post
327
402
  end
328
403
 
@@ -348,6 +423,19 @@ module ActiveMerchant #:nodoc:
348
423
  end
349
424
  end
350
425
 
426
+ def add_level_three(post, options)
427
+ level_three = {}
428
+
429
+ copy_when_present(level_three, [:merchant_reference], options)
430
+ copy_when_present(level_three, [:customer_reference], options)
431
+ copy_when_present(level_three, [:shipping_address_zip], options)
432
+ copy_when_present(level_three, [:shipping_from_zip], options)
433
+ copy_when_present(level_three, [:shipping_amount], options)
434
+ copy_when_present(level_three, [:line_items], options)
435
+
436
+ post[:level3] = level_three unless level_three.empty?
437
+ end
438
+
351
439
  def add_expand_parameters(post, options)
352
440
  post[:expand] ||= []
353
441
  post[:expand].concat(Array.wrap(options[:expand]).map(&:to_sym)).uniq!
@@ -355,13 +443,13 @@ module ActiveMerchant #:nodoc:
355
443
 
356
444
  def add_external_account(post, card_params, payment)
357
445
  external_account = {}
358
- external_account[:object] ="card"
446
+ external_account[:object] = 'card'
359
447
  external_account[:currency] = (options[:currency] || currency(payment)).downcase
360
448
  post[:external_account] = external_account.merge(card_params[:card])
361
449
  end
362
450
 
363
451
  def add_customer_data(post, options)
364
- metadata_options = [:description, :ip, :user_agent, :referrer]
452
+ metadata_options = %i[description ip user_agent referrer]
365
453
  post.update(options.slice(*metadata_options))
366
454
 
367
455
  post[:external_id] = options[:order_id]
@@ -369,7 +457,8 @@ module ActiveMerchant #:nodoc:
369
457
  end
370
458
 
371
459
  def add_address(post, options)
372
- return unless post[:card] && post[:card].kind_of?(Hash)
460
+ return unless post[:card]&.kind_of?(Hash)
461
+
373
462
  if address = options[:billing_address] || options[:address]
374
463
  post[:card][:address_line1] = address[:address1] if address[:address1]
375
464
  post[:card][:address_line2] = address[:address2] if address[:address2]
@@ -382,7 +471,7 @@ module ActiveMerchant #:nodoc:
382
471
 
383
472
  def add_statement_address(post, options)
384
473
  return unless statement_address = options[:statement_address]
385
- return unless [:address1, :city, :zip, :state].all? { |key| statement_address[key].present? }
474
+ return unless %i[address1 city zip state].all? { |key| statement_address[key].present? }
386
475
 
387
476
  post[:statement_address] = {}
388
477
  post[:statement_address][:line1] = statement_address[:address1]
@@ -392,11 +481,12 @@ module ActiveMerchant #:nodoc:
392
481
  post[:statement_address][:state] = statement_address[:state]
393
482
  end
394
483
 
395
- def add_creditcard(post, creditcard, options)
484
+ def add_creditcard(post, creditcard, options, use_sources = false)
396
485
  card = {}
397
486
  if emv_payment?(creditcard)
398
487
  add_emv_creditcard(post, creditcard.icc_data)
399
- post[:card][:read_method] = "contactless" if creditcard.read_method == 'contactless'
488
+ post[:card][:read_method] = 'contactless' if creditcard.read_method == 'contactless'
489
+ post[:card][:read_method] = 'contactless_magstripe_mode' if creditcard.read_method == 'contactless_magstripe'
400
490
  if creditcard.encrypted_pin_cryptogram.present? && creditcard.encrypted_pin_ksn.present?
401
491
  post[:card][:encrypted_pin] = creditcard.encrypted_pin_cryptogram
402
492
  post[:card][:encrypted_pin_key_id] = creditcard.encrypted_pin_ksn
@@ -407,14 +497,14 @@ module ActiveMerchant #:nodoc:
407
497
  if creditcard.respond_to?(:read_method)
408
498
  card[:fallback_reason] = 'no_chip' if creditcard.read_method == 'fallback_no_chip'
409
499
  card[:fallback_reason] = 'chip_error' if creditcard.read_method == 'fallback_chip_error'
410
- card[:read_method] = "contactless_magstripe_mode" if creditcard.read_method == 'contactless_magstripe'
500
+ card[:read_method] = 'contactless_magstripe_mode' if creditcard.read_method == 'contactless_magstripe'
411
501
  end
412
502
  else
413
503
  card[:number] = creditcard.number
414
504
  card[:exp_month] = creditcard.month
415
505
  card[:exp_year] = creditcard.year
416
506
  card[:cvc] = creditcard.verification_value if creditcard.verification_value?
417
- card[:name] = creditcard.name if creditcard.name
507
+ card[:name] = creditcard.name if creditcard.name && !use_sources
418
508
  end
419
509
 
420
510
  if creditcard.is_a?(NetworkTokenizationCreditCard)
@@ -424,12 +514,12 @@ module ActiveMerchant #:nodoc:
424
514
  end
425
515
  post[:card] = card
426
516
 
427
- add_address(post, options)
517
+ add_address(post, options) unless use_sources
428
518
  elsif creditcard.kind_of?(String)
429
519
  if options[:track_data]
430
520
  card[:swipe_data] = options[:track_data]
431
- elsif creditcard.include?("|")
432
- customer_id, card_id = creditcard.split("|")
521
+ elsif creditcard.include?('|')
522
+ customer_id, card_id = creditcard.split('|')
433
523
  card = card_id
434
524
  post[:customer] = customer_id
435
525
  else
@@ -444,19 +534,16 @@ module ActiveMerchant #:nodoc:
444
534
  end
445
535
 
446
536
  def add_payment_token(post, token, options = {})
447
- post[:card] = token.payment_data["id"]
537
+ post[:card] = token.payment_data['id']
448
538
  end
449
539
 
450
540
  def add_customer(post, payment, options)
451
- if options[:customer] && !payment.respond_to?(:number)
452
- ActiveMerchant.deprecated "Passing the customer in the options is deprecated. Just use the response.authorization instead."
453
- post[:customer] = options[:customer]
454
- end
541
+ post[:customer] = options[:customer] if options[:customer] && !payment.respond_to?(:number)
455
542
  end
456
543
 
457
544
  def add_flags(post, options)
458
545
  post[:uncaptured] = true if options[:uncaptured]
459
- post[:recurring] = true if (options[:eci] == 'recurring' || options[:recurring])
546
+ post[:recurring] = true if options[:eci] == 'recurring' || options[:recurring]
460
547
  end
461
548
 
462
549
  def add_metadata(post, options = {})
@@ -464,7 +551,6 @@ module ActiveMerchant #:nodoc:
464
551
  post[:metadata].merge!(options[:metadata]) if options[:metadata]
465
552
  post[:metadata][:email] = options[:email] if options[:email]
466
553
  post[:metadata][:order_id] = options[:order_id] if options[:order_id]
467
- post.delete(:metadata) if post[:metadata].empty?
468
554
  end
469
555
 
470
556
  def add_emv_metadata(post, creditcard)
@@ -472,15 +558,59 @@ module ActiveMerchant #:nodoc:
472
558
  post[:metadata][:card_read_method] = creditcard.read_method if creditcard.respond_to?(:read_method)
473
559
  end
474
560
 
475
- def fetch_application_fee(identification, options = {})
476
- options.merge!(:key => @fee_refund_api_key)
561
+ def add_shipping_address(post, payment, options = {})
562
+ return unless shipping = options[:shipping_address]
563
+ return unless shipping_name = shipping[:name]
564
+
565
+ post[:shipping] = {}
477
566
 
478
- fetch_charge = commit(:get, "charges/#{CGI.escape(identification)}", nil, options)
479
- application_fee_response!(fetch_charge, "Application fee id could not be retrieved: #{fetch_charge.message}")
567
+ post[:shipping][:name] = shipping_name
568
+ post[:shipping][:address] = {}
569
+ post[:shipping][:address][:line1] = shipping[:address1]
570
+ post[:shipping][:address][:line2] = shipping[:address2] if shipping[:address2]
571
+ post[:shipping][:address][:city] = shipping[:city] if shipping[:city]
572
+ post[:shipping][:address][:country] = shipping[:country] if shipping[:country]
573
+ post[:shipping][:address][:state] = shipping[:state] if shipping[:state]
574
+ post[:shipping][:address][:postal_code] = shipping[:zip] if shipping[:zip]
575
+ post[:shipping][:phone] = shipping[:phone_number] if shipping[:phone_number]
480
576
  end
481
577
 
482
- def application_fee_response!(response, message)
483
- response.success? ? response : Response.new(false, message)
578
+ def add_source_owner(post, creditcard, options)
579
+ post[:owner] = {}
580
+ post[:owner][:name] = creditcard.name if creditcard.name
581
+ post[:owner][:email] = options[:email] if options[:email]
582
+
583
+ if address = options[:billing_address] || options[:address]
584
+ owner_address = {}
585
+ owner_address[:line1] = address[:address1] if address[:address1]
586
+ owner_address[:line2] = address[:address2] if address[:address2]
587
+ owner_address[:country] = address[:country] if address[:country]
588
+ owner_address[:postal_code] = address[:zip] if address[:zip]
589
+ owner_address[:state] = address[:state] if address[:state]
590
+ owner_address[:city] = address[:city] if address[:city]
591
+
592
+ post[:owner][:phone] = address[:phone] if address[:phone]
593
+ post[:owner][:address] = owner_address
594
+ end
595
+ end
596
+
597
+ def add_connected_account(post, options = {})
598
+ post[:on_behalf_of] = options[:on_behalf_of] if options[:on_behalf_of]
599
+
600
+ return unless options[:transfer_destination]
601
+
602
+ post[:transfer_data] = { destination: options[:transfer_destination] }
603
+ post[:transfer_data][:amount] = options[:transfer_amount] if options[:transfer_amount]
604
+ post[:transfer_group] = options[:transfer_group] if options[:transfer_group]
605
+ post[:application_fee_amount] = options[:application_fee_amount] if options[:application_fee_amount]
606
+ end
607
+
608
+ def add_radar_data(post, options = {})
609
+ radar_options = {}
610
+ radar_options[:session] = options[:radar_session_id] if options[:radar_session_id]
611
+ radar_options[:skip_rules] = ['all'] if options[:skip_radar_rules]
612
+
613
+ post[:radar_options] = radar_options unless radar_options.empty?
484
614
  end
485
615
 
486
616
  def parse(body)
@@ -490,45 +620,62 @@ module ActiveMerchant #:nodoc:
490
620
  def post_data(params)
491
621
  return nil unless params
492
622
 
493
- params.map do |key, value|
623
+ flatten_params([], params).join('&')
624
+ end
625
+
626
+ def flatten_params(flattened, params, prefix = nil)
627
+ params.each do |key, value|
494
628
  next if value != false && value.blank?
629
+
630
+ flattened_key = prefix.nil? ? key : "#{prefix}[#{key}]"
495
631
  if value.is_a?(Hash)
496
- h = {}
497
- value.each do |k, v|
498
- h["#{key}[#{k}]"] = v unless v.blank?
499
- end
500
- post_data(h)
632
+ flatten_params(flattened, value, flattened_key)
501
633
  elsif value.is_a?(Array)
502
- value.map { |v| "#{key}[]=#{CGI.escape(v.to_s)}" }.join("&")
634
+ flatten_array(flattened, value, flattened_key)
503
635
  else
504
- "#{key}=#{CGI.escape(value.to_s)}"
636
+ flattened << "#{flattened_key}=#{CGI.escape(value.to_s)}"
505
637
  end
506
- end.compact.join("&")
638
+ end
639
+ flattened
640
+ end
641
+
642
+ def flatten_array(flattened, array, prefix)
643
+ array.each_with_index do |item, idx|
644
+ key = "#{prefix}[#{idx}]"
645
+ if item.is_a?(Hash)
646
+ flatten_params(flattened, item, key)
647
+ elsif item.is_a?(Array)
648
+ flatten_array(flattened, item, key)
649
+ else
650
+ flattened << "#{key}=#{CGI.escape(item.to_s)}"
651
+ end
652
+ end
507
653
  end
508
654
 
509
655
  def headers(options = {})
510
- key = options[:key] || @api_key
656
+ key = options[:key] || @api_key
511
657
  idempotency_key = options[:idempotency_key]
512
658
 
513
659
  headers = {
514
- "Authorization" => "Basic " + Base64.encode64(key.to_s + ":").strip,
515
- "User-Agent" => "Stripe/v1 ActiveMerchantBindings/#{ActiveMerchant::VERSION}",
516
- "Stripe-Version" => api_version(options),
517
- "X-Stripe-Client-User-Agent" => stripe_client_user_agent(options),
518
- "X-Stripe-Client-User-Metadata" => {:ip => options[:ip]}.to_json
660
+ 'Authorization' => 'Basic ' + Base64.strict_encode64(key.to_s + ':').strip,
661
+ 'User-Agent' => "Stripe/v1 ActiveMerchantBindings/#{ActiveMerchant::VERSION}",
662
+ 'Stripe-Version' => api_version(options),
663
+ 'X-Stripe-Client-User-Agent' => stripe_client_user_agent(options),
664
+ 'X-Stripe-Client-User-Metadata' => { ip: options[:ip] }.to_json
519
665
  }
520
- headers.merge!("Idempotency-Key" => idempotency_key) if idempotency_key
521
- headers.merge!("Stripe-Account" => options[:stripe_account]) if options[:stripe_account]
666
+ headers['Idempotency-Key'] = idempotency_key if idempotency_key
667
+ headers['Stripe-Account'] = options[:stripe_account] if options[:stripe_account]
522
668
  headers
523
669
  end
524
670
 
525
671
  def stripe_client_user_agent(options)
526
672
  return user_agent unless options[:application]
527
- JSON.dump(JSON.parse(user_agent).merge!({application: options[:application]}))
673
+
674
+ JSON.dump(JSON.parse(user_agent).merge!({ application: options[:application] }))
528
675
  end
529
676
 
530
677
  def api_version(options)
531
- options[:version] || @options[:version] || "2015-04-07"
678
+ options[:version] || @options[:version] || self.class::DEFAULT_API_VERSION
532
679
  end
533
680
 
534
681
  def api_request(method, endpoint, parameters = nil, options = {})
@@ -548,59 +695,55 @@ module ActiveMerchant #:nodoc:
548
695
  def commit(method, url, parameters = nil, options = {})
549
696
  add_expand_parameters(parameters, options) if parameters
550
697
  response = api_request(method, url, parameters, options)
551
-
552
- success = success_from(response)
698
+ response['webhook_id'] = options[:webhook_id] if options[:webhook_id]
699
+ success = success_from(response, options)
553
700
 
554
701
  card = card_from_response(response)
555
- avs_code = AVS_CODE_TRANSLATOR["line1: #{card["address_line1_check"]}, zip: #{card["address_zip_check"]}"]
556
- cvc_code = CVC_CODE_TRANSLATOR[card["cvc_check"]]
557
-
702
+ avs_code = AVS_CODE_TRANSLATOR["line1: #{card['address_line1_check']}, zip: #{card['address_zip_check']}"]
703
+ cvc_code = CVC_CODE_TRANSLATOR[card['cvc_check']]
558
704
  Response.new(success,
559
705
  message_from(success, response),
560
706
  response,
561
- :test => response_is_test?(response),
562
- :authorization => authorization_from(success, url, method, response),
563
- :avs_result => { :code => avs_code },
564
- :cvv_result => cvc_code,
565
- :emv_authorization => emv_authorization_from_response(response),
566
- :error_code => success ? nil : error_code_from(response)
567
- )
707
+ test: response_is_test?(response),
708
+ authorization: authorization_from(success, url, method, response),
709
+ avs_result: { code: avs_code },
710
+ cvv_result: cvc_code,
711
+ emv_authorization: emv_authorization_from_response(response),
712
+ error_code: success ? nil : error_code_from(response))
568
713
  end
569
714
 
570
715
  def authorization_from(success, url, method, response)
571
- return response.fetch("error", {})["charge"] unless success
716
+ return response.fetch('error', {})['charge'] unless success
572
717
 
573
- if url == "customers"
574
- [response["id"], response["sources"]["data"].first["id"]].join("|")
575
- elsif method == :post && url.match(/customers\/.*\/cards/)
576
- [response["customer"], response["id"]].join("|")
718
+ if url == 'customers'
719
+ [response['id'], response.dig('sources', 'data').first&.dig('id')].join('|')
720
+ elsif method == :post && (url.match(/customers\/.*\/cards/) || url.match(/payment_methods\/.*\/attach/))
721
+ [response['customer'], response['id']].join('|')
577
722
  else
578
- response["id"]
723
+ response['id']
579
724
  end
580
725
  end
581
726
 
582
727
  def message_from(success, response)
583
- success ? "Transaction approved" : response.fetch("error", {"message" => "No error details"})["message"]
728
+ success ? 'Transaction approved' : response.fetch('error', { 'message' => 'No error details' })['message']
584
729
  end
585
730
 
586
- def success_from(response)
587
- !response.key?("error") && response["status"] != "failed"
731
+ def success_from(response, options)
732
+ !response.key?('error') && response['status'] != 'failed'
588
733
  end
589
734
 
590
735
  def response_error(raw_response)
591
- begin
592
- parse(raw_response)
593
- rescue JSON::ParserError
594
- json_error(raw_response)
595
- end
736
+ parse(raw_response)
737
+ rescue JSON::ParserError
738
+ json_error(raw_response)
596
739
  end
597
740
 
598
741
  def json_error(raw_response)
599
742
  msg = 'Invalid response received from the Stripe API. Please contact support@stripe.com if you continue to receive this message.'
600
743
  msg += " (The raw response returned by the API was #{raw_response.inspect})"
601
744
  {
602
- "error" => {
603
- "message" => msg
745
+ 'error' => {
746
+ 'message' => msg
604
747
  }
605
748
  }
606
749
  end
@@ -624,13 +767,13 @@ module ActiveMerchant #:nodoc:
624
767
  end
625
768
 
626
769
  def card_from_response(response)
627
- response["card"] || response["active_card"] || response["source"] || {}
770
+ response['card'] || response['active_card'] || response['source'] || {}
628
771
  end
629
772
 
630
773
  def emv_authorization_from_response(response)
631
- return response["error"]["emv_auth_data"] if response["error"]
774
+ return response['error']['emv_auth_data'] if response['error']
632
775
 
633
- card_from_response(response)["emv_auth_data"]
776
+ card_from_response(response)['emv_auth_data']
634
777
  end
635
778
 
636
779
  def error_code_from(response)
@@ -653,18 +796,18 @@ module ActiveMerchant #:nodoc:
653
796
  country: 'US',
654
797
  currency: 'usd',
655
798
  routing_number: bank_account.routing_number,
656
- name: bank_account.name,
657
- account_holder_type: account_holder_type,
799
+ account_holder_name: bank_account.name,
800
+ account_holder_type: account_holder_type
658
801
  }
659
802
  }
660
803
 
661
804
  token_response = api_request(:post, "tokens?#{post_data(post)}")
662
- success = token_response["error"].nil?
805
+ success = token_response['error'].nil?
663
806
 
664
- if success && token_response["id"]
807
+ if success && token_response['id']
665
808
  Response.new(success, nil, token: token_response)
666
809
  else
667
- Response.new(success, token_response["error"]["message"])
810
+ Response.new(success, token_response['error']['message'])
668
811
  end
669
812
  end
670
813
 
@@ -673,14 +816,32 @@ module ActiveMerchant #:nodoc:
673
816
  when String, nil
674
817
  false
675
818
  else
676
- card_brand(payment_method) == "check"
819
+ card_brand(payment_method) == 'check'
677
820
  end
678
821
  end
679
822
 
680
823
  def auth_minimum_amount(options)
681
824
  return 100 unless options[:currency]
825
+
682
826
  return MINIMUM_AUTHORIZE_AMOUNTS[options[:currency].upcase] || 100
683
827
  end
828
+
829
+ def copy_when_present(dest, dest_path, source, source_path = nil)
830
+ source_path ||= dest_path
831
+ source_path.each do |key|
832
+ return nil unless source[key]
833
+
834
+ source = source[key]
835
+ end
836
+
837
+ if source
838
+ dest_path.first(dest_path.size - 1).each do |key|
839
+ dest[key] ||= {}
840
+ dest = dest[key]
841
+ end
842
+ dest[dest_path.last] = source
843
+ end
844
+ end
684
845
  end
685
846
  end
686
847
  end