Portreeve
explainer · 3 Sept 202613 min read

Stripe Radar: what it catches, what it misses, what to add

What Stripe Radar screens by default, what the paid tiers add, the rules worth writing, and the signup, trial, and login abuse it structurally cannot see.

Stripe Radar is the fraud screen that runs on every card payment you process through Stripe, whether you asked for it or not. If you are deciding whether Radar is enough for a small software business, the answer has two halves. On the payment itself, Radar is good and you should lean on it. Before the payment exists, at signup, at a card-free trial, at login, Radar is not in the room, and no rule you write will put it there.

One naming note. Stripe retired "Radar for Fraud Teams" this summer and split Radar into four tiers. If you searched for Fraud Teams pricing and landed here, the paid rules engine is now called Radar Plus. Stripe's transition notice says Fraud Teams accounts moved onto it on July 29, 2026.

What Radar does out of the box

Radar evaluates risk and runs rules on three API objects: Charges, PaymentIntents, and SetupIntents. Every card payment gets a machine-learning risk assessment and a risk_level of normal, elevated, or highest on the charge's outcome. The model is trained across Stripe's network, which is why it works as well as it does: Stripe says there is a 92% chance it has already seen the card being presented to you.

The free tier is now called Radar Lite. Stripe's plan comparison lists it as AI-based fraud prevention for payments and card testing, plus fraud alerts. Note what is missing from that row: risk levels, default rules, default block lists, and reviews are all Standard and above. On Lite, Radar blocks what its model is confident about and tells you very little about why.

Card testing gets special handling regardless of tier. If you use Checkout or the Payment Element, Stripe applies rate limiters, AI models, and CAPTCHA triggers when it detects an attack on your account, and those payments show up as "Blocked by Stripe". That is the single strongest argument for a hosted or Elements-based integration over tokenizing cards yourself.

Two defaults matter for SetupIntents, the $0 card-validation object card testers prefer because authorizations during card setup don't typically show up on cardholder statements. First, Radar does not scan SetupIntents at all unless you turn on "Use Radar on payment methods saved for future use" in Radar settings. Second, even when enabled, SetupIntents support request-3DS, allow, and block rules but not review. If your product saves a card at trial start and you have never touched that toggle, your card-setup endpoint is unscreened.

What the paid tiers add, and what they cost

As of September 2026 Stripe sells Radar Standard, Plus, and Pro for businesses starting at $10, $14, and $20 per month, or pay as you go per screened transaction. Stripe does not print the per-tier transaction rate in the plan comparison, so check your own account rather than a blog post. The same notice says the new pricing starts billing on January 22, 2027.

What each tier buys, per Stripe's own comparison:

Standard adds the risk level on every charge, the default rules (block if highest, review if elevated), default allow and block lists, and fraud analytics.

Plus is the old Fraud Teams product: custom rules with backtesting, the numeric 0–99 risk score, custom lists, the manual review queue, risk preferences, adaptive 3DS, Smart Refunds, and the Radar Assistant that writes rules from English. Everything in the next two sections requires Plus or above.

Pro adds dynamic risk thresholds, a bot score on Checkout payments, and "customer abuse" controls for free-trial abuse, multi-accounting, and account sharing. Those last three are the interesting ones for a SaaS, and they come with conditions most descriptions skip. More on that below.

How rules work

A rule is {action} if {condition}. Four actions exist, and Radar evaluates them in a fixed priority: request 3DS first, then allow, then block, then review. The first match wins and evaluation stops, so an allow rule silently overrides every block rule you own. Stripe makes you contact support before you can create allow rules at all, which tells you how often they go wrong.

Conditions compare an attribute to a value. Attributes are wrapped in colons, metadata in double colons, and lists are referenced with @. A few real ones:

Block if :card_country: != :ip_country:
Review if :is_disposable_email: and :card_funding: = 'prepaid'
Request 3D Secure if :risk_level: != 'normal' and :amount_in_usd: > 25
Block if :email_domain: in @blocked_domains

The velocity attributes are where card testing rules live. They count previous events per IP, card, email, customer, or address across hourly, daily, weekly, and all-time windows, and the count excludes the payment being evaluated. Two details bite people. The windows are bucketed, so "hourly" is up to 3,900 seconds. And some counters are bounded at 25, so > 25 never matches on those.

