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

# Get Order Status

> Fetch the current status of an order by ID. Use this to poll for async completion after a payment is submitted.

## Overview

After creating an order with [`POST /v1/order`](/api-reference/order/create-order) and directing the user through an external payment flow, use this endpoint to poll for the outcome. The order `status` will progress from `STARTED` to one of the terminal states: `COMPLETED`, `FAILED`, or `EXPIRED`.

## Request

### Headers

<ParamField header="Authorization" type="string" required>
  Bearer token for the authenticated user. Format: `Bearer <userAccessToken>`
</ParamField>

<ParamField header="X-Client-ID" type="string" required>
  Your application's client ID, issued during onboarding.
</ParamField>

### Path Parameters

<ParamField path="orderId" type="string" required>
  The unique ID of a previously created order, as returned by `POST /v1/order`. Example: `"abcd_1234"`
</ParamField>

### Example Request

<CodeGroup>
  ```javascript Node.js theme={null}
  const response = await fetch(`https://api.baanx.com/v1/order/${orderId}`, {
    headers: {
      'X-Client-ID': 'your_client_id',
      'Authorization': `Bearer ${userAccessToken}`
    }
  });

  const order = await response.json();
  console.log(order.status); // e.g. "COMPLETED"
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      f'https://api.baanx.com/v1/order/{order_id}',
      headers={
          'X-Client-ID': 'your_client_id',
          'Authorization': f'Bearer {user_access_token}'
      }
  )

  order = response.json()
  print(order['status'])  # e.g. "COMPLETED"
  ```

  ```bash cURL theme={null}
  curl --request GET \
    --url https://api.baanx.com/v1/order/abcd_1234 \
    --header 'Authorization: Bearer <userAccessToken>' \
    --header 'X-Client-ID: your_client_id'
  ```
</CodeGroup>

## Response

### 200 — Success

```json theme={null}
{
  "requestId": "payment_1234",
  "orderId": "abcd_1234",
  "status": "COMPLETED",
  "paidAt": "2023-03-27 17:07:12.662+03",
  "metadata": {
    "paymentId": "abcpaymentId1234ABC",
    "txHash": "0x3a11a86cf218c448be519728cd3ac5c741fb3424",
    "note": "payment_refunded"
  }
}
```

<ResponseField name="requestId" type="string">
  The payment request identifier, correlating this order to a payment gateway transaction. Example: `"payment_1234"`
</ResponseField>

<ResponseField name="orderId" type="string" required>
  The unique identifier of the order.
</ResponseField>

<ResponseField name="status" type="enum" required>
  The current state of the order.

  | Value       | Description                                                        |
  | ----------- | ------------------------------------------------------------------ |
  | `STARTED`   | Order created; payment not yet confirmed. Continue polling.        |
  | `COMPLETED` | Payment received and order fulfilled successfully.                 |
  | `FAILED`    | Payment failed or was rejected. Check `metadata.note` for context. |
  | `EXPIRED`   | Order was not paid within the allowed time window.                 |
</ResponseField>

<ResponseField name="paidAt" type="string">
  Timestamp of when payment was confirmed. Only present when `status` is `COMPLETED`.
</ResponseField>

<ResponseField name="metadata" type="object">
  Additional context about the payment outcome. Individual fields may be absent depending on the result.

  <Expandable title="metadata fields">
    <ResponseField name="metadata.paymentId" type="string">
      The identifier assigned to the payment by the payment gateway.
    </ResponseField>

    <ResponseField name="metadata.txHash" type="string">
      The on-chain transaction hash for the crypto payment.
    </ResponseField>

    <ResponseField name="metadata.note" type="string">
      A short note providing context in failure cases, if available. Example: `"payment_refunded"`
    </ResponseField>
  </Expandable>
</ResponseField>

### Error Responses

<AccordionGroup>
  <Accordion title="401 — Authentication Error">
    The bearer token is missing, expired, or invalid.
  </Accordion>

  <Accordion title="403 — Authorization Error">
    The authenticated user does not have permission to access this order.
  </Accordion>

  <Accordion title="404 — Order Not Found">
    No order exists with the given `orderId`. Verify the ID matches one returned by `POST /v1/order`.

    ```json theme={null}
    {
      "error": "Order not found"
    }
    ```
  </Accordion>

  <Accordion title="498 — Invalid Client Key">
    The `X-Client-ID` header value is not recognised.
  </Accordion>

  <Accordion title="499 — Missing Client Key">
    The `X-Client-ID` header is absent from the request.
  </Accordion>

  <Accordion title="500 — Internal Server Error">
    An unexpected server error occurred. Retry with exponential backoff.
  </Accordion>
</AccordionGroup>

## Polling Pattern

Order completion is asynchronous. Poll this endpoint after the user completes the external payment step, stopping when `status` reaches a terminal value (`COMPLETED`, `FAILED`, or `EXPIRED`).

```javascript theme={null}
async function waitForOrderCompletion(orderId, clientId, accessToken) {
  const TERMINAL_STATES = ['COMPLETED', 'FAILED', 'EXPIRED'];
  const MAX_ATTEMPTS = 40; // ~2 minutes at 3s intervals
  const POLL_INTERVAL_MS = 3000;

  for (let i = 0; i < MAX_ATTEMPTS; i++) {
    const response = await fetch(`https://api.baanx.com/v1/order/${orderId}`, {
      headers: {
        'X-Client-ID': clientId,
        'Authorization': `Bearer ${accessToken}`
      }
    });

    if (!response.ok) throw new Error(`Unexpected error: ${response.status}`);

    const order = await response.json();

    if (TERMINAL_STATES.includes(order.status)) return order;

    await new Promise(resolve => setTimeout(resolve, POLL_INTERVAL_MS));
  }

  throw new Error('Order polling timed out. Please check back later.');
}

const order = await waitForOrderCompletion(orderId, clientId, accessToken);

if (order.status === 'COMPLETED') {
  // Unlock product, show success UI
} else {
  // Handle failure or expiry
  console.warn('Order did not complete:', order.metadata?.note);
}
```

## Related Endpoints

<CardGroup cols={2}>
  <Card title="Create Order" icon="plus" href="/api-reference/order/create-order">
    Initiate a new order and receive the `orderId` to track here.
  </Card>

  <Card title="Get Available Products" icon="list" href="/api-reference/order/get-products">
    Discover which products are available and eligible before ordering.
  </Card>
</CardGroup>
