DEV Community

Alex Morgan
Alex Morgan

Posted on

How to Integrate a Third-Party API with Shopify: A Practical Guide

How to Integrate a Third-Party API with Shopify: A Practical Guide

A common Shopify integration flow looks like this:

Shopify Webhook

Your Backend

Third-Party API

In this example, when an order is created in Shopify, a webhook sends the order data to your backend, which forwards the required data to an external API.

1. Create a Webhook Endpoint

Example using Node.js and Express:

import express from "express";

const app = express();

app.use(express.json());

app.post("/webhooks/orders/create", async (req, res) => {
  const order = req.body;

  console.log("New order:", order.id);

  // Process asynchronously in production
  await syncOrder(order);

  res.status(200).send("OK");
});

app.listen(3000, () => {
  console.log("Server running on port 3000");
});
Enter fullscreen mode Exit fullscreen mode

2. Send Data to a Third-Party API

Only send the data required by the external system.

async function syncOrder(order) {
  const payload = {
    orderId: order.id,
    email: order.email,
    total: order.total_price,
  };

  const response = await fetch(
    "https://api.example.com/orders",
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${process.env.API_KEY}`,
      },
      body: JSON.stringify(payload),
    }
  );

  if (!response.ok) {
    throw new Error("Failed to sync order");
  }

  return response.json();
}
Enter fullscreen mode Exit fullscreen mode

3. Verify the Shopify Webhook

Never process webhook requests without verification.

import crypto from "crypto";

function verifyWebhook(rawBody, hmacHeader) {
  const generatedHmac = crypto
    .createHmac("sha256", process.env.SHOPIFY_API_SECRET)
    .update(rawBody, "utf8")
    .digest("base64");

  return crypto.timingSafeEqual(
    Buffer.from(generatedHmac),
    Buffer.from(hmacHeader)
  );
}
Enter fullscreen mode Exit fullscreen mode

For webhook verification, make sure you use the raw request body before JSON parsing.

4. Add Basic Retry Logic

External APIs can fail temporarily.

async function retryRequest(fn, retries = 3) {
  for (let attempt = 1; attempt <= retries; attempt++) {
    try {
      return await fn();
    } catch (error) {
      if (attempt === retries) throw error;

      const delay = 1000 * attempt;

      await new Promise(resolve =>
        setTimeout(resolve, delay)
      );
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Usage:

await retryRequest(() => syncOrder(order));
Enter fullscreen mode Exit fullscreen mode

5. Avoid Duplicate Processing

Webhooks can be delivered more than once.

const processedOrders = new Set();

async function processOrder(order) {
  if (processedOrders.has(order.id)) {
    console.log("Order already processed");
    return;
  }

  await syncOrder(order);

  processedOrders.add(order.id);
}
Enter fullscreen mode Exit fullscreen mode

In production, use a database or Redis instead of an in-memory Set.

Final Flow

Shopify
   ↓
Webhook
   ↓
Verify HMAC
   ↓
Check Duplicate Event
   ↓
Queue / Process Job
   ↓
Third-Party API
   ↓
Retry on Temporary Failure
Enter fullscreen mode Exit fullscreen mode

A reliable Shopify integration is usually built around webhook verification, idempotency, retries, and asynchronous processing.

Top comments (0)