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

# Order lifecycle

> How orders move from pending to completed, and where the codes live.

## Status model

Three levels track progress independently:

**Checkout / order** — the overall record:

| Status       | Meaning                           |
| ------------ | --------------------------------- |
| `pending`    | Created, awaiting payment         |
| `processing` | Paid, fulfillment running         |
| `completed`  | Every item fulfilled              |
| `partial`    | Some items fulfilled, some failed |
| `failed`     | Nothing could be fulfilled        |
| `expired`    | Never paid within the window      |

**Item** — one product line: `pending → processing → completed` or `failed`.

**Fulfillment** — one unit within a line (a line with `quantity: 3` gets three fulfillment entries): each carries its own `status`, code fields, and `fulfilledAt`.

## Reading codes

Codes live on the fulfillment entries once a unit completes:

```json theme={null}
{
  "index": 0,
  "status": "completed",
  "cardCode": "AQ4X-...-9PLM",
  "cardPin": "1234",
  "cardUrl": "https://redeem.example/...",
  "fulfilledAt": 1753142400000
}
```

* `cardCode` is the redeemable code; `cardPin` and `cardUrl` are present when the product uses them.
* Serial-less deliveries (direct top-ups to a player account) complete without any code fields — the item status is the receipt.

## Partial fulfillment

Large orders can partially succeed: the order lands on `partial`, completed units carry codes, and failed units carry a customer-safe `errorMessage`. Request a refund for the failed portion — the refund amount is computed from the failed quantities automatically.

<Note>
  `errorMessage` on fulfillments is always a mapped, customer-safe message. Raw vendor errors are never exposed through the API.
</Note>

## Sealed cards

Pass `sealCards: true` at creation to deliver codes *sealed*:

* The fulfillment carries `sealed: true` and a `giftCardId` instead of plain code fields.
* The recipient reveals the card on the Wizzgift hosted page — useful when you do not want plain codes passing through your systems.
* Default is `false`: codes come back in plain form.

## Polling guidance

* Poll the detail endpoint (`GET /b2b/orders/{id}` or `GET /retailer/v1/checkouts/{id}`) every few seconds after payment confirms; most orders finish within a minute.
* On the retailer surface, prefer [webhooks](/webhooks/overview) and use polling as the fallback. Webhooks tell you *when* to fetch; the GET is always the source of truth.
* Statuses only move forward. Once you observe `completed`, `partial`, or `failed`, the order is terminal (refunds are a separate record).
