From 810b55cf61b3d1764da885cdb4ed49ed0fe1f3a2 Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Tue, 6 Apr 2021 09:03:00 -0500 Subject: [PATCH] Block users who get too many card declines If a customer has > 2 card declines in 24 hours or an ip has > 4, then treat all attempts as declines without looking as an anti-fraud measure. --- config.ru | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/config.ru b/config.ru index c04f33f..67b2fdd 100644 --- a/config.ru +++ b/config.ru @@ -65,6 +65,7 @@ class Plan "INSERT INTO plan_log VALUES ($1, $2, $3, $4)", [customer_id, @plan[:name], Time.now, Date.today >> months] ) + true end end @@ -125,17 +126,35 @@ class CreditCardGateway ) end - def buy_plan(plan_name, months, nonce) + def decline_guard(ip) + customer_declines, ip_declines = REDIS.mget( + "jmp_pay_decline-#{@customer_id}", + "jmp_pay_decline-#{ip}" + ) + customer_declines.to_i < 2 && ip_declines.to_i < 4 + end + + def sale(ip:, **kwargs) + return false unless decline_guard(ip) + result = @gateway.transaction.sale(**kwargs) + return true if result.success? + + REDIS.incr("jmp_pay_decline-#{@customer_id}") + REDIS.expire("jmp_pay_decline-#{@customer_id}", 60 * 60 * 24) + REDIS.incr("jmp_pay_decline-#{ip}") + REDIS.expire("jmp_pay_decline-#{ip}", 60 * 60 * 24) + false + end + + def buy_plan(plan_name, months, nonce, ip) plan = Plan.for(plan_name) - result = @gateway.transaction.sale( + sale( + ip: ip, amount: plan.price(months), payment_method_nonce: nonce, merchant_account_id: plan.merchant_account, options: {submit_for_settlement: true} - ) - return false unless result.success? - plan.activate(@customer_id, months) - true + ) && plan.activate(@customer_id, months) end protected @@ -251,7 +270,8 @@ class JmpPay < Roda Plan.active?(gateway.customer_id) || gateway.buy_plan( request.params["plan_name"], 5, - request.params["braintree_nonce"] + request.params["braintree_nonce"], + request.ip ) end if result -- 2.45.2