SecurityDecember 19, 20254 min read

Beyond Stripe Radar: A Senior Dev's Guide to Stopping Card-Testing Bots

Why standard Radar rules aren't enough and how to implement a proactive 'Circuit Breaker' for your Stripe account.

S
Sangmin Lee
Founder & CEO, RecoverPay

Most founders treat Stripe Radar as a "set-it-and-forget-it" firewall. Then they get hit by 5,000 card-testing attempts in a single hour. Even if Stripe blocks the charges, your merchant reputation takes a hit, and you are often still on the hook for the Radar "screen" fees.

As a Senior Engineer, I've seen how reactive security can fail. This guide covers how to harden your Radar syntax and why you need a proactive layer to keep your account safe.

Understanding the Radar Risk Score

Every transaction processed through Stripe receives a risk score from 0-100. While the defaults are a good start, they often miss sophisticated, distributed botnets.

Score Range Risk Level Action
0-20 Low Allow
21-65 Medium Monitor
66-85 High Manual Review
86-100 Very High Block

Essential Radar Rules (The Senior Dev's Config)

To stop modern card-testing, you need to go beyond country blocking and implement velocity checks based on metadata.

1. The Velocity "Circuit Breaker"

Bots often spam a single IP or card. Use this syntax to shut them down:

  • Rule: Block if :total_charges_per_ip_hourly: > 5
  • Why: This prevents a single bot node from spamming your API and flagged your account for "excessive 402" errors.

2. High-Confidence Metadata Mismatches

Legitimate customers rarely browse through anonymous proxies during a $100 checkout.

  • Rule: Block if :is_anonymous_proxy: = 'true' and :risk_score: > 40
  • Why: Combining proxy detection with risk scores reduces false positives while nuking automated traffic.

3. Preventing "Card-Run" Attacks

  • Rule: Block if :total_charges_per_card_daily: > 3
  • Why: A single credit card should not be attempting three or more distinct charges in 24 hours for a standard SaaS product.

The Radar Gap: Why Syntax Isn't Enough

The fundamental limitation of Radar is that it is reactive. It triggers after the request hits the Stripe API, meaning the bot has already reached your "front door."

If you are hit by a massive botnet, your "Dispute-to-Transaction" ratio can spike before Radar even catches up. This is where a proactive layer is required.

By blocking at the "Handshake" level, you save on Radar fees and keep your Stripe account reputation pristine even against direct API attacks.

Implementation: The Two-Layer Defense

A robust defense requires a "Client-side Block" to stop the bot from triggering expensive Stripe API calls, and a "Server-side Check" to ensure the request is legitimate before processing the charge.

1. Frontend (Client-side)

Integrate the Shield.js SDK directly into your checkout flow. This handles device fingerprinting and browser-level behavioral analysis.

JavaScript
// Install: npm install @recoverpay/shield
import { shield } from '@recoverpay/shield';

async function handleCheckout() {
  const result = await shield.scan({
    email: 'customer@example.com',
    amount: 9900 // $99.00 in cents
  });

  if (result.action === 'BLOCK') {
    // The "Circuit Breaker" triggers here
    // No API call to your backend or Stripe is made
    alert('Transaction declined for security reasons');
    return;
  }
  
  // Proceed to your backend payment endpoint
  processPayment(result.sessionId);
}

2. Backend (Server-side)

Even if a bot bypasses the frontend, the shield-node middleware ensures the request is validated against RecoverPay's intelligence before you hit the Stripe SDK.

JavaScript
// Install: npm install @recoverpay/shield-node
const express = require('express');
const { shieldMiddleware } = require('@recoverpay/shield-node');
const app = express();

app.post('/api/checkout', 
  shieldMiddleware({
    apiKey: process.env.RECOVERPAY_SECRET_KEY,
    onError: (req, res) => res.status(403).json({ error: 'Bot signature detected' })
  }), 
  async (req, res) => {
    // This code only runs if the shield passes
    const paymentIntent = await stripe.paymentIntents.create({ ... });
    res.json(paymentIntent);
  }
);

Conclusion

Stripe Radar is a solid foundation, but in 2026, you need to be proactive. Hardening your rules is step one; implementing this two-layer shield is how you ensure your business stays online and your fees stay low.

RecoverPay Circuit is launching in 18 days. Join the beta waitlist to automate your fraud defense.


Ready to protect your Stripe account?

RecoverPay helps you prevent chargebacks, recover failed payments, and maintain a healthy Stripe account. Start your free trial today.