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

# Order Tracking

> Poll the authoritative checkout result and display a protected receipt.

After Stripe redirects back to the storefront, recover the cart session from tab-scoped storage and poll the protected order-result endpoint.

## Result states

| State             | Meaning                                                          |
| ----------------- | ---------------------------------------------------------------- |
| `payment_pending` | Stripe has not reached a terminal payment state                  |
| `order_pending`   | Payment succeeded and Crave is finalizing the order              |
| `completed`       | The response contains the public order detail                    |
| `failed`          | Checkout reached a terminal failure with a machine-readable code |

```ts theme={null}
async function waitForOrder(locationId: string, cartId: string) {
  for (let attempt = 0; attempt < 40; attempt += 1) {
    const result = await storefront.checkout.getOrderResult(locationId, cartId);
    if (result.state === "completed" || result.state === "failed")
      return result;
    await new Promise((resolve) =>
      setTimeout(resolve, Math.min(1000 + attempt * 250, 3000)),
    );
  }
  throw new Error("Order confirmation is taking longer than expected.");
}
```

Do not treat a redirect, cart lock, timeout, or missing response as success. Keep the capability until terminal handling finishes, then clear it from persisted storage.

## Receipt links

Guest receipt links place a receipt capability in the URL fragment so browsers do not send it to servers as part of the request URL. Capture it in the browser, immediately remove it with `history.replaceState`, store it in versioned, tab-scoped `sessionStorage` keyed by API environment, merchant, and receipt ID, and send it as `X-Receipt-Token`:

```ts theme={null}
const order = await storefront.receipts.get(receiptId, { receiptToken });
```

A signed-in customer can access their own order through the customer JWT instead. Receipt identifiers alone never authorize access.

## Ratings

Submit a rating while the completed cart capability is still available in memory:

```ts theme={null}
await storefront.ratings.submit(locationId, cartId, {
  rating: 5,
  comment: "Great food and fast service.",
});
```

<CardGroup cols={2}>
  <Card title="Error Codes" icon="triangle-exclamation" href="/guides/error-codes">
    Handle terminal and retryable failures.
  </Card>

  <Card title="SDK Reference" icon="code" href="/getting-started/storefront-sdk">
    Review all checkout and receipt methods.
  </Card>
</CardGroup>
