Building Fraud Rules
- Start with six rules. Amount ceilings, velocity limits, country mismatch, repeated declines, new-account risk
- Use allow and block lists to override decisions for trusted customers and confirmed fraudsters
- Shadow mode everything before enforcing. Plan the sample and follow-up window; two weeks alone isn't proof
- Lifecycle: Create, Shadow, Live, Tune, Retire. Monthly reviews keep the set healthy
- Rules are your first line. They catch known patterns, and ML catches the rest
Rules turn "we know this is fraud" into automated decisions. They're fast to deploy and easy to explain, and they only catch the patterns you already understand. That's the tradeoff, not a flaw.
Here's a working starter set. Then list management, then the full lifecycle from creation to retirement.
For the theory behind rules vs. ML, see Rules vs. ML. For velocity tuning, see Velocity Rules, and for platform syntax, see Processor Rules Configuration.
How Fraud Rules Work
Rule Anatomy
Every fraud rule has three parts: a condition (what to check), an action (what to do), and a threshold (where to draw the line). The amounts, counts, score bands and list lifetimes below are illustrative starting settings. Choose them from your own order distribution, confirmed fraud and review capacity, then test before enforcing.
RULE: High-value new customer
CONDITION: account_age < 30 days AND order_total > $300
ACTION: review
THRESHOLD: any match
RATIONALE: Test whether new, high-value accounts contain enough confirmed fraud to justify review
The condition reads transaction data in real time. The action fires when the condition is true, and the threshold sets the sensitivity.
Decision Actions
Most fraud systems support these actions:
| Action | What Happens | When to Use |
|---|---|---|
| Approve | Transaction proceeds normally | Low-risk, trusted customers |
| Review | Transaction queued for manual inspection | Ambiguous signals, medium risk |
| Decline | Transaction rejected | High confidence of fraud |
| Request 3DS | Trigger authentication challenge | Moderate risk, want liability shift |
When several rules fire on one transaction, the highest-risk action wins, so if one says "review" and another says "decline," it gets declined. Allow list entries are the one exception, and they override everything else (see Allow Lists below).
How Rules Map Across Vendors
The concepts are the same everywhere. The syntax differs.
| Concept | Stripe Radar | Sift | Forter | Adyen |
|---|---|---|---|---|
| Block a transaction | Block if ... | Workflow: set decision = "block" | Decision rule: Decline | Risk rule: Refuse |
| Send to review | Review if ... | Workflow: set decision = "watch" | Decision rule: Manual Review | Risk rule: Review |
| Allow a trusted customer | Allow if ... | Allow list + workflow | Approve list | Risk rule: Accept |
| Trigger 3DS | Request 3D Secure if ... | Not native (use processor) | Not native (use processor) | Risk rule: 3D Secure |
| Score threshold | :risk_score: > 75 | abuse_score > 75 | Confidence < 60% | Risk score > threshold |
On a processor like Stripe or Adyen, you build rules in their dashboard. On a standalone vendor like Sift or Forter, you build them in the vendor's console, which then passes its decision back to your processor. Until your fraud outgrows the processor's own tools, build in the processor dashboard. A standalone vendor is a second bill and a second console you don't need yet. See Processor Rules Configuration for platform-specific setup.
Your Day-One Rule Set
These six rules are candidates to test, not a ready-made defense. Deploy them in shadow mode first (see Shadow Mode below). Choose the rule that addresses a pattern you've actually seen. A rule that declines orders saves review time, but can still block good customers.
Rule 1: Transaction Amount Ceiling
Flag unusually large orders for review. Fraudsters maximize value per stolen card.
RULE: high_value_review
IF order_total > $X
THEN review
Choose $X from your normal high-value orders and the loss you can absorb. For illustration, $300 is 3.75x an $80 AOV. Shadow that amount and check which legitimate orders it catches before using it.
What it catches: Stolen card purchases. Fraudsters buy the most expensive thing they can.
Stripe Radar:
Review if :amount_in_usd: > 300
Rule 2: Hourly Velocity Limit
Several charges on one card in a short window. That's usually automation, or card testing.
RULE: card_velocity_hourly
IF transactions_per_card_1hr > 3
THEN decline
What it catches: Card testing attacks, automated purchases with stolen cards.
Stripe Radar:
Block if :total_charges_per_card_number_hourly: > 3
See Velocity Rules for tuning windows and thresholds by business type.
Rule 3: Daily Velocity Limit
A broader window catches slower attacks that dodge hourly limits.
RULE: card_velocity_daily
IF transactions_per_card_24hr > 10
THEN review
What it catches: Distributed card testing. Repeated small purchases off one stolen card.
Stripe Radar:
Review if :total_charges_per_card_number_daily: > 10
Rule 4: Country Mismatch
The card's issuing country doesn't match the customer's IP. Worth a second look.
RULE: country_mismatch
IF card_country != ip_country
THEN review
What it catches: Cross-border fraud on stolen card numbers. One of the highest-signal indicators there is.
Stripe Radar:
Review if :ip_country: != :card_country:
Travelers, expats and VPN users trigger this constantly. Start with "review," not "decline." Measure confirmed legitimate cases among hits and price the lost margin before tightening. Use the Fraud Metrics definitions, and check Velocity Rules edge cases for VPN and travel patterns.
Rule 5: Repeated Declines
Failed authorization attempts stacked up in minutes. Classic card testing.
RULE: repeated_declines
IF declined_transactions_per_card_10min > 3
THEN decline
What it catches: Fraudsters cycling stolen card numbers to find the live ones.
Stripe Radar:
Block if :total_declined_charges_per_card_number_hourly: > 3
# This attribute counts an hour, not the generic rule's 10-minute window.
# Backtest it separately; the two rules don't measure the same window.
Rule 6: New Account + High Value
Brand new accounts making large purchases are high risk. Real new customers don't start with their biggest order.
RULE: new_account_high_value
IF account_age < 30_days
AND order_total > $300
THEN review
What it catches: Account takeover on a freshly compromised account, synthetic accounts built for fraud, and stolen credentials on new signups.
Stripe Radar:
Review if :seconds_since_first_seen: < 2592000 AND :amount_in_usd: > 300
Putting It Together
| Rule | Condition | Action | Primary Fraud Type |
|---|---|---|---|
| Amount ceiling | order > $X (3-5x AOV) | Review | Stolen card maximization |
| Hourly velocity | More than 3 charges/card/hour | Decline | Card testing |
| Daily velocity | More than 10 charges/card/day | Review | Distributed card testing |
| Country mismatch | card country != IP country | Review | Cross-border fraud |
| Repeated declines | More than 3 declines in 10 min (generic example) | Decline | Card testing |
| New account + high value | account < 30 days + order > $300 | Review | ATO, synthetic identity |
Under $100K/month: Start with processor controls and a rule for a pattern you've actually seen. Check its coverage; a revenue band can't prove that six rules are enough.
$100K-$1M/month: Add product-specific rules (gift cards, electronics) and customer tenure exceptions.
Over $1M/month: Layer these with ML scoring and device fingerprinting. Rules become backstops, not your primary defense.
Device Intelligence as Rule Inputs
The six rules above use transaction data. Amount, velocity, country, decline count, account age. Device intelligence adds a second layer that transaction data can't see. Run a device vendor, or your processor's built-in fingerprinting, and these become rule conditions.
This section shows what's possible. Fields and syntax depend on your vendor. See Device Fingerprinting for the deep dive.
Example: Combining Transaction Rules with Device Signals
A transaction rule catches what happened. A device signal catches how it happened and who did it.
RULE: high_value_new_account (transaction-only)
IF account_age < 30_days AND order_total > $300
THEN review
RULE: high_value_new_account_v2 (with device signals)
IF account_age < 30_days
AND order_total > $300
AND (device_age_hours < 1 OR emulator_detected = true OR vpn_detected = true)
THEN decline
The second version is sharper. New account, high-value order, brand-new device, VPN. That stack beats transaction data on its own.
Signals You Can Use in Rules
Examples of what device platforms expose as rule-able fields.
| Signal Category | Example Rule Conditions | What It Catches |
|---|---|---|
| Device reputation | Device seen on 3+ fraud accounts | Known bad devices, fraud rings |
| Device age | Device first seen < 1 hour ago | Freshly created emulator instances, factory-reset farm devices |
| Emulator/VM | emulator_detected = true | Fraud factories running virtual devices at scale |
| VPN/proxy (deep) | true_ip != visible_ip via WebRTC/TLS analysis | Pierces VPNs to find the real IP. Basic VPN/IP-type detection is available from enrichment APIs without an SDK |
| Remote desktop | remote_software_detected = true | Remote access scams where a fraudster controls the victim's device |
| True IP mismatch | true_ip_country != visible_ip_country | VPN users whose real location differs from their presented location |
| Behavioral anomaly | behavioral_risk = high | Bots, scripted form filling, coached victims |
| Copy-paste in identity fields | name_field_pasted = true | Fraudsters working from stolen data lists (legitimate users type their own name) |
| Multiple accounts per device | accounts_per_device_30d > 3 | Promo abuse, multi-accounting, synthetic identity |
| Sensor anomaly | gyroscope_data = none AND device_type = mobile | Emulator (no physical sensors) or phone farm device on a rack |
Layering Transaction and Device Rules
Use device signals to sharpen the rules you already have. Don't build a separate device rule set.
| Existing Rule | Enhanced With Device Signal | Result |
|---|---|---|
| Country mismatch (card != IP) | + vpn_detected = false | If no VPN, the mismatch is a real geographic discrepancy, not a traveler |
| High-value new account | + device_age > 30_days | New account on a long-established device = lower risk (probably a real person, new to your site) |
| Hourly velocity > 3 | + emulator_detected = true | Velocity from an emulator = almost certainly automated card testing |
| Repeated declines | + accounts_per_device > 5 | Multiple accounts with failed auths from one device = fraud ring testing cards |
On Stripe Radar or Adyen RevenueProtect, the basics are already in your ML score: IP type, device fingerprint, velocity per device. Standalone vendors add the deeper stuff: behavioral biometrics, sensor data, True IP, remote desktop detection. Layer those in when your fraud outgrows the processor tools. See Device Fingerprinting: Choosing a Vendor for when to upgrade.
Data Enrichment as Rule Inputs
The rules above use transaction and device data. Enrichment adds a third layer. Server-side API lookups on the IP, email and phone. Is the IP a datacenter? Is the email disposable? Is the phone a prepaid burner?
These signals are cheap, often free, and need no client-side SDK. That makes enrichment the cheapest of the three layers to add once your six starter rules are live. See Data Enrichment for Fraud Rules for the full catalog, the vendors, and example rules.
Rules That Prevent Fraud Losses
The rules above block fraud. But with friendly fraud the transaction IS legitimate, so blocking it means blocking a real customer. You need two other kinds of rule instead: 3DS for liability shift, and evidence collection so you win the chargeback when it lands.
Preventing fraud and preventing fraud losses aren't the same job. See Defending Against Fraud Losses for the full strategy.
Rules That Trigger 3DS
3DS moves liability to the issuer on fraud chargebacks. So any transaction you'd decline for fraud risk, challenge with 3DS instead. Customer passes, you get the sale and the liability shift. Customer fails, you lost a sale you were declining anyway.
Trigger it selectively, on the transactions most likely to be disputed:
RULE: 3ds_high_value_new_customer
IF account_age < 60_days AND order_total > $200
THEN request_3ds
RATIONALE: New customer + high value = highest chargeback rate segment
RULE: 3ds_high_dispute_category
IF product_category IN (digital_goods, subscriptions, electronics)
THEN request_3ds
RATIONALE: These categories have 2-3x the dispute rate of general retail
RULE: 3ds_repeat_disputer
IF customer_prior_disputes > 0
THEN request_3ds
RATIONALE: Customers who dispute once are 40% likely to dispute again
| Rule | Condition | Why 3DS | Friction Impact |
|---|---|---|---|
| High-value + new customer | account < 60d, order > $200 | Highest friendly fraud segment | Measure frictionless completion on your own issuer mix |
| High-dispute product category | digital goods, subscriptions, electronics | These categories generate the most disputes | Low to medium |
| Prior disputer | customer has 1+ previous disputes | Repeat behavior is predictable | Acceptable (protecting yourself) |
| Moderate risk score | risk_score 50-75 (not high enough to decline) | Grey zone transactions benefit from authentication | Low |
| International + high value | cross-border AND order > $150 | Cross-border disputes are harder to win | Medium (some issuers have higher challenge rates) |
Stripe Radar examples:
Request 3D Secure if :amount_in_usd: > 200 AND :seconds_since_first_seen: < 5184000
Request 3D Secure if :risk_score: > 50
For friendly fraud, 3DS is your strongest defense. The customer authenticated with their own bank, so when they later claim "I didn't make this purchase," liability sits with the issuer. It's your best answer to the most common reason code, fraud (10.4/4837). See 3D Secure for implementation details.
Rules That Trigger Evidence Collection
Not every rule has to block or challenge. Some should quietly escalate evidence collection. Then you're ready when a chargeback lands weeks later.
RULE: evidence_escalation_high_value
IF order_total > $150
THEN require_signature_on_delivery
RATIONALE: Signature confirmation wins "not received" disputes
RULE: evidence_escalation_digital
IF product_type = digital
THEN log_device_fingerprint + log_ip + log_usage_after_delivery
RATIONALE: CE 3.0 requires device/IP match to prior undisputed transactions
RULE: evidence_escalation_subscription_renewal
IF transaction_type = recurring AND renewal_count > 1
THEN send_renewal_reminder_email + log_email_delivery
RATIONALE: "I cancelled" is the #1 subscription dispute. Renewal reminder email with confirmed delivery defeats it
| Trigger Condition | Evidence Action | What It Defeats |
|---|---|---|
| Order > $150 (physical goods) | Require signature on delivery | "Not received" (Visa 13.1, MC 4855) |
| Digital goods delivery | Log device fingerprint, IP, download timestamp | Fraud claim (Visa 10.4) via CE 3.0 |
| Subscription renewal | Send reminder email 7 days before, log delivery receipt | "I cancelled" (Visa 13.2) |
| First purchase from customer | Capture device ID, IP, and link to account | Builds CE 3.0 history for future disputes |
| Order > $500 | Require delivery photo + signature | "Not received" and "not as described" |
| Customer has prior dispute history | Log all post-purchase activity (logins, usage, downloads) | Friendly fraud repeat behavior |
None of these rules add checkout friction. The customer doesn't see a difference. You're storing data you already have, in a form you can pull back when a dispute arrives. The cost is a few lines of integration code, not conversion. See Defending Against Fraud Losses for the full evidence strategy.
Allow Lists and Block Lists
Allow and block lists are manual overrides. They bypass the rule engine entirely. Simple, powerful, and they rot if nobody manages them.
Block Lists
Block lists prevent known bad actors from transacting. Add entries when you have confirmed fraud.
What to block:
| Identifier | When to Block | Notes |
|---|---|---|
| Email address | Confirmed fraud from this email | Fraudsters reuse emails less than you'd think |
| Card hash/fingerprint | Chargeback received, confirmed stolen | Most effective single identifier |
| IP address | Active attack from this IP | Set an expiration (see warning below) |
| Device ID | Device linked to multiple fraud incidents | Requires device fingerprinting |
| Shipping address | Known reshipping address | Common with package forwarding fraud |
If you only maintain one of these, maintain the card hash list. Every other identifier expires, some in as little as 30 days. A card that produced a chargeback stays compromised.
When to add entries:
- Confirmed chargeback (automatic in most processors)
- Manual review confirms fraud (reviewer marks as fraudulent)
- Fraud reported by customer (e.g., "I didn't make this purchase")
Expiration policy:
| Entry Type | Recommended Expiration |
|---|---|
| Card hash | Permanent (card is compromised) |
| 12 months, then review | |
| IP address | 30-90 days |
| Device ID | 6 months |
| Shipping address | 6 months, then review |
Set expiration dates on IP and device blocks. A fraudster's IP today is an innocent customer's IP tomorrow. Shared IPs can take out thousands of real users. VPNs, corporate networks, mobile carriers. Review the list quarterly and prune it.
Allow Lists
Allow lists let trusted customers bypass rules that would otherwise flag them. Use them sparingly, because an allow list entry nobody prunes is a fraud backdoor with your own signature on it.
What to allow:
| Identifier | When to Allow | Scope |
|---|---|---|
| Customer ID | Verified repeat customer with clean history | Time-capped (12 months) |
| Email domain | Your own corporate domain, trusted partners | Permanent |
| Card fingerprint | Customer's primary card, verified via support | Transaction cap ($5,000/month) |
Precedence: Allow list entries override block rules. A customer on the allow list who trips a velocity rule still gets through.
Bounded scope: Don't give unlimited allow list access. Set limits:
- Time cap: Allow list entry expires after 12 months
- Spend cap: Allow list bypasses rules only up to $X per month
- Rule cap: Allow list bypasses velocity rules but NOT amount ceilings
Automatic vs. Manual Management
| Trigger | Action | Manual or Auto |
|---|---|---|
| Chargeback received | Add card hash to block list | Automatic (most processors do this) |
| Review confirms fraud | Add email + device to block list | Manual (reviewer action) |
| Review confirms legitimate | Add customer to allow list | Manual (reviewer action) |
| Block list entry expires | Remove from block list | Automatic (TTL-based) |
| Customer contacts support about block | Investigate, potentially add to allow list | Manual |
Everything a reviewer decides stays manual on purpose. An automatic block on anything softer than a confirmed chargeback will eventually take out a real customer, and nobody will know why.
On a paid Radar tier (Standard, Plus or Pro), lists live under Dashboard > Radar > Lists. Radar Lite ships free with Stripe Payments and doesn't do lists. Build custom lists of emails, card fingerprints or IPs, then call them in rules:
Block if :email: in @block_list
Allow if :customer_id: in @trusted_customers
For other processors, see Processor Rules Configuration.
Shadow Mode: Test Before You Block
In shadow mode a rule fires and logs the result. It doesn't block anything. Every rule should spend time there before it goes live. Skip it and you learn about false positives from customer complaints, not your dashboard.
The Decision Framework
Deploy each new rule in shadow mode. Plan how much comparable traffic and follow-up you need, then analyze:
- Fraud coverage: Which confirmed fraud cases would it catch that existing controls miss?
- Customer cost: What margin and repeat business would you lose on confirmed good orders?
- Review load: Can you investigate the cases before fulfillment deadlines?
Use the Fraud Metrics definitions, with unknown outcomes separate. Set the cost and capacity limits before testing. Neither a fixed fraud-in-hits percentage nor a fixed share of traffic tells you to enforce.
Promoting a rule is a live change. Two weeks of hits haven't had time to turn into chargebacks yet, so set the owner, the loss cap and the outcome window first (before any live test).
The full 4-week method lives in Velocity Rules: How to Actually Test a Rule. Shadow, analyze, enforce, monitor, plus backtest math and sample sizes. The process is the same for any rule type.
Stripe doesn't have a native shadow mode toggle. Write a Review rule instead of a Block rule. Review flags a transaction without blocking it. After two weeks, read the queue to see what you'd have caught.
For Adyen, use the simulation feature in RevenueProtect. It runs rules against historical transactions.
The Rule Lifecycle
Rules are never "done." They follow a lifecycle from creation to retirement.
| Stage | Duration | Key Activity |
|---|---|---|
| Create | Your planning time | Write a rule based on an observed fraud pattern |
| Shadow | Until the planned sample and outcome window are ready | Measure trigger rate, fraud-in-hits and unknown outcomes |
| Live | Ongoing | Rule actively blocking or reviewing transactions |
| Tune | Monthly starting cadence | Adjust from measured losses, customer impact and review load |
| Retire | When coverage is no longer useful | Review inactive rules against seasonal and returning attacks |
Monthly Review Checklist
Run this every month to keep your rule set healthy:
□ Pull trigger rate per rule
- Which rules are firing most?
- Has a rule's block rate moved outside its planned range?
□ Check fraud caught vs. false positives per rule
- Are outcomes mature, and are unknowns shown separately?
- Does prevented loss justify lost good-order margin and review time?
- If a budget is breached: pause or roll back as agreed before launch
□ Test changes before tightening or loosening
- Low false positives alone don't prove tighter rules will pay
- High false positives: investigate affected customers and conditions
- Keep the owner, loss cap and rollback in place
□ Review rules that haven't triggered in your chosen lookback window
- Check whether the pattern disappeared or is seasonal
- Keep a log of retired rules in case the pattern returns
- Keep a log of retired rules in case the pattern returns
□ Check for new fraud patterns not covered by existing rules
- Review recent chargebacks: what got through?
- Talk to your review team: what patterns are they seeing?
For processor-specific review processes, see Processor Rules Configuration: Monthly Review.
When to Create New Rules
New rules come from patterns you've watched happen, not guesses:
- Chargeback analysis reveals a pattern (e.g., all recent chargebacks came from accounts under 7 days old)
- Review team flags a trend (e.g., "we're seeing a lot of gift card orders from the same IP range")
- Fraud attack post-mortem (e.g., "this attack would have been caught by a BIN-range rule") - see Survive a Fraud Attack
- Industry alert (e.g., new fraud technique targeting your product category)
Getting Started
One order looks risky and you want a checklist, not a rule? Use AI on suspicious orders and scam messages; the decision stays yours.
Just getting started?
- Deploy the day-one rule set in shadow mode
- Set up your block list to auto-add on chargebacks
- Review shadow results after 2 weeks
Do next
- Running Fraud Operations - Daily/weekly/monthly operational cadence
- Manual Review - Managing the review queue
- Fraud Model Feedback - How your vendor's ML learns from your data
Look up
- Experimentation - A/B testing rule changes
Deeper
- Fraud Metrics - Measuring rule effectiveness
Rules deployed but need tuning?
- Run the monthly review checklist
- Check your allow list scope and expiration dates