Fraud
The fraud module (schema fraud) owns three things no other module wants
to: an append-only order-attempt log for sliding-window velocity checks,
an operator-managed blocklist (bans on ip / email /
card_fingerprint / person), and the pure AVS/CVV + velocity
decisioning that checkout runs before money moves. It is its own module
(not a table inside checkout or payments) because it owns a schema and is a
shared decision surface — checkout composes it
through the published createFraudRepo seam and calls it inside the
order-placement path.
Enrolment and enforcement of velocity + AVS/CVV happen in checkout; this
module supplies the durable state and the pure policy. The AVS/CVV
code->disposition mapping itself lives in payments
(evaluateAvsCvv), because that is where the gateway codes surface.
Privacy / no enumeration oracle: every subject is stored only as a
tenant-salted fingerprint (domain/fingerprint.ts), never in the clear — no
raw email, IP, or PAN is persisted. And checkout refuses a banned entity with
the same generic decline a normal card decline produces, so probing “is
this email banned?” through checkout is impossible.
Operator routes
x-operator-token, rate-limited. Each ban write is audited.
| Method | Path | Purpose |
|---|---|---|
POST | /v1/tenants/:tenant/fraud/bans | Add a ban on an ip/email/card_fingerprint/person subject (stored as a tenant-salted fingerprint). |
GET | /v1/tenants/:tenant/fraud/bans | List the tenant’s active bans (fingerprint previews only). |
DELETE | /v1/tenants/:tenant/fraud/bans/:id | Lift a ban. |
GET | /v1/tenants/:tenant/fraud/velocity-events | Read the tenant’s recent order-attempt velocity events (the append-only sliding-window log). |
GET | /v1/fraud/audit | Operator audit-log read (makeAuditReadRoute). |
Merchant routes
fdk_ credential, tenant from the credential per credential-carries-ownership,
scope manage:own_fraud. Same repo methods as the operator ban routes —
mounted at /v1/merchant/fraud.
| Method | Path | Scope | Purpose |
|---|---|---|---|
GET | /v1/merchant/fraud/bans | manage:own_fraud | List the caller’s bans. |
POST | /v1/merchant/fraud/bans | manage:own_fraud | Add a ban. |
DELETE | /v1/merchant/fraud/bans/:id | manage:own_fraud | Lift a ban. |
Events
| Direction | Event |
|---|---|
| Publishes | (none) |
| Consumes | (none) |
Decisioning is synchronous and in-process (checkout calls the repo on the order-placement path); there is no bus traffic.
Manifest gates
None. Fraud decisioning is a server-side gate inside checkout; it has no storefront manifest toggle.
Seams (honest notes)
- Velocity + AVS/CVV enforcement lives in checkout, not here — this module is the durable state (the attempt log + blocklist) and the pure policy the checkout path consults.
- Bans are keyed to a fingerprint an operator copied from the fraud audit trail, never a raw identifier — there is no reverse lookup from a ban row back to a plaintext email/IP/PAN.