Support
Manage orders and customersProcess an order

How to process an order

View as Markdown

Create, 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:read for queries; commerce.order:create, :update, :complete, or :cancel for the corresponding mutations)
  • your storeId

    Find 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 channelId for 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.

  1. 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 } } }"}'
  2. 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.

  1. 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>"
          }
        }
      }'
  2. To verify the customer was attached, include customerId in the response. Go to the Orders API reference for all optional input fields available on order creation mutations.

  3. Save the id from 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.

  1. Add a line item by SKU ID (using the id from 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"
          }
        }
      }'
  2. 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.

  1. 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}\"}}"
  2. 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.

  1. 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}\"}}"
  2. 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.

  1. 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}\"}}"
  2. 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:

StatusMost likely causeNote
400Malformed 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 }.
401PAT is missing or expired.Go to Authentication to generate a new token.
403Token doesn't include the scope for the requested operation.Ensure your PAT includes the required scopes for the operation.
404Order ID doesn't exist or isn't accessible with the provided token.
422Invalid status transition.For example, cancel/complete/refund a DRAFT, or openOrder with no line items.
429Rate limit exceeded.Honor the Retry-After header before retrying.

Agent & Automation Notes

Scopescommerce.order:read, commerce.order:create, commerce.order:update, commerce.order:complete, commerce.order:cancel
IdempotentNo
DestructiveNo
On failureQuery operations are safe to retry. For mutations, check the current order state with orderById before retrying — re-creating a draft can produce duplicate orders.

Last updated on

How is this guide?

On this page