Working with Draft Orders
What this covers
All actions you can perform while an order is DRAFT in Order-based Checkout: create, update metadata & addresses, add/read/remove lines, and delete.
At a glance
- All edits happen while the order is DRAFT.
- After placement, the Commercial Order becomes immutable; progression is reflected by Logistic Orders.
- This page is header-level for the order; detailed line payloads are shown only where relevant to DRAFT actions.
📑 Quick navigation
- Create a DRAFT order
- Read a DRAFT order
- Update metadata (custom fields)
- Add lines
- Read lines
- Remove lines
- Update shipping information
- Update billing information
- Place (validate) the order
- Delete the order
🆕 Create a DRAFT order
Create an empty DRAFT order that becomes the single source of truth for the checkout session.
OperationId: ORDER-108
Endpoint: POST /v2/shop/commercial-orders
Behavior
- Initializes header-level fields (identifiers, scope, timestamps).
- May store snapshots for account/user.
- Does not pre-create lines by default.
- Supports order-level custom fields at creation.
Feature flag: required only when
sourceType=OPERATION(flagOPERATIONS). Not required forQUOTE.
{
"sourceType": "OPERATION | QUOTE",
"sourceId": "string",
"isFull": true,
"customFields": [
{
"customFieldId": "string",
"customFieldValue": "string"
}
],
"customFieldIdType": "DJUST_ID | EXTERNAL_ID"
}Default:
customFieldIdType = "EXTERNAL_ID".- When a source is provided,
isFulldefaults totrue.Response : 201 Created with the id and reference of the created order.
Line selection
- OPERATION
isFull=true: add all eligible & visible Operation lines.isFull=false: create empty order linked to the Operation; add lines later via ORDER-150.
- QUOTE
- Only
isFull=trueis supported (forced). - Attempt all quote lines; stock check only at init. Out-of-stock lines are ignored.
- Only
Flows
Standard creation
flowchart LR A[Request to create order] --> H[Headers & scope check<br>Account • Store • Store-view] H --> INIT[Initialize Draft<br>header fields • snapshots] INIT --> RES[Return Draft Order] %% ---------- Styles ---------- classDef sys fill:#f2f4f7,stroke:#475569,stroke-width:2px,color:#111827; classDef ok fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b; class A,H,INIT sys class RES ok style A rx:8,ry:8 style H rx:8,ry:8 style INIT rx:8,ry:8 style RES rx:8,ry:8
From QUOTE creation
flowchart LR IN[POST /v2/shop/commercial-orders<br>sourceType=QUOTE] --> AUTH[Auth & headers<br>dj-client=ACCOUNT - api-key] AUTH --> STORE[Resolve effective store<br>dj-store or tenant default] STORE --> ATT[Check store attachment<br>caller attached?] ATT -->|No| ERR403S[403 F-E-030] ATT -->|Yes| OWN[Check quote ownership<br>same account?] OWN -->|No| ERR403O[403 F-E-030] OWN -->|Yes| QST[Check quote status<br>WAITING_FOR_CUSTOMER & not expired] QST -->|No| ERR422S[422 F-E-040] QST --> LINES[Collect quote lines<br>stock check only] LINES --> NONE[No eligible line?] NONE -->|Yes| ERR422E[422 F-E-039] NONE -->|No| CREATE[Create Commercial Order<br>add eligible quote lines] CREATE --> OUT[201 Created] %% Styles classDef sys fill:#f2f4f7,stroke:#475569,stroke-width:2px,color:#111827; classDef ok fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b; classDef stop fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d; class IN,AUTH,STORE,ATT,OWN,QST,LINES,NONE sys class CREATE,OUT ok class ERR403S,ERR403O,ERR422S,ERR422E stop style IN rx:8,ry:8 style AUTH rx:8,ry:8 style STORE rx:8,ry:8 style ATT rx:8,ry:8 style OWN rx:8,ry:8 style QST rx:8,ry:8 style LINES rx:8,ry:8 style NONE rx:8,ry:8 style CREATE rx:8,ry:8 style OUT rx:8,ry:8 style ERR403S rx:8,ry:8 style ERR403O rx:8,ry:8 style ERR422S rx:8,ry:8 style ERR422E rx:8,ry:8
📘 Read a draft order
OperationId: ORDER-500
Endpoint: GET /v1/shop/commercial-orders/{commercialOrderId}
Path: {commercialOrderId}is the order identifier. In Order-based Checkout, using the business reference is recommended; if your tenant supports multiple id kinds on this route, add?idType=REFERENCE.
Query parameters
idType(optional) -DJUST_ID|EXTERNAL_ID|REFERENCE. Use when passing a non-default id kind.
Response (summary)
Header-level data only: identifiers, timestamps, orderLogisticPrices (aggregates), productCount, lineCount, account/user snapshots, and optional source { sourceType, sourceId }.
Lines are not included — use Read lines - (ORDER-561).
Example
GET /v1/shop/commercial-orders/FO-2025-000123?idType=REFERENCEResolution flow
flowchart LR IN[GET order] --> AUTH[Auth & headers<br>dj-client=ACCOUNT - api-key] AUTH --> SCOPE[Resolve effective scope<br>store / store-view] SCOPE --> RID[Resolve id by idType<br>DJUST_ID - EXTERNAL_ID - REFERENCE] RID --> FIND[Load Commercial Order<br>header only] FIND --> OUT[200 OK<br>order header] %% ---------- Styles ---------- classDef sys fill:#f2f4f7,stroke:#475569,stroke-width:2px,color:#111827; classDef ok fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b; class IN,AUTH,SCOPE,RID,FIND sys class OUT ok style IN rx:8,ry:8 style AUTH rx:8,ry:8 style SCOPE rx:8,ry:8 style RID rx:8,ry:8 style FIND rx:8,ry:8 style OUT rx:8,ry:8
✏️ Update metadata (custom fields)
Edit your own model with custom fields on a DRAFT order.
OperationId: ORDER-222
Endpoint: PUT /v2/shop/commercial-orders/{commercialOrderId}
Rules
- Only DRAFT is editable.
- Some fields are immutable (e.g., Order ID, creation timestamps).
- Stores and store-views must remain compatible with the buyer context.
Path parameter
{commercialOrderId}is the business reference (REFERENCE).- No
idTypequery; do not accept other id kinds (external/internal IDs).
{
"customFields": [
{
"customFieldId": "string",
"customFieldValue": "string"
}
],
"customFieldIdType": "DJUST_ID | EXTERNAL_ID"
}Default:
customFieldIdType = "EXTERNAL_ID".
➕ Add lines
Add or augment product lines on the DRAFT order.
OperationId: ORDER-150
Endpoint: PUT /v2/shop/commercial-orders/{commercialOrderId}/lines
Path: {commercialOrderId} is a REFERENCE (business ref only; no internal/external IDs).
{
"lineType": "OFFER_PRICE", // "OFFER_PRICE" | "PRODUCT_VARIANT" (default: OFFER_PRICE)
"lineIdType": "EXTERNAL_ID", // "EXTERNAL_ID" | "DJUST_ID" (today: EXTERNAL_ID only)
"customFieldIdType": "EXTERNAL_ID", // "EXTERNAL_ID" | "DJUST_ID" (default: EXTERNAL_ID)
"updateOrderCommercialLines": [
{
"id": "123456", // offer price id or variant id per lineType
"quantity": 10,
"updateAction": "ADD_QUANTITY", // "ADD_QUANTITY" | "REMOVE_QUANTITY" | "REPLACE_QUANTITY"
"customFields": [
{
"customFieldId": "string",
"customFieldValue": "string"
}
]
}
]
}Defaults
lineType:OFFER_PRICElineIdType:EXTERNAL_ID- Today only
EXTERNAL_IDis supported forlineIdType.
Rules
- Order must be DRAFT_ORDER.
- Up to 1000 lines per call.
- Quantity semantics via
updateAction:ADD_QUANTITY: add to existing.REMOVE_QUANTITY: subtract from existing.REPLACE_QUANTITY: set new value (≥ 0).
- Reject or warn on invalid combinations:
- Unknown
lineType/lineIdType/updateAction. updateActionprovided but missing quantity, or quantity provided withoutupdateAction.
- Unknown
- Constraints: negative qty; > stock; > max orderable; < min orderable; not multiple of pack.
- Non-owner edits: allowed when the user belongs to the same Account and holds permission
ORDER_UPDATE_LINES_ON_ALL_ACCOUNT.
Validation pipeline
flowchart LR IN[Incoming lines<br>id • qty • updateAction] --> TYPE[lineType / lineIdType<br>resolve targets] TYPE --> VIS[Visibility check<br>Catalog Views] VIS --> QTY[Quantity rules<br>min • max • pack • stock] QTY --> ACT[Apply updateAction<br>ADD / REMOVE / REPLACE] ACT --> LIM[Limit check<br>≤ 1000 lines] LIM --> OUT[Merge or create lines] classDef sys fill:#f2f4f7,stroke:#475569,stroke-width:2px,color:#111827; classDef ok fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b; class IN,TYPE,VIS,QTY,ACT,LIM sys class OUT ok style IN rx:8,ry:8 style TYPE rx:8,ry:8 style VIS rx:8,ry:8 style QTY rx:8,ry:8 style ACT rx:8,ry:8 style LIM rx:8,ry:8 style OUT rx:8,ry:8
Source-based starts: if the Draft was initialized from a Quote or an Operation, lines are re-validated at add time and again at placement.
📖 Read lines
Retrieve the current lines of the DRAFT order for display and checks.
OperationId: ORDER-561
Endpoint: GET /v1/shop/commercial-orders/{commercialOrderId}/lines
Path param: {commercialOrderId} is a REFERENCE (business reference only; not internal/external IDs).
Query parameters
currency(required) — currency for computing/returning totals on lines.supplierIds(optional) — filter by supplier id(s).productVariantIds(optional) — filter by variant id(s).offerPriceIds(optional) — filter by offer price id(s).idType(optional) —DJUST_IDorEXTERNAL_ID; applies only to the filter ids above.- (The path param remains a REFERENCE;
idTypedoes not affect it.)
- (The path param remains a REFERENCE;
Response
- Paginated list of Commercial Order lines.
- Line items reuse the existing Logistic Order line model (same fields & semantics).
- Includes monetary fields expressed in the requested
currency.
Notes
- Expect standard pagination where applicable.
- Lines reflect server-evaluated visibility and pricing for the buyer context.
- Avoid assuming totals from the lines list; use the order’s aggregated prices for consistency.
➖ Remove lines
Remove one or more lines from a DRAFT order.
OperationId: ORDER-350
Endpoint: DELETE /v2/shop/commercial-orders/{commercialOrderId}/lines
Path: {commercialOrderId} is a REFERENCE (business reference only).
{
"lines": [
{
"offerPriceId": "string"
}
]
}Rules
- Order must be DRAFT_ORDER.
- The caller must act within the same Account as the order.
- Non-owner deletion allowed if the user has ORDER_UPDATE_LINES_ON_ALL_ACCOUNT and belongs to the same Account.
- Cascade: if all lines of a child Logistic Order are removed, that Logistic Order (and its linked objects) is deleted.
- Path param is REFERENCE-only.
Decision flow
flowchart LR IN[DELETE order lines] --> AUTH[Auth & headers<br>dj-client=ACCOUNT • api-key] AUTH --> SCOPE[Account scope check] SCOPE --> PERM[Right check<br>OWNER or ORDER_UPDATE_LINES_ON_ALL_ACCOUNT] PERM --> STATE[Order is DRAFT_ORDER?] STATE -->|Yes| APPLY[Delete requested lines<br>cascade delete empty Logistics] STATE -->|No| ERR400[400 F-E-028] APPLY --> OK[204 No Content] %% ---------- Styles ---------- classDef sys fill:#f2f4f7,stroke:#475569,stroke-width:2px,color:#111827; classDef ok fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b; classDef stop fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d; class IN,AUTH,SCOPE,PERM,STATE sys class APPLY,OK ok class ERR400 stop style IN rx:8,ry:8 style AUTH rx:8,ry:8 style SCOPE rx:8,ry:8 style PERM rx:8,ry:8 style STATE rx:8,ry:8 style APPLY rx:8,ry:8 style OK rx:8,ry:8 style ERR400 rx:8,ry:8
📦 Update shipping information
Update the shipping information of a Commercial Order during checkout.
The update is applied to the order and to all linked Logistic Orders.
OperationId: ORDER-215
Endpoint: PUT /v2/shop/commercial-orders/{commercialOrderId}/shipping-information
Path: {commercialOrderId} is a REFERENCE (business reference only).
Request body
{
"shippingAddressId": "EXT-ADDR-001",
"shippingType": "EXPRESS"
}
shippingAddressId- external id (typed as shipping) of a valid shipping address.shippingType- free string indicating delivery mode (e.g., STANDARD, EXPRESS, PICKUP).Both fields are required.
Flow
flowchart LR IN[PUT shipping-information] --> HDR[Headers & auth] HDR --> RID[Resolve order by REFERENCE id] RID --> VAL[Validate body<br>external shippingAddressId - shippingType] VAL -->|Invalid| ERR404[404 Not Found] VAL -->|OK| APPLY[Apply to order<br>+ all linked Logistic Orders] APPLY --> OUT[204 No Content] %% ---------- Styles ---------- classDef sys fill:#f2f4f7,stroke:#475569,stroke-width:2px,color:#111827; classDef ok fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b; classDef stop fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d; class IN,HDR,RID,VAL,APPLY sys class OUT ok class ERR404 stop style IN rx:8,ry:8 style HDR rx:8,ry:8 style RID rx:8,ry:8 style VAL rx:8,ry:8 style APPLY rx:8,ry:8 style OUT rx:8,ry:8 style ERR404 rx:8,ry:8
🧾 Update billing information
Update the billing information of a Commercial Order during checkout.
The update is applied to the order and to all linked Logistic Orders.
OperationId: ORDER-213
Endpoint: PUT /v2/shop/commercial-orders/{commercialOrderId}/billing-information
Path: {commercialOrderId} is a REFERENCE (business reference only).
Request body
{
"billingAddressId": "EXT-BILLING-001"
}
billingAddressId- external id (typed as billing) of a valid billing address.
Flow
flowchart LR IN[PUT billing-information] --> HDR[Headers & auth] HDR --> RID[Resolve order by REFERENCE id] RID --> VAL[Validate body<br>external billingAddressId - typed as billing] VAL -->|Invalid| ERR404[404 Not Found] VAL -->|OK| APPLY[Apply to order<br>+ all linked Logistic Orders] APPLY --> OUT[204 No Content] %% ---------- Styles ---------- classDef sys fill:#f2f4f7,stroke:#475569,stroke-width:2px,color:#111827; classDef ok fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b; classDef stop fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d; class IN,HDR,RID,VAL,APPLY sys class OUT ok class ERR404 stop style IN rx:8,ry:8 style HDR rx:8,ry:8 style RID rx:8,ry:8 style VAL rx:8,ry:8 style APPLY rx:8,ry:8 style OUT rx:8,ry:8 style ERR404 rx:8,ry:8
✅ Place (validate) the order
Validate a DRAFT_ORDER Commercial Order and transition it to placed. This action transitions all child Logistic Orders to CREATED for OMS processing, locks further edits on the Commercial Order, and sets validatedAt.
OperationId: ORDER-212
Endpoint: PUT /v2/shop/commercial-orders/{commercialOrderId}/created
Pre-checks (high level)
- The order must be DRAFT_ORDER, owned and in scope for the caller. Validation enforces typical business constraints:
- Activation state: product, variant, offer inventory, offer price, and supplier are ACTIVE.
- Quantity & stock: requested qty > 0; within min/max; respects pack multiple; stock ≥ requested.
- Addresses & shipping: shipping and billing addresses present; shipping method/type present when required.
- Custom fields: mandatory role-based fields (e.g., product/shipping roles) are filled when roles are enabled.
- Payment readiness (if applicable): a PSP is configured or the “no-payment” mode is allowed.
What happens
- Final visibility/stock checks on lines.
- Split into child Logistic Orders per OMS rules (supplier/warehouse, etc.).
- Set each child Logistic Order to CREATED (ready for OMS).
- Freeze the Commercial Order (immutable) and set
validatedAt. - Recompute aggregates on the Commercial Order (
orderLogisticPrices,productCount,lineCount).
Decision flow
flowchart LR IN[Place order - ORDER-212] --> AUTH[Auth & headers<br>dj-client=ACCOUNT • api-key] AUTH --> SCOPE[Scope & store check] SCOPE --> STATE[Order is DRAFT_ORDER?] STATE -->|No| ERR400[400 Not in draft] STATE -->|Yes| REQ[Required data present?<br>addresses • shipping • mandatory CFs] REQ -->|No| ERR422A[422 Missing/invalid fields] REQ -->|Yes| LNS[Lines valid?<br>active objects • qty bounds • pack • stock] LNS -->|No| ERR422L[422 Line validation] LNS -->|Yes| SPLIT[Create child Logistic Orders] SPLIT --> SET[Set child LOs to CREATED] SET --> LOCK[Lock Commercial Order<br>set validatedAt • recompute aggregates] LOCK --> OUT[Order placed] %% ---------- Styles ---------- classDef sys fill:#f2f4f7,stroke:#475569,stroke-width:2px,color:#111827; classDef ok fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b; classDef stop fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d; class IN,AUTH,SCOPE,STATE,REQ,LNS,SPLIT,SET,LOCK sys class OUT ok class ERR400,ERR422A,ERR422L stop style IN rx:8,ry:8 style AUTH rx:8,ry:8 style SCOPE rx:8,ry:8 style STATE rx:8,ry:8 style REQ rx:8,ry:8 style LNS rx:8,ry:8 style SPLIT rx:8,ry:8 style SET rx:8,ry:8 style LOCK rx:8,ry:8 style OUT rx:8,ry:8 style ERR400 rx:8,ry:8 style ERR422A rx:8,ry:8 style ERR422L rx:8,ry:8
🗑️ Delete the order
Deletion is allowed only in DRAFT and only when no blocking links exist (e.g., payment intents, shipments, or other downstream objects).
OperationId: ORDER-300
Endpoint: DELETE /v2/shop/commercial-orders/{commercialOrderId}
Path: {commercialOrderId} is a REFERENCE (business reference only; do not accept internal/external IDs).
Rules
- Requires permission
CHECKOUT_ORDER_DELETE. - The order must be DRAFT_ORDER, e.g. all child Logistic Orders must also be DRAFT_ORDER.
- Caller must be in the same Account (buyer scope).
- Cascade: deletes the Commercial Order and its child Logistic Orders.
- Path param is REFERENCE-only (do not accept internal/external ids).
Decision flow
flowchart LR IN[DELETE order] --> AUTH[Auth & headers<br>dj-client=ACCOUNT • api-key] AUTH --> PERM[Check right<br>CHECKOUT_ORDER_DELETE] PERM --> SCOPE[Account scope check] SCOPE --> DRAFT[Order status is DRAFT_ORDER<br>& all child Logistics are DRAFT_ORDER?] DRAFT -->|Yes| DEL[Delete Commercial Order<br>& child Logistic Orders] DRAFT -->|No| ERR400[400 F-E-028] %% Styles classDef sys fill:#f2f4f7,stroke:#475569,stroke-width:2px,color:#111827; classDef ok fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b; classDef stop fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d; class IN,AUTH,PERM,SCOPE,DRAFT sys class DEL ok class ERR400 stop style IN rx:8,ry:8 style AUTH rx:8,ry:8 style PERM rx:8,ry:8 style SCOPE rx:8,ry:8 style DRAFT rx:8,ry:8 style DEL rx:8,ry:8 style ERR400 rx:8,ry:8
🧯 Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Cannot update order | Order not in DRAFT | Keep edits in DRAFT; after placement it is immutable |
| Some items cannot be added | Not visible for the Account | Adjust Catalog Views or choose eligible items |
| Quantity rejected | Min / Max / Pack constraint | Respect constraints; adjust quantity |
| Delete rejected | Blocking links exist | Remove links first or keep the DRAFT for audit |
| Can’t place the order | Missing addresses/shipping, inactive objects, quantity/pack/stock constraints, or required custom fields missing. | Complete mandatory fields; ensure products/suppliers/prices are ACTIVE; fix quantities; ensure stock. |
| Order already placed | Order is no longer in DRAFT (already validated). | Use read-only endpoints; amendments must follow post-placement flows. |
🔗 API quicklinks
- Create DRAFT order - ORDER-108
- Get Commercial Order by id - ORDER-500
- Update DRAFT order (custom fields) - ORDER-222
- Add lines - ORDER-150
- Read lines - ORDER-561
- Remove lines - ORDER-350
- Update shipping information - ORDER-215
- Update billing information - ORDER-213
- Place / validate an order - ORDER-212
- Delete DRAFT order - ORDER-300
Also useful
- List Commercial Orders - ORDER-560
Updated about 1 month ago
