Order Statuses
You can configure the values for each of an order's three status types. This page is for a store administrator adding, renaming or retiring a status, and for a developer who needs to know what code reads.
Before you begin
- Order statuses are edited under KahunaCart → Settings → Order statuses.
- Editing them needs
kahunacart.orders.manage. Reading them needskahunacart.orders.view.
The three axes
Every order answers three questions at once. Each has its own column and its own list of values.
| Axis | Column | What it answers |
|---|---|---|
| Order status | status |
Is this a cart, a placed order, a canceled one? |
| Payment status | payment_status |
Where is the money? |
| Fulfillment status | fulfillment_status |
Where are the goods? |
The three move independently. An order can be placed, paid and unshipped, or placed, unpaid and shipped. No combination is invalid.
What ships, and what you can add
The values on each axis are rows in kahunacart_order_statuses. KahunaCart seeds thirteen. You can add, rename, recolour, reorder and switch off as many more as the store needs.
| Axis | Code | Label | Flag |
|---|---|---|---|
status |
cart |
In progress | new |
status |
completed |
Placed | complete |
status |
canceled |
Canceled | cancelled |
status |
archived |
Archived | complete |
payment_status |
pending |
Awaiting payment | new |
payment_status |
paid |
Paid | complete |
payment_status |
partially_refunded |
Partly refunded | complete |
payment_status |
refunded |
Refunded | cancelled |
payment_status |
failed |
Failed | new |
fulfillment_status |
unfulfilled |
Not shipped | new |
fulfillment_status |
partial |
Partly shipped | new |
fulfillment_status |
fulfilled |
Shipped | complete |
fulfillment_status |
na |
Digital | complete |
The flag is what code reads
Each status carries a flag. The flag is the only field with a fixed meaning across every store.
| Flag | Means | Examples |
|---|---|---|
new |
Has not happened yet | cart, pending, unfulfilled |
complete |
Has happened | completed, paid, fulfilled |
cancelled |
Came undone | canceled, refunded |
Code reads the flag, never the label, and only rarely the code. That is what makes a rename safe: a store that renames Placed to Auftrag erteilt keeps its reports, retention rules, permission checks and add-ons.
Four more columns describe what a status does.
| Column | Question |
|---|---|
counts_as_paid |
Has the money arrived at this payment status? |
reduces_stock |
Has stock left the shelf by the time an order reaches this status? |
restores_stock |
Do units go back on the shelf here? |
is_final |
Will anything further happen on this axis? |
is_final also decides whether an order needs unlocking before it can be edited. See Unlock a closed order.
What each flag decides
| The store asks | It reads |
|---|---|
| Which orders count towards a report | status flagged complete, and a payment status that is not both cancelled and final |
| Which orders a bulk action may be moved onto | Every enabled status code not flagged new, so cart and quote are never offered |
| Whether an order can be refunded | status flagged complete. Whether there is anything to send back is decided separately, by the captured payment |
| Whether a download still works | The payment status, stopped when you mark one final and cancelled |
| Which orders the retention sweep touches | The retention schedule |
| Whether the calculator still recalculates an order | status flagged new |
Add a status flagged complete beside completed and every one of those follows it, with nothing edited anywhere.
Add a status
- Go to KahunaCart → Settings → Order statuses.
- Pick the axis the status belongs to.
- Click Add a status.
- Enter a code: lowercase letters, digits and underscores. At most 16 characters on the order-status axis and 20 on the other two.
- Enter the label you see in the admin. This is free text and can be changed at any time.
- Choose the flag. It decides whether orders in this status count as sales.
- Set the four behaviour columns if the status needs them.
- Click Save.
The status appears in the admin's filters and in the status menu on the order detail.
Important
A status flagged complete on the status axis counts towards revenue in every report. A status flagged new is swept by the cart-retention rule if orders sit in it past cart.retention_days. Choose the flag before the label.
Warning
The code is permanent. Every order that reaches this status stores it, so it cannot be renamed afterwards.
Rename or recolour a status
- Go to KahunaCart → Settings → Order statuses.
- Choose the status.
- Edit the label, the colour or the position, and click Save.
The axis and the code are not editable. Every order already written carries the code.
Reorder an axis
- Go to KahunaCart → Settings → Order statuses.
- Drag the statuses on one axis into the order you want.
The order decides how statuses appear in filters and menus. It carries no meaning for code.
Delete a status
- Go to KahunaCart → Settings → Order statuses.
- Choose the status, then click Delete.
Two refusals, and both name what to do instead.
- A status KahunaCart ships with cannot be deleted.
cartis what a new cart is written as,paidis what download grants key off,refundedis what the reports subtract. You can rename, recolour, reorder and switch off a shipped status, but not remove it. - A status orders are standing in cannot be deleted. The refusal says how many. Move those orders to another status first.
Switching a status off is refused for the same reason: the admin filters and the storefront would stop naming a state those orders are in.
Statuses contributed by an add-on
An add-on registers statuses of its own on onKahunaCartRegisterOrderStatuses:
public function onKahunaCartRegisterOrderStatuses(Event $event): void
{
$event['registry']->contribute('status', 'awaiting_stock', [
'label' => 'Awaiting stock',
'colour' => 'warn',
'flag' => 'new',
'position' => 25,
]);
}
A contributed status lives for the request. It is not stored, it cannot be edited or deleted from the admin, and it disappears when the add-on is switched off. A contribution for a code the store already has is ignored: your own row always wins.
KahunaCart uses that extension point itself. The quote status on the status axis is contributed by the quote machinery rather than seeded by a migration. It is flagged new, it does not reduce stock, and it sits between cart and completed. See Quotes.
What replaced the old constants
The three axes were once thirteen constants on OrderRepository. The constants are still there and still hold the same strings, so a plugin that spells OrderRepository::STATUS_COMPLETED keeps working. They are no longer the list of what is possible.
Warning
An add-on that compares a stored status against OrderRepository::STATUS_* keeps running and quietly misses every status you added. Read the registry instead: KahunaCart::instance()->statusRegistry() answers flagOf(), countsAsPaid(), reducesStock(), restoresStock(), isFinal() and codesWithFlag(). Code that already holds an OrderRepository asks it directly with $orders->statuses(), which is the same object.
API and MCP tools
| Route | Tool | Permission |
|---|---|---|
GET /kahunacart/order-statuses |
list_order_statuses |
kahunacart.orders.view |
POST /kahunacart/order-statuses |
create_order_status |
kahunacart.orders.manage |
PATCH /kahunacart/order-statuses/{id} |
update_order_status |
kahunacart.orders.manage |
DELETE /kahunacart/order-statuses/{id} |
delete_order_status |
kahunacart.orders.manage |
POST /kahunacart/order-statuses/reorder |
reorder_order_statuses |
kahunacart.orders.manage |
Related
- Order changes — staged edits, versioning, returns, and the unlock
is_finalgates - Orders and the admin — the order detail and what each axis controls there
- Reports and the rollup — which statuses count towards revenue
- Customers, wishlists, reviews and retention — the retention rules that read these flags
- Events —
onKahunaCartRegisterOrderStatuses - REST API — every route with its permission