> ## Documentation Index
> Fetch the complete documentation index at: https://docs.winampay.de/llms.txt
> Use this file to discover all available pages before exploring further.

# State Machine

> Transaction lifecycle — all possible states and transitions.

## Deposit states

```mermaid theme={null}
stateDiagram-v2
    [*] --> pending : POST /api/v1/deposits
    pending --> provider_acknowledged : USSD sent to player
    provider_acknowledged --> succeeded : SMS confirmation received
    provider_acknowledged --> failed : Player refused or timeout
    pending --> failed : Provider error
    pending --> expired : Confirmation window closed
    provider_acknowledged --> expired : Confirmation window closed
    expired --> requires_manual_resolution : Late confirmation received
    failed --> requires_manual_resolution : Late confirmation received
    requires_manual_resolution --> succeeded : Operator confirms
    requires_manual_resolution --> failed : Operator rejects
    succeeded --> [*]
    failed --> [*]
    expired --> [*]
```

| State                        | Description                                                                                                                                                                                                                |
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pending`                    | Transaction created, USSD being sent                                                                                                                                                                                       |
| `provider_acknowledged`      | USSD sent — player has received the notification on their phone                                                                                                                                                            |
| `succeeded`                  | Player confirmed with PIN — payment received on merchant SIM                                                                                                                                                               |
| `failed`                     | Player refused, timeout, or provider error                                                                                                                                                                                 |
| `expired`                    | Confirmation window (`expires_at`) passed without player confirmation                                                                                                                                                      |
| `requires_manual_resolution` | A confirmation (operator SMS/USSD) arrived **after** the deposit expired or failed. The money may have been received, so it is held for a Winam operator to confirm or reject — never auto-credited. Not a terminal state. |

<Note>
  A deposit only reaches `requires_manual_resolution` via a **late** confirmation. No webhook is sent in this state — it fires when the operator resolves it to `succeeded` or `failed`.
</Note>

***

## Withdrawal states

```mermaid theme={null}
stateDiagram-v2
    [*] --> pending_approval : POST /api/v1/withdrawals
    pending_approval --> approved : Winam operator approves
    pending_approval --> failed : Winam operator rejects
    approved --> provider_submitted : USSD transfer sent
    provider_submitted --> succeeded : USSD success (final)
    provider_submitted --> failed : Provider error / insufficient balance
    provider_submitted --> requires_manual_resolution : Stuck > 1 hour
    succeeded --> [*]
    failed --> [*]
    requires_manual_resolution --> [*]
```

| State                        | Description                                                                                                                                                |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pending_approval`           | Awaiting manual approval from a Winam operator                                                                                                             |
| `approved`                   | Approved — being submitted to the provider                                                                                                                 |
| `provider_submitted`         | USSD transfer sent. Transient: a successful USSD response is **final** for a withdrawal, so the transaction moves straight to `succeeded` in the same step |
| `succeeded`                  | Transfer confirmed — player received funds (the operator `provider_tx_id` may be backfilled from the SMS afterwards, without re-sending the webhook)       |
| `failed`                     | Rejected by operator, provider refusal, or insufficient SIM balance                                                                                        |
| `requires_manual_resolution` | Transaction stuck — human intervention required (escalated automatically after 1 hour)                                                                     |

***

## Terminal states & webhooks

Only the two terminal states trigger a webhook to your `callback_url`:

| Event               | Terminal state |
| ------------------- | -------------- |
| `payment.succeeded` | `succeeded`    |
| `payment.failed`    | `failed`       |

`requires_manual_resolution` is **not** terminal and sends **no** webhook. It is a holding state awaiting a Winam operator decision; once resolved to `succeeded` or `failed`, the matching webhook is sent.
