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");
});
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();
}
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)
);
}
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)
);
}
}
}
Usage:
await retryRequest(() => syncOrder(order));
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);
}
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
A reliable Shopify integration is usually built around webhook verification, idempotency, retries, and asynchronous processing.
Top comments (0)