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

# Track Orders

> Follow an order through payment and delivery with polling or webhook events

After the buyer pays, track the order through payment and delivery so your UI can show progress and handle the outcome. There are two ways to track an order: poll the Get Order API or subscribe to webhooks.

## Poll the Get Order API

Fetch the order and watch `order.phase` plus each line item's `delivery.status` (`awaiting-payment` → `in-progress` → `completed` or `failed`):

`GET` `https://staging.crossmint.com/api/2022-06-09/orders/{orderId}` — see the [API reference](https://docs.crossmint.com/api-reference/headless/get-order.md).

> [!NOTE]
>
> Crossmint recommends a polling interval of about 2500ms and never below 500ms.

```tsx theme={null}
const getOrderDeliveryStatus = async () => {
    const res = await fetch(`https://staging.crossmint.com/api/2022-06-09/orders/${order.orderId}`, {
        method: "GET",
        headers: {
            "Content-Type": "application/json",
            "x-api-key": process.env.NEXT_PUBLIC_CROSSMINT_API_KEY,
            authorization: clientSecret, // required with a client-side API key — see /payments/concepts/environments-and-api-keys
        },
    });

    const refreshedOrder = await res.json();
    setOrder(refreshedOrder);

    return refreshedOrder.lineItems[0].delivery.status;
};

const pollDeliveryStatus = async () => {
    const intervalId = setInterval(async () => {
        try {
            const status = await getOrderDeliveryStatus();
            if (status === "completed") {
                clearInterval(intervalId);
            }
        } catch (e) {
            clearInterval(intervalId);
            console.error("Error polling delivery status: ", e);
        }
    }, 2500);

    // Stop polling after 60 seconds
    setTimeout(() => clearInterval(intervalId), 60000);
};
```

With a server-side API key, proxy the request through your own backend instead of calling Crossmint from the browser.

> [!WARNING]
>
> When `order.phase` reaches `completed`, it does not mean every item succeeded — check each line item's
> `delivery.status` individually. See [How Checkout Works](https://docs.crossmint.com/payments/concepts/how-checkout-works.md).

## Subscribe to Webhook Events

For server-side tracking, register a webhook endpoint to receive order lifecycle events instead of polling. Checkout webhooks notify you about payment and order events in real time — for example when an order is paid or delivered.

See [Webhook Events](https://docs.crossmint.com/payments/advanced/webhooks.md) for event types, payload shapes, and how to register your endpoint.

## Track Hosted Checkout Orders

Hosted Checkout opens in a separate window or tab. The SDK does not give your page a callback when the order completes. Use one of these methods:

* **Webhooks:** subscribe to [webhooks](https://docs.crossmint.com/payments/advanced/webhooks.md). This works for all Hosted orders.
* **Polling:** create the order on your server, then pass `orderId` and `clientSecret` to `CrossmintHostedCheckout`. Your app then knows the order ID and can poll the Get Order API as shown above.

## Next Steps

> [card] [Handle Errors](https://docs.crossmint.com/payments/guides/handle-errors.md)
>
> Surface declines and failures to buyers

> [card] [Webhooks](https://docs.crossmint.com/payments/advanced/webhooks.md)
>
> Event types, payloads, and registration
