Every validation request returns a risk_score between 0 and 100. This score is calculated by running multiple independent checks, each contributing a weighted score based on how strongly the signal indicates fraud.
The scoring model
Fidro runs up to 23 checks per request across five categories:
Email checks
| Check | What it detects | Weight |
|---|---|---|
| Disposable email | Throwaway inbox services (Mailinator, Guerrilla Mail, etc.) | Medium |
| Invalid email | Invalid format, missing MX records | High |
| Custom blocklist (email) | Matches your account's email blocklist entries | Critical |
IP checks
| Check | What it detects | Weight |
|---|---|---|
| VPN | Commercial VPN services | Medium |
| Proxy | Open proxies and anonymous relays | Medium |
| Tor | Tor exit nodes | High |
| Bad ISP | Hosting providers and suspicious ISPs | Low |
| Bad IP reputation | IPs on known abuse lists | High |
| Custom blocklist (IP) | Matches your account's IP blocklist entries | Critical |
| Geolocation mismatch | IP country differs from billing/expected country | Medium |
Stripe card & payment checks
These run automatically on chargeback prevention, no extra integration needed.
| Check | What it detects | Weight |
|---|---|---|
| Prepaid card | Prepaid/virtual cards (2–4x higher chargeback rates) | Medium |
| AVS mismatch | Address verification failed (address or postal code) | Medium |
| CVC failure | Card security code check failed | High |
| Stripe Radar flag | Stripe's own risk assessment flagged the transaction | High |
| Card/IP country mismatch | Card issuing country differs from IP geolocation | Medium |
| Billing/card country mismatch | Billing address country differs from card country | High |
| High-value transaction | Amount exceeds $500 (severity scales with amount) | Medium |
| Transaction velocity | 3+ transactions from same email/IP in 60 minutes | Medium |
| New customer | No previous transactions from this email | Low |
| Card reuse | Same card (by Stripe fingerprint) used across 2+ other customer emails in 30 days | High |
| Card velocity | 3+ charges on the same card in 24 hours | Medium |
| Card testing | Same customer using 3+ different cards in 24 hours | High |
| Custom blocklist (card) | Card fingerprint matches your account's blocklist entries | Critical |
The card fingerprint checks are covered in depth in Card Fingerprint Tracking.
Anomaly checks
These only run on /validate calls that carry an event or a user_id, and they look at your account's own history rather than at the email or IP in isolation. See Velocity and Anomalies for the exact rules.
| Check | What it detects | Weight |
|---|---|---|
| IP signup burst | 3+ signups from one IP in an hour, or 5+ in 24 hours | +40, floors at challenge |
| Email pattern burst | 3+ signups in 24 hours whose addresses reduce to one pattern (sam+1@, s.a.m@, sam42@) |
+40, floors at challenge |
| Impossible travel | One user_id seen from two countries within 60 minutes |
+30, floors at challenge |
| Subnet signup burst | 5+ signups from one /24 in an hour | +20 |
| Shared IP | 5+ different user_ids from one IP in 24 hours |
+20 |
| New country for user | An established user (3+ events from one country) appears from another | +15 |
Optional merchant metadata checks
These only run when you pass additional metadata on your Stripe PaymentIntent. See Passing Customer Metadata for setup.
| Check | What it detects | Weight |
|---|---|---|
| New account | Customer account created less than 30 minutes ago | Medium |
| No phone number | Customer has no phone on file (only scored when you send other metadata) | Low |
| Device velocity | Same device fingerprint used across 3+ different emails in 24 hours | Medium |
| Short session | Checkout completed in under 30 seconds (bot/automation signal) | Medium |
How scores combine
Each failed check adds points to the score. Checks are weighted by fraud correlation and adjusted by severity, a Tor exit node is a stronger fraud signal than a missing phone number.
The final score is capped at 100. Multiple moderate signals can combine to push a user into the middle range even if no single check is alarming on its own.
Score ranges and recommendations
Signup and login validation (/api/validate):
| Score | Recommendation | Meaning |
|---|---|---|
| 0 to 49 | allow |
Low risk, proceed normally |
| 50 to 79 | challenge |
Medium risk, add friction or send to a review queue |
| 80 to 100 | block |
High risk, reject |
An anomaly with a floor (IP signup burst, email pattern burst, impossible travel) returns at least challenge whatever the score.
Stripe chargeback prevention uses its own labels on the same 0 to 100 scale:
| Score | Recommendation | Meaning |
|---|---|---|
| 0 to 40 | allow |
Low risk, let the payment stand |
| 41 to 70 | review |
Medium risk, flag for manual review |
| 71 to 100 | refund |
High risk, auto-refund if enabled |
The chargeback thresholds are configurable in your chargeback settings if you're on the Pro plan.
Reading check results
The data.checks array in the response shows exactly which checks ran and what they found:
{
"risk_score": 72,
"recommendation": "refund",
"data": {
"checks": [
{
"name": "disposable_email",
"passed": false,
"score": 25,
"detail": "Domain mailinator.com is a known disposable email provider"
},
{
"name": "prepaid_card",
"passed": false,
"score": 30,
"detail": "Prepaid card detected"
},
{
"name": "avs_mismatch",
"passed": false,
"score": 35,
"detail": "Address verification failed"
}
]
}
}
Use these details to build custom logic, for example, you might allow prepaid cards but always block disposable emails combined with AVS failures.
Tips for tuning
- Start with defaults. The built-in thresholds are calibrated across thousands of real-world fraud patterns.
- Monitor your review queue. If you're reviewing too many legitimate users, consider raising your review threshold.
- Use blocklists. If you see repeat offenders, add them to your custom blocklist for instant blocking on future attempts.
- Pass optional metadata. Adding account age, order count, and device fingerprint data gives Fidro significantly more signal for chargeback scoring.