Understanding the order lifecycle
In Propeller, orders, quotes and quote requests are all the same object: an Order. What distinguishes them is the combination of type and status on the order. This unified model means you query, display and manage all three using the same API. Understanding how the order lifecycle works helps you build checkout flows, quote request forms, order history pages and status displays correctly.
The unified order model
Every order in Propeller has two fields that define what it represents:
type(OrderType) categorizes the order by its business purpose.status(a string matching a configured OrderStatus code) determines where the order sits in its lifecycle.
OrderType
The type field is an enum with four values:
| Type | Purpose |
|---|---|
dropshipment | A standard order fulfilled by shipping to the customer |
quotation | A quote or quote request |
purchase | A purchase order (procurement) |
stock | A stock order (internal inventory) |
For most frontend applications, you work with dropshipment (orders) and quotation (quotes and quote requests).
OrderStatus
Each order status is a configured object with its own fields:
| Field | Description |
|---|---|
code | The status identifier (e.g. NEW, QUOTATION, SHIPPED) |
name | Human-readable label |
orderType | Categorizes the status as ORDER, QUOTATION or REQUEST |
type | Whether the status is SYSTEM (built-in) or CUSTOM (user-defined) |
isPublic | Whether the status is visible to customers |
isDefault | Whether this is the default status for its order type |
nextStatuses | Which statuses this status can transition to |
previousStatuses | Which statuses can transition to this status |
statusSet | The parent group this status belongs to |
The orderType field on a status is what ultimately tells you whether an order is a quote request (REQUEST), a quote (QUOTATION) or an order (ORDER).
How type and status combine
| What it represents | OrderType | OrderStatus orderType | Status examples |
|---|---|---|---|
| Quote request | quotation | REQUEST | QUOTE_REQUEST |
| Draft quote | quotation | QUOTATION | DRAFT_QUOTATION |
| Published quote | quotation | QUOTATION | QUOTATION |
| Order | dropshipment | ORDER | NEW, PROCESSING, SHIPPED |
Because quotes and orders share the same data model, you query them using the same orders query and filter by type or status to display the right records in the right context.
How orders are created
There are three paths to creating an order. Each produces the same Order object but serves a different use case.
Cart (storefront checkout)
The most common path for customer-facing applications. A customer builds a cart, sets addresses, selects shipping and payment, then converts the cart into an order using cartProcess.
cartStart → add items → set addresses → choose shipping → choose payment → cartProcess
The cartProcess mutation takes an orderStatus (typically UNFINISHED for orders requiring payment or NEW for orders on account) and returns the created order with its cartOrderId.
This is the path covered in Cart management and Checkout flow.
Tender (sales portal)
A tender is an extended cart used by sales representatives. It allows adjusting item prices, applying discounts, viewing margins and managing customer-specific pricing. Tenders are typically used in a sales portal, not in a frontend customer portal.
tenderStart → add items → adjust pricing and discounts → tenderProcess
Key differences from a cart:
| Aspect | Cart | Tender |
|---|---|---|
| User | Customer | Sales representative |
| Pricing | Fixed (based on price sheets and rules) | Adjustable per item |
| Discounts | Applied via action codes | Manually set with margin visibility |
| Owner | The customer placing the order | The sales rep (ownerId), separate from the customer |
| Output | cartProcess → order | tenderProcess → order |
When a tender is processed, it creates the same Order object as a cart would. The source field on the resulting order indicates where it originated (e.g. "Sales Portal").
Direct creation (API and admin)
For integrations and backend systems, orders can be created directly using the orderCreate mutation. This creates a complete order in a single call without going through the cart or tender flow.
All paths converge
Regardless of how an order is created, the result is the same Order object. The cartId field on an order indicates whether it originated from a cart. The source field records where the order came from.
Cart (storefront) ──→
Tender (sales portal) ──→ Order
orderCreate (API) ──→
Order statuses and transitions
Order statuses in Propeller are not just labels. They form a directed graph of allowed transitions. Each status defines which other statuses it can move to (nextStatuses) and which statuses can move to it (previousStatuses).
Status sets
Statuses are organized into sets (OrderStatusSet). A set is a named group of related statuses. This is useful for workflow organization, for example grouping all quote-related statuses into one set and all fulfillment statuses into another.
Common statuses
These are common system statuses found in a typical Propeller environment. Statuses are fully configurable, so your environment may have different codes and transitions.
| Status code | Order type | Description |
|---|---|---|
QUOTE_REQUEST | REQUEST | Customer submitted a quote request |
DRAFT_QUOTATION | QUOTATION | Sales rep is drafting a quote (not visible to customer) |
QUOTATION | QUOTATION | Published quote, visible to customer |
UNFINISHED | ORDER | Order created, awaiting payment |
NEW | ORDER | Confirmed order |
PROCESSING | ORDER | Order is being processed |
SHIPPED | ORDER | Order has been shipped |
COMPLETED | ORDER | Order delivered and completed |
Enforced transitions
The orderSetStatus mutation enforces valid transitions. If you attempt a transition that is not allowed by the status configuration, the API returns an ORDER_STATUS_TRANSITION_NOT_ALLOWED error.
The orderSetStatus input accepts:
| Field | Description |
|---|---|
orderId | The order to update |
status | The new status code |
payStatus | Optional payment status update |
sendOrderConfirmationEmail | Whether to send a confirmation email |
addPDFAttachment | Whether to attach a PDF to the email |
deleteCart | Whether to delete the originating cart |
Public vs. internal statuses
The isPublic flag on a status controls whether it is visible to customers. Internal statuses (where isPublic is false) are only visible to admin users and sales representatives. Use this flag to decide which statuses to display in a customer-facing order history page.
Example lifecycle: quote to order
This example walks through a complete lifecycle from quote request to fulfilled order, showing how the same Order object moves through different statuses.
1. Customer submits a quote request
A customer builds a cart and processes it with a quote request status. The resulting order has type quotation and status QUOTE_REQUEST.
2. Sales rep creates a draft quote
A sales representative opens the order in the sales portal and adjusts pricing and discounts. The status moves to DRAFT_QUOTATION. This status is not public, so the customer cannot see the draft.
3. Sales rep publishes the quote
When the quote is ready, the sales rep transitions the status to QUOTATION. This status is public, so the customer can now view the quote and its pricing. The quote may have a validUntil date after which it expires.
4. Sales rep revises the quote
If changes are needed, the sales rep transitions back to DRAFT_QUOTATION, makes adjustments and publishes again. Each change is tracked in the version history (see below).
5. Customer accepts the quote
The customer accepts the quote, which transitions the status from QUOTATION to an order status like NEW. At this point the order type remains quotation but the status order type changes from QUOTATION to ORDER.
6. Order moves through fulfillment
The order progresses through fulfillment statuses: PROCESSING → SHIPPED → COMPLETED. Shipments are created and tracked along the way.
QUOTE_REQUEST → DRAFT_QUOTATION → QUOTATION → DRAFT_QUOTATION → QUOTATION → NEW → PROCESSING → SHIPPED → COMPLETED
(1) (2) (3) (4) (4) (5) (6) (6) (6)
Version history
Orders track every change as a revision. Each revision stores a sequential number, a timestamp, who made the change and a snapshot of the order state at that point.
Revision fields
| Field | Description |
|---|---|
revisionNumber | Sequential number, starting at 1 |
createdAt | When the revision was created |
createdByAdminUser | The admin user who made the change (if applicable) |
createdByContact | The contact who made the change (if applicable) |
createdByCustomer | The customer who made the change (if applicable) |
createdFromRevisionNumber | The revision this one was branched from |
Snapshots
Each revision contains a snapshot of the order state, including the status, type and visibility flags. Two fields are particularly relevant for frontends:
public: whether this revision is visible to customers.publicVersionNumber: the version number that customers see.
Public revisions get an incrementing publicVersionNumber. Private revisions (like draft edits) do not increment this number and are not visible to customers.
Example revision trail
For the quote-to-order lifecycle described above, the revision history might look like this:
| Revision | Status | Public | Customer sees |
|---|---|---|---|
| 1 | DRAFT_QUOTATION | No | Nothing |
| 2 | QUOTATION | Yes | Version 1 |
| 3 | DRAFT_QUOTATION | No | Still version 1 |
| 4 | QUOTATION | Yes | Version 2 |
| 5 | NEW | Yes | Version 3 (order confirmed) |
Revision mutations
Two mutations manage revisions:
orderRevisionRestorerestores an order to a previous revision state. TakesorderIdandrevisionNumber.orderRevisionsInvalidatemarks specific revisions as invalid.
Shipment tracking
After an order is confirmed, shipments track the physical fulfillment. Each shipment has a status that progresses through delivery stages:
| Status | Description |
|---|---|
CREATED | Shipment record created |
PROCESSING | Being prepared |
IN_TRANSIT | Picked up by carrier |
OUT_FOR_DELIVERY | Out for final delivery |
DELIVERED | Successfully delivered |
PARTIALLY_DELIVERED | Some items delivered |
FAILED_DELIVERY | Delivery attempt failed |
CANCELED | Shipment canceled |
EXCEPTION | An exception occurred |
An order can have multiple shipments for partial deliveries. Each shipment can carry track-and-trace codes for carrier tracking.
Key fields on the Order object
These are the fields most relevant to understanding the order lifecycle. For complete field documentation, see the GraphQL API reference.
| Field | Description |
|---|---|
id | Auto-increment order ID |
uuid | UUID identifier |
status | Current status code |
type | Order type (dropshipment, quotation, purchase, stock) |
source | Where the order was created (e.g. webshop name, "Sales Portal") |
cartId | The originating cart ID, if created via cartProcess |
originalOrderId | Reference to the original order (for copies) |
validUntil | Expiry date (used for quotes) |
createdAt | Creation timestamp |
lastModifiedAt | Last modification timestamp |
statusDate | When the status was last changed |
companyId | The company this order belongs to |
invoiceUserId | The user responsible for payment |
items | The order line items |
total | Order totals (subtotal, tax, shipping, grand total) |
orderAddresses | Billing and shipping addresses |
shipments | Associated shipments |
What this means for your frontend
Understanding the order lifecycle helps you build the right features for each stage:
- Cart management creates and manages the mutable cart before checkout. See Cart management.
- Checkout flow sets addresses, shipping and payment on the cart and converts it to an order with
cartProcess. See Checkout flow. - Quote requests use
cartProcesswith a quote request status to submit the cart as a request for quotation. - Order history queries orders and filters by type or status to display the right records. Use
isPublicon statuses to decide which statuses to show customers. See Order history. - Payment integration handles the payment flow after
cartProcesscreates an order with statusUNFINISHED. See Payment integration. - Shipment tracking displays shipment statuses and track-and-trace codes for fulfilled orders.