Fraud controls that stay friendly
Abuse gets stopped at the door; real customers never notice the lock. Every decision is explainable — no black boxes, no dark ops panels.
Velocity limits
Redemption attempts are rate-limited at multiple levels, backed by Upstash rate limiting that degrades gracefully.
- Per-code caps — a leaked code stops paying out after N redemptions.
- Per-customer limits — one customer can't stack the same discount endlessly.
- Per-API-key throttling — burst traffic is smoothed before it hits your checkout.
Blocklists
Known-bad actors get rejected at validation — before a discount ever touches an order.
- Block customer references, emails, or domains in one place.
- Retire compromised codes instantly without touching the promotion rules.
- Every blocklist decision is written to the audit log with a reason.
A review queue you'll actually use
PreviewSuspicious redemptions are held for review instead of silently killed — so a loyal customer who trips a rule doesn't become a lost customer.
| Code | Customer | Signal | Status |
|---|---|---|---|
| WELCOME10 | cus_4821 | 12 redemptions in 4 minutes | Held |
| SPRING20 | cus_1093 | Blocklisted email domain | Blocked |
| VIPONLY | cus_7710 | Order total mismatch | Held |
| WELCOME10 | cus_2266 | Velocity limit cleared | Released |
The signals behind every decision
Burst redemptions
Many redemptions of one code in a short window — the classic leaked-code pattern.
Per-customer caps hit
A single customer reference burning through its allowed uses across several codes.
Mismatched order totals
Redeem calls whose order total doesn't match the checkout — a stack-tampering tell.
Disposable contact data
Signups or orders tied to throwaway email addresses placing repeated redemption attempts.
Repeat rejection patterns
The same customer hitting the same rule wall over and over — a sign the code is being gamed.