Gestionarea promoțiilor și bonusurilor la nivel backend
Articol complet
1) De ce să ia promo la un backend separat
Invarianţi monetari. Bonus ≠ „soldul adăugat”: acesta este un contract cu condiții (vager, contribuție la jocuri, pariu maxim/câștig).
Rata de schimbare. Echipele de marketing lansează zilnic campanii - aveți nevoie de un motor de reguli declarative și rollback.
Anti-abuz/conformitate. KYC/RG/AML, viteză, segmentare, sarcini cu patru ochi pentru oferte scumpe.
Observabilitate şi raportare. SLO, cost promoțional, impact asupra GGR/NGR/LTV.
Principiu: nucleul promoțional este un serviciu separat cu propriile mașini de stare, iar banii se mișcă numai prin portofel, în mod idempotic.
2) Tipologia bonusului și invarianții
Meci de depozit (100% înainte de X): acumulat după depunerea capturii, vager X ×.
Cashback: calculat după fereastra de timp/jocuri, poate fi lipicios/non-lipicios.
Învârtiri gratuite/pariuri gratuite: cupoane/jetoane cu un preț per rotire/pariu, piscină fixă RTP.
Misiuni/misiuni: sarcină → progres → recompensă.
Turnee/evenimente de zbor: contribuția evenimentelor, rating, premiu în bani.
Invarianţi:- Lipicios: nu poate fi de ieșire până când condițiile sunt îndeplinite.
- Pariul maxim/câștigul maxim: limitele pariului/plății din fondurile bonus.
- Contribuție: contribuție prin joc (ex. sloturi = 100%, live = 10%).
- Expirare: Perioada de valabilitate a bonusului și fereastra vager.
3) Arhitectura serviciului bonus
Admin ─Promo ─Rules Motor API/Eligibilitate
│
├─Bonus Ledger (starea ofertelor)
Motor ├─Wagering (progres)
├─Anti -Abuz (limite/fraudă/viteză)
└─Outbox (evenimente) ─Kafka/Pulsar ─BI/DWH/CRM
 Comenzi Idempotente  Reguli Motor - condiții declarative (segmente, geo/licență, canale, KYC/RG).
