> For the complete documentation index, see [llms.txt](https://docs.wynta.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.wynta.com/bonus/flows/expiry-forfeit-reconciliation.md).

# Expiry, Forfeit & Reconciliation

## Flow 5 — Expiry (Wynta → PAM)

**Trigger:** a scheduled Wynta job detects chunks or bonuses past their validity:

* **Chunk expiry** — `chunk_expiry_days` after release (or grant); individual chunks expire independently.
* **Bonus expiry** — `bonus_expiry_days` after grant; all non-terminal chunks of the bonus expire together.

**Effect:** expired `PENDING` amounts leave **Pending**; expired unconsumed `RELEASED` remainders leave **Available**. Wynta emits **`BONUS_EXPIRED`** with per-chunk detail so the PAM adjusts both buckets with the correct split.

## Flow 5b — Forfeit (Wynta → PAM)

**Trigger:** player- or operator-initiated cancellation — player opt-out, responsible-gaming action, fraud/AML decision.

**Effect:** identical mechanics to expiry, emitted as **`BONUS_FORFEITED`**. Forfeit events are recorded in the ledger and visible in `bonus_player_transaction_detail`.

{% hint style="warning" %}
Expiry and forfeit are one-directional pushes. The PAM must accept them even for bonuses it believed active — **Wynta wins conflicts**.
{% endhint %}

## Flow 7 — Reconciliation (batch, cross-system)

The safety net for missed webhooks, out-of-order delivery, and optimistic-debit drift.

**Cadence:** daily scheduled run, plus on-demand for flagged players.

**Inputs:**

| Side  | Source                                                                                                                                                                                                                                                                           |
| ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Wynta | `bonus_player_summary` (per-player, per-chip-type balances); `bonus_player_transactions` + `bonus_player_transaction_detail` (ledger with chunk/forfeit/expiry granularity); `bonus_get_summary(site_id)` (site-level KPIs and monthly budget totals for aggregate cross-checks) |
| PAM   | Bonus Wallet snapshots (Pending/Available per chip type)                                                                                                                                                                                                                         |

**Procedure:**

1. Aggregate check — compare site-level totals (`bonus_get_summary`) against the PAM's summed wallet buckets; a mismatch scopes the per-player pass.
2. Per-player pass — diff `bonus_player_summary` vs. PAM wallet for every player active in the window.
3. For each discrepancy, replay the ledger (`bonus_player_transaction_detail`) against the PAM's webhook receipts to locate the missing or double-applied event.
4. Apply a compensating wallet adjustment on the **PAM side** (Wynta is the system of record for lifecycle), tagged with the reconciliation run ID.
5. Alert if the discrepancy rate exceeds threshold; retain reports per compliance requirements.
