When building a custom Shopify App, one of the most essential aspects is receiving real-time updates about store events, such as new orders, customer creations, or inventory changes. That's where Shopify Webhooks come into play.
Webhooks allow Shopify to send instant notifications to your server whenever an event occurs. But to handle them securely and efficiently, developers must verify their authenticity using HMAC validation and process them through reliable queue systems.
In this guide we’ll explore how to implement secure webhook handling using Node.js and Python, verify payloads with HMAC, and process them asynchronously using queues.
1. What are Shopify Webhooks?
Shopify webhooks are HTTP callbacks that notify your app when specific event happens in a store, for example:
-
orders/create
— when a new order is placed -
orders/fulfilled
— when an order is marked fulfilled -
customers/create
— when a customer signs up
Instead of polling APIs repeatedly, your server receives an event payload directly from Shopify in real time.
2. Why verification Matters
Anyone could try to send a fake POST request to your endpoint, pretending to be Shopify. To ensure authenticity, Shopify includes a header in each workbook request.
Your app must:
- Generate an HMAC from the raw request body using your app secret key.
- Compare it securely to the
X-Shopify-Hmac-Sha256
header. - Accept only verified requests and ignore everything else.
This prevents malicious actors from injecting fake data or triggering unwanted actions in your system.
3. Secure HMAC Verification (Node.js Example)
Let’s implement a secure webhook verification handler using Node.js and Express.
import crypto from "crypto";
import express from "express";
const app = express();
app.use(express.raw({ type: "application/json" }));
app.post("/webhooks/orders/create", (req, res) => {
const secret = process.env.SHOPIFY_WEBHOOK_SECRET;
const hmacHeader = req.get("X-Shopify-Hmac-Sha256");
const digest = crypto
.createHmac("sha256", secret)
.update(req.body, "utf8")
.digest("base64");
const verified = crypto.timingSafeEqual(
Buffer.from(digest),
Buffer.from(hmacHeader)
);
if (!verified) return res.sendStatus(401);
const data = JSON.parse(req.body.toString("utf8"));
console.log("Verified Order:", data.id);
// Enqueue for background processing
queue.add("order_created", data);
res.sendStatus(200);
});
Here, the request is verified first, and only then pushed into a queue for asynchronous processing.
4. Secure HMAC Verification(Python Example)
A Python equivalent using FastAPI looks like this:
import hmac, hashlib, base64, json, os
from fastapi import FastAPI, Request, Header, HTTPException
app = FastAPI()
SECRET = os.getenv("SHOPIFY_WEBHOOK_SECRET")
@app.post("/webhooks/orders/create")
async def handle_webhook(request: Request, x_shopify_hmac_sha256: str = Header(...)):
raw = await request.body()
digest = base64.b64encode(hmac.new(SECRET.encode(), raw, hashlib.sha256).digest()).decode()
if not hmac.compare_digest(digest, x_shopify_hmac_sha256):
raise HTTPException(status_code=401, detail="Invalid HMAC signature")
payload = json.loads(raw.decode("utf-8"))
print("Verified order:", payload.get("id"))
# Send to queue or background task
return {"status": "success"}
Both examples verify the webhook payload before performing any logic—ensuring that your app only processes genuine data from Shopify.
5. Why Use Queues for Webhook Processing
Webhook endpoints should respond fast (within 1–2 seconds). If they take too long, Shopify retries the request or marks it failed.
That’s why queue processing is essential.
Instead of handling the logic immediately, enqueue the event for asynchronous processing.
Example (Node.js + BullMQ):
import Queue from "bull";
const queue = new Queue("shopify-webhooks");
queue.process("order_created", async (job) => {
const order = job.data;
// Sync order with ERP, send email, or update CRM
console.log("Processing order:", order.id);
});
This approach ensures your endpoint remains responsive while heavy lifting happens in the background. It also provides reliability — retries, monitoring, and scalability.
6. Handling Duplicates and Retries
Shopify may send the same webhook more than once.
Use the X-Shopify-Webhook-Id
header to track unique events and avoid duplicates.
Store this ID in a database or cache like Redis, and ignore if it’s already processed. This keeps your systems idempotent and prevents duplicate records or emails.
7. Security & Reliability Best Practices
- Always use HTTPS endpoints.
- Verify
X-Shopify-Hmac-Sha256
for every webhook. - Respond with
200 OK
quickly after queuing. - Store logs of webhook deliveries and failures.
- Rotate app secrets periodically. Following these best practices ensures your webhook handling remains secure, scalable, and developer-friendly.
8. When to Involve Professionals
While the examples above are straightforward, building a production-grade webhook system with retry logic, HMAC verification, and queue orchestration can get complex—especially if you’re integrating with multiple systems like ERPs or CRMs.
That’s where experienced Shopify expert developers can make a huge difference. They can help design robust architectures that handle thousands of webhook events per minute without downtime or data loss.
For enterprises or global brands running on Shopify Plus, working with a specialized Shopify Plus Agency ensures advanced infrastructure setup—secure webhook endpoints, scalable queue management, and compliance with data standards.
Conclusion
Implementing secure and reliable Shopify webhooks is a must for any serious app or store integration. By verifying payloads with HMAC, processing events asynchronously, and utilizing queues effectively, you ensure that your system remains both secure and scalable.
Whether you’re automating order updates or syncing customers with external platforms, this approach gives you full control over your store’s data flow.
And if you need help building high-performance solutions tailored to your business, partnering with professional Shopify expert developers or a trusted Shopify Plus Agency can take your integration to the next level.
Top comments (0)