One naming distinction decides whether your rules see $0 probes. Attributes with _charges_ in the name count only card charges. Attributes with _transactions_ count charges, local payment method attempts, and card setup attempts. A rule on :total_charges_per_ip_address_hourly: will not fire on a SetupIntent ladder at any threshold. You want :total_transactions_per_ip_address_hourly: and the SetupIntent toggle enabled, together.

Reviews and lists

A review rule does not stop the payment. Stripe processes it and charges the customer, then puts it in a Dashboard queue where you approve, refund, or refund-and-report, with review.opened and review.closed webhooks. For a SaaS that provisions instantly, review is a post-hoc refund tool rather than a gate.

Refunding with reason fraudulent adds the card fingerprint and every associated email to your default block lists. That is the one piece of cross-payment memory Radar keeps for you, and it is per-account. The card you convict is blocked on your Stripe account and feeds the network model, but the fraudster's second card and third email are new to you.

Rules worth writing on day one

These are for a small SaaS on Plus, with Checkout or Elements, selling subscriptions in a known price range. Backtest each one before enabling; Stripe shows you the legitimate payments it would have caught over the last six months.

RuleWhy
Block if :total_transactions_per_ip_address_hourly: > 3Stripe's own card testing guide starts at > 1 on charges; _transactions_ covers SetupIntents and 3 leaves room for a retry.
Block if :blocked_transactions_per_ip_address_hourly: > 1Two blocks from one IP in an hour is a script, not a customer fat-fingering a card.
Block if :card_count_for_ip_address_transactions_daily: > 2Distinct cards per IP per day is the cleanest card-testing shape. Real customers rarely present three cards.
Block if :email_count_for_card_transactions_weekly: > 2One card across three emails is multi-account trial abuse, once a card is present.
Request 3D Secure if :risk_level: != 'normal' and :amount_in_usd: > 25Stripe's recommended shape: friction only for risky payments, and liability shifts on authenticated ones.
Review if :is_disposable_email: and :card_funding: = 'prepaid'Both signals alone are noisy; together they describe a trial abuser. Review, not block.

What not to write: Block if :card_country: != 'US' or any rule on :card_funding: = 'prepaid' alone. Stripe's docs use both as the canonical example of a rule that is too broad, and EU sellers can violate geo-blocking regulation with the first. Per-IP thresholds also need headroom: corporate NAT, mobile carriers, and VPN egress put hundreds of real users behind one address, so a > 1 per-IP block declines your second customer at the same university.

What Radar structurally cannot see

None of this is criticism. Radar screens transactions on your Stripe account, and every limit below follows from that sentence.

It does not see signups. A user who registers with a disposable email from a datacenter IP on a browser that created eleven other accounts this week has generated zero Stripe objects. Radar has no event to score. The multi-accounting signal in Pro is the exception, and it comes with conditions: it is a separate v2 API in preview that you call from your own registration handler, it wants a Stripe Customer object or at least an email per registration, it needs a Radar Session created by Stripe.js on your signup page, and it returns a score you act on yourself. That is Stripe offering to become your signup screen, not Radar catching it for you.

It does not see card-free trials. Pro's free-trial-abuse control blocks high-risk trial starts, but read the integration guide: it evaluates payment method collections that represent a free trial, meaning the SetupIntent at trial start, with the SetupIntent toggle enabled. A trial that does not collect a card produces nothing to evaluate. That is most trials at AI tools and API products, where requiring a card at signup is the conversion killer everyone tells you to accept. Do not accept it. Screen the signup instead.

It has no device identity you can use. Stripe.js collects device signals, and Stripe says advanced risk factors are the single largest input to the model at an estimated 36% improvement. But that fingerprint never reaches you. There is no :device: attribute, no device velocity counter, and no way to say "this browser has presented four cards". Your rules get IP, email, card fingerprint, and addresses. IP is the weakest of those and the only one an attacker cannot avoid giving you.

Its counters start at the first transaction. :seconds_since_email_first_seen: is null until an email has completed a payment on your account. :card_count_for_ip_address_daily: starts at zero for a fresh IP. Radar's memory of an attacker begins with their first payment attempt, which for trial abuse is weeks after they started using your product.

