---
id: order-lifecycle
title: "Order lifecycle"
sidebar_label: Order lifecycle
hide_title: true
description: "Management API - Order statuses and the actions each one allows"
---

import Ingress from '../../../src/components/ingress/ingress.react';

<Ingress title="Order lifecycle">
    Every order carries a status, and that status decides which actions Walley accepts. Read this
    page once and the state rules on each endpoint will make sense.
</Ingress>

## Where orders come from

An order can reach the Management API from more than one place. Whichever route created it, the
statuses and actions below work the same way.

- A customer completes a [Walley Checkout](/docs/checkout/introduction) session
- An [authorization in the tokenized flow](/docs/checkout/tokenization/authorization) succeeds
- An [AddInvoice](/docs/paymentsApi/integration/creating-purchases/addinvoice) call is made in the Payments API

Each of these raises a [`walley:order:created` webhook](/docs/webhooks/orders).

## The main path

An order starts uncaptured. You capture items as you ship them, and the order moves toward
`Activated`. If you never capture, it expires on the date in `expiresAt`.

```mermaid
stateDiagram-v2
    [*] --> NotActivated: Order is created
    NotActivated --> PartActivated: Capture some of the items
    NotActivated --> Activated: Capture the whole order
    PartActivated --> Activated: Capture what is left
    NotActivated --> Expired: expiresAt passes, nothing captured
    Activated --> Returned: Refund the whole order
```

Capturing is what triggers payout. Once an order is fully captured, the amount is marked for
payout to your bank account and the order joins the reconciliation report.

## Order statuses

The `status` field on the order tells you where it is.

| Status           | What it means                                                                                       |
| ---------------- | --------------------------------------------------------------------------------------------------- |
| `NotActivated`   | The order exists and nothing is captured yet. It expires at `expiresAt`.                            |
| `PartActivated`  | Some items are captured and some are not.                                                           |
| `Activated`      | Every item is captured. The amount is marked for payout.                                            |
| `Returned`       | The order has been fully refunded.                                                                  |
| `Expired`        | The order passed `expiresAt` without being captured. You can still cancel it.                       |
| `OnHold`         | Walley has not yet made a decision on the order. Wait for the [`walley:order:authorized` webhook](/docs/webhooks/orders). |
| `Closed`         | The order is settled and no longer open for changes. Capture and reauthorize both reject it.        |

## Item statuses

Each entry in `items` carries its own status, so a `PartActivated` order holds a mix of them.

| Status         | What it means                                                    |
| -------------- | ---------------------------------------------------------------- |
| `NotActivated` | Not captured yet.                                                |
| `Activated`    | Captured. `captureId` and `capturedAt` are set.                  |
| `Returned`     | Refunded. `refundedAt` is set.                                   |
| `Canceled`     | Canceled before capture. It will not be delivered, and it is never settled or paid out. On a direct payment method, the customer is refunded for it. |
| `Expired`      | The order expired before this item was captured.                 |

## What each status allows

Before you call an endpoint, check the order status against this table.

| Action                                                          | Allowed on                               | Notes                                                                    |
| --------------------------------------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------ |
| [Get order](/docs/manage/orders/get)                            | Any status                               | Reading is always safe.                                                  |
| [Capture order](/docs/manage/orders/capture)                    | `NotActivated`, `PartActivated`          | Rejected on `Closed` and `Expired`.                                      |
| [Reauthorize order](/docs/manage/orders/reauthorize)            | `NotActivated`, `PartActivated`          | Raising the amount works on credit payment methods only, not on prepaid. |
| [Refund order](/docs/manage/orders/refund)                      | `Activated`, `PartActivated`             | You can only refund what has been captured.                              |
| [Cancel order](/docs/manage/orders/cancel)                      | `NotActivated`, `PartActivated`, `Expired` | Cancels every uncaptured item. This cannot be undone.                    |

Calling an endpoint against the wrong status returns `422` with an error code that names the
problem. See [Errors](/docs/manage/errors).

## Two things worth knowing

**Capture and cancel are one-way.** A capture settles the items you shipped and a cancel releases
the ones you did not. Neither has an undo. To give money back after a capture, refund the order.

**An order that has not been captured will expire.** Check `expiresAt` on the order and capture
before that date. An expired order can no longer be captured, only canceled.

## Next steps

- [Asynchronous operations](/docs/manage/concepts/asynchronous-operations) explains why a status change is not visible the moment you get a response
- [Errors](/docs/manage/errors) covers the responses you get when a status blocks an action
