在后端级别管理促销和奖金
文章全文
1)为什么把促销带到一个单独的后端
货币不变量。奖金≠"平衡":这是带有条件的合同(vager,游戏贡献,最高投注/获胜)。
更改速度。营销团队每天发布活动-需要声明性规则引擎和回滚。
反Abuse/合规性。KYC/RG/AML,velocity,细分,"四只眼睛"对昂贵的离群值。
可观察性和可报告性。SLO,促销成本,对GGR/NGR/LTV的影响。
原则:促销核心是具有自己的状态机器的独立服务,金钱只能通过钱包,相等地移动。
2)奖金类型和不变式
Deposit match (100%到X):捕获存款后收取费用,vager X ×。
现金(亏损):根据时间/游戏窗口计算,可能是sticky/non-sticky。
Free Spins/Free Bets:优惠券/代币与自旋/投注价格,固定RTP池。
任务/任务:任务→进展→奖励。
赛事/飞行活动:赛事贡献,排名,奖金。
不变量:- Sticky:在满足条件之前不能退出。
- Max bet/Max赢:从奖金中扣除利率/付款限制。
- 贡献:游戏贡献(例如,slots=100%, live=10%)。
- Expiry:奖金和vager窗口的到期日。
3)奖金服务架构
管理(活动/规则)─Promo API ─Rules Engine/Eligibility
│
├─Bonus Ledger(Offers状态)
├─Wagering引擎(进度)
├─Anti-Abuse (限制/frod/velocity)
└─Outbox (events) ─Kafka/Pulsar ─BI/DWH/CRM
Wallet/Ledger── Idempotent Commands ───┘规则引擎-声明性条件(细分,地理/许可,通道,KYC/RG)。
4)数据模型(简化)
`bonus_grant`
`wager_progress`- `grant_id, required_minor, contributed_minor, remaining_minor, last_update_at`
- `schema_id, rules: [{game_type:"slot", pct:100},{game_type:"live", pct:10}]`
"bonus_ledger_entry"(审核)
5)状态机器和传奇
5.1演示(issue)-传奇
1.eligibility.检查(段,RG/KYC, velocity)
2.grant.create (status=`issued`)
3.wallet.credit [bonus](平均值;在sticky-在奖励子资产负债表)
4.activate (status=`active`)
5.emit `bonus.issued`
Rollback: 在第3步下降时→ 'grant。cancel"+事件"奖金。revoked`.
5.2 Vager进步
在'bet上。设置为"计算贡献='stake_minor contribution_pct'(或根据win/loss规则)。
原子更新"wager_progress";达到100%-"complete"。
5.3完成(消费)
complete → `wallet.convert_bonus_to_cash'(如非粘贴)或解除输出限制。
emit `bonus.consumed`.
5.4到期/召回
根据"expires_at"或弗罗德规则→ "revoke"(偶数),可以根据政策进行补偿。
6)钱包合同(仅通过API,始终是偶数)
累积奖金
POST /v1/wallet/credit
Headers: X-Idempotency-Key: bonus_grant_123
{
"player_id":"p_001",  "amount":{"minor_units":100000,"currency":"EUR"},  "balance_type":"bonus",  "reference":{"grant_id":"gr_123","offer_id":"of_777"}
}
→ 200 {"status":"credited","entry_id":"e_9001"}满足条件后转换为缓存
POST /v1/wallet/convert
Headers: X-Idempotency-Key: bonus_convert_gr_123
{
"player_id":"p_001",  "from_balance":"bonus",  "to_balance":"cash",  "amount_minor":100000,  "reference":{"grant_id":"gr_123"}
}
→ 200 {"status":"converted","entry_id":"e_9010"}- 要求'bets。"authorize"被代码"BONUS_MAX_BET_EXCEED"拒绝。
7)促销服务API(基准)
创建Offer (admin)
POST /v1/offers
{
"name":"Welcome 100% up to 100€",  "type":"deposit_match",  "params":{"match_pct":100,"cap_minor":10000,"wager_x":20,"sticky":true,       "max_bet_minor":200,"max_win_minor":50000,"contribution_schema_id":"c_slot100_live10"},  "eligibility":{"brands":["A"],"regions":["EU"],"segment":"new_depositors"},  "schedule":{"start":"2025-10-20T00:00:00Z","end":"2025-11-30T23:59:59Z"}
}
→ 201 {"offer_id":"of_777"}发放奖金(runtime)
POST /v1/bonus/grants
Headers: X-Idempotency-Key: grant_p001_of777
{
"player_id":"p_001","offer_id":"of_777","trigger":"deposit_captured","amount_minor":10000
}
→ 200 {"grant_id":"gr_123","status":"active"}Vager进步(阅读)
GET /v1/bonus/grants/gr_123/progress
→ 200 {"required_minor":200000,"contributed_minor":45000,"remaining_minor":155000,"pct":0.225}撤销/撤销
POST /v1/bonus/grants/gr_123/revoke
Headers: X-Idempotency-Key: revoke_gr_123
{ "reason":"fraud_velocity" }
→ 200 {"status":"revoked"}所有写作呼叫均来自"X-Idempotency-Key"和"X-Trace-Id"。
8)反滥用和合规性
Velocity限制:发放/转换/尝试存款(Redis counters+TTL+Lua)。
触发器:根据规则,一笔存款→一笔赠款。
细分和RG:排除自我释放/限制;per品牌/地区许可证。
离岸冲突块:同时只有一个欢迎奖金;优先次序。
异常检测器:多个帐户/设备/ASN,快速"重置"vager。
"四眼"大笔赠款和人工调整。
WORM审核所有规则/赠款/转换更改。
9)可观察性,度量和SLO
SLO(地标):- `grant.issue p95` (issue→credited) ≤ 300–500 мс.
- 从"bet"开始更新"wager_progress p95" ≤ 200毫秒。settled`.
- 发生的"bonus."事件发生在p95总线上≤ 2分钟。
- "损失/重复赠款/转换"=0。
- Rate/latency по `issue/convert/revoke`, error-rate (business/4xx/5xx), `IDEMPOTENCY_MISMATCH`.
- Vager转换,平均"时间完成",逾期百分比。
- 促销费用:队列上的"promo_cost"(次要)和"promo_roi"。
- 反抽象:velocity触发,max bet/win偏转。
Tracing: OpenTelemetry在'trigger → grant → wallet链条上。credit → progress.update → convert`.
10)与RGS/游戏集成
Free Spins/Free Bets优惠券-通过"entitlements" API:代币发行,rantime注销,遥测使用。
Max bet/Win-Bets中的规则。authorize` и `bets.settle`;返回代码"BONUS_RULE_VIOLATION"。
贡献是'bet级别的方案。设置为"(通过'game_type/provider_id'),对方案进行反转。
11) DWH/BI和报告
Outbox活动→ Lake(铜牌)→ Silver (dedoop, SCD2) → Gold店面:- `fact_bonus_grants`, `fact_wager_progress`, `fact_bonus_cost`, `fact_promo_roi`.
- SLA新鲜:Silver ≤ 15分钟,Gold ≤ 30-60分钟。
- 面板:转换到离线/片段,时间到完成,贡献到游戏,数据表事件。
12)安全和居住权
mTLS + OAuth2 CC;scope’ы `promo:issue`, `promo:convert`, `promo:revoke`.
钥匙/代币-按品牌/地区简短;Vault/HSM中的秘密。
PII隔离: "player_id"是别名;RLS по `brand/region`.
发行限额和配额;防御暴风雨。
13)支票单
平台/操作员
- 所有现金交易都是通过"Idempotency-Key"通过Wallet进行的。
- 规则/可扩展性是可转换的;移民事件的"双重写作"。
- 贡献方案是集中的,由测试覆盖。
- 包括Velocity和反氟化物;"四只眼睛"大量。
- Outbox/CDC,DLQ和"bonus."的托管重播。
- SLO-dashbords, OpenTelemetry, WORM审核。
- 用于ROI和合规性(RG/AML)的DWH店面。
集成(RGS/钱包/CRM)
- 检查max bet/win;返回业务错误代码。
- 通过"trace_id"和"idempotency_key"。
- 触发器和交付保证(webhooks已签名)。
14)红旗(反模式)
手动累积奖金直接进入资产负债表,绕过Wallet。
缺乏相容性→双倍赠款/转换。
Vager被认为是'bet。放置"而不是"bet的结果。settled`.
没有贡献方案,或者它们在提供商代码中"缝合"。
冲突的offers同时激活。
没有velocity/anti-frod和WORM审核。
"Bonus."事件是绕过outbox/CDC发布的。
促销指标与Ledger/BI不一致(没有ROI店面)。
15)结果
可靠的后端促销是合同和不变量而不是"增加平衡"。它将规则与金钱分开,根据实际结果计算进展,保证相等性和可观察性,防止借贷并提供合规性。有了这样的核心,市场营销就迅速发展,玩家可以看到诚实的条件,财务和监管机构可以准确了解每个离职者的成本和影响。
