Skip to main content
Glama

complete_draft_order

Complete an open draft order into a Shopify order. Set paymentPending to true to create the order without capturing payment, ideal for offline collection. Default false captures payment immediately. Returns the new order's GID.

Instructions

Convert an OPEN draft order into a real Shopify order. With paymentPending=false (default), Shopify attempts to capture payment immediately; the call fails if no payment method is on file. With paymentPending=true, the order is created in payment-pending status — useful when collecting payment offline (cash, bank transfer, manual processing). Once completed, the draft transitions to COMPLETED and the new order's GID is returned. The transition is one-way: completed drafts cannot be re-opened or edited via draft tools (use the order tools, or refund/cancel for the resulting order).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
idYesGID of an OPEN draft order. Already-completed drafts are rejected.
paymentPendingNoIf true, the resulting order is marked payment-pending — Shopify creates the order but does NOT capture payment. Use when you'll collect payment offline (cash, bank transfer, manual card auth) or via a separate flow. Default false (attempts to capture immediately).

Implementation Reference

  • The tool handler for 'complete_draft_order': executes the draftOrderComplete GraphQL mutation with optional paymentPending flag, then formats a response with the resulting order info.
    server.tool(
      "complete_draft_order",
      "Convert an OPEN draft order into a real Shopify order. With paymentPending=false (default), Shopify attempts to capture payment immediately; the call fails if no payment method is on file. With paymentPending=true, the order is created in payment-pending status — useful when collecting payment offline (cash, bank transfer, manual processing). Once completed, the draft transitions to COMPLETED and the new order's GID is returned. The transition is one-way: completed drafts cannot be re-opened or edited via draft tools (use the order tools, or refund/cancel for the resulting order).",
      completeDraftOrderSchema,
      async (args) => {
        const data = await client.graphql<{
          draftOrderComplete: {
            draftOrder: DraftOrder | null;
            userErrors: ShopifyUserError[];
          };
        }>(COMPLETE_DRAFT_ORDER_MUTATION, {
          id: args.id,
          paymentPending: args.paymentPending ?? false,
        });
        throwIfUserErrors(data.draftOrderComplete.userErrors, "draftOrderComplete");
        const d = data.draftOrderComplete.draftOrder;
        if (!d) {
          return {
            content: [
              { type: "text" as const, text: "draftOrderComplete returned no draft order." },
            ],
          };
        }
        const orderInfo = d.order
          ? ` → order ${d.order.name} (${d.order.id})`
          : "";
        return {
          content: [
            {
              type: "text" as const,
              text: `Completed draft order ${d.name} [${d.status}]${orderInfo}`,
            },
          ],
        };
      },
  • Zod schema for 'complete_draft_order' input: requires an 'id' (draft order GID) and optional 'paymentPending' boolean.
    const completeDraftOrderSchema = {
      id: z
        .string()
        .describe("GID of an OPEN draft order. Already-completed drafts are rejected."),
      paymentPending: z
        .boolean()
        .optional()
        .describe(
          "If true, the resulting order is marked payment-pending — Shopify creates the order but does NOT capture payment. Use when you'll collect payment offline (cash, bank transfer, manual card auth) or via a separate flow. Default false (attempts to capture immediately).",
        ),
    };
  • The tool is registered on the MCP server via server.tool() inside registerDraftOrderTools(), using the name 'complete_draft_order'.
    server.tool(
      "complete_draft_order",
      "Convert an OPEN draft order into a real Shopify order. With paymentPending=false (default), Shopify attempts to capture payment immediately; the call fails if no payment method is on file. With paymentPending=true, the order is created in payment-pending status — useful when collecting payment offline (cash, bank transfer, manual processing). Once completed, the draft transitions to COMPLETED and the new order's GID is returned. The transition is one-way: completed drafts cannot be re-opened or edited via draft tools (use the order tools, or refund/cancel for the resulting order).",
      completeDraftOrderSchema,
      async (args) => {
        const data = await client.graphql<{
          draftOrderComplete: {
            draftOrder: DraftOrder | null;
            userErrors: ShopifyUserError[];
          };
        }>(COMPLETE_DRAFT_ORDER_MUTATION, {
          id: args.id,
          paymentPending: args.paymentPending ?? false,
        });
        throwIfUserErrors(data.draftOrderComplete.userErrors, "draftOrderComplete");
        const d = data.draftOrderComplete.draftOrder;
        if (!d) {
          return {
            content: [
              { type: "text" as const, text: "draftOrderComplete returned no draft order." },
            ],
          };
        }
        const orderInfo = d.order
          ? ` → order ${d.order.name} (${d.order.id})`
          : "";
        return {
          content: [
            {
              type: "text" as const,
              text: `Completed draft order ${d.name} [${d.status}]${orderInfo}`,
            },
          ],
        };
      },
    );
  • The GraphQL mutation string 'COMPLETE_DRAFT_ORDER_MUTATION' that the handler uses to complete a draft order.
    const COMPLETE_DRAFT_ORDER_MUTATION = /* GraphQL */ `
      mutation DraftOrderComplete($id: ID!, $paymentPending: Boolean) {
        draftOrderComplete(id: $id, paymentPending: $paymentPending) {
          draftOrder {
            id
            name
            status
            order { id name }
          }
          userErrors { field message }
        }
      }
    `;
  • The 'throwIfUserErrors' helper imported from shopify/client.js, used to handle Shopify user errors in the handler.
    import { throwIfUserErrors } from "../shopify/client.js";
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, but the description fully discloses payment capture behavior, one-way transition, and side effects (completed drafts cannot be re-opened, new order GID returned).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single paragraph with each sentence adding value, front-loaded with the main action. Slightly long but still concise given the amount of information conveyed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers preconditions (id must be OPEN), behavior of both paymentPending modes, postconditions (draft transitions to COMPLETED, new order GID returned), and side effects (one-way, cannot re-open). No output schema but return value is mentioned. Comprehensive.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, but the description adds significant context: default behavior for paymentPending=false, practical use cases for each mode, and validation that id must be OPEN. This goes well beyond the schema definitions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it converts an OPEN draft order into a real Shopify order, with specific behavior for paymentPending flag. It distinguishes itself from sibling tools like update_draft_order and delete_draft_order by clarifying the one-way transition.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly describes when to use paymentPending=false vs true, warns about already-completed drafts, and mentions alternatives (use order tools, refund/cancel). Provides clear context for both modes.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/miller-joe/shopify-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server