# How to process an order (https://developer.godaddy.com/en/docs/api-users/commerce/manage-orders-and-customers)

***

title: How to process an order
description: Create, manage, and complete orders through the Order GraphQL subgraph — all order lifecycle operations from draft through completion.
agentNotes:
permissions: \[]
scopes: \["commerce.order:read", "commerce.order:create", "commerce.order:update", "commerce.order:complete", "commerce.order:cancel"]
idempotent: false
destructive: false
failureRecovery: "Query operations are safe to retry. For mutations, check the current order state with orderById before retrying — re-creating a draft can produce duplicate orders."
related:
apis:

* title: "Order GraphQL reference"
  href: "/docs/references/rest/orders"
  guides:
* title: "Manage a store"
  href: "/docs/api-users/commerce/set-up-a-store"
* title: "List sales channels"
  href: "/docs/api-users/commerce/set-up-a-store/channel"
* title: "Manage catalog items"
  href: "/docs/api-users/commerce/manage-catalog"
* title: "Manage a customer"
  href: "/docs/api-users/commerce/manage-orders-and-customers/customer"
  concepts:
* title: "About the Commerce API"
  href: "/docs/api-users/commerce"
* title: "Authentication"
  href: "/docs/api-users/auth"
* title: "Rate limits"
  href: "/docs/api-users/rate-limits"
* title: "Paginate results"
  href: "/docs/api-users/pagination"

***

