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

Preview

Suspicious redemptions are held for review instead of silently killed — so a loyal customer who trips a rule doesn't become a lost customer.

CodeCustomerSignalStatus
WELCOME10cus_482112 redemptions in 4 minutesHeld
SPRING20cus_1093Blocklisted email domainBlocked
VIPONLYcus_7710Order total mismatchHeld
WELCOME10cus_2266Velocity limit clearedReleased

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.

Plain-language reasons

When a redemption is held or blocked, the API returns the reason in plain words alongside the machine code — so your support team can explain it without an engineer.

See the fraud model in the docs

Machine-readable error codes, review-queue states, and the rate-limit headers — all documented with examples.