Fulfillment states
Fulfillment lifecycles are shared across all 5 fulfillment types (shipment, digital, access, service, in_person). The terminal definition varies by type.
State machine
stateDiagram-v2 [*] --> pending: POST /fulfillments pending --> in_progress: shipment label created / digital prepared / access pending in_progress --> fulfilled: shipped+delivered / file delivered / access granted / service complete / in-person handoff pending --> cancelled: merchant cancels before in_progress in_progress --> cancelled: merchant cancels mid-fulfillment cancelled --> [*] fulfilled --> [*]
States
pending— fulfillment row created, no provider activity yet.in_progress— provider has acknowledged the work (label printed, digital file prepared, access pending). Firesfulfillment.shippedfor shipment type.fulfilled— terminal. Per type:shipment— carrier marks delivered (fulfillment.delivered).digital— file generated and a presigned URL was returned at least once.access— access grant row inserted and active.service/in_person— merchant marks complete via API.
cancelled— terminal. Reachable frompendingorin_progress. For shipment, cancelling after label creation requires merchant void via the carrier.
When the order is considered fulfilled
All-or-nothing roll-up
The parent order transitions to
fulfilled only when every attached fulfillment row reaches fulfilled. A mix of fulfilled + cancelled rows means the order moves to fulfilled as long as at least one row was fulfilled and no rows remain in non-terminal states.