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

# Webhooks overview

> Get notified when payments confirm and orders complete.

The retailer surface delivers signed webhooks for payment, order, and refund events. Configure one endpoint per account, verify every delivery's signature, and fetch the authoritative state with the API when an event arrives.

<Info>
  Webhooks fire for **retailer** checkouts. B2B orders have a separate, simpler [legacy callback](/webhooks/b2b-callback).
</Info>

## Set up your endpoint

<Steps>
  <Step title="Register the URL">
    ```bash theme={null}
    curl -X PUT https://api.wizzgift.com/retailer/v1/webhook \
      -H "X-API-Key: wg_live_..." \
      -H "Content-Type: application/json" \
      -d '{
        "url": "https://yourshop.com/wizzgift/webhook",
        "events": ["order.completed", "order.partial", "order.failed"]
      }'
    ```

    * The URL must be **https** with a public hostname — IPs, localhost, and internal hosts are rejected.
    * Omit `events` (or send `null`) to subscribe to everything.

    <Warning>
      The response includes `secret` (`whsec_...`) **only on first create**. Store it now — later updates return the config without it, and the only way to get a new one is rotation.
    </Warning>
  </Step>

  <Step title="Verify your handler">
    Send a synchronous signed ping and check your endpoint's actual response:

    ```bash theme={null}
    curl -X POST https://api.wizzgift.com/retailer/v1/webhook/test \
      -H "X-API-Key: wg_live_..."
    ```

    ```json Response theme={null}
    { "ok": true, "status": 200 }
    ```

    Use this to test your [signature verification](/webhooks/verify-signatures) end to end before going live.
  </Step>

  <Step title="Handle deliveries">
    Each delivery is a `POST` with a JSON envelope and three headers:

    | Header                 | Contents                                               |
    | ---------------------- | ------------------------------------------------------ |
    | `X-Wizzgift-Signature` | `t=<unix-ms>,v1=<hmac-hex>` — verify on every delivery |
    | `X-Wizzgift-Event`     | Event type, for routing before parsing                 |
    | `X-Wizzgift-Delivery`  | Delivery id (`whd_...`) — your idempotency key         |

    Respond with any `2xx` within 10 seconds. Do heavy work asynchronously — acknowledge first, process after.
  </Step>
</Steps>

## Delivery guarantees

* **Retries:** failed deliveries are retried up to 5 times with exponential backoff. A delivery that exhausts retries is marked `failed` in the delivery log.
* **Idempotency:** retries reuse the same delivery id — deduplicate on `X-Wizzgift-Delivery` (also in the body as `id`).
* **Ordering is not guaranteed.** Treat events as *hints* and read the authoritative state with `GET /retailer/v1/checkouts/{id}`.
* **Card codes are never in webhook payloads.** The webhook tells you when to fetch; the authenticated GET returns the codes.

## Per-checkout override

Pass `callbackUrl` on `POST /retailer/v1/checkouts` to route that checkout's events to a different URL — useful for multi-tenant platforms. The override is signed with the same business secret, so a business-level endpoint must exist (it holds the secret). Without one, per-checkout URLs are ignored and you are on polling only. The endpoint's event filter applies to overrides too.

## Debugging deliveries

```bash theme={null}
curl "https://api.wizzgift.com/retailer/v1/webhook/deliveries?checkoutId=chkr_ab12cd34" \
  -H "X-API-Key: wg_live_..."
```

Returns recent delivery attempts with status (`sent` / `failed`), attempt counts, and a SHA-256 hash of the delivered body — enough to confirm what was sent and when without storing payloads.

## Endpoint management

| Operation                   | Endpoint                              |
| --------------------------- | ------------------------------------- |
| Create / update             | `PUT /retailer/v1/webhook`            |
| Read config (secret masked) | `GET /retailer/v1/webhook`            |
| Rotate secret               | `POST /retailer/v1/webhook/rotate`    |
| Test ping                   | `POST /retailer/v1/webhook/test`      |
| Delivery log                | `GET /retailer/v1/webhook/deliveries` |
| Delete                      | `DELETE /retailer/v1/webhook`         |