4) Modelul de date (simplificat)
'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' (audit)
5) Mașini de stare și sagas
5. 1 Număr - Saga
1. eligibilitate. verificare (segment, RG/KYC, viteză)
2. grant. create (status = 'emise')
3. portofel. credit [bonus] (idempotent; la lipicios - la bonus sub-balance)
4. activate (status = 'active')
5. Emit bonusul. "
Rollback: atunci când se încadrează la pasul 3 → 'grant. anulează bonusul „+ eveniment”. revocată.
5. 2 Progresul Vager
Na 'bet. solded 'count contribution =' mize _ minor contribution_pct' (sau conform regulilor de câștig/pierdere).
Update 'wager _ progress' atomic; când se ajunge la 100% - „complet”.
5. 3 Finish (consuma)
completează portofelul lui →. convert_bonus_to_cash' (dacă nu sunt lipicioase) sau eliminați restricțiile de ieșire.
Emit bonusul. consumate ".
5. 4 Expirare/Rechemare
Prin "expires _ at' sau regula fraudei →" revocare "(idempotent), compensarea în conformitate cu politica este posibilă.
6) Contracte de pungi (numai prin API, întotdeauna idempotent)
Bonus de acumulare
POST/v1/portofel/credit
Anteturi: X-Idempotency-Key: bonus_grant_123
{
„player_id":"p_001,” „sumă”: {„minor _ units': 100000”, valută „:” EUR „}”, balance_type":"bonus, „referință”: {„grant _ id':” gr _ 123 „,” oferta _ id': „of _ 777”}
}
→ 200 {"status": "credited", "entry _ id':" e _ 9001 "}Conversia în memoria cache atunci când sunt îndeplinite condițiile
POST/v1/portofel/conversie
Anteturi: X-Idempotency-Key: bonus_convert_gr_123
{
" " " " " " ", referință": {"grant _ id':" gr _ 123 "}
}
→ 200 {"status": "convertit", "entry _ id':" e _ 9010 "}- cerere "pariuri. autorizați "este respins de codul 'BONUS _ MAX _ BET _ EXCEED'.
7) API de serviciu promo (șabloane)
Creează o ofertă (admin)
POST/v1/oferte
{
"name": "Welcome 100% până la 100 €", "type": "deposit _ match", "params': {" match _ pct': 100, "cap _ minor": 10000, "wager _ x": 20, "sticky": "trUE", "eligibilitate": {"brands': [" A "]," regiuni ": [" EU ""] ", segment": "new _ deponenți"}, "program": {"start": "2025-10-20T00: 00: 00Z", "end':" 2025-11-30T23: 59: 59Z "}
}
→ 201 {"offer _ id':" of _ 777 "}Emiteți un bonus (durata)
POST/v1/bonus/granturi
Anteturi: 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 ":" activ "}Progresul pariurilor (citit)
GET/ v1/bonus/grants/gr_123/progress
→ 200 {"required _ minor": 200000 ", contribuit _ minor": 45000 ", rămas _ minor": 155000 "pct': 0. 225}Anulare/Revocare
POST/ v1/bonus/grants/gr_123/revoke
Anteturi: X-Idempotency-Key: revoke_gr_123
{„motiv „: „fraudă _ viteză”}
→ 200 {„stare „:” revocat”}Toate apelurile de scriere sunt cu "X-Idempotency-Key" și "X-Trace-Id'.
8) Anti-abuz și conformitate
Limite de viteză: emisiuni/conversii/încercări de depunere (contoare Redis + TTL + Lua).
Trigger dedup: un depozit → un grant după regulă.
Segmentarea și RG: excluderea auto-exclusă/limită; per licență de marcă/regiune.
Bloc de conflicte de oferte: doar un singur bonus de bun venit este activ la un moment dat; priorități.
Detector de anomalii: conturi/dispozitive multiple/ASN, „zeroing” rapid al vagerului.
„Patru ochi” pe granturi mari și ajustări manuale.
Auditul WORM al tuturor modificărilor de regulă/grant/conversie.
9) Observabilitate, valori și SLO
SLO (repere):- "grant. problema p95 '(issue→credited) ≤ 300-500 мс.
- Actualizați 'wager _ progress p95' ≤ 200ms de la 'bet. settled'.
- Bonusul evenimentelor. În autobuzul p95 ≤ la 2 minute de ce s-a întâmplat.
- „Granturi/conversii pierdute/duplicate” = 0.
- Rata/latenta по 'issue/convert/revoce', error-rate (business/4xx/5xx), 'IDEMPOTENCY _ MISMATCH'.
- Vager conversie, medie „timp-la-complet”, proporție restante.
- Costul promoțional: 'promo _ cost' (minor) și 'promo _ roi' pe cohorte.
- Anti-abuz: declanșează viteza respinsă de pariul maxim/câștig.
Urmărire: OpenTelemetry pe chain 'trigger → acorda portofelul →. credit → progres. actualizați → convertiți ".
10) Integrarea cu RGS/jocuri
Free Spins/Free Bets coupons - via 'entitlements' API: emiterea de jetoane, casare în timpul rulării, telemetrie prin utilizare.
Max pariu/câștig - reguli în pariuri. autorizează pariurile „и”. soluţionare "; codurile de returnare „BONUS _ RULE _ VIOLATION”.
Contribuție - schemă la nivelul "pariu. settled '(prin' game _ type/provider _ id'), versiune schema.
11) DWH/BI și rapoarte
Evenimente outbox → Lacul (bronz) → Argint (dedup, SCD2) → Vitrine aur:- 'act _ bonus _ grants',' fact _ wager _ progress', 'fact _ bonus _ cost', 'fact _ promo _ roi'.
- SLA prospețime: argint ≤ 15 min, aur ≤ 30-60 min.
- Panouri: conversie pe oferte/segmente, timp până la finalizare, contribuție pe jocuri, incidente de abuz.
12) Siguranță și rezidență
mTLS + OAuth2 CC; scope'ы 'promo: issue', 'promo: convert', 'promo: revoce'.
Chei/jetoane - per brand/regiune, de scurtă durată; secrete în Vault/HSM.
Izolarea PII: 'player _ id' - alias; RLS по „marcă/regiune”.
Limitele ratei și cotele de emitere; protecție împotriva furtunilor retraverse.
13) Liste de verificare
Platformă/Operator
- Toate tranzacțiile monetare trec prin portofel cu 'Idempotency-Key'.
- Regulile/Eligibilitatea sunt versionate; „scrisoare dublă” a evenimentelor privind migrațiile.
- Schemele de contribuții sunt centralizate, acoperite cu teste.
- Viteza și antifraudă activate; „patru ochi” pe sume mari.
- Outbox/CDC, DLQ și reluarea gestionată pentru "bonus. '.
- Tablouri de bord SLO, OpenTelemetry, audit WORM.
- storefronturi DWH pentru ROI și conformitate (RG/AML).
Integrări (RGS/portofel/CRM)
- Verificarea pariului maxim/câștigului; returnarea codului de eroare de afaceri.
- Eu arunc 'trace _ id' și' idempotency _ key '.
- Deadup declanșează și garanții de livrare (webhooks semnat).
14) Steaguri roșii (anti-modele)
Încărcarea bonusului „manual” direct în balanță, ocolind Portofel.
Lipsa idempotenței → subvenții duble/conversii.
Pariul este considerat prin „bet. plasat”, și nu în funcție de rezultatele „bet. decontate”.
Nu există sisteme de contribuții sau sunt „protejate” în codul furnizorilor.
Ofertele contradictorii sunt activate simultan.
Nu există viteză/antifraudă și audit WORM.
"bonus. 'evenimentele sunt postate ocolind outbox/CDC.
Valorile promoționale nu se adaugă la Ledger/BI (fără vitrine ROI).
15) Linia de jos
Promo-uri backend de încredere sunt contracte și invariante, nu "adăuga echilibru. "Aceasta separă regulile de bani, ia în considerare progresul în funcție de rezultatele reale, garantează idempotența și observabilitatea, protejează împotriva abuzurilor și asigură conformitatea. Cu un astfel de nucleu, marketingul se mișcă rapid, jucătorul vede condiții oneste, iar finanțele și autoritățile de reglementare primesc o imagine exactă a costului și a efectului fiecărei oferte.
