Automatisation des événements et des récompenses : règles et webhooks
La gamification repose sur deux « moteurs » : les événements (ce que l'utilisateur a fait) et les règles (ce qui compte pour cela). Pour que cela fonctionne à grande échelle et sans erreur, il faut un pneu d'événements fiable, un moteur de règles, un mécanisme de livraison/délivrance de prix et une protection stricte contre les frods. Voici l'architecture pratique, les modèles et les chèques-feuilles.
1) Architecture du flux « événement → règle → récompense »
1. Ingest (connexion d'événements) : SDK/Web, webhooks serveur du payeur/fournisseur de jeux → API Gateway → file d'attente/bus (Kafka/Rabbit/Cloud Pub/Sub).
2. Normalizer : validation, enrichissement (geo, device, payer_flag), version du schéma.
3. Moteur Rules : scoring de lunettes/XR, vérification de missions/quêtes, déclencheurs de récompenses/notifications.
4. Reward Orchestrator : calcul des récompenses, budget-chèque, gates RG/KYC, création d'une « tâche d'émission », entrée dans le journal.
5. Payout/Bonus Service : Cache/Bonus/Frispins/Coupons, webhooks externes (portefeuille, fournisseurs).
6. Notifier : push/in-app/email/messagers avec limites de fréquence.
7. Storage/Analytics : événements bruts, vitrines, A/B, alertes.
8. Anti-Fraud/RG : kaps, heuristiques/ML, hold-and-review des grands prix.
2) Modèle d'événement (ensemble minimum)
json
{
"event_id": "d9e8-...-5c2", "event_name": "bet", "version": "1. 2. 0", "ts": "2025-10-24T11:37:21Z", "user": {
"id": "u_123", "geo": "TR", "platform": "android", "payer_flag": true, "risk_flags": ["vp_nightly"]
}, "context": {
"session_id": "s_789", "device_fp": "fp_...", "ip": "203. 0. 113. 24"
}, "payload": {
"game_id": "slot_wolf", "bet": 0. 5, "win": 1. 25, "currency": "EUR", "provider": "GameCo"
}
}
Базовые типы: `login`, `session_start/end`, `bet/spin`, `win`, `deposit`, `withdraw_request`, `kyc_status_changed`, `mission_view/join/progress/complete`, `tournament_join/score/update/reward`, `reward_issued`, `rg_event`.
3) Moteur de règles : comment décrire la logique
Concepts : règles (if/then), segments, fenêtres temporelles, caps, priorités, versioning.
Exemple de règle déclarative (style YAML) :yaml rule_id: r_points_winmult_v2 when:
event_name: bet filters:
- payload. bet >= 0. 2
- user. geo in ["TR","BR","PE"]
- now between "2025-11-01" and "2025-11-30"
score:
formula: "floor((payload. win / payload. bet) 3)"
caps:
per_bet: 50 per_minute: 200 per_day: 1500 reward_trigger:
on_progress:
threshold: [100, 300, 800]
reward: [{type: "fs", value: 10}, {type: "bonus_cash", value: 2}, {type: "loot", rarity: "rare"}]
guardrails:
kyc_min_level: 2 rg_limits_ok: true budget_pool: "nov_season"
budget_soft_cap: 80000 meta:
version: "2. 0"
experiment: "scoring_ab_2025w45"
4) Webhooks : Serveur d'intégration
4. 1. Webhooks sortants (de vous aux fournisseurs/portefeuille)
Méthode : 'POST https ://partner. example/payouts`
Подпись: `X-Signature: HMAC-SHA256(secret, body)` + `X-Request-Id` (idempotency).
Retrai : exponentielle backoff, 'max _ retries = 8', jitter, DLQ.
Idempotency : Répétition du même 'X-Request-Id' → partenaire doit répondre au même 'payout _ id/status'.
Exemple de payload :json
{
"request_id": "rid_7f5...", "user_id": "u_123", "reward": {"type":"cash","amount":10. 00,"currency":"EUR"}, "reason": "milestone_300_points", "kyc_level": 2, "constraints": {"wagering": 0, "expiry_at": "2025-12-01T00:00:00Z"}
}
4. 2. Webhooks entrants (à vous)
N'autorisez que les listes IP/MTLS, vérifiez le HMAC et la durée de vie de la signature ('X-Timestamp', ± 5 minutes).
Conservez les titres « bruts » dans le référentiel d'audit (WORM).
N'importe quelle prise/répétition → vérifiez la clé d'idempotency contre le journal.
5) Fiabilité : Flux « régulier » sans double paiement
At-least-once sur ingest + processeurs idempotent → standard or.
Idempotency key : 'hash (event_id + user_id + rule_id)' pour l'attribution de points ; une clé séparée pour émettre une récompense 'reward _ task _ id'.
La sémantique exactly-once n'est réaliste que logiquement (par idempotence) et non par transport.
Ordre des événements : stockez 'event _ ts'et' ingest _ ts' ; appliquez reordering window (par exemple 60 secondes) et replay de la file d'attente à la clé 'user _ id'.
Dead Letter Queue (DLQ):- Nous écrivons des messages avec une erreur permanente (le schéma temporel n'est pas passé, la signature n'est pas validée, le budget est fermé).
- Service « revoyez DLQ » avec boutons reprocess/drop/fix schema.
6) Budgets et protection des marges
Pools de budget : 'novembre _ saison', 'daily _ sprint', 'vip _ weekend'.
Quotas : soft/hard cap, « circuit breaker » - lorsque vous atteignez 90 % du budget pour transférer des prix importants à l'état hold.
Coût unique : 'Prix & Bonus Cost per Active/Payor', Net Uplift.
Priorités : RG et conformité sont plus importants que la promo - en cas de conflit, la récompense est reportée.
Exemple de vérification du budget (sketch SQL) :sql
SELECT pool_id, SUM(amount) AS spent, budget AS limit, SUM(amount)/budget AS fill
FROM reward_ledger
WHERE pool_id =:pool AND date(ts) = current_date
GROUP BY pool_id, budget;
7) RG/KYC/Geo-gates (sécurité du joueur et conformité)
KYC : minimum L2 pour le cache/grands prix ; les frispins sont admissibles avec la L1.
RG : vérification des limites de dépôt, d'auto-exclusion, de « cool-off » → des récompenses « gelées » jusqu'à la levée des restrictions.
Geo : liste des pays autorisés pour chaque règle/pool de récompenses.
Alerts de seuil : croissance spectaculaire « presque-atteint » chez les comptes individuels = occasion sur hold & review.
8) Règles antifrod et télémétrie
Caps de lunettes à un taux/min/heure/jour, dispersion minimale des paris, interdiction des patterns « parfaits ».
Signaux techniques : headless, device_fp répétitifs, sous-réseaux proxy.
Anomalies : « lunettes/paris » et « lunettes/min » sont de longues « queues » sur 99-percentile.
Hold-and-review pour les meilleurs lauréats : chèque automatique KYC + vue manuelle.
9) Surveillance, métriques et alertes
SLO/SLA:- Ingest p95 ≤ 250 ms ; traitement de la règle p95 ≤ 150 ms ; mise à jour du leader ≤ 2 s ; délivrance du prix ≤ 60 s.
- Error budget < 0. 1 % d'événements/24 heures.
- SRM sur les expériences (distorsion du trafic), croissance du DLQ, baisse de la signature de validation HMAC, dépassement de budget, surtension des doublons idempotent.
- Événements/s, lag, tolérance aux pannes ;
- Entonnoir : événement → règle → reward_task → reward_issued ;
- Coût : Prix/Bonus par actif, Net Uplift ;
- Qualité : drapeaux frod, blocs KYC, actionnements RG.
10) Versioning et migration
Chaque règle est convertie ('rules. version`).
Vous ne pouvez pas modifier une règle active sans nouvelle version ; utilisez une ficheflag et un « réchauffage en douceur » (10 % → 50 % → 100 %).
Diagramme des événements via schema registry ; les modifications incompatibles ne sont qu'une version majeure.
11) Tests d'automatisation A/B (court)
Unité - utilisateur ; sticky-assignment; stratification (payer/geo/platform).
Les leaders séparés ou la normalisation des lunettes pour éliminer l'interférence.
Primary: participation_net, completion, Net ARPPU; Guardrails : plaintes/1k, drapeaux frod, actionnements RG.
CUPED et covariables pour réduire la dispersion.
12) Exemples : De la règle à la délivrance
12. 1. Déclencheur « micro-récompense du progrès »
json
{
"type": "reward_task. created", "reward_task_id": "rt_456", "user_id": "u_123", "origin": {"rule_id":"r_points_winmult_v2","threshold":300}, "reward": {"type": "bonus_cash", "amount": 2, "currency":"EUR", "wagering": 15}, "pool_id": "nov_season", "status": "pending", "created_at": "2025-10-24T11:38:30Z"
}
12. 2. Webhook sortant sur le portefeuille
POST /wallet/credit
X-Request-Id: rid_7f5...
X-Timestamp: 1730061700
X-Signature: sha256=7b9a...
{ "user_id":"u_123", "amount":2. 00, "currency":"EUR", "reason":"rule:r_points_winmult_v2" }
Succès → 'reward _ task' = 'succeeded' et entrée dans 'reward _ ledger'.
Échec (5xx/timaut) → rétrospective avec le même "X-Request-Id'.
Échec (4xx) → DLQ + analyse manuelle.
13) Dépôts et tableaux (sketch)
sql
-- Journal des prix
CREATE TABLE reward_ledger (
id BIGSERIAL PRIMARY KEY, reward_task_id TEXT UNIQUE, user_id TEXT, pool_id TEXT, type TEXT, value NUMERIC(18,2), currency TEXT, cost NUMERIC(18,2) DEFAULT 0, -- реальная стоимость для P&L status TEXT, -- succeeded/failed/held created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ
);
-- indempotence
CREATE UNIQUE INDEX uniq_reward_task ON reward_ledger (reward_task_id);
-- Budget
CREATE TABLE reward_budget (
pool_id TEXT PRIMARY KEY, budget NUMERIC(18,2), spent NUMERIC(18,2), period DATE
);
14) Sécurité et vie privée
Signatures HMAC, MTLS, allow-list IP.
Cryptage en transit/repos, rotation des clés, secrets en vault.
Minimisation des données dans payload (PII séparément, par token de référence, TTL).
Les logs d'audit sont immuables (WORM).
Politique de stockage et de suppression (droit à l'oubli, déduplication-sécurité).
15) Chèque de démarrage
- Schémas d'événements et de registres, contrats de webhooks (signatures, TTL).
- Files d'attente, retraits, DLQ, manipulateurs idempotent.
- Les kaps/gardes dans les règles, KYC/RG-gates.
- Budget-pools, circuits-breakers, alertes de débordement.
- Dashboards SLO + vortex reward.
- A/B-ficheflagi et surveillance SRM.
- Runbook des incidents (replay, gel, délivrance manuelle).
16) Mini-case (synthétique)
Les événements des fournisseurs de jeux et du portefeuille sont connectés ; le scoring « win/bet » avec les kaps est inclus.
Webhooks signés HMAC, retraits jusqu'à 8 tentatives, DLQ avec rhubarbe toutes les 2 heures
En 4 semaines : Traitement de larme p95 180 ms ; DLQ < 0,06%; doublons de paiement 0 ; drapeaux frod − 0,4 PP ; ΔParticipation_net +6,3 п.п.; ΔARPPU (net) +€2,1 при Prize&Bonus/Active +€0,7.
Conclusion : mise à l'échelle des règles sur de nouveaux géos avec des pools de budget locaux.
L'automatisation des récompenses n'est pas « envoyer push avec des frispins ». C'est un système d'ingénierie : livraison fiable des événements, versioning strict des règles, idempotency et signatures, budget-capers, KYC/RG-gates, antifrod et surveillance. Construisez ce cadre un jour - et toutes les missions, tournois et « moments de luth » fonctionneront de manière prévisible, à temps et avec un effet net positif.