Antifraud
Velocity protection, client blocking, FTD/STD/TRUSTED/VIP segmentation, device fingerprinting, and trust-based cascade routing
Antifraud
Syncra V2 includes a layered antifraud stack: payment creation rate limiting (velocity), blocking of abusive clients, automatic client segmentation by trust level, device fingerprinting, and cascade routing by client type. These mechanisms run on the backend side and are transparent to the merchant — but you can extend their effectiveness by passing extra headers when creating a PayIn.
Overview
The antifraud functionality solves four tasks:
- Payment spam protection (velocity) — one
client_idcannot create more than 10 PayIn per hour. - Fraudster blocking — an administrator can block a client forever or for a set period.
- Trust segmentation — clients are automatically promoted through
the
FTD → STD → TRUSTEDtiers as deposits succeed;VIPis a manual assignment. - Device tracking — IP, User-Agent, and the device's SHA-256 fingerprint are stored on the client record.
This data also feeds trust-based cascade routing: cascade rules can
filter teams by customer_type, routing VIP clients to vetted traders.
Velocity protection
Velocity protection prevents DDoS attacks through mass PayIn creation
by a single client. The limit is hard-coded in the domain: one
client_id cannot create more than 10 PayIn within a sliding 1-hour
window.
How it works
- The check runs before the deal is saved to the DB — a rejected request leaves no zombie records and takes no trader slot.
- The limit applies only to known clients (
client_idis not empty). Anonymous PayIn pass without a check. - The protection is fail-open on a DB error: a temporary storage outage does not block legitimate money — but the incident is logged.
What happens when the limit is exceeded
The CreateMerchantPayIn request returns an error (RFC 9457
problem+json):
HTTP/1.1 429 Too Many Requests
{
"type": "about:blank",
"title": "Too Many Requests",
"status": 429,
"detail": "client rate limit exceeded: velocity ceiling of 10 PayIn/hour reached",
"instance": "/api/v1/p2p/merchant/deals/payin"
}What the merchant should do
- Do not retry the request immediately — the client has already exhausted the limit (see the retry matrix).
- Show the client a "too many attempts, try again later" message.
- The limit resets on a sliding window — in an hour, the capability returns.
Customer blocking
An administrator can block a client (IsBlocked = true) with a deadline
(BlockedUntil) or indefinitely. A blocked client cannot create new
payments or open checkout.
Blocking logic
A client counts as blocked when this condition holds:
IsBlocked == true
AND (BlockedUntil == nil // indefinite block
OR BlockedUntil > now()) // a timed block is still activeBlockedUntil == nil— blocked forever (manual unblock only).BlockedUntilin the future — blocked until the given date.BlockedUntilin the past — the block has expired, and the client is active again.
Error on a payment attempt
HTTP/1.1 403 Forbidden
{
"type": "about:blank",
"title": "Forbidden",
"status": 403,
"detail": "customer is blocked",
"instance": "/api/v1/p2p/merchant/deals/payin"
}Managing blocks
Blocking is managed only through the Syncra admin panel (the Customers section). The merchant API does not allow merchants to block clients on their own — the decision is made by the support team based on antifraud analytics.
Client segmentation (FTD / STD / TRUSTED / VIP)
Every client has a type (customer_type) reflecting their trust level.
Segmentation is used for cascade routing and analytics.
The four tiers
| Type | Stands for | How it is assigned |
|---|---|---|
FTD | First-Time Depositor | The default type for new clients. |
STD | Standard Depositor | Automatically after 3 deposits. |
TRUSTED | Trusted | Automatically after 10 deposits. The top of the automatic ladder. |
VIP | VIP | Manual assignment by an administrator only. Never changes automatically (neither up nor down). |
Automatic segmentation
When a PayIn deal reaches the COMPLETED status, the backend increments
the client's deposit counter and checks the threshold:
FTD → STD at DepositCount >= 3
STD → TRUSTED at DepositCount >= 10
TRUSTED / VIP — manual control, no auto-promotionThe thresholds are fixed in the specification (Phase 5). TRUSTED is
the top of the automatic ladder: beyond it, only manual VIP. VIP is
never demoted automatically — it is an explicit administrative
override.
Example: client lifecycle
New client → FTD (1 deposit)
→ FTD (2 deposits)
3rd successful deposit → STD (auto-promotion)
...
10th deposit → TRUSTED (auto-promotion)
...
Admin decision → VIP (manual override)Device fingerprinting
A device fingerprint is a SHA-256 hash of the client's device
characteristics, sent by the payform SPA. It is stored in the client
record's LastFingerprint field and used for session linking and
antifraud analytics.
The fingerprint is stored only as a SHA-256 hash, with no raw canvas/WebGL/personal data. This is a GDPR-compliant approach: the hash is irreversible and cannot restore personal information.
How to pass the fingerprint
The Payform SPA sends the fingerprint automatically. If you use your own frontend, pass the header when creating a PayIn or when opening checkout:
X-Player-Fingerprint: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1bThe header is read by the backend from gRPC metadata
(x-player-fingerprint or grpcgateway-x-player-fingerprint for the
REST gateway) and passed to the provider's UpdatePayer if the adapter
supports payer enrichment.
Player tracking (IP and User-Agent)
Besides the fingerprint, Syncra records the client's network attributes for antifraud analytics:
| Client field | Source | Header |
|---|---|---|
FirstIP / LastIP | The client's IP address | X-Forwarded-For (fallback: X-Real-IP) |
LastUserAgent | The browser's User-Agent string | User-Agent |
FirstSeen / LastSeen | Timestamps of the first and the latest visit | Computed by the backend |
These fields are updated at every client touch (PayIn creation, checkout opening). IP and UA are used to detect suspicious activity (for example, geo switches, emulators).
Request example with full tracking
curl -X POST https://api.syncra.money/api/v1/p2p/merchant/deals/payin \
-H "X-Merchant-Token: $TOKEN" \
-H "X-Timestamp: $TS" \
-H "X-Signature: t=$TS,v1=$SIG" \
-H "Content-Type: application/json" \
-H "X-Player-Fingerprint: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b" \
-d '{
"amount": 150000,
"currency": "RUB",
"client_id": "player_9921",
"idempotency_key": "f3b8a1c2-4d5e-4f6a-9b0c-1d2e3f4a5b6c"
}'X-Forwarded-For and User-Agent are usually set automatically by the
HTTP gateway/browser — you do not need to set them manually.
X-Player-Fingerprint is the only header you must pass explicitly
(when you use your own frontend; the payform SPA does it on its own).
Trust-based cascade routing
Cascade rules (CascadeRule) can additionally filter teams by client
type (customer_type). This lets you route VIP clients to vetted trader
teams and new clients to a wider network.
Matching logic
The customer_type field in a cascade rule works like this:
customer_typeempty/absent — a universal rule; it matches all client types. Backward-compatible with rules created before segmentation was introduced.customer_type = "VIP"— the rule applies only to VIP clients.- Unknown client (
client_idempty, type not determined) — matches only universal rules.
Cascade configuration example
| Priority | Merchant | PaymentMethod | Team | CustomerType | Purpose |
|---|---|---|---|---|---|
| 1 | Merchant A | SBP | Team Gold | VIP | VIP → premium team |
| 2 | Merchant A | SBP | Team Beta | TRUSTED | Trusted → experienced team |
| 3 | Merchant A | SBP | Team Pool | (empty) | Everyone else → the pool |
The cascade router iterates the rules by priority ASC and picks the
first team with eligible on-shift traders and a matching
customer_type.
The customer_type setting in a cascade rule is configured through the
admin panel (the Cascade Rules section). The merchant API does not
allow editing cascades — this is tenant-level routing configuration.
Antifraud error summary
| Error | HTTP | When it occurs | Retry? |
|---|---|---|---|
CLIENT_RATE_LIMITED | 429 | client_id exceeded 10 PayIn/hour | Yes, with backoff |
CUSTOMER_BLOCKED | 403 | The client is blocked (IsBlocked = true, the block has not expired) | No |
The full reference of codes and retry strategies is in Error codes.
Related materials
- Error codes — the full
reference, including
CLIENT_RATE_LIMITEDandCUSTOMER_BLOCKED. - Accepting payments (PayIn) — creating a PayIn with tracking headers.
- Hosted Checkout — payform sends the fingerprint automatically.
- Deals — cascade routing and matching.