It does not see logins. Account takeover, credential stuffing, and a stolen session cashing out saved credits are invisible until the attacker charges the card on file, at which point Radar sees a known card, a known customer, and often a normal risk score. The account-sharing signal in Pro is the same preview API as multi-accounting, with the same integration work.

Hosted surfaces limit what you can put in front of it. You cannot run your own device script on buy.stripe.com, so if you sell through Payment Links, Radar is your only pre-payment control. Checkout Sessions are better: you create the session server-side, so you have a moment to decide before redirecting.

A practitioner on Hacker News, rameerez, described a 2023 card testing wave with "400+ cards and 40+ names under one single IP" and wrote that "even dumb heuristics would have blocked 90%" of the fraudulent payments. In the same thread ruffrey wrote that "Stripe has the tools to deal with it, but you must configure it." Both are right, and both are describing rules on payments. Neither had a tool for the accounts those cards were attached to.

Covering the gaps: screen before the card

The fix is not a different payment processor. Radar's model is trained on more card data than anything you can buy, and it sits on the object that costs you money. Keep it, upgrade to Plus if you have any fraud at all, write the six rules above, and turn on SetupIntent screening.

Then put your own decision in front of the PaymentIntent, at the events Radar cannot see, keyed on the identities Radar cannot give you.

The mechanism is an identity graph rather than a rule list. Every signup, trial start, checkout attempt, and login contributes hashed identity keys: email, a browser fingerprint from a script you control, phone if you collect it, and once a card appears, the same card_fingerprint Stripe gives you on the PaymentMethod. Accounts sharing any key are one cluster. Velocity counts run per device and per cluster as well as per IP, so a script rotating residential proxies across 40 emails still hits one device counter. Convicting one account convicts the cluster, so the abuser's fifth signup is blocked at the form, weeks before Radar would have seen a card.

This is what Portreeve is: one API call at signup, trial_start, checkout_attempt, or login that returns allow, review, or block with reason codes in under 100 ms, before you create the Stripe object, using device fingerprint, email quality, IP intelligence, and cluster memory. On checkout you pass in the Stripe card fingerprint and funding type, and they feed per-device card counters that Radar's attribute set does not expose. It sits in front of Radar, and review never blocks anyone: the flow proceeds, the event lands in a queue, and a later deny arrives at your server as a signed webhook. Card numbers never touch it.

Two design points matter whichever tool you use. First, review must be free for the end user. A pre-payment review that pauses the user is a block with worse UX, so the right shape is allow-and-flag, then revoke via webhook. Get how you handle each verdict right before you tune thresholds. Second, the browser fingerprint is not optional for card testing. Every other signal in a $0 probe is disposable per request; the device is the one thing the script reuses. Without a device token on the checkout page, card-testing shapes at normal subscription amounts can only be flagged, never blocked.

A sane setup for a small SaaS on Stripe

Assume Checkout or Elements, a free tier or trial, subscriptions under $100.

  1. Load Stripe.js on every page. Stripe asks for this explicitly because browsing behavior feeds the model.
  2. Enable "Use Radar on payment methods saved for future use". Without it, your SetupIntents are unscreened.
  3. Upgrade to Radar Plus. At $14 per month it is cheaper than one dispute fee, and rules and the risk score are what make Radar debuggable.
  4. Write the six rules above. Backtest each. Prefer _transactions_ counters over _charges_ counters.
  5. Refund confirmed fraud with reason fraudulent, always. That is how your block lists and the network model learn.
  6. Screen signup, trial start, and login with a device- and cluster-keyed decision before any Stripe object exists. Pass the Stripe card fingerprint into it at checkout so the two layers share one identity.
  7. Feed outcomes back both ways: Radar's fraud refund, and your own screen's confirmed_abuse or chargeback on the event that let it through, so the cluster is convicted. The reason codes on each verdict show which signal fired.

Radar is the backstop. It catches what reaches the card. Everything before that is yours to catch, and the attackers know which half is unguarded.

If you want the first half in place this week, Portreeve's free tier screens 1,000 events a month with no card required.

← Back to all posts