> ## 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.

# Idempotency

> Retry order creation safely with externalRef.

Network timeouts happen. `externalRef` — your own order id — makes `POST /b2b/orders` and `POST /retailer/v1/checkouts` safe to retry.

## How it works

Send your internal order id (up to 128 characters) with the create call:

```json theme={null}
{
  "externalRef": "shop-order-889",
  "items": [{ "productId": "prod_x", "skuId": "sku_y", "amount": 25, "quantity": 1 }]
}
```

* **First call** creates the order and returns `201`.
* **Any repeat** with the same `externalRef` on the same surface returns `200` with the *existing* order — no duplicate charge, no duplicate fulfillment.
* **Cross-surface reuse** returns `409 CONFLICT`: `externalRef` is unique per account across both surfaces, so a ref already used on `/b2b` cannot be reused on `/retailer/v1` (and vice versa). Treat this as an integration bug, not a replay.

## The retry recipe

```text theme={null}
1. Generate the externalRef from your own order id (stable, not random per attempt).
2. POST the create call.
3. On timeout, connection error, or 5xx: retry the same request unchanged.
4. Stop on any 2xx (201 = created now, 200 = already existed) or a non-retryable 4xx.
```

<Warning>
  Never generate a fresh `externalRef` per retry attempt — that defeats the mechanism and can double-charge your balance.
</Warning>

## Reconciliation

`externalRef` is also a filter on the list endpoints, which makes reconciling against your own database a single call per order:

```bash theme={null}
curl "https://api.wizzgift.com/b2b/orders?externalRef=shop-order-889" \
  -H "X-API-Key: wg_live_..."
```

Webhook payloads echo `externalRef` too, so you can match events to your records without a lookup.

## Related idempotency behavior

* **Payment invoices** — re-creating a payment with the same method refreshes the same provider invoice instead of creating a second one.
* **Webhook deliveries** — each delivery has a stable id (`whd_...`) that retries reuse; deduplicate on it. See [verifying signatures](/webhooks/verify-signatures).
