0

Create Draft Order

by
Published Nov 8, 2023

Create a draft order (quote) from variants or custom items.

Script shopify Verified

The script

Submitted by hugo989 Typescript (fetch-only)
Verified 2 hours ago
1
//native
2

3
/**
4
 * Create Draft Order
5
 * Create a draft order (a quote or invoice to send before payment). Each line item is either a variant ({ variant_id, quantity }) or a custom item ({ title, price, quantity }; price in the shop currency). Send it with Send Draft Order Invoice or turn it into an order with Complete Draft Order.
6
 */
7
export async function main(
8
  auth: RT.Shopify,
9
  line_items: {
10
    variant_id?: string
11
    title?: string
12
    price?: number
13
    quantity: number
14
  }[],
15
  customer_id: string | undefined,
16
  email: string | undefined,
17
  shipping_address:
18
    | {
19
        firstName?: string
20
        lastName?: string
21
        company?: string
22
        address1?: string
23
        address2?: string
24
        city?: string
25
        provinceCode?: string
26
        zip?: string
27
        countryCode?: string
28
        phone?: string
29
      }
30
    | undefined,
31
  discount:
32
    | {
33
        value: number
34
        value_type: "PERCENTAGE" | "FIXED_AMOUNT"
35
        title?: string
36
      }
37
    | undefined,
38
  note: string | undefined,
39
  tags: string[] | undefined,
40
  use_customer_default_address: boolean | undefined
41
) {
42
  const endpoint = `https://${auth.store_name}.myshopify.com/admin/api/2026-10/graphql.json`
43
  const call = async (body: { query: string; variables?: object }) => {
44
    const response = await fetch(endpoint, {
45
      method: "POST",
46
      headers: {
47
        "X-Shopify-Access-Token": auth.token,
48
        "Content-Type": "application/json",
49
        Accept: "application/json",
50
      },
51
      body: JSON.stringify(body),
52
    })
53
    if (!response.ok) {
54
      throw new Error(`${response.status} ${await response.text()}`)
55
    }
56
    const { data, errors } = await response.json()
57
    if (errors) {
58
      throw new Error(JSON.stringify(errors))
59
    }
60
    return data
61
  }
62
  const gid = (value: string, type: string) =>
63
    value.startsWith("gid://") ? value : `gid://shopify/${type}/${value}`
64

65
  // Custom-item prices need a currency: use the shop's.
66
  const currencyCode = line_items.some((item) => item.price != null)
67
    ? (await call({ query: `query { shop { currencyCode } }` })).shop
68
        .currencyCode
69
    : undefined
70

71
  const data = await call({
72
    query: `mutation ($input: DraftOrderInput!) { draftOrderCreate(input: $input) { draftOrder { id legacyResourceId name status email invoiceUrl tags note2 totalPriceSet { shopMoney { amount currencyCode } } customer { id displayName } lineItems(first: 50) { nodes { id name quantity custom originalUnitPriceSet { shopMoney { amount currencyCode } } variant { id } } } } userErrors { field message } } }`,
73
    variables: {
74
      input: {
75
        lineItems: line_items.map((item) => ({
76
          variantId: item.variant_id
77
            ? gid(item.variant_id, "ProductVariant")
78
            : undefined,
79
          title: item.title || undefined,
80
          originalUnitPriceWithCurrency:
81
            item.price != null
82
              ? { amount: item.price, currencyCode }
83
              : undefined,
84
          quantity: item.quantity,
85
        })),
86
        purchasingEntity: customer_id
87
          ? { customerId: gid(customer_id, "Customer") }
88
          : undefined,
89
        email: email || undefined,
90
        shippingAddress: shipping_address || undefined,
91
        appliedDiscount: discount
92
          ? {
93
              value: discount.value,
94
              valueType: discount.value_type,
95
              title: discount.title || undefined,
96
            }
97
          : undefined,
98
        note: note || undefined,
99
        tags: tags?.length ? tags : undefined,
100
        useCustomerDefaultAddress: use_customer_default_address || undefined,
101
      },
102
    },
103
  })
104

105
  if (data.draftOrderCreate.userErrors.length) {
106
    throw new Error(JSON.stringify(data.draftOrderCreate.userErrors))
107
  }
108

109
  return data.draftOrderCreate
110
}
111

Other submissions
  • Submitted by hugo697 Typescript (fetch-only)
    Created 528 days ago
    1
    type Shopify = {
    2
      token: string;
    3
      store_name: string;
    4
    };
    5
    /**
    6
     * Create a new DraftOrder
    7
     * Creates a draft order.
    8
     */
    9
    export async function main(
    10
      auth: Shopify,
    11
      api_version: string = "2023-10",
    12
      body: {
    13
        draft_order?: {
    14
          line_items?: {
    15
            applied_discount?: {
    16
              amount?: string;
    17
              description?: string;
    18
              title?: string;
    19
              value?: string;
    20
              value_type?: string;
    21
              [k: string]: unknown;
    22
            };
    23
            price?: string;
    24
            quantity?: number;
    25
            title?: string;
    26
            [k: string]: unknown;
    27
          }[];
    28
          [k: string]: unknown;
    29
        };
    30
        [k: string]: unknown;
    31
      }
    32
    ) {
    33
      const url = new URL(
    34
        `https://${auth.store_name}.myshopify.com/admin/api/${api_version}/draft_orders.json`
    35
      );
    36
    
    
    37
      const response = await fetch(url, {
    38
        method: "POST",
    39
        headers: {
    40
          "Content-Type": "application/json",
    41
          "X-Shopify-Access-Token": auth.token,
    42
        },
    43
        body: JSON.stringify(body),
    44
      });
    45
      if (!response.ok) {
    46
        const text = await response.text();
    47
        throw new Error(`${response.status} ${text}`);
    48
      }
    49
      return await response.json();
    50
    }
    51