Order status workflow

Every order has one of five statuses. The lifecycle is mostly linear — an order moves forward through the workflow — with a branch for cancellation at two early points.

The five statuses

StatusWhat it meansBadge color
SUBMITTEDThe order has been placed but you haven't acknowledged it yet. Default state for every new order.Blue
CONFIRMEDYou've accepted the order and are preparing to ship.Purple
SHIPPEDThe order is on its way to the customer.Yellow
DELIVEREDThe customer has it. End of the happy path.Green
CANCELLEDThe order was cancelled — either before confirmation or after, but always before shipping.Gray

The badge renders on the orders list, the order detail header, and customer- facing storefront pages. Customers see the same status you do — there's no hidden internal state.

Allowed transitions

       ┌──────────────┐
       │  SUBMITTED   │
       └──────┬───────┘
         ┌───▼─────────┐
         │             │
         ▼             ▼
┌──────────────┐  ┌─────────────┐
│  CONFIRMED   │  │  CANCELLED  │
└──────┬───────┘  └─────────────┘
   ┌───▼───────┐
   │           │
   ▼           ▼
┌─────────┐  ┌─────────────┐
│ SHIPPED │  │  CANCELLED  │
└────┬────┘  └─────────────┘
     ▼
┌───────────┐
│ DELIVERED │
└───────────┘

Written out:

FromCan move to
SUBMITTEDCONFIRMED, CANCELLED
CONFIRMEDSHIPPED, CANCELLED
SHIPPEDDELIVERED
DELIVERED(terminal — no transitions)
CANCELLED(terminal — no transitions)

A few things worth noting:

  • Once shipped, you can't cancel. The package is out there — the status has to move forward to DELIVERED. If a shipped order comes back to you (returns, refusal), that's handled out-of-band in your accounting system; Distribu doesn't model returns today.
  • Once cancelled or delivered, the order is done. There's no "reopen" button. If you made a mistake cancelling, place a new order for the same items.
  • There's no "PROCESSING" or "PACKING" status. If you want more granular fulfillment state, the notes field is the workaround — append lines like "Picked 2026-04-10" manually.

How to change status

From the dashboard

Open the order at /dashboard/orders/{id}. Below the order meta block, you'll see action buttons for every allowed transition from the current state:

  • On a SUBMITTED order: Confirm order (purple), Cancel order (red outline).
  • On a CONFIRMED order: Mark as shipped (yellow), Cancel order (red outline).
  • On a SHIPPED order: Mark as delivered (green).
  • On DELIVERED or CANCELLED: no buttons — the status is final.

Most buttons write the change and refresh the page immediately. Mark as shipped is the exception — it opens an inline form that captures tracking info first (see Shipment tracking below). No confirmation dialog, no undo — the transition rules above are the guardrail.

Shipment tracking

When you mark an order as SHIPPED, Distribu asks for tracking info before it accepts the transition. That info then flows through to the customer's order page and the shipping email, and into the order.status_changed webhook payload.

The inline form captures three fields:

  • Carrier — one of UPS, USPS, FEDEX, DHL, CANADA_POST, or OTHER.
  • Tracking number — required. Whitespace is stripped; 3–64 characters.
  • Tracking URL — optional for the named carriers (Distribu builds the correct URL automatically). Required when carrier is OTHER, since Distribu has no template to fall back to.

For the named carriers, the auto-generated URL points to the carrier's public tracking page (UPS's ups.com/track, USPS's tools.usps.com/go/TrackConfirmAction, etc.). If your 3PL issues you a branded tracking URL you'd rather use, paste it into the Tracking URL field and it overrides the default.

What the customer sees

The customer's order page at /store/{slug}/orders/{id} shows a blue "Your order is on its way" card with the carrier name, tracking number, and a Track package button that opens the tracking URL in a new tab.

The shipping email the customer receives includes the same carrier + tracking number + Track package button, so they can click through without logging in.

What staff see

Back on the dashboard order detail page, once tracking is captured a "Shipment tracking" card appears above the status controls with the carrier label, tracking number, and the same Track package link. Tracking details are immutable after they're set — if you need to correct them, contact support for now.

Webhook payload extension

The order.status_changed webhook for a SHIPPED transition includes a tracking sub-object alongside the usual fields:

{
  "tracking": {
    "carrier": "UPS",
    "number": "1Z999AA10123456784",
    "url": "https://www.ups.com/track?tracknum=1Z999AA10123456784"
  }
}

See Webhooks → Event types — order.status_changed for the full payload.

Via the REST API

PATCH /api/v1/orders/{id} with { "status": "CONFIRMED" }. Same rules apply — illegal transitions are rejected server-side. See REST API — Orders endpoints.

Side effects of status changes

Every status update has three side effects:

1. Audit log

An audit-log entry is written with action OrderStatusChanged, the actor (staff user or API key), and the from / to statuses as metadata. Visible in Settings → Audit log.

2. Webhook

Distribu fires an order.status_changed webhook event to every registered endpoint for your company. Payload includes:

{
  "id": "clxx...",
  "status": "CONFIRMED",
  "previousStatus": "SUBMITTED",
  "total": 134.50,
  "customerId": "clxx..."
}

See Webhooks → Event types for the full event reference and Webhooks → Signature verification for how to verify incoming payloads.

3. Customer email

If the order has a customerId (storefront or API-placed), the customer receives an email about the new status — confirmation, shipping, delivery, or cancellation notice.

Dashboard-created orders have no customer, so no email is sent on status changes.

Stock and status

Stock is decremented once, at order creation time, and only for storefront or API-placed orders. Status transitions — including CANCELLED — do not touch stock.

This is intentional. In B2B, most cancellations happen either before fulfillment (the units are still on the shelf) or after (the units shipped and won't come back). Automatically restocking on cancel would create a lot of ghost inventory adjustments that don't reflect what's actually in your warehouse.

If you do need to put units back into stock after a cancel, bump them up manually in Inventory — see Stock tracking → Adjusting stock.

What customers can do

Customers on the storefront can view their orders at /store/{slug}/orders and see the current status. They cannot change it — even cancel. If they want to cancel, they have to contact you, and you do it from the dashboard.

Contacts with the VIEWER role can view orders but can't place new ones (see Customer contacts). Neither role can edit existing orders.


Next: Filtering & search.