How to Create a Shopify Draft Order in Shopify Remix Using GraphQL?

How to Create a Shopify Draft Order in Shopify Remix Using GraphQL

Shopify’s Draft Orders feature is an essential tool for merchants, allowing them to create orders on behalf of customers. This is particularly useful for custom orders, phone orders, or situations where a customer needs assistance in placing their order. You can add products, apply discounts, and send invoices to customers, which they can pay online. Leveraging Shopify’s GraphQL API, you can create draft orders programmatically, and using Shopify Remix, a modern React-based framework, you can seamlessly integrate this functionality into your storefront.

In this tutorial, we’ll walk through how to create a draft order in Shopify using GraphQL in a Shopify Remix app.

Why Use Shopify Draft Orders?

Draft orders simplify the sales process by allowing merchants to:

  • Create orders without customers immediately checking out.
  • Manually input customer details and product variants.
  • Send invoice links directly to customers for payment.
  • Apply discounts, shipping charges, and taxes before finalizing the order.

This flexibility makes draft orders particularly useful for businesses that deal with custom orders or need to provide personalized service.

Steps to Create a Shopify Draft Order in Shopify Remix Using GraphQL:

Step 1: Prepare Static Data for the Draft Order

For demonstration purposes, we will use static data to simulate the customer order. Here’s an example of the static draft order data:

// Static draft order data (customer, line items, and attributes)

const draftOrderData = {
  customerId: "gid://shopify/Customer/123456789",
  email: "customer@example.com",
  note: "Custom order for VIP client",
  lineItems: [
    {
      variant_id: "gid://shopify/ProductVariant/987654321",
      quantity: 2
    }
  ],
  customAttributes: {
    name: "John Doe",
    email: "customer@example.com",
    message: "This is a special order"
  },
  Tags: ["VIP", "CustomOrder"],
};

Explanation:

  • customerId: The unique identifier for the customer in Shopify.
  • Email: The email address for sending invoice links.
  • Note: A note for the draft order.
  • LineItems: An array of items the customer wants to purchase, each containing the product variant ID and quantity.
  • CustomAttributes: Any additional information relevant to the order, such as the customer’s name and a special message.
  • Tags: Tags can be used to categorize or identify the draft order for easier management.

Step 2: Create the GraphQL Mutation for Draft Order Creation

To create a draft order, we need to define a GraphQL mutation. Here’s the mutation we’ll use:

graphql
mutation draftOrderCreate($input: DraftOrderInput!) {
  draftOrderCreate(input: $input) {
    draftOrder {
      id
      invoiceUrl
    }
    userErrors {
      field
      message
    }
  }
}

Explanation:

  • draftOrderCreate: This mutation takes an input of type `DraftOrderInput!` and creates a new draft order.
  • DraftOrder: The response returns the draft order’s ID and the URL for the invoice.
  • UserErrors: This field captures any validation errors that occur when creating the draft order.

Step 3: Implement the Action to Handle Draft Order Creation

Now, let’s implement the action in our Remix app that will handle the draft order creation using the static data defined earlier.

Create a new route in your Remix app for creating draft orders:

// app/routes/create-draft-order.jsx

import { json } from '@remix-run/node';
import { authenticate } from '../shopify.server';

export async function action() {
  const { admin } = await authenticate.admin();

  // Static draft order data
  const draftOrderData = {
    customerId: "gid://shopify/Customer/123456789",
    email: "customer@example.com",
    note: "Custom order for VIP client",
    lineItems: [
      {
        variant_id: "gid://shopify/ProductVariant/987654321",
        quantity: 2
      }
    ],
    customAttributes: {
      name: "John Doe",
      email: "customer@example.com",
      message: "This is a special order"
    },
    Tags: ["VIP", "CustomOrder"],
  };

  const draftOrderInput = {
    customerId: draftOrderData.customerId,
    note: draftOrderData.note,
    email: draftOrderData.email,
    lineItems: draftOrderData.lineItems.map(item => ({
      variantId: item.variant_id,
      quantity: parseInt(item.quantity, 10),
    })),
    customAttributes: [
      { key: "Name", value: draftOrderData.customAttributes.name },
      { key: "Email", value: draftOrderData.customAttributes.email },
      { key: "Message", value: draftOrderData.customAttributes.message }
    ],
    tags: draftOrderData.Tags,
    taxExempt: true,
  };

  try {
    const response = await admin.graphql(
      `#graphql
      mutation draftOrderCreate($input: DraftOrderInput!) {
        draftOrderCreate(input: $input) {
          draftOrder {
            id
            invoiceUrl
          }
          userErrors {
            field
            message
          }
        }
      }`,
      { input: draftOrderInput }
    );

    const result = response.data;

    if (result.draftOrderCreate.userErrors.length > 0) {
      console.error('Error creating draft order:', result.draftOrderCreate.userErrors);
      return json({ success: false, errors: result.draftOrderCreate.userErrors }, { status: 400 });
    }

    console.log('Draft Order Created:', result.draftOrderCreate.draftOrder);
    return json({ success: true, draftOrder: result.draftOrderCreate.draftOrder });

  } catch (error) {
    console.error('Failed to create draft order:', error);
    return json({ success: false, error: error.message }, { status: 500 });
  }
}

Explanation:

  • Input Preparation: We prepare the input object for the GraphQL mutation, ensuring that the data structure aligns with what Shopify expects.
  • GraphQL Request: The `admin.graphql` function is used to send the mutation request to the Shopify API.
  • Error Handling: We check for user errors returned by the API. If there are any errors, we log them and return a JSON response with the error details.
  • Logging Success: If the draft order is created successfully, we log the order details and return a success response.

Step 4: Testing the Draft Order Creation

Now that the code is set up, you can test the draft order creation functionality by visiting the route you defined in your Remix app. Make sure to have a running development server and authenticate against your Shopify store.

Testing Steps:

  1. Start your Remix app and navigate to the `/create-draft-order` route.
  2. Observe the console logs for success messages or errors.
  3. Check your Shopify admin panel to see if the draft order appears under  Orders > Drafts.

Sample Output:

Upon successful execution, the console log will display the following:

Draft Order Created: { id: “gid://shopify/DraftOrder/123456789”, invoiceUrl: “https://yourstore.myshopify.com/admin/orders/123456789/invoice” }

Practical Tips for Using Draft Orders

  • Utilize Webhooks: To stay updated on draft order changes, consider setting up webhooks in Shopify. This will allow you to trigger actions in your app whenever a draft order is created or updated.
  • Error Handling: Ensure robust error handling, especially for network-related errors or API limits. Use retries with exponential backoff for API calls in production.
  • Optimize Data Handling: If you’re working with large datasets, consider optimizing the way you fetch and process data to reduce latency and improve user experience.
  • User Interface: Design an intuitive UI that guides merchants through the order creation process, minimizing input errors and enhancing productivity.
  • Testing: Always test draft order functionalities thoroughly in both development and production environments to ensure everything works as expected.

Conclusion

Creating draft orders using Shopify’s GraphQL API in a Remix application opens up various possibilities for enhancing customer service and streamlining order management. By following the steps outlined in this tutorial, you can build a robust feature that leverages the flexibility of draft orders.

Previous Article

How to Use CSS with Shopify Remix Vite?

Next Article

How to Add a Column to Tier Price in Magento 2 Admin?

Write a Comment

Leave a Comment

Your email address will not be published. Required fields are marked *

Get Connect With Us

Subscribe to our email newsletter to get the latest posts delivered right to your email.
Pure inspiration, zero spam ✨