# Risk controls

> Prepaid credits attract stolen cards. Each brand screens its payments with rules — velocity limits, new-customer limits, blocklists, disposable emails and a risk score — that refuse a payment, ask the bank for 3-D Secure, or hold it for review. Fresh balances can be capped.

Stolen cards are tested on small purchases and cashed out through anything that can be spent at once, and prepaid credits are both. Every brand screens its payments with its own **risk rules**, on top of your processor's own fraud checks (Stripe Radar stays on). The rules run three times during a checkout and once before every auto-reload:

| When                             | What the rules know                                                                            |
| -------------------------------- | ---------------------------------------------------------------------------------------------- |
| Before the payment intent exists | The email, the IP network and country, the billing country, the customer's history, the amount |
| Once the card is entered         | Also the card's fingerprint (from the processor) and its country                               |
| At confirmation                  | The same again, so a blocklist entry added in the meantime still holds                         |
| Before an auto-reload is charged | The customer, the saved card, the reload amount (no IP: the charge is off-session)             |

Each rule that fires has an **action**:

- **Block**: the payment is refused before it reaches the card. The buyer sees "This payment can't be accepted" (`risk_payment_declined`), never which rule: an answer that names the rule teaches a fraudster how to get around it. An auto-reload is skipped (`risk_blocked`).
- **Ask for 3-D Secure**: the payment intent asks the card's bank to authenticate the customer. Off-session charges can't, so they go through.
- **Hold for review**: the payment goes through, and waits in the review queue (below).

## The rules and their defaults

The defaults suit prepaid credits. Test and live mode have their own rules (test mode is a parallel world); the **counting rules** — velocity and the new-customer top-up limits — are on in live mode and off in test mode, where every customer pays with the same few test cards from the developer's own machine. Turn them on in test mode to try them.

| Rule                       | Default                                                                                                                                                            |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| New customers' top-ups     | At most 2 top-ups (payments that buy credits, auto-reloads included) in 24 hours; the third is blocked. A customer is new until their first payment is 7 days old. |
| First top-up               | At most 100 EUR, USD, GBP or CHF; more is blocked. Other currencies have no limit until you set one.                                                               |
| First payment              | 3-D Secure.                                                                                                                                                        |
| One IP network             | At most 10 payment attempts and 3 cards an hour from one /24 (IPv4) or /48 (IPv6) network. Private and loopback networks aren't counted.                           |
| One card                   | At most 5 payment attempts in 24 hours with one card, whoever uses it.                                                                                             |
| One email domain           | At most 10 attempts an hour by new customers of one domain. Large mail providers (gmail.com, outlook.com and others) aren't counted.                               |
| Disposable email addresses | Blocked. The list of throwaway mail services is a maintained data file.                                                                                            |
| Blocklists                 | Always: emails, card fingerprints, IP ranges and countries you list.                                                                                               |
| Customer risk              | A customer whose risk is `blocked` is refused; `elevated` (after a lost dispute) adds 40 points.                                                                   |

A payment attempt is counted once, however many times the rules run for it; each card tried counts for the card rules. A window of N hours counts the current clock hour and the N before it, so it looks back at least N hours.

### The score

Country mismatches add points: the IP country differs from the billing country (20), the card's country from the billing country (25), the IP country from the card's (15). A new customer adds 10, an elevated one 40. At 20 points the payment asks for 3-D Secure, at 75 it is held for review; a block threshold is off until you set one.

Change any of it in **Brand → Risk → Rules**, or with `PATCH /api/v1/risk/settings`. Each rule's action can be any of the three.

## Blocklists

**Brand → Risk → Blocklists** lists the values whose payments are refused:

- `email`: an address, in any case;
- `card_fingerprint`: the processor's fingerprint of a card number, so the card is refused whatever its expiry or the customer using it (a risk evaluation shows it);
- `ip_range`: CIDR such as `203.0.113.0/24`. Ownrecord never keeps a full IP address, only its /24 (or /48) network, so a range is at most that narrow;
- `country`: matched with the IP country, the billing country and the card's country.

Rejecting a held payment adds the customer's email and card for you.

## The review queue

A held payment is recorded, booked and invoiced like any other — the money moved. In the same step:

- the customer's wallet in the payment's currency is **frozen** when the payment bought credits, so they can't be spent yet;
- the customer's risk becomes `elevated`;
- your team gets a `RISK_REVIEW` alert, and your webhook endpoints `risk.review.opened`. Hold the delivery of your own goods until the review is decided.

In **Brand → Risk** each review shows why the rules held it — every reason with its points, the countries, the IP network, the card — and two decisions:

- **Approve** unfreezes the wallet (unless another review of the customer is pending), puts the customer's risk back and sends `risk.review.approved`.
- **Refund and block** refunds the payment exactly as `refunds.create` does (a credit note at the original rates; for credits, the unused ones — the hold kept them unspent), puts the customer's email and card on the blocklist, makes the customer's risk `blocked` and sends `risk.review.rejected`. The wallet stays frozen.

Support approves; rejecting needs refund rights (support up to its limit, finance above it). Over the API: `GET /api/v1/risk/reviews`, `POST /api/v1/risk/reviews/{id}/approve`, `POST /api/v1/risk/reviews/{id}/reject`.

Why any payment attempt was allowed, asked for 3-D Secure, held or refused is in its **risk evaluation**: `GET /api/v1/risk/evaluations?paymentId=…` or `?checkoutSessionId=…`.

## Fresh balances

For high-risk products, cap what can be done with credits bought in the last hours: with `wallet.usageCapUntilAgeHours` (for example 24) and `wallet.usageCap` (for example 10 EUR), credits from a payment younger than that can be reserved or spent up to the cap in total; older credits are never capped. Reservations and leases beyond it are refused with `wallet_fresh_balance_capped` (402) and `details.freeAt`, when the credits stop being fresh. Off by default.
