Skip to main content
RapidDev - Software Development Agency
stripe-guide

How to block fraudulent customers in Stripe

Stripe Radar is a machine learning fraud detection system included with every Stripe account. You can enhance it with custom rules to block specific emails, IP addresses, countries, or card fingerprints. This guide covers enabling Radar, creating block rules, managing block lists, and handling blocked payments — all through the Dashboard and API.

What you'll learn

  • How Stripe Radar detects and blocks fraud automatically
  • How to create custom Radar rules to block specific patterns
  • How to manage block lists for emails, IPs, and card fingerprints
  • How to review blocked payments and reduce false positives
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner6 min read15 minutesStripe API v2024-12+, Radar included on all accountsMarch 2026RapidDev Engineering Team
TL;DR

Stripe Radar is a machine learning fraud detection system included with every Stripe account. You can enhance it with custom rules to block specific emails, IP addresses, countries, or card fingerprints. This guide covers enabling Radar, creating block rules, managing block lists, and handling blocked payments — all through the Dashboard and API.

Blocking Fraudulent Payments with Stripe Radar

Stripe Radar uses machine learning trained on billions of transactions across the Stripe network to detect fraud. It is enabled by default and blocks high-risk payments automatically. You can extend Radar with custom rules to block specific customer attributes — email domains, IP addresses, card countries, or repeat offenders. For businesses needing more control, Radar for Fraud Teams ($0.07/screened transaction) adds manual review queues and advanced rules.

Prerequisites

  • A Stripe account in live or test mode
  • Access to the Stripe Dashboard
  • Node.js 18 or later for API examples
  • Stripe Node.js SDK: npm install stripe

Step-by-step guide

1

Understand Stripe Radar's default protection

Radar runs automatically on every payment. It assigns a risk score and blocks payments that exceed the threshold. No code changes are needed for basic protection.

typescript
1// Radar evaluates every PaymentIntent automatically
2// Risk levels: normal, elevated, highest
3// Check a charge's risk assessment:
4const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
5
6async function checkRiskLevel(chargeId) {
7 const charge = await stripe.charges.retrieve(chargeId);
8 const outcome = charge.outcome;
9
10 console.log('Risk level:', outcome.risk_level); // normal, elevated, highest
11 console.log('Risk score:', outcome.risk_score); // 0-100
12 console.log('Seller message:', outcome.seller_message);
13 console.log('Type:', outcome.type); // authorized, blocked, manual_review
14}
15
16checkRiskLevel('ch_chargeId');

Expected result: Console displays the charge's risk assessment including risk level, score, and whether it was blocked.

2

Create custom block rules in the Dashboard

Go to Dashboard → Radar → Rules. Create rules to block payments matching specific criteria. Rules use Stripe's rule language.

typescript
1// Example Radar rules (create these in Dashboard → Radar → Rules):
2//
3// Block payments from disposable email domains:
4// Block if :email_domain: in ('mailinator.com', 'guerrillamail.com', 'tempmail.com')
5//
6// Block payments from specific countries:
7// Block if :card_country: in ('XX', 'YY')
8//
9// Block payments over a threshold from new customers:
10// Block if :is_new_customer: and :amount_in_usd: > 500
11//
12// Block if CVC check fails:
13// Block if :cvc_check: = 'fail'
14//
15// Block if ZIP code does not match:
16// Block if :zip_check: = 'fail' and :amount_in_usd: > 100
17
18console.log('Create these rules in Dashboard → Radar → Rules');

Expected result: Custom rules are created in the Radar Dashboard and will apply to all future payments.

3

Manage block lists via the API

Add specific emails, card fingerprints, or IP addresses to block lists using the Stripe API. Blocked entries are checked on every payment.

typescript
1// Add an email to the block list
2async function blockEmail(email) {
3 const rule = await stripe.radar.valueListItems.create({
4 value_list: 'rsl_blockedEmails', // Create this list first in Dashboard
5 value: email,
6 });
7 console.log('Blocked email:', rule.value);
8}
9
10// Add a card fingerprint to the block list
11async function blockCard(cardFingerprint) {
12 const rule = await stripe.radar.valueListItems.create({
13 value_list: 'rsl_blockedCards',
14 value: cardFingerprint,
15 });
16 console.log('Blocked card fingerprint:', rule.value);
17}
18
19// Create a value list first
20async function createBlockList() {
21 const list = await stripe.radar.valueLists.create({
22 alias: 'blocked_emails',
23 name: 'Blocked Emails',
24 item_type: 'email',
25 });
26 console.log('Block list created:', list.id);
27}
28
29createBlockList();

Expected result: Block lists are created and populated. Any payment from a blocked email or card is automatically declined.

4

Handle blocked payments in your webhook

When Radar blocks a payment, you receive a charge.failed or payment_intent.payment_failed event with an outcome type of 'blocked'. Handle this in your webhook to log fraud attempts.