## 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.

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)](https://developer.godaddy.com/docs/api-users/auth) 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`

  Go to [Your stores](https://developer.godaddy.com/docs/api-users/commerce#your-stores) to find your store ID.
* your `channelId` (required to create orders)

  Go to [List sales channels](https://developer.godaddy.com/docs/api-users/commerce/set-up-a-store/channel) to retrieve the `channelId` for your store.

## List orders

`orders(first, after)` returns a paginated list of orders. Go to [Paginate results](https://developer.godaddy.com/docs/api-users/pagination) for cursor-based pagination guidance.

The following procedure retrieves the first page of orders.

1. Query the first 10 orders:

   ```bash tab="curl"
   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 } } }"}'
   ```

   ```js tab="Node"
   const token = process.env.GODADDY_PAT;

   const res = await fetch("https://api.godaddy.com/v1/commerce/order-subgraph", {
     method: "POST",
     headers: {
       Authorization: `Bearer ${token}`,
       "Content-Type": "application/json",
       "x-store-id": process.env.STORE_ID,
     },
     body: JSON.stringify({
       query: `{
         orders(first: 10) {
           edges { node { id number statuses { status } totals { total { value currencyCode } } } }
           pageInfo { hasNextPage endCursor }
         }
       }`,
     }),
   });
   const data = await res.json();
   console.log(data.data.orders);
   ```

   ```python tab="Python"
   import os, requests

   token = os.environ["GODADDY_PAT"]

   res = requests.post(
       "https://api.godaddy.com/v1/commerce/order-subgraph",
       headers={
           "Authorization": f"Bearer {token}",
           "Content-Type": "application/json",
           "x-store-id": os.environ["STORE_ID"],
       },
       json={
           "query": "{ orders(first: 10) { edges { node { id number statuses { status } totals { total { value currencyCode } } } } pageInfo { hasNextPage endCursor } } }"
       },
   )
   res.raise_for_status()
   print(res.json()["data"]["orders"])
   ```

   ```go tab="Go"
   package main

   import (
       "bytes"
       "encoding/json"
       "fmt"
       "net/http"
       "os"
   )

   func main() {
       token := os.Getenv("GODADDY_PAT")

       payload := map[string]any{
           "query": `{ orders(first: 10) { edges { node { id number statuses { status } totals { total { value currencyCode } } } } pageInfo { hasNextPage endCursor } } }`,
       }
       body, _ := json.Marshal(payload)

       req, _ := http.NewRequest("POST", "https://api.godaddy.com/v1/commerce/order-subgraph", bytes.NewReader(body))
       req.Header.Set("Authorization", "Bearer "+token)
       req.Header.Set("Content-Type", "application/json")
       req.Header.Set("x-store-id", os.Getenv("STORE_ID"))

       res, err := http.DefaultClient.Do(req)
       if err != nil { panic(err) }
       defer res.Body.Close()

       var result map[string]any
       json.NewDecoder(res.Body).Decode(&result)
       fmt.Println(result)
   }
   ```

2. Review the paginated response:

   ```json
   {
     "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`:

  ```bash tab="curl"
  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 } }\"}"
  ```

  ```js tab="Node"
  const token = process.env.GODADDY_PAT;
  const orderId = "<ORDER_ID>";

  const res = await fetch("https://api.godaddy.com/v1/commerce/order-subgraph", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${token}`,
      "Content-Type": "application/json",
      "x-store-id": process.env.STORE_ID,
    },
    body: JSON.stringify({
      query: `query OrderById($id: ID!) {
        orderById(id: $id) { id number statuses { status } totals { total { value currencyCode } } createdAt }
      }`,
      variables: { id: orderId },
    }),
  });
  const data = await res.json();
  console.log(data.data.orderById);
  ```

  ```python tab="Python"
  import os, requests

  token = os.environ["GODADDY_PAT"]
  order_id = "<ORDER_ID>"

  res = requests.post(
      "https://api.godaddy.com/v1/commerce/order-subgraph",
      headers={
          "Authorization": f"Bearer {token}",
          "Content-Type": "application/json",
          "x-store-id": os.environ["STORE_ID"],
      },
      json={
          "query": "query OrderById($id: ID!) { orderById(id: $id) { id number statuses { status } totals { total { value currencyCode } } createdAt } }",
          "variables": {"id": order_id},
      },
  )
  res.raise_for_status()
  print(res.json()["data"]["orderById"])
  ```

  ```go tab="Go"
  package main

  import (
      "bytes"
      "encoding/json"
      "fmt"
      "net/http"
      "os"
  )

  func main() {
      token := os.Getenv("GODADDY_PAT")
      orderId := "<ORDER_ID>"

      payload := map[string]any{
          "query":     `query OrderById($id: ID!) { orderById(id: $id) { id number statuses { status } totals { total { value currencyCode } } createdAt } }`,
          "variables": map[string]any{"id": orderId},
      }
      body, _ := json.Marshal(payload)

      req, _ := http.NewRequest("POST", "https://api.godaddy.com/v1/commerce/order-subgraph", bytes.NewReader(body))
      req.Header.Set("Authorization", "Bearer "+token)
      req.Header.Set("Content-Type", "application/json")
      req.Header.Set("x-store-id", os.Getenv("STORE_ID"))

      res, err := http.DefaultClient.Do(req)
      if err != nil { panic(err) }
      defer res.Body.Close()

      var result map[string]any
      json.NewDecoder(res.Body).Decode(&result)
      fmt.Println(result)
  }
  ```

## 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:

   ```bash tab="curl"
   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>"
         }
       }
     }'
   ```

   ```js tab="Node"
   const token = process.env.GODADDY_PAT;
   const storeId = process.env.STORE_ID;
   const channelId = "<SALES_CHANNEL_ID>";
   const customerId = "<CUSTOMER_ID>";

   const res = await fetch("https://api.godaddy.com/v1/commerce/order-subgraph", {
     method: "POST",
     headers: {
       "Authorization": `Bearer ${token}`,
       "Content-Type": "application/json",
       "x-store-id": process.env.STORE_ID,
     },
     body: JSON.stringify({
       query: `mutation AddDraftOrder($input: AddDraftOrderInput!) {
         addDraftOrder(input: $input) { id number customerId statuses { status } }
       }`,
       variables: {
         input: {
           context: { storeId, channelId },
           customerId,
         },
       },
     }),
   });
   const data = await res.json();
   console.log(data.data.addDraftOrder);
   ```

   ```python tab="Python"
   import os, requests

   token = os.environ["GODADDY_PAT"]
   store_id = os.environ["STORE_ID"]
   channel_id = "<SALES_CHANNEL_ID>"
   customer_id = "<CUSTOMER_ID>"

   res = requests.post(
       "https://api.godaddy.com/v1/commerce/order-subgraph",
       headers={
           "Authorization": f"Bearer {token}",
           "Content-Type": "application/json",
           "x-store-id": os.environ["STORE_ID"],
       },
       json={
           "query": "mutation AddDraftOrder($input: AddDraftOrderInput!) { addDraftOrder(input: $input) { id number customerId statuses { status } } }",
           "variables": {
               "input": {
                   "context": {
                       "storeId": store_id,
                       "channelId": channel_id,
                   },
                   "customerId": customer_id,
               }
           },
       },
   )
   res.raise_for_status()
   print(res.json()["data"]["addDraftOrder"])
   ```

   ```go tab="Go"
   package main

   import (
       "bytes"
       "encoding/json"
       "fmt"
       "net/http"
       "os"
   )

   func main() {
       token := os.Getenv("GODADDY_PAT")
       storeId := os.Getenv("STORE_ID")
       channelId := "<SALES_CHANNEL_ID>"
       customerId := "<CUSTOMER_ID>"

       payload := map[string]any{
           "query": `mutation AddDraftOrder($input: AddDraftOrderInput!) {
               addDraftOrder(input: $input) { id number customerId statuses { status } }
           }`,
           "variables": map[string]any{
               "input": map[string]any{
                   "context": map[string]any{
                       "storeId":   storeId,
                       "channelId": channelId,
                   },
                   "customerId": customerId,
               },
           },
       }
       body, _ := json.Marshal(payload)

       req, _ := http.NewRequest("POST", "https://api.godaddy.com/v1/commerce/order-subgraph", bytes.NewReader(body))
       req.Header.Set("Authorization", "Bearer "+token)
       req.Header.Set("Content-Type", "application/json")
       req.Header.Set("x-store-id", os.Getenv("STORE_ID"))

       res, err := http.DefaultClient.Do(req)
       if err != nil { panic(err) }
       defer res.Body.Close()

       var result map[string]any
       json.NewDecoder(res.Body).Decode(&result)
       fmt.Println(result)
   }
   ```

2. To verify the customer was attached, include `customerId` in the response. Go to the [Orders API reference](https://developer.godaddy.com/docs/references/rest/orders) 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):

   ```json
   {
     "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):

   ```bash tab="curl"
   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"
         }
       }
     }'
   ```

   ```js tab="Node"
   const token = process.env.GODADDY_PAT;
   const orderId = "<ORDER_ID>";
   const skuId = "<SKU_UUID>";

   const res = await fetch("https://api.godaddy.com/v1/commerce/order-subgraph", {
     method: "POST",
     headers: {
       Authorization: `Bearer ${token}`,
       "Content-Type": "application/json",
       "x-store-id": process.env.STORE_ID,
     },
     body: JSON.stringify({
       query: `mutation AddLineItem($input: AddLineItemInput!) {
         addLineItemBySkuId(input: $input) { id name status }
       }`,
       variables: {
         input: {
           orderId,
           skuId,
           quantity: 1,
           fulfillmentMode: "NONE",
           status: "UNFULFILLED",
         },
       },
     }),
   });
   const data = await res.json();
   console.log(data.data.addLineItemBySkuId);
   ```

   ```python tab="Python"
   import os, requests

   token = os.environ["GODADDY_PAT"]
   order_id = "<ORDER_ID>"
   sku_id = "<SKU_UUID>"

   res = requests.post(
       "https://api.godaddy.com/v1/commerce/order-subgraph",
       headers={
           "Authorization": f"Bearer {token}",
           "Content-Type": "application/json",
           "x-store-id": os.environ["STORE_ID"],
       },
       json={
           "query": "mutation AddLineItem($input: AddLineItemInput!) { addLineItemBySkuId(input: $input) { id name status } }",
           "variables": {
               "input": {
                   "orderId": order_id,
                   "skuId": sku_id,
                   "quantity": 1,
                   "fulfillmentMode": "NONE",
                   "status": "UNFULFILLED",
               }
           },
       },
   )
   res.raise_for_status()
   print(res.json()["data"]["addLineItemBySkuId"])
   ```

   ```go tab="Go"
   package main

   import (
       "bytes"
       "encoding/json"
       "fmt"
       "net/http"
       "os"
   )

   func main() {
       token := os.Getenv("GODADDY_PAT")
       orderId := "<ORDER_ID>"
       skuId := "<SKU_UUID>"

       payload := map[string]any{
           "query": `mutation AddLineItem($input: AddLineItemInput!) {
               addLineItemBySkuId(input: $input) { id name status }
           }`,
           "variables": map[string]any{
               "input": map[string]any{
                   "orderId":         orderId,
                   "skuId":           skuId,
                   "quantity":        1,
                   "fulfillmentMode": "NONE",
                   "status":          "UNFULFILLED",
               },
           },
       }
       body, _ := json.Marshal(payload)

       req, _ := http.NewRequest("POST", "https://api.godaddy.com/v1/commerce/order-subgraph", bytes.NewReader(body))
       req.Header.Set("Authorization", "Bearer "+token)
       req.Header.Set("Content-Type", "application/json")
       req.Header.Set("x-store-id", os.Getenv("STORE_ID"))

       res, err := http.DefaultClient.Do(req)
       if err != nil { panic(err) }
       defer res.Body.Close()

       var result map[string]any
       json.NewDecoder(res.Body).Decode(&result)
       fmt.Println(result)
   }
   ```

2. Review the returned line item:

   ```json
   {
     "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:

   ```bash tab="curl"
   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}\"}}"
   ```

   ```js tab="Node"
   const token = process.env.GODADDY_PAT;
   const orderId = "<ORDER_ID>";

   const res = await fetch("https://api.godaddy.com/v1/commerce/order-subgraph", {
     method: "POST",
     headers: {
       Authorization: `Bearer ${token}`,
       "Content-Type": "application/json",
       "x-store-id": process.env.STORE_ID,
     },
     body: JSON.stringify({
       query: `mutation OpenOrder($id: ID!) { openOrder(id: $id) { id statuses { status } } }`,
       variables: { id: orderId },
     }),
   });
   const data = await res.json();
   console.log(data.data.openOrder);
   ```

   ```python tab="Python"
   import os, requests

   token = os.environ["GODADDY_PAT"]
   order_id = "<ORDER_ID>"

   res = requests.post(
       "https://api.godaddy.com/v1/commerce/order-subgraph",
       headers={
           "Authorization": f"Bearer {token}",
           "Content-Type": "application/json",
           "x-store-id": os.environ["STORE_ID"],
       },
       json={
           "query": "mutation OpenOrder($id: ID!) { openOrder(id: $id) { id statuses { status } } }",
           "variables": {"id": order_id},
       },
   )
   res.raise_for_status()
   print(res.json()["data"]["openOrder"])
   ```

   ```go tab="Go"
   package main

   import (
       "bytes"
       "encoding/json"
       "fmt"
       "net/http"
       "os"
   )

   func main() {
       token := os.Getenv("GODADDY_PAT")
       orderId := "<ORDER_ID>"

       payload := map[string]any{
           "query":     `mutation OpenOrder($id: ID!) { openOrder(id: $id) { id statuses { status } } }`,
           "variables": map[string]any{"id": orderId},
       }
       body, _ := json.Marshal(payload)

       req, _ := http.NewRequest("POST", "https://api.godaddy.com/v1/commerce/order-subgraph", bytes.NewReader(body))
       req.Header.Set("Authorization", "Bearer "+token)
       req.Header.Set("Content-Type", "application/json")
       req.Header.Set("x-store-id", os.Getenv("STORE_ID"))

       res, err := http.DefaultClient.Do(req)
       if err != nil { panic(err) }
       defer res.Body.Close()

       var result map[string]any
       json.NewDecoder(res.Body).Decode(&result)
       fmt.Println(result)
   }
   ```

2. Confirm the order status updated to `OPEN`:

   ```json
   {
     "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:

   ```bash tab="curl"
   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}\"}}"
   ```

   ```js tab="Node"
   const token = process.env.GODADDY_PAT;
   const orderId = "<ORDER_ID>";

   const res = await fetch("https://api.godaddy.com/v1/commerce/order-subgraph", {
     method: "POST",
     headers: {
       Authorization: `Bearer ${token}`,
       "Content-Type": "application/json",
       "x-store-id": process.env.STORE_ID,
     },
     body: JSON.stringify({
       query: `mutation CompleteOrder($id: ID!) { completeOrder(id: $id) { id statuses { status } } }`,
       variables: { id: orderId },
     }),
   });
   const data = await res.json();
   console.log(data.data.completeOrder);
   ```

   ```python tab="Python"
   import os, requests

   token = os.environ["GODADDY_PAT"]
   order_id = "<ORDER_ID>"

   res = requests.post(
       "https://api.godaddy.com/v1/commerce/order-subgraph",
       headers={
           "Authorization": f"Bearer {token}",
           "Content-Type": "application/json",
           "x-store-id": os.environ["STORE_ID"],
       },
       json={
           "query": "mutation CompleteOrder($id: ID!) { completeOrder(id: $id) { id statuses { status } } }",
           "variables": {"id": order_id},
       },
   )
   res.raise_for_status()
   print(res.json()["data"]["completeOrder"])
   ```

   ```go tab="Go"
   package main

   import (
       "bytes"
       "encoding/json"
       "fmt"
       "net/http"
       "os"
   )

   func main() {
       token := os.Getenv("GODADDY_PAT")
       orderId := "<ORDER_ID>"

       payload := map[string]any{
           "query":     `mutation CompleteOrder($id: ID!) { completeOrder(id: $id) { id statuses { status } } }`,
           "variables": map[string]any{"id": orderId},
       }
       body, _ := json.Marshal(payload)

       req, _ := http.NewRequest("POST", "https://api.godaddy.com/v1/commerce/order-subgraph", bytes.NewReader(body))
       req.Header.Set("Authorization", "Bearer "+token)
       req.Header.Set("Content-Type", "application/json")
       req.Header.Set("x-store-id", os.Getenv("STORE_ID"))

       res, err := http.DefaultClient.Do(req)
       if err != nil { panic(err) }
       defer res.Body.Close()

       var result map[string]any
       json.NewDecoder(res.Body).Decode(&result)
       fmt.Println(result)
   }
   ```

2. Confirm the order status updated to `COMPLETED`:

   ```json
   {
     "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:

   ```bash tab="curl"
   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}\"}}"
   ```

   ```js tab="Node"
   const token = process.env.GODADDY_PAT;
   const orderId = "<ORDER_ID>";

   const res = await fetch("https://api.godaddy.com/v1/commerce/order-subgraph", {
     method: "POST",
     headers: {
       Authorization: `Bearer ${token}`,
       "Content-Type": "application/json",
       "x-store-id": process.env.STORE_ID,
     },
     body: JSON.stringify({
       query: `mutation CancelOrder($id: ID!) { cancelOrder(id: $id) { id statuses { status } } }`,
       variables: { id: orderId },
     }),
   });
   const data = await res.json();
   console.log(data.data.cancelOrder);
   ```

   ```python tab="Python"
   import os, requests

   token = os.environ["GODADDY_PAT"]
   order_id = "<ORDER_ID>"

   res = requests.post(
       "https://api.godaddy.com/v1/commerce/order-subgraph",
       headers={
           "Authorization": f"Bearer {token}",
           "Content-Type": "application/json",
           "x-store-id": os.environ["STORE_ID"],
       },
       json={
           "query": "mutation CancelOrder($id: ID!) { cancelOrder(id: $id) { id statuses { status } } }",
           "variables": {"id": order_id},
       },
   )
   res.raise_for_status()
   print(res.json()["data"]["cancelOrder"])
   ```

   ```go tab="Go"
   package main

   import (
       "bytes"
       "encoding/json"
       "fmt"
       "net/http"
       "os"
   )

   func main() {
       token := os.Getenv("GODADDY_PAT")
       orderId := "<ORDER_ID>"

       payload := map[string]any{
           "query":     `mutation CancelOrder($id: ID!) { cancelOrder(id: $id) { id statuses { status } } }`,
           "variables": map[string]any{"id": orderId},
       }
       body, _ := json.Marshal(payload)

       req, _ := http.NewRequest("POST", "https://api.godaddy.com/v1/commerce/order-subgraph", bytes.NewReader(body))
       req.Header.Set("Authorization", "Bearer "+token)
       req.Header.Set("Content-Type", "application/json")
       req.Header.Set("x-store-id", os.Getenv("STORE_ID"))

       res, err := http.DefaultClient.Do(req)
       if err != nil { panic(err) }
       defer res.Body.Close()

       var result map[string]any
       json.NewDecoder(res.Body).Decode(&result)
       fmt.Println(result)
   }
   ```

2. Confirm the order status updated to `CANCELED`:

   ```json
   {
     "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](https://developer.godaddy.com/docs/api-users/auth) 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.                                                                                                    |
