Understand and tune fraud controls
The fraud floor runs inside checkout, before any money moves. It has two parts with two very different control surfaces:
- AVS/CVV decisioning and velocity — automatic at checkout, tuned through your store manifest, not an API.
- A blocklist (bans) — a real merchant API you call directly, scoped
manage:own_fraud.
A banned entity is refused at checkout with the same generic decline a normal card decline produces. There is no way to probe “is this email banned?” through checkout, and no raw email, IP, or card number is ever stored — every subject is kept only as a tenant-salted fingerprint.
What is automatic: AVS/CVV and velocity
When a checkout is placed, the fraud floor consults bans first, then velocity,
both before any tender is charged. The policy it enforces comes from your store
manifest’s behavior.fraud block, which the storefront resolves and forwards
into the checkout request. You do not call a fraud API to change this — you
change the manifest.
The shape is:
{
"behavior": {
"fraud": {
"avsPolicy": "warn",
"cvvPolicy": "enforce",
"velocity": { "maxPerWindow": 10, "windowMinutes": 10 }
}
}
}avsPolicy/cvvPolicyare eachoff,warn, orenforce.enforcedeclines on a failing gateway code;warnrecords but allows;offdisables the check.velocity.maxPerWindowis the number of order attempts allowed insidewindowMinutesbefore the next attempt is blocked. Setting either to0disables velocity.
The backend default is permissive: AVS and CVV off, velocity disabled. Nothing
is enforced until your manifest declares it. A realistic starting point is
cvvPolicy: "enforce", avsPolicy: "warn", and a 10-per-10-minute velocity
cap. A malformed value for any single key degrades to that key’s default rather
than failing the checkout.
Velocity is a sliding window: once the earlier attempts age out past
windowMinutes, the block recovers on its own. A fraud read that cannot
complete fails the checkout closed (503) rather than silently allowing it.
What you manage: the blocklist
Bans are a merchant API mounted under /v1/merchant/fraud, scoped
manage:own_fraud. You can ban an ip, email, card_fingerprint, or
person.
Add a ban
Send the raw subject as value; the platform fingerprints it before storing.
For card_fingerprint, pass the fingerprint copied from your fraud audit trail,
not a raw card number.
curl -X POST https://api.ruo.pro/v1/merchant/fraud/bans \
-H "Authorization: Bearer fdk_your_key_here" \
-H "content-type: application/json" \
-d '{ "entity_type": "email", "value": "abuse@example.com", "reason": "chargeback ring" }'The response returns ban_id, entity_type, an entity_hash_preview (never the
raw value), reason, created_at, and replayed. Re-adding an already-active
subject is idempotent — it returns the existing ban with replayed: true.
List your active bans
curl https://api.ruo.pro/v1/merchant/fraud/bans \
-H "Authorization: Bearer fdk_your_key_here"Only fingerprint previews come back — there is no reverse lookup from a ban row to the plaintext subject.
Lift a ban
curl -X DELETE https://api.ruo.pro/v1/merchant/fraud/bans/{id} \
-H "Authorization: Bearer fdk_your_key_here"A ban id that is not active returns 404 ban_not_found.
What is automatic vs. what you configure
- Automatic at checkout: ban enforcement, AVS/CVV decisioning, and sliding-window velocity — all before capture, all fail-closed on a read error.
- Tuned via manifest (
behavior.fraud): AVS/CVV modes and velocity thresholds. - Managed via API (
manage:own_fraud): your blocklist of banned subjects.
Related
- Fraud reference — the append-only attempt log, blocklist model, and decisioning seam in detail.
- Quickstart — credentials and the base URL.