E-commerce Order Lifecycle State Machine

State Machines · state diagram · CC-BY-4.0

Complete e-commerce order state machine — from Created through Paid, Fulfillment, Shipped, Delivered, plus all the failure modes (PaymentFailed, Backordered, ReturnedUndelivered, Cancelled, Refunded).

Source: https://shopify.engineering/
Curated by Archigram editorial
ecommerce state-machine order payment fulfillment

Mermaid source

stateDiagram-v2
    [*] --> Created
    Created --> AwaitingPayment: place order

    AwaitingPayment --> PaymentFailed: card declined
    PaymentFailed --> AwaitingPayment: retry
    PaymentFailed --> Cancelled: give up

    AwaitingPayment --> Paid: payment authorised
    Paid --> Cancelled: customer cancels

    Paid --> InFulfillment: warehouse picks
    InFulfillment --> Backordered: out of stock
    Backordered --> InFulfillment: stock arrives
    Backordered --> Cancelled: too long

    InFulfillment --> Shipped: handed to carrier
    Shipped --> InTransit
    InTransit --> Delivered
    InTransit --> ReturnedUndelivered: failed delivery
    ReturnedUndelivered --> InFulfillment: re-ship
    ReturnedUndelivered --> Refunded: give up

    Delivered --> ReturnRequested: customer return
    ReturnRequested --> Returned: warehouse confirms
    Returned --> Refunded
    Delivered --> [*]: 30-day window closes

    Cancelled --> Refunded: refund issued
    Refunded --> [*]

What this diagram shows

An e-commerce order lifecycle with explicit handling for the unhappy paths that account for a surprisingly large fraction of real orders. After Created, the order moves through AwaitingPayment, with PaymentFailed → retry / give-up loops. Once Paid, it enters InFulfillment, where Backordered is a first-class state with its own re-entry and timeout transitions. Shipped → InTransit → Delivered is the happy path; ReturnedUndelivered and the post-delivery ReturnRequested → Returned → Refunded loops cover the rest. Cancellations from any pre-shipped state route to Refunded.

When to use it

Reach for an explicit state machine like this any time multiple teams (checkout, payments, warehouse, carrier integration, customer support) need to coordinate around the same record without stepping on each other. It is also valuable as documentation when onboarding new engineers — they can see what states exist, what transitions are legal, and what the failure modes are without grepping the codebase.

How to adapt it for your project

Implement this in code with a state-machine library (XState, statelyai, robot, or a hand-rolled enum + transition table). Persist the current state on the order row and the transition history in a separate event-log table — that gives you both fast reads and a full audit trail. For partial fulfillment (multiple shipments per order), promote shipment to its own entity with its own state machine. For subscriptions, replace the post-delivery branch with a recurring-cycle state machine and reuse the payment branch.

Key concepts

Related diagrams