Balance und Wallets: Die Multi-Wallet-Architektur
1) Warum Multi-Wallet und welche Ziele
Ein einziger „balance = number“ -Eintrag deckt die iGaming-Realität nicht ab. Sie benötigen separate Wallets/Unterkonten: echtes Geld (Cash), Bonusgelder, Vager Pool, Freispiele, Comp-Points, manchmal - Währungs-Wallets (EUR/USD/BRL).
Ziele der Architektur:- Genauigkeit des Geldes (Double-Entry, Auditierbarkeit).
- Abbuchungsrichtlinien (z.B. erst Bonus/Wager, dann Cash).
- Geschwindigkeit (p95 API ≤ 250-400 ms, Wette/Echtzeit-Settlement).
- Sicherheit und Compliance (KYC/AML, Grenzen des verantwortungsvollen Spielens, Regulatoren).
- Skala: Spitzen → Zehntausende von Operationen/s, Milliarden von Postings/Monat.
2) Datenmodell: „Ledger + Subwallets“
Minimale Entitäten
Konto: Spieler/Marke/Markt.
Beispieltabellen (vereinfacht)
sql
-- Bilanzkonten für Double-Entry (einschließlich Service)
accounts(id, owner_user_id, type, currency, status,...)
-- Buchung (Doppeleintrag, Verweis auf Geschäftsvorgang)
ledger_entries(id, posting_id, debit_account_id, credit_account_id,        amount_minor, currency, category, operation_id, created_at)
-- Holds (Reserven)
holds(id, account_id, amount_minor, currency, reason, expires_at, state,    operation_id, created_at)
-- Abschreibungspolitik (Prioritäten)
spend_policies(id, market, wallet_priority jsonb, updated_at)
- Wechselkurse fx_rates (ccy_from, ccy_to, Rate, Präzision, valid_from)Regel: Die Wahrheit lebt im Buchungsprotokoll ('ledger _ entries'). Die aktuelle Bilanz ist entweder ein Aggregat (materialisierter Snapshot) oder wird aus einem Protokoll berechnet (teuer, aber einzig richtig).
3) Arten von Wallets und ihr Verhalten
4) Abschreibungspolitik und Prioritätsreihenfolge
Formalisieren Sie den Algorithmus der Geldquelle klar: Beispiel (Slots/Casino):1. Zuerst bei WAGER abschreiben (wenn der Wager aktiv ist).
2. Dann von BONUS, bis erschöpft.
3. Der Rest ist von CASH.
Beispiel (Sport):1. Zuerst CASH (Regulator/Tax).
2. Dann BONUS (Freebet), Überweisung an WAGER.
Speichern Sie die „Richtlinienentscheidung“ als Attribut in Postings, damit Saport und Audit sehen, „warum so abgeschrieben wurde“.
5) Der Lebenszyklus von Geld und Operationen
Depositum
1. 'POST/Wallet/Deposit' → Erstellen Sie einen Pending-Eintrag (Inbox-PSP-Stift).
2. Webhook PSP (Signatur HMAC, idempotency durch "operation _ id") → credit CASH, Kategorie = "DEPOSIT'.
3. Wir veröffentlichen das Ereignis' wallet _ updated'.
Satz
1. „POST/bet/place“ → erstellen einen Hold (Reserve) auf dem Quellenkonto (CASH/BONUS/WAGER).
2. Bei der Bestätigung der Wette → die Übertragung von Hold → Debit der Quelle, Credit Service „Settlement“ Konto des Anbieters.
3. Bei Stornierung - release hold.
Settlement (Ergebnis)
Gewinn: Debit „Settlement“ -Konto des Anbieters → Credit CASH oder Policy WAGER→BONUS→CASH.
Verlust: Wir schließen die „Ausgaben“ des Anbieters → ohne Kredite an den Spieler.
1. KYC/AML-Check, verantwortungsvolle Spielgrenzen.
2. Halten Sie den Auszahlungsbetrag.
3. Der Erfolg der PSP → die endgültige Debit CASH → Credit-Konto „Auszahlung“.
4. PSP → Release Hold
6) Idempotenz und exactly-once „im Sinne von“
Überall 'operation _ id' (UUID/enhanced ULID) mit einem eindeutigen Index. Eine erneute Anfrage → den Status der vergangenen Transaktion.
PSP Webhooks/Spieleanbieter: Inbox-Tabelle mit dedupe durch 'event _ id + signature'. Die Verarbeitung ist ein idempotenter Worker (Outbox-Muster).
Idempotency-Key auf HTTP für den Client; TTL ≥ 24-72 Stunden aufbewahren.
7) Reserven und Holds (Holds)
Hold ist keine Abschreibung, sondern ein „Einfrieren“ des verfügbaren Guthabens.
Regeln:- Lebensdauer des Hold: seconds→minutes (Wette) oder Stunden (Schlussfolgerung).
- Der Hold kann teilweise oder vollständig eingelöst werden (partial settle).
- Bei expire - Automatische Freigabe und Ereignis.
- Speichern Sie die Verbindung 'hold _ id' ↔ 'bet _ id/withdraw _ id'.
8) Währungen, FX und Rundungen
Geldsummen - in kleinen Einheiten (Cents), Typ - das Ganze.
Rundungen Bank (round half to even) oder durch T & C.
FX: „CASH (EUR)“ ↔ „CASH (USD)“ ist besser, die Brieftaschen zu teilen. Umwandlung als separate Operation:- "Debit EUR, Credit FX_EURUSD' und" Debit FX_EURUSD, Credit USD "- transparent für die Prüfung.
- Es ist verboten, den Kurs im Streitfall mit einer Maschine zu „erreichen“; Alle Regeln sind in der FX-Richtlinie.
9) Verantwortungsvolles Spielen und Grenzen
Deposit/Bet/Loss/Session Limits (Tag/Woche/Monat), „cooling-off“, Selbstausschluss.
Implementiert als Pre-Check vor Hold/Debit.
Fehlerprotokolle - in einem separaten Audit-Log, verfügbar für Sapport und Regulator.
10) Anti-Fraud-Signale um den Geldbeutel
Gerätecluster/ASNs, häufige Einzahlungen kleiner Beträge → große Leads, Waschmuster.
Velocity-Limits für 'deposit/withdraw' nach BIN/Land/Gerät.
Blocklisten für Empfänger (Wallets/IBAN), Liste der „Maultiere“.
Wallet-Ereignisse → im Feature-Scoring-Store (Login/Einzahlung/Wette) angezeigt.
11) Konsistenz und Leistung
True vs Cache
Die Wahrheit liegt in ledger. Für die API „get balance“ - halten Sie einen materialisierten Schnappschuss ('user _ id + wallet _ type → balance_minor, version').
Schreiben: Eine Transaktion in der Datenbank → den Cache deaktivieren.
Im „heavy“ -Flow (live) ist ein short-TTL von 1-5 s + obligatorischer Wahrheitscheck vor dem Abschluss/Major Bet angebracht.
Clipping
Sharding durch 'user _ id' (Modul/Ranking), separate Shard-Pools unter CASH vs. BONUS.
Hot Keys (VIP/Bots) - Anfrage coalescing durch 'user _ id'.
Asynchrone Aggregationen („Posting“ → „Snap-Shot-Updater“ im Hintergrund).
12) API-Verträge (Pseudo)
Gleichgewicht
http
GET /v1/wallets? types=CASH,BONUS
→ 200 {"wallets":[
{"type":"CASH","currency":"EUR","available":12050,"hold":500,"version":1942},  {"type":"BONUS","currency":"EUR","available":3000,"wager_req":15000}
]}Wette (mit Hold)
http
POST /v1/bets/place
{"bet_id":"b_123","amount":500,"currency":"EUR","source_policy":"casino_default", "idempotency_key":"ik_abc"}
→ 201 {"status":"HELD","hold_id":"h_789","expires_in":30}Settlement
http
POST /v1/bets/settle
{"bet_id":"b_123","result":"WIN","payout":1250}
→ 200 {"status":"SETTLED","cash_delta":+1250}http
POST /v1/withdrawals
{"withdraw_id":"w_456","amount":10000,"currency":"EUR","method":"sepa", "idempotency_key":"ik_def"}
→ 202 {"state":"PENDING","next_check_sec":2,"status_url":"/v1/withdrawals/w_456"}13) Buchungsbeispiele (Double-Entry)
Kaution €100 (PSP Gebühr €1, kommis. Konto - separat)
Debit: PSP_Settlements(EUR)   10000
Credit: User. CASH(EUR)         10000
Debit: User. CASH (EUR) 100 (fee shift)
Credit: PSP_Fees(EUR)          1005 € Einsatz aus BONUS (Überweisung an WAGER)
Debit: User. BONUS(EUR)       500
Credit: User. WAGER (EUR) 500 (Umzug nach „vager“)
Debit: User. WAGER(EUR)       500
Credit: Provider. Siedlung (EUR) 500 (Rate abgeschrieben)Der Gewinn beträgt 12 €. 5 → in Cash
Debit: Provider. Settlement(EUR)  1250
Credit: User. CASH(EUR)         1250Hold-Abbuchung (Umsetzung über das HOLD-Servicekonto)
Debit: User. CASH(EUR)       500
Credit: User. HOLD (EUR) 500 (erstellt von hold)
-- bei settle
Debit: User. HOLD(EUR)       500
Credit: Provider. Settlement(EUR)   500
-- bei Stornierung
Debit: User. HOLD(EUR)       500
Credit: User. CASH(EUR)         50014) Audit, Unveränderlichkeit und Compliance
WORM/immutability für Log (Objektspeicher/WAL-Archiv).
Zugriffsmetajmagazine: wer die Grenzen gelesen/geändert hat, wer manuelle Anpassungen vorgenommen hat (nur über „adjustment-posting“ mit Begründung).
GDPR/Regulatoren: Speicherung von Transaktionen für 5-10 Jahre (nach Gerichtsbarkeit), Transparenz der Berechnungen für den Spieler (Historie der Abschreibungen/Vager).
15) Fehlertoleranz und DR
Multi-AZ ist obligatorisch; DR-Region für die Brieftasche: Sync-Replikation in der Zone, async - in der Region; PITR ist eingeschaltet.
Promote standby - nur manuell per Checkliste (Split-Brain ausschließen).
Die Wiederherstellung wird wöchentlich überprüft (Test-Restore), der Abgleich der Summe nach den Kontrollberichten.
16) Beobachtbarkeit der Brieftasche
SLI: `deposit_success_ratio`, `withdraw_success_ratio`, `bet_hold_latency_p95`, `settlement_latency_p95`.
Тех: `ledger_postings_rate`, `db_connections_saturation`, `queue_lag_seconds`, `hold_expired_rate`.
Alertas: Rückgang des PSP-Erfolgs auf dem Markt, Wachstum von 'hold _ expired _ rate', Unsynchron des Spieleanbieters (keine Bestätigung> N min).
17) Prüfung und Qualitätskontrolle
Vertragstests mit PSPs/Spieleanbietern (Webhooks/Signaturen).
Eigenschaftsbasierte Geldtests: Höhe der Belastungen = = Höhe der Gutschriften in jedem Posting.
Fuzz/Chaos: PSP/Provider-Verzögerungen, Webhook-Wiederholungen, Netzwerk-Flappies.
Last: Burst Wetten (60-120 s), Soaks (4-8 h), Steuerung 'queue _ lag' und p99.
18) Checkliste Produktionsbereitschaft
- Doppelter Ledger-Eintrag, alle Operationen über Posting mit 'operation _ id'.
- Klare Spend-Richtlinien und Prioritätsreihenfolge (persistent mit Posting).
- Holds mit TTL/partial settle/expiry, Kommunikation mit bet/withdraw.
- Inbox/Outbox, HMAC-Webhooks, Idempotenz an allen Grenzen.
- Separate CASH/BONUS/WAGER/FS/POINTS Wallets; Aufteilung nach Währungen.
- FX und Rundungen in Moll-Einheiten; Konvertierung ist eine separate Operation.
- Verantwortliche Spiellimits vor Hold/Debit; Prüfung von Fehlern.
- Lesecache (kurze TTL) + obligatorische Wahrheitsprüfung vor kritischen Aktionen.
- PITR/Backups/DR-Skripte; manuelle promote, regelmäßige DR-Übungen.
- Dashboards/SLI alerts + technical; WORM Logs und Zugriffsmetajmagazine.
- Last-/Chaos-Tests; reconciliation reports mit PSPs/Providern.
Zusammenfassung
Bei der Multi-Wallet-Architektur geht es nicht um „viele Bilanzzahlen“, sondern um ein Finanzsystem mit doppeltem Eintrag, Ausgabenrichtlinien, Reservierung und transparentem Fußabdruck für Audits und Spieler. Halten Sie die Wahrheit im Tagebuch, verwenden Sie Holds und Idempotenz, trennen Sie Wallets und Währungen, automatisieren Sie Reconciliation und DR.So wird die Wallet schnell für UX, genau für Geld und stabil für Spitzenlasten und regulatorische Überprüfungen.
