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

# Orders

> Secure order creation, statuses, and nickname changes.

A customer can create an order without an account. The built-in storefront checkout is the safest integration: it displays the current legal documents, collects the required consents, creates an idempotency key, and obtains a Turnstile token.

## Creation

If you build a custom checkout, first fetch the current storefront and show the legal documents selected by the shop. Submit their exact `legalDocumentVersion` with the three informed consents:

```bash theme={null}
curl -X POST https://api.itemshop.dev/api/v2/orders \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: <random-32-to-128-character-value>" \
  -H "cf-turnstile-response: <widget-token>" \
  -d '{
    "productId": "<productId>",
    "nickname": "Steve",
    "paymentMethodName": "imojeTransfer:blik",
    "email": "customer@example.com",
    "quantity": 1,
    "termsAccepted": true,
    "immediatePerformanceConsent": true,
    "withdrawalAcknowledged": true,
    "legalDocumentVersion": "<64-character-SHA-256-of-the-documents-shown>"
  }'
```

Reuse an `Idempotency-Key` only for an identical retry. A new purchase attempt needs a new random key. In production, a missing Turnstile token or a stale/mismatched legal-document version blocks checkout.

The guest response contains limited data, a `redirectUrl`, `orderId`, and an opaque `statusToken`. Store that capability only on the client that needs to track the order; never put it in logs or a public URL.

## Statuses

| Status       | Meaning                              |
| ------------ | ------------------------------------ |
| `pending`    | Created, awaiting payment            |
| `paid`       | Paid and ready for plugin fulfilment |
| `processing` | The plugin started fulfilment        |
| `completed`  | The plugin acknowledged fulfilment   |
| `cancelled`  | Cancelled                            |
| `failed`     | Payment failed                       |
| `dispute`    | Dispute                              |

The customer reads the limited status through `GET /orders/public/{orderId}/status` with the capability returned by checkout:

```bash theme={null}
curl https://api.itemshop.dev/api/v2/orders/public/<orderId>/status \
  -H "x-order-status-token: <statusToken>"
```

`GET /orders/payment-status/{orderId}` exposes additional provider data and therefore requires a Bearer session for a user who can access the order's shop.

## Changing status (dashboard or integration)

A user with access or a shop key with `orders:write` can change status manually:

```bash theme={null}
curl -X PUT https://api.itemshop.dev/api/v2/orders/<shopId>/orders/<orderId>/status \
  -H "X-API-Key: <shop-key>" \
  -H "Content-Type: application/json" \
  -d '{ "status": "completed", "reason": "Fulfilled manually" }'
```

## Nickname change

Before fulfilment completes, a customer can change the nickname by confirming a code sent to the email stored on the order:

<Steps>
  <Step title="Request a code">
    `POST /orders/public/{orderId}/nickname/request-change` with the order's email. The API sends a 6-digit code valid for 10 minutes.
  </Step>

  <Step title="Confirm">
    `POST /orders/public/{orderId}/nickname/change` with the code and new nickname. After verification, the nickname changes and the previous value remains in history.
  </Step>
</Steps>
