//native
/**
* Create Draft Order
* 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.
*/
export async function main(
auth: RT.Shopify,
line_items: {
variant_id?: string
title?: string
price?: number
quantity: number
}[],
customer_id: string | undefined,
email: string | undefined,
shipping_address:
| {
firstName?: string
lastName?: string
company?: string
address1?: string
address2?: string
city?: string
provinceCode?: string
zip?: string
countryCode?: string
phone?: string
}
| undefined,
discount:
| {
value: number
value_type: "PERCENTAGE" | "FIXED_AMOUNT"
title?: string
}
| undefined,
note: string | undefined,
tags: string[] | undefined,
use_customer_default_address: boolean | undefined
) {
const endpoint = `https://${auth.store_name}.myshopify.com/admin/api/2026-10/graphql.json`
const call = async (body: { query: string; variables?: object }) => {
const response = await fetch(endpoint, {
method: "POST",
headers: {
"X-Shopify-Access-Token": auth.token,
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(body),
})
if (!response.ok) {
throw new Error(`${response.status} ${await response.text()}`)
}
const { data, errors } = await response.json()
if (errors) {
throw new Error(JSON.stringify(errors))
}
return data
}
const gid = (value: string, type: string) =>
value.startsWith("gid://") ? value : `gid://shopify/${type}/${value}`
// Custom-item prices need a currency: use the shop's.
const currencyCode = line_items.some((item) => item.price != null)
? (await call({ query: `query { shop { currencyCode } }` })).shop
.currencyCode
: undefined
const data = await call({
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 } } }`,
variables: {
input: {
lineItems: line_items.map((item) => ({
variantId: item.variant_id
? gid(item.variant_id, "ProductVariant")
: undefined,
title: item.title || undefined,
originalUnitPriceWithCurrency:
item.price != null
? { amount: item.price, currencyCode }
: undefined,
quantity: item.quantity,
})),
purchasingEntity: customer_id
? { customerId: gid(customer_id, "Customer") }
: undefined,
email: email || undefined,
shippingAddress: shipping_address || undefined,
appliedDiscount: discount
? {
value: discount.value,
valueType: discount.value_type,
title: discount.title || undefined,
}
: undefined,
note: note || undefined,
tags: tags?.length ? tags : undefined,
useCustomerDefaultAddress: use_customer_default_address || undefined,
},
},
})
if (data.draftOrderCreate.userErrors.length) {
throw new Error(JSON.stringify(data.draftOrderCreate.userErrors))
}
return data.draftOrderCreate
}
Submitted by hugo989 3 hours ago