Remix

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.

Click to rate this post!
[Total: 0 Average: 0]
Bharat Desai

Bharat Desai is a Co-Founder at MageComp. He is an Adobe Magento Certified Frontend Developer ? with having 8+ Years of experience and has developed 150+ Magento 2 Products with MageComp. He has an unquenchable thirst to learn new things. On off days you can find him playing the game of Chess ♟️ or Cricket ?.

Share
Published by
Bharat Desai

Recent Posts

How to Use CSS with Shopify Remix Vite?

CSS (Cascading Style Sheets) is essential in web development to create visually appealing and responsive…

2 days ago

Latest Hyvä Theme Trends to Elevate your Magento UI/UX

Your eCommerce website theme is highly important for your business's online success as it reflects…

2 days ago

Use Hyvä Products at their Full Potential

Hyvä represents more than just a theme; it is a comprehensive suite of extensions and…

3 days ago

Magento 2: Add Number of Products Displayed Per Page in Invoice PDF

Hello Magento mates, Invoices are critical documents in every eCommerce business, providing details of product…

4 days ago

Magento 2: How to Call phtml Based on Selection of Payment Method at Multishipping Payment

Hello Magento Friends, Multishipping in Magento 2 allows customers to split their orders into multiple…

7 days ago

SearchGPT vs. ChatGPT: Key Differences, Advantages, and Future Trends

In recent years, artificial intelligence (AI) has made remarkable strides, with models like ChatGPT and…

1 week ago