How to process an order
View as MarkdownCreate, manage, and complete orders through the Order GraphQL subgraph — all order lifecycle operations from draft through completion.
Overview
The Order subgraph manages orders through their full lifecycle: DRAFT to OPEN to COMPLETED (or CANCELED). All operations (reads, creates, and status transitions) are GraphQL queries and mutations sent to POST /v1/commerce/order-subgraph. This endpoint requires an x-store-id header to select the store; it doesn't take a storeId path parameter. Mutations that take an input object also include the store context as context.storeId; id-only mutations (for example, cancelOrder) rely on the header alone. The following article provides examples of how to use the Order subgraph to manage orders in your store.
Retrying a create safely
The Order subgraph has no Idempotency-Key header, but creates are still safe to retry when you supply your own identifiers. With addOrderWithId, the service enforces uniqueness on both the id you generate and your optional externalId (unique per channel), so replaying the same create is rejected instead of producing a duplicate. After a network timeout, confirm the result before resending: look the order up with orderById, or with orderByExternalId (which also requires the channelId). Resend only if the order didn't land. Creates where the service assigns the id (like addDraftOrder) don't have this safeguard, so a blind retry can create a second order.
Prerequisites
The following prerequisites are required before you can process orders:
- a GoDaddy account with an active commerce store
- a Personal Access Token (PAT) with the scopes for the operations you need (
commerce.order:readfor queries;commerce.order:create,:update,:complete, or:cancelfor the corresponding mutations) - your
storeIdFind your store ID
Go to Your stores to find your store ID.
- your
channelId(required to create orders)Find your channel ID
Go to List sales channels to retrieve the
channelIdfor your store.
List orders
orders(first, after) returns a paginated list of orders. Go to Paginate results for cursor-based pagination guidance.
The following procedure retrieves the first page of orders.
-
Query the first 10 orders:
curl -s -X POST "https://api.godaddy.com/v1/commerce/order-subgraph" \ -H "Authorization: Bearer $GODADDY_PAT" \ -H "Content-Type: application/json" \ -H "x-store-id: $STORE_ID" \ -d '{"query": "{ orders(first: 10) { edges { node { id number statuses { status } totals { total { value currencyCode } } } } pageInfo { hasNextPage endCursor } } }"}' -
Review the paginated response:
{ "data": { "orders": { "edges": [ { "node": { "id": "<ORDER_ID>", "number": "<ORDER_NUMBER>", "statuses": { "status": "<ORDER_STATUS>" }, "totals": { "total": { "value": 550, "currencyCode": "USD" } } } } ], "pageInfo": { "hasNextPage": true, "endCursor": "<PAGINATION_CURSOR>" } } } }
Get an order
orderById(id: ID!) retrieves a single order by its ID.
The following procedure reads a single order by ID.
-
Retrieve an order by its
id:ORDER_ID="<ORDER_ID>" curl -s -X POST "https://api.godaddy.com/v1/commerce/order-subgraph" \ -H "Authorization: Bearer $GODADDY_PAT" \ -H "Content-Type: application/json" \ -H "x-store-id: $STORE_ID" \ -d "{\"query\": \"query { orderById(id: \\\"${ORDER_ID}\\\") { id number statuses { status } totals { total { value currencyCode } } createdAt } }\"}"
Create a draft order
addDraftOrder(input: AddDraftOrderInput!) creates a new order in DRAFT status. The only required input is context, which must include both storeId and channelId. Save the returned id. The returned id is required for all subsequent order operations.
The following procedure creates a draft order for a specific store and channel.
-
Create a draft order:
curl -s -X POST "https://api.godaddy.com/v1/commerce/order-subgraph" \ -H "Authorization: Bearer $GODADDY_PAT" \ -H "Content-Type: application/json" \ -H "x-store-id: $STORE_ID" \ -d '{ "query": "mutation AddDraftOrder($input: AddDraftOrderInput!) { addDraftOrder(input: $input) { id number customerId statuses { status } } }", "variables": { "input": { "context": { "storeId": "<STORE_UUID>", "channelId": "<SALES_CHANNEL_ID>" }, "customerId": "<CUSTOMER_ID>" } } }' -
To verify the customer was attached, include
customerIdin the response. Go to the Orders API reference for all optional input fields available on order creation mutations. -
Save the
idfrom the response (you'll need it for every subsequent mutation on this order):{ "data": { "addDraftOrder": { "id": "<ORDER_ID>", "number": "<ORDER_NUMBER>", "customerId": "<CUSTOMER_ID>", "statuses": { "status": "DRAFT" } } } }
Add a line item
addLineItemBySkuId(input: AddLineItemInput!) adds a catalog SKU to an existing order. The orderId is in the format Order_<KSUID> returned from addDraftOrder. Both fulfillmentMode and status are required.
The following procedure adds a SKU to a draft order.
-
Add a line item by SKU ID (using the
idfrom step 3 above):curl -s -X POST "https://api.godaddy.com/v1/commerce/order-subgraph" \ -H "Authorization: Bearer $GODADDY_PAT" \ -H "Content-Type: application/json" \ -H "x-store-id: $STORE_ID" \ -d '{ "query": "mutation AddLineItem($input: AddLineItemInput!) { addLineItemBySkuId(input: $input) { id name status } }", "variables": { "input": { "orderId": "<ORDER_ID>", "skuId": "<SKU_UUID>", "quantity": 1, "fulfillmentMode": "NONE", "status": "UNFULFILLED" } } }' -
Review the returned line item:
{ "data": { "addLineItemBySkuId": { "id": "<LINE_ITEM_ID>", "name": "<SKU_DISPLAY_NAME>", "status": "UNFULFILLED" } } }
Open an order
openOrder(id: ID!) transitions a DRAFT order to OPEN status. The draft must have at least one line item. cancelOrder, completeOrder, and refundOrder apply to non-draft orders (OPEN / completed as documented on each mutation). Use updateDraftOrder for drafts (updateOrder is rejected on drafts).
filterOrders(status: [DRAFT]) can list drafts. addOrder / addOrderWithId use OrderStatusInput, which is only OPEN, COMPLETED, or CANCELED (not DRAFT). Those mutations also require a full OrderTotalsInput (subTotal, shippingTotal, discountTotal, feeTotal, taxTotal, total).
The following procedure opens a draft order.
-
Open the draft order:
ORDER_ID="<ORDER_ID>" curl -s -X POST "https://api.godaddy.com/v1/commerce/order-subgraph" \ -H "Authorization: Bearer $GODADDY_PAT" \ -H "Content-Type: application/json" \ -H "x-store-id: $STORE_ID" \ -d "{\"query\": \"mutation OpenOrder(\$id: ID!) { openOrder(id: \$id) { id statuses { status } } }\", \"variables\": {\"id\": \"${ORDER_ID}\"}}" -
Confirm the order status updated to
OPEN:{ "data": { "openOrder": { "id": "<ORDER_ID>", "statuses": { "status": "OPEN" } } } }
Complete an order
completeOrder(id: ID!) marks an OPEN order as COMPLETED. Only OPEN orders can be completed.
The following procedure completes an open order.
-
Complete the order:
ORDER_ID="<ORDER_ID>" curl -s -X POST "https://api.godaddy.com/v1/commerce/order-subgraph" \ -H "Authorization: Bearer $GODADDY_PAT" \ -H "Content-Type: application/json" \ -H "x-store-id: $STORE_ID" \ -d "{\"query\": \"mutation CompleteOrder(\$id: ID!) { completeOrder(id: \$id) { id statuses { status } } }\", \"variables\": {\"id\": \"${ORDER_ID}\"}}" -
Confirm the order status updated to
COMPLETED:{ "data": { "completeOrder": { "id": "<ORDER_ID>", "statuses": { "status": "COMPLETED" } } } }
Cancel an order
cancelOrder(id: ID!) cancels an OPEN order.
The following procedure cancels an open order.
-
Cancel the order:
ORDER_ID="<ORDER_ID>" curl -s -X POST "https://api.godaddy.com/v1/commerce/order-subgraph" \ -H "Authorization: Bearer $GODADDY_PAT" \ -H "Content-Type: application/json" \ -H "x-store-id: $STORE_ID" \ -d "{\"query\": \"mutation CancelOrder(\$id: ID!) { cancelOrder(id: \$id) { id statuses { status } } }\", \"variables\": {\"id\": \"${ORDER_ID}\"}}" -
Confirm the order status updated to
CANCELED:{ "data": { "cancelOrder": { "id": "<ORDER_ID>", "statuses": { "status": "CANCELED" } } } }
Common errors
The following table lists common errors when processing orders, the most likely cause, and additional notes:
| Status | Most likely cause | Note |
|---|---|---|
400 | Malformed GraphQL query, or missing required input field. | Order has statuses { status }, not status. List connections use edges { node }, not nodes. Money fields need { value currencyCode }. |
401 | PAT is missing or expired. | Go to Authentication to generate a new token. |
403 | Token doesn't include the scope for the requested operation. | Ensure your PAT includes the required scopes for the operation. |
404 | Order ID doesn't exist or isn't accessible with the provided token. | |
422 | Invalid status transition. | For example, cancel/complete/refund a DRAFT, or openOrder with no line items. |
429 | Rate limit exceeded. | Honor the Retry-After header before retrying. |
Agent & Automation Notes
commerce.order:read, commerce.order:create, commerce.order:update, commerce.order:complete, commerce.order:cancelRelated
Last updated on
How is this guide?