Payment Fraud Prevention
Fraud erodes margins and trust. A layered approach — risk signals, velocity limits, blacklists, and selective manual review — blocks most abuse without hurting good customers. This guide shows the practical patterns.
🚦 Risk Signals
Score each transaction on multiple signals rather than any single rule.
| Signal | Higher risk when |
|---|---|
| Velocity | Many attempts from one user/card/IP |
| Mismatch | Card country ≠ phone/IP country |
| New account | Account age under 24h with high amount |
| Device | Shared device across many accounts |
| BIN/issuer | Known high-fraud BIN ranges |
def risk_score(txn):
score = 0
if txn['attempts_last_hour'] > 3: score += 30
if txn['card_country'] != txn['ip_country']: score += 25
if txn['account_age_hours'] < 24 and txn['amount'] > 20000: score += 25
if txn['device_account_count'] > 5: score += 20
return score
⏱️ Velocity Rules
Cap attempts per identity over a window to stop card testing and abuse.
const limits = { perCardPerHour: 3, perIpPerHour: 10, perUserPerDay: 5 };
async function checkVelocity(txn) {
if (await count('card', txn.card, '1h') >= limits.perCardPerHour) return 'block';
if (await count('ip', txn.ip, '1h') >= limits.perIpPerHour) return 'review';
return 'allow';
}
🚫 Blacklists & Allowlists
Maintain lists keyed by stable identifiers (card fingerprint, email, phone, device).
def precheck(txn):
if txn['card_fingerprint'] in blacklist: return 'block'
if txn['email'] in allowlist: return 'allow' # trusted repeat customer
return 'score'
Add confirmed-fraud identifiers to the blacklist automatically when a chargeback lands.
🧑⚖️ Manual Review Queue
Route medium-risk transactions to a queue instead of auto-deciding. Hold fulfillment until reviewed.
function decide(score) {
if (score >= 70) return 'block';
if (score >= 40) return 'review'; // queue, hold fulfillment
return 'allow';
}
| Decision | Score | Action |
|---|---|---|
| Allow | < 40 | Process normally |
| Review | 40–69 | Hold, queue for human |
| Block | ≥ 70 | Decline immediately |
💡 Best Practices
- Layer signals — never rely on a single rule.
- Tune thresholds with your real chargeback data, not guesses.
- Hold fulfillment for review-tier transactions.
- Auto-blacklist confirmed fraud identifiers.
- Use 3DS to shift liability on risky card charges — see Card Payments.
- Log every decision for audit and appeals.
⚠️ Common Pitfalls
- Over-aggressive rules that block legitimate cross-border African customers.
- Blacklisting by IP alone — easily rotated.
- No feedback loop from chargebacks back into the rules.
📚 Related Resources
Last Updated: May 2026