Order lifecycle
This page explains how an Order progresses from ingestion to closure. It also shows how Order status rolls up from fulfillment orders and Shipments. All three lifecycles are distinct but connected; knowing how they relate is the foundation of order management.
Status flow
An Order's status is computed from the statuses of its Fulfillment orders. Fulfillment order status is in turn computed from the statuses of its line items. The progression looks like:
open → partially_allocated → allocated → processing → fulfilled → closed
↘ cancelled (alternative terminal)
| Status | Meaning |
|---|---|
open | No fulfillment orders yet, or all FOs are still open. |
partially_allocated | Some FOs are allocated; others are still open. |
allocated | All FOs reached at least allocated. |
processing | At least one FO is in pick / pack / fulfillment. |
fulfilled | All FOs are fulfilled (or in a terminal state). |
closed | All Shipments delivered → line items closed → FOs closed → Order closed. |
cancelled | Every FO was cancelled. |
For the full criteria, see Order status codes.
How the rollup works
The cascade from leaf to root:
- A Shipment reaches
delivered. - Every line item linked to that Shipment moves to
closed. - The fulfillment order moves through
processing→fulfilled→closedas its line items reach those states. - The Order moves through
allocated→processing→fulfilled→closedas its FOs reach those states.
Cancellations propagate the same way: when every leaf is cancelled the parent flips to cancelled.
See Fulfillment order status codes and Line item status codes for the full criteria at each level.
Order status vs shipment status
A common point of confusion. They're related but answer different questions:
| Status | Question it answers |
|---|---|
| Order status | "How far through fulfillment is this customer purchase?" |
| Shipment status | "Where is this specific parcel right now?" |
An Order can be fulfilled while one of its Shipments is still
in_transit. The Order moves to fulfilled once handover is
complete; delivery (and the cascade to closed) can follow
later.
Allocation timing
When does allocation happen? Two patterns:
- At ingestion. Allocation rules fire as soon as the order lands. Fulfillment orders are created and allocated immediately. Best when inventory and rules are stable enough to commit early.
- On-demand. The Order sits in
openwhile ops or an upstream system decides allocation. Fulfillment orders are produced manually or via a deferred rule run.
Both are valid. Most integrations pick at-ingestion for speed; ops override (re-allocate) when needed.
Cancellation semantics
Cancelling the whole Order. An Order can be cancelled only
while it's in open, partially_allocated, or allocated.
Once any FO enters processing, wholesale order cancellation
is no longer allowed. Cancellation must then happen at the
fulfillment order or line-item level.
Cancelling a fulfillment order that has already been
fulfilled. A fulfilled FO must be unfulfilled before it
can be cancelled. Unfulfilling reverses the fulfillment state
and cascades back to Shipments. Any Shipment whose items all
become unfulfilled is automatically cancelled, provided the
Shipment is still in a cancellable state.
Partial cancellation. Cancelling a single line item or
Fulfillment order while leaving the others in place is
supported. The Order continues toward fulfilled / closed
based on the lines that did fulfil.
Closing an order from external status updates
When a partner system books and tracks the parcel outside
Carriyo, Carriyo can still act as the order of record. Use
POST /orders/shipment-status-update to push a Shipment
payload keyed by references.partner_order_reference. When
post_shipping_info.status is delivered, Carriyo runs the
standard auto-close logic on the matched fulfillment line
items. That cascade propagates through to fulfillment order
and Order status.
The payload uses the Carriyo Shipment shape, so a partner system can forward what it already has, with no shape translation needed. Shopify-sourced orders are skipped (Shopify manages its own order closure).
Audit and diagnostics
Every order exposes two log types:
- Change logs.
GET /orders/{reference}/change-logsreturns the transactional history of the order itself: creation, status transitions, field updates, line-item changes. Sorted oldest-first by default; passsort_order=DESCfor newest-first. - System logs.
GET /orders/{reference}/system-logsreturns a paginated list of integration log entries: outbound API calls, webhook deliveries, and other traffic associated with the order. Filter bycorrelation_id,event_type,request_type, or HTTP response code. For a single entry's full request/response payload, callGET /orders/{reference}/system-logs/{identifier}to get a time-limited presigned URL to the S3-stored body. You can also push entries inbound viaPOST /orders/{reference}/system-logsto record your own middleware traffic against the order.
Change logs answer "what changed and when"; system logs answer "what did the integrations actually exchange". Together they're the first diagnostic stop when an order looks wrong.