Автоматизация событий и наград: правила и вебхуки
Геймификация держится на двух «моторчиках»: события (что сделал пользователь) и правила (что за это полагается). Чтобы это работало масштабно и безошибочно, нужна надёжная шина событий, движок правил, механизм доставки/выдачи наград и строгая защита от фрода. Ниже — практическая архитектура, шаблоны и чек-листы.
1) Архитектура потока «событие → правило → награда»
1. Ingest (вход событий): SDK/web, серверные вебхуки от платёжки/провайдера игр → API Gateway → очередь/шина (Kafka/Rabbit/Cloud Pub/Sub).
2. Normalizer: валидация, обогащение (geo, device, payer_flag), версия схемы.
3. Rules Engine: скоринг очков/XP, проверка миссий/квестов, триггеры наград/уведомлений.
4. Reward Orchestrator: расчёт награды, бюджет-чек, RG/KYC-гейты, создание «задачи выдачи», запись в журнал.
5. Payout/Bonus Service: кэш/бонус-кэш/фриспины/купоны, внешние вебхуки (кошелёк, провайдеры).
6. Notifier: push/in-app/email/мессенджеры с частотными лимитами.
7. Storage/Analytics: сырые события, витрины, A/B, алерты.
8. Anti-Fraud/RG: капы, эвристики/ML, hold-and-review крупных призов.
2) Модель событий (минимальный набор)
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) Движок правил: как описывать логику
Концепции: правила (if/then), сегменты, окна времени, капы, приоритеты, версионирование.
Пример декларативного правила (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) Вебхуки: сервер-сервер интеграции
4.1. Исходящие вебхуки (от вас к провайдерам/кошельку)
Метод: `POST https://partner.example/payouts`
Подпись: `X-Signature: HMAC-SHA256(secret, body)` + `X-Request-Id` (idempotency).
Ретраи: экспоненциальный backoff, `max_retries=8`, jitter, DLQ.
Idempotency: повтор тот же `X-Request-Id` → партнёр обязан отвечать тем же `payout_id/status`.
Пример 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. Входящие вебхуки (к вам)
Разрешайте только списки IP/MTLS, проверяйте HMAC и время жизни подписи (`X-Timestamp`, ±5 минут).
Сохраняйте «сырой» body + заголовки в аудит-хранилище (WORM).
Любой дубль/повтор → проверяйте idempotency key против журнала.
5) Надёжность: «ровный» поток без двойных выплат
At-least-once на ingest + idempotent обработчики → золотой стандарт.
Idempotency key: `hash(event_id + user_id + rule_id)` для начисления очков; отдельный ключ для выдачи награды `reward_task_id`.
Exactly-once семантика реалистична только логически (через идемпотентность), а не транспортом.
Порядок событий: храните `event_ts` и `ingest_ts`; применяйте reordering window (например, 60 сек) и replay из очереди по ключу `user_id`.
Dead Letter Queue (DLQ):- Пишем туда сообщения с перманентной ошибкой (временная схема не прошла, подпись невалидна, бюджет закрыт).
- Сервис «ревью DLQ» с кнопками reprocess / drop / fix schema.
6) Бюджеты и защита маржи
Пулы бюджетов: `nov_season`, `daily_sprint`, `vip_weekend`.
Квоты: soft/hard cap, «circuit breaker» — при достижении 90% бюджета переводить крупные призы в hold-state.
Единая стоимость: `Prize & Bonus Cost per Active/Payor`, Net Uplift.
Приоритеты: RG и комплаенс важнее промо — при конфликте награда откладывается.
Пример проверки бюджета (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-гейты (безопасность игрока и комплаенс)
KYC: минимум L2 для кэша/крупных призов; фриспины допустимы с L1.
RG: проверка лимитов депозита, самоисключения, «cool-off» → награды «замораживаются» до снятия ограничений.
Geo: список разрешённых стран для каждого правила/пула наград.
Пороговые алерты: резкий рост «почти-достиг» у отдельных аккаунтов = повод на hold & review.
8) Антифрод-правила и телеметрия
Капы очков по ставке/мин/час/сутки, минимальная дисперсия ставок, запрет «идеальных» паттернов.
Техсигналы: headless, повторяющиеся device_fp, прокси-субсети.
Аномалии: «очков/ставок» и «очков/мин» — длинные «хвосты» на 99-перцентиле.
Hold-and-review для топ-призёров: автоматический чек KYC + ручной просмотр.
9) Мониторинг, метрики и алерты
SLO/SLA:- Ingest p95 ≤ 250 мс; обработка правила p95 ≤ 150 мс; обновление лидерборда ≤ 2 с; выдача награды ≤ 60 с.
- Error budget < 0.1% событий/сутки.
- SRM на экспериментах (перекос трафика), рост DLQ, падение подписи HMAC-валидации, превышение бюджета, всплеск idempotent-дублей.
- События/с, лаг, отказоустойчивость;
- Воронка: событие → правило → reward_task → reward_issued;
- Стоимость: Prize/Bonus per Active, Net Uplift;
- Качество: фрод-флаги, KYC-блоки, RG-срабатывания.
10) Версионирование и миграции
Каждое правило — versioned (`rules.version`).
Нельзя редактировать активное правило без новой версии; используйте фичефлаг и «плавный прогрев» (10% → 50% → 100%).
Схема событий через schema registry; несовместимые изменения — только major-версия.
11) A/B-тесты автоматизации (коротко)
Единица — пользователь; sticky-assignment; стратификация (payer/geo/platform).
Раздельные лидерборды или нормализация очков, чтобы исключить интерференцию.
Primary: participation_net, completion, Net ARPPU; Guardrails: жалобы/1k, фрод-флаги, RG-срабатывания.
CUPED и ковариаты для снижения дисперсии.
12) Примеры: от правила до выдачи
12.1. Триггер «микро-награда за прогресс»
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. Исходящий вебхук на кошелёк
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" }
Успех → `reward_task` = `succeeded` и запись в `reward_ledger`.
Провал (5xx/таймаут) → ретрай с тем же `X-Request-Id`.
Провал (4xx) → DLQ + ручной разбор.
13) Хранилища и таблицы (скетч)
sql
-- журнал наград
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
);
-- индемпотентность
CREATE UNIQUE INDEX uniq_reward_task ON reward_ledger (reward_task_id);
-- бюджет
CREATE TABLE reward_budget (
pool_id TEXT PRIMARY KEY, budget NUMERIC(18,2), spent NUMERIC(18,2), period DATE
);
14) Безопасность и приватность
HMAC-подписи, MTLS, allow-list IP.
Шифрование в транзите/покое, ротация ключей, секреты в vault.
Минимизация данных в payload (PII отдельно, по ссылке-токену, TTL).
Аудит-логи неизменяемые (WORM).
Политика хранения и удаления (право на забвение, дедупlication-safe).
15) Чек-лист запуска
- Схемы событий и registry, контракты вебхуков (сигнатуры, TTL).
- Очереди, ретраи, DLQ, идемпотентные обработчики.
- Капы/гвардrail-ы в правилах, KYC/RG-гейты.
- Бюджет-пулы, circuit-breakers, алерты переполнения.
- Дашборды SLO + воронка reward.
- A/B-фичефлаги и SRM-мониторинг.
- Runbook инцидентов (переигровка, заморозка, ручная выдача).
16) Мини-кейс (синтетический)
Подключены события из провайдеров игр и кошелька; включён «win/bet» скоринг с капами.
Вебхуки подписаны HMAC, ретраи до 8 попыток, DLQ с ревью каждые 2 ч.
За 4 недели: лаг обработки p95 180 мс; DLQ < 0,06%; дубли выплат 0; фрод-флаги −0,4 п.п.; ΔParticipation_net +6,3 п.п.; ΔARPPU (net) +€2,1 при Prize&Bonus/Active +€0,7.
Вывод: масштабирование правил на новые гео с локальными бюджет-пулами.
Автоматизация наград — это не «отправить пуш с фриспинами». Это инженерная система: надёжная доставка событий, строгое версионирование правил, idempotency и подписи, бюджет-каперы, KYC/RG-гейты, антифрод и мониторинг. Постройте этот каркас однажды — и любые миссии, турниры и «лут-моменты» будут работать предсказуемо, вовремя и с положительным нетто-эффектом.