typescript
1const express = require('express');
2const app = express();
3
4app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
5 const sig = req.headers['stripe-signature'];
6 let event;
7 try {
8 event = stripe.webhooks.constructEvent(
9 req.body,
10 sig,
11 process.env.STRIPE_WEBHOOK_SECRET
12 );
13 } catch (err) {
14 return res.status(400).send(`Webhook Error: ${err.message}`);
15 }
16
17 if (event.type === 'charge.failed') {
18 const charge = event.data.object;
19 if (charge.outcome && charge.outcome.type === 'blocked') {
20 console.log('FRAUD BLOCKED:', {
21 chargeId: charge.id,
22 riskScore: charge.outcome.risk_score,
23 riskLevel: charge.outcome.risk_level,
24 reason: charge.outcome.reason,
25 email: charge.billing_details?.email,
26 ip: charge.metadata?.customer_ip,
27 });
28 // Log to your fraud monitoring system
29 }
30 }
31
32 res.json({ received: true });
33});
34
35app.listen(3000);

Expected result: Your webhook handler logs all Radar-blocked payments for fraud monitoring and investigation.

Complete working example

fraud-blocking.js
1const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
2const express = require('express');
3const app = express();
4
5app.use(express.json());
6
7// Block a customer by email
8app.post('/api/fraud/block-email', async (req, res) => {
9 try {
10 const item = await stripe.radar.valueListItems.create({
11 value_list: req.body.listId,
12 value: req.body.email,
13 });
14 res.json({ blocked: item.value });
15 } catch (err) {
16 res.status(400).json({ error: err.message });
17 }
18});
19
20// List all blocked items
21app.get('/api/fraud/blocked/:listId', async (req, res) => {
22 try {
23 const items = await stripe.radar.valueListItems.list({
24 value_list: req.params.listId,
25 limit: 100,
26 });
27 res.json(items.data.map(i => ({ id: i.id, value: i.value })));
28 } catch (err) {
29 res.status(400).json({ error: err.message });
30 }
31});
32
33// Remove a block
34app.delete('/api/fraud/unblock/:itemId', async (req, res) => {
35 try {
36 await stripe.radar.valueListItems.del(req.params.itemId);
37 res.json({ unblocked: true });
38 } catch (err) {
39 res.status(400).json({ error: err.message });
40 }
41});
42
43// Webhook for fraud events
44app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
45 const sig = req.headers['stripe-signature'];
46 let event;
47 try {
48 event = stripe.webhooks.constructEvent(
49 req.body, sig, process.env.STRIPE_WEBHOOK_SECRET
50 );
51 } catch (err) {
52 return res.status(400).send(`Webhook Error: ${err.message}`);
53 }
54 if (event.type === 'charge.failed') {
55 const charge = event.data.object;
56 if (charge.outcome?.type === 'blocked') {
57 console.log(`Blocked: ${charge.id} | Risk: ${charge.outcome.risk_score}`);
58 }
59 }
60 if (event.type === 'radar.early_fraud_warning.created') {
61 console.log('Early fraud warning:', event.data.object.charge);
62 }
63 res.json({ received: true });
64});
65
66app.listen(3000, () => console.log('Fraud blocking server on port 3000'));

Common mistakes when blockking fraudulent customers in Stripe

Why it's a problem: Creating overly broad block rules that catch legitimate customers

How to avoid: Start with review rules instead of block rules. Monitor for false positives before promoting to block.

Why it's a problem: Not passing billing details to Stripe for Radar to evaluate

How to avoid: Include email, name, and address in PaymentIntent billing_details. More data gives Radar better fraud detection.

Why it's a problem: Relying solely on Radar without monitoring blocked charges

How to avoid: Set up webhooks for charge.failed and radar.early_fraud_warning.created to track and investigate fraud patterns.

Why it's a problem: Blocking by IP address only, which catches users behind shared IPs

How to avoid: Use multiple signals (email, card fingerprint, device fingerprint) rather than IP alone.

Best practices

  • Pass billing_details (email, name, address) on every PaymentIntent for better Radar accuracy
  • Start with review rules and promote to block rules after confirming the pattern
  • Use Radar value lists for dynamic blocking instead of hardcoding blocked emails
  • Monitor the radar.early_fraud_warning.created webhook for proactive fraud detection
  • Review Radar's blocked and elevated-risk payments weekly to tune your rules
  • Combine CVC and ZIP checks with amount thresholds for nuanced fraud prevention
  • For high-volume businesses, consider Radar for Fraud Teams for manual review queues

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

How do I block fraudulent customers in Stripe? I want to use Radar rules to block specific emails, card fingerprints, and high-risk patterns. Show me how to create block lists via the API in Node.js.

Stripe Prompt

Help me set up fraud blocking for my Stripe integration. I need custom Radar rules, block lists for emails and card fingerprints, a webhook handler for blocked charges, and an API for managing the block list. Use Node.js.

Frequently asked questions

Is Stripe Radar free?

Basic Radar is included with every Stripe account at no extra cost. Radar for Fraud Teams, which adds manual review queues and advanced rules, costs $0.07 per screened transaction.

Can I block an entire country with Radar?

Yes. Create a rule like 'Block if :card_country: in (XX, YY)' where XX and YY are ISO country codes. Be careful as this blocks all legitimate customers from those countries too.

How do I unblock a customer who was incorrectly blocked?

Remove their email, card fingerprint, or IP from the Radar value list via Dashboard or API. The next payment attempt from that customer will be evaluated normally.

What is a card fingerprint?

A card fingerprint is a unique hash of the card number. Different customers using the same card have the same fingerprint, making it useful for blocking specific cards regardless of which account uses them.

Can RapidDev help set up advanced fraud rules?

Yes. RapidDev can help configure Radar rules, build fraud monitoring dashboards, and implement custom fraud detection logic tailored to your business patterns.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.