Non-Functional Requirements & Failure Handling
Non-functional requirements
Idempotency. All PAM→Wynta mutations carry client-generated IDs (consume_txn_id, wager_tnx_id, event envelope event_id); all Wynta→PAM webhooks carry event_id. Consume replays return 409 Conflict — the PAM stores consume_txn_id before calling and treats a 409 for a known ID as "already recorded". Webhook replays are deduped by the PAM on event_id.
Ordering. Webhooks may arrive out of order. The PAM applies signed deltas and uses resulting_balance for immediate drift detection; per-player sequence numbers, if provided, take precedence.
Latency. Promo validation and grant (player-facing, synchronous): p95 < 500 ms. Wallet webhooks: delivery target < 5 s; the PAM UI tolerates brief staleness.
Retries & DLQ. Webhook retries with exponential backoff ≥ 24 h; DLQ swept by reconciliation. PAM retries transient S2S failures with the same idempotency key.
Concurrency. Wagering-progress updates are serialized per player-bonus in Wynta (no double release). Consume requests for the same player are safe to send concurrently — chunk debits are transactional.
Consume model (client-first). The PAM — the external client — debits its own Bonus Wallet at spend time, then notifies Wynta via bonus_consume_bonus. The BONUS_CONSUMED webhook is a confirmation matched by consume_txn_id, never a second debit. Wynta's ledger is final authority; a rejected notification means the PAM reverses its local debit.
Security. The User Bonus API authenticates with the X-Client-Id header (resolved to site_id server-side) — an identifier, not a signature — so calls must be strictly server-to-server over TLS with network-level controls (IP allow-listing / private networking); client_id never ships in browser or app code. Inbound webhooks carry the proposed timestamped HMAC-SHA256 signature with replay protection and secret rotation — see Webhook Authentication. PII event properties (email, phone, ip) are hashed before persistence; payloads carry no PII beyond user_id.
Auditability. Wynta's ledger (grants, chunk releases, per-chunk consumption, reversions, forfeits, expiry events) is the audit trail; configuration changes carry actor fields and full history endpoints. The PAM retains webhook receipts and reconciliation reports per compliance requirements.
Budget enforcement. Grant-time budget checks are atomic across Configure → Subhead → Head caps (DAILY/WEEKLY/MONTHLY); a cap breach can never leak a grant to the PAM.
Failure scenarios
Webhook lost
Retry → DLQ → reconciliation corrects PAM wallet
Duplicate consume notification from PAM
409 Conflict on the replayed consume_txn_id; PAM treats known-ID 409 as already-recorded; single ledger entry
Wynta rejects consume notification (ledger mismatch)
Client wallet has drifted — PAM reverses its local debit and flags for targeted reconciliation
Consume notification undeliverable (Wynta down)
PAM's local debit stands; notification queued and retried with the same consume_txn_id; reconciliation closes any residual gap
Game round voided after consume
PAM calls bonus_revert_bonus_consumption; chunk-exact reversal; webhook restores wallet
Voided wager after chunk release
Progress reduced; released chunks are not clawed back
Budget cap reached at grant evaluation
No grant created — no ledger entry, no webhook; the code may still have validated earlier (validation is not a reservation)
Wynta unavailable during wager stream
PAM buffers/replays wager events (deduped on wager_tnx_id); release evaluation catches up
Balance drift via resulting_balance
PAM flags player; targeted reconciliation run
Chunk expires between consume and revert
Reverted amount follows expiry rules; webhook deltas make the outcome explicit
Open questions
Game contribution rates —
bet_placedcarriesgame_category/game_provider; confirm whether contribution weighting per category exists or all qualifying wagers count at 100%.Wager progress attribution — the ledger tracks progress per chunk (
chunks[].wager_amount); confirm overflow carry-over to the next chunk and rounding on the final chunk (e.g. 3 × ₹166.67 vs ₹500.01 requirement).Multiple active bonuses — enforce a single active wagering bonus per chip type (recommended), or attribute wager contribution across concurrent bonuses? How does
priorityinteract?Expiry countdown display — the PAM can show countdowns from
chunk_expiry_days/bonus_expiry_days(transaction detail) and the proposedexpires_aton webhook chunks; confirm the webhook carries expiry timestamps at grant time.Webhook envelope sign-off — confirm the proposed schema (incl. per-player sequence numbers) with the PAM (SR) team, and version it (
v1) from day one for multi-PAM future-proofing.release_bucket— confirm intended semantics and whether the PAM needs it in webhook payloads.Unauthenticated endpoints —
POST /validate-code,POST /consume/{consume_txn_id}/revert, and the referral/applicable-codes reads require noX-Client-Id; confirm the intended network-level protection for these, particularly revert (a mutation reachable with only aconsume_txn_id).BONUS_RELEASEevent &system_auto_apply— the applicable-codes endpoint references backend auto-application "when aBONUS_RELEASEevent fires"; confirm the definition of this internal event and howsystem_auto_applydiffers from the player-visibleauto_applyflag.Reconciliation cadence/cutoff — daily proposed; confirm with finance/compliance.
Last updated
Was this helpful?