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

# Order Status & Tracking

> Identifiers, statuses and how to reliably find out the outcome of every order.

## Identifiers

| Identifier | Example | Who sets it | Use it for |
| - | - | - | - |
| `orderId` | `788fcae0-5214-403c-baa2-f318c0eb1b5b` | C2C | [Status queries](/api-reference/endpoints/query-order-status) and webhook matching. Always store it. |
| `orderReference` | `ORD-20261008120620-3f6b` | C2C | Human-readable reference shown to the customer and used with support. Also accepted by [status queries](/api-reference/endpoints/query-order-status). |
| `merchantOrderRef` | `INV-10045` | You (optional) | Your own reference, echoed in webhooks and [queryable](/api-reference/endpoints/query-order-status#query-by-merchantorderref). One live order per reference (see below). |
| `Idempotency-Key` | `INV-10045` | You (required) | Safe retries of order creation |

<Note>
  [Query order status](/api-reference/endpoints/query-order-status) accepts C2C's `orderId` or `orderReference`, or your own `merchantOrderRef`, and works with **any** of your API keys, including after a key rotation. If an order-creation call timed out before you got the `orderId`, retry it with the **same** `Idempotency-Key` (the response contains the original `orderId`), or look the order up by its `merchantOrderRef`.
</Note>

### `merchantOrderRef` rules

* It's optional. When you send it, only **one live order** can use a reference. Creating another order with a reference already used by an order that is in progress or completed returns `409`:
  `merchantOrderRef 'INV-10045' is already used by order ORD-…. Reuse the same Idempotency-Key to retry a request, or use a new reference for a new payment.`
* You **can** reuse a reference whose earlier order failed (`Rejected`, `Expired`, `CancelledTimeout`, `Cancelled`, `CancelledAuto`), for example to retry a checkout. A lookup by reference returns the **latest** order with that reference.

## Lifecycle stages

Every order also reports a canonical **stage** in the create-order response, [status inquiry](/api-reference/endpoints/query-order-status) and [webhooks](/guides/webhooks). Stages are the same for deposits and withdrawals, so you can branch on them instead of on individual statuses.

```text theme={null}
Awaiting → Assigned → Sent → Approved / Rejected → Completed / Failed
```

| Stage | Meaning |
| - | - |
| `Awaiting` | Accepted, waiting for an eligible member |
| `Assigned` | A member has the order. No money has been sent yet. |
| `Sent` | Deposit: the customer confirmed their payment on the payment page. Withdrawal: the member sent the payout. |
| `Approved` / `Rejected` | The member's decision |
| `Completed` | Settled: your merchant wallet was credited (deposit) or debited (withdrawal) |
| `Failed` | Final without settlement |

| Status | Stage |
| - | - |
| `Awaiting` | `Awaiting` |
| `Queued`, `AwaitingCustomerPayment`, `AwaitingMemberPayout` (and legacy `Assigned`, `Frozen`) | `Assigned` |
| `AwaitingMemberConfirmation` | `Sent` |
| `ManualReview` | `Sent` if the customer had already paid, otherwise `Assigned` |
| `Completed`, `Confirmed` | `Completed` |
| `Rejected`, `Expired`, `CancelledTimeout`, `Cancelled`, `CancelledAuto` | `Failed` |

With today's processing, approval and rejection happen in the same step as completion or failure, so the current stage is normally one of the other five. The `lifecycle` timestamps (`awaitingAt`, `assignedAt`, `sentAt`, `approvedAt`, `rejectedAt`, `completedAt`, `failedAt`) still record each step, or are `null` if it wasn't reached. For a withdrawal, the member's single confirmation means `sentAt`, `approvedAt` and `completedAt` share one timestamp.

## Statuses

<Tabs>
  <Tab title="In progress">
    | Status | Order type | Waiting for |
    | - | - | - |
    | `Awaiting` | Both | An eligible member. Deposit: assigned when the customer opens the payment page. Withdrawal: assigned automatically as soon as a member is available — or, when you created it without `customerAccountNumber`, waiting first for the customer to enter their account on the hosted page. |
    | `Queued` | Deposit | Customer to open the payment page |
    | `AwaitingCustomerPayment` | Deposit | Customer to pay and confirm on the payment page: the last digits of the transaction ID, or on the QR methods the account they pay from. See [Payment methods](/guides/payment-methods#what-the-customer-submits). |
    | `AwaitingMemberConfirmation` | Deposit | Member to verify the payment |
    | `AwaitingMemberPayout` | Withdrawal | Member to send and confirm the payout |
    | `ManualReview` | Both | C2C operations to resolve the order |
  </Tab>

  <Tab title="Final: success">
    | Status | Meaning |
    | - | - |
    | `Completed` | Deposit received and credited / withdrawal paid out and debited |
    | `Confirmed` | Legacy equivalent of `Completed` (older orders) |
  </Tab>

  <Tab title="Final: not completed">
    | Status | Meaning |
    | - | - |
    | `Rejected` | Member rejected the order |
    | `Expired` | Deposit checkout link (15 minutes) expired before the customer paid |
    | `CancelledTimeout` | No eligible member became available in time (an `Awaiting` order reached its timeout) |
    | `Cancelled` | Cancelled by C2C or the member |
    | `CancelledAuto` | Cancelled automatically by the system |
  </Tab>
</Tabs>

Legacy orders can also show `Assigned` or `Frozen`. Treat both as in progress.

## Getting the outcome reliably

Use both mechanisms:

1. **Webhooks** for fast notification of every final outcome: `order.completed` or `order.failed`. See [Webhooks](/guides/webhooks).
2. **Status queries** as the source of truth: confirm a webhook before moving money, follow orders in `ManualReview` (no webhook until they're resolved), and catch deliveries that never reached you.

### Recommended polling schedule

| Phase | Interval |
| - | - |
| Customer is on the payment page (first \~15 minutes of a deposit) | every 5–10 s |
| `Awaiting` withdrawal (up to 120 minutes) | every 1–2 min |
| Waiting for member confirmation or payout | every 30–60 s |
| `ManualReview` | every 10–15 min |
| Final status reached | stop |

The Merchant API has no request rate limits, but prefer webhooks to tight polling loops and stop polling once an order is final.

## Handling each outcome

| Outcome | Deposit | Withdrawal |
| - | - | - |
| `Completed` / `Confirmed` | Fulfil the purchase | Mark the payout as paid |
| `Rejected`, `Expired`, `CancelledTimeout`, `Cancelled`, `CancelledAuto` | Don't fulfil. The customer can start a new checkout (new order, new `Idempotency-Key`). | Payout not made. Create a new withdrawal if appropriate. |
| `ManualReview` | Hold. The customer may already have paid. | Hold. Don't re-pay. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.