Guide to Walmart Webhooks: Features and Best Practices
Walmart Marketplace webhooks notify sellers about store activity: a purchase order is created, an item goes out of stock, the buy box changes, a return is created. If you're building on Walmart Marketplace, webhooks are how you react to seller events without polling.
This guide covers how Walmart's two notification systems work, how inbound verification actually works (it's not the public-key scheme you might expect), and the best practices for production.
What are Walmart webhooks?
Walmart Marketplace has two notification systems, and they verify differently:
- General event notifications: you create a subscription with an
eventType,resourceName, andeventUrl, and set anauthMethod(BASIC_AUTH,HMACwith your client secret, orOAUTH). Walmart uses those credentials to authenticate itself to your endpoint; it does not sign the payload for you to verify with a public key. - Performance webhooks (
SELLER_PERFORMANCE_ALARMS/REPORT): signed with an HMAC-SHA256 over a canonical string, delivered inWM_SEC.*headers.
Crucially, inbound verification is not the SHA256WithRSA public-key scheme (WM_SEC.AUTH_SIGNATURE / WM_CONSUMER.*). That scheme is how a seller signs outbound calls to Walmart, not how you verify inbound webhooks. Confirm which system your integration targets; this guide covers inbound verification.
Walmart webhook features
| Feature | Details |
|---|---|
| Configuration | Webhooks Subscription API (eventType + resourceName + eventUrl + authMethod) |
| General-notification auth | BASIC_AUTH, HMAC (HMAC-SHA256 with client secret), or OAUTH, set by you |
| Performance-webhook signature | WM_SEC.SIGNATURE (base64 HMAC-SHA256), WM_SEC.TIMESTAMP, WM_SEC.KEY_ID |
| Canonical string | METHOD\nPATH_AND_QUERY\nWM_SEC.TIMESTAMP\nSHA256_HEX(rawBody) |
| Replay window | ~5 minutes (+2 min skew) |
| Deduplication | By delivery id, over 7 days |
| Acknowledgement | 2xx within 3 seconds |
| General retries | 5 min, then 15 min, then 45 min |
| SDK | None |
Common events
Walmart event names are uppercase (verified from the Get Event Types API):
| Event | Fires when |
|---|---|
PO_CREATED | A purchase order is created |
INVENTORY_OOS | An item goes out of stock |
BUY_BOX_CHANGED | The buy box changes for an item |
RETURN_CREATED | A return is created |
Subscribe to the events you process, and consult Walmart's Get Event Types API for the full list.
Setting up Walmart webhooks
Create a subscription via the Webhooks Subscription API with eventType, resourceName, eventUrl, and an authMethod. For general notifications, the authMethod is how Walmart proves itself to you, so choose one and configure your endpoint to check it. Respond 2xx within 3 seconds.
Securing Walmart webhooks
General event notifications: verify the credentials you set
For general notifications, Walmart authenticates using the authMethod you configured. If you set BASIC_AUTH, verify the Authorization credentials; if HMAC, verify the HMAC-SHA256 computed with your client secret; if OAUTH, validate the token. There's no separate payload signature to check.
Performance webhooks: verify WM_SEC.SIGNATURE
Performance webhooks are signed. Build the canonical string METHOD\nPATH_AND_QUERY\nWM_SEC.TIMESTAMP\nSHA256_HEX(rawBody), compute a base64 HMAC-SHA256 with your shared secret, and compare against the WM_SEC.SIGNATURE header. Verify against the raw body, enforce the ~5-minute replay window, and dedupe by delivery id.
const crypto = require("crypto");
const SECRET = process.env.WALMART_WEBHOOK_SECRET;
function verifyPerformance(req, rawBody) {
const timestamp = req.headers["wm_sec.timestamp"];
// Reject stale deliveries (~5 min window, +2 min skew)
if (Math.abs(Date.now() - Number(timestamp)) > 7 * 60 * 1000) return false;
const bodyHash = crypto.createHash("sha256").update(rawBody).digest("hex");
const canonical = [
req.method,
req.originalUrl, // path + query
timestamp,
bodyHash,
].join("\n");
const expected = crypto
.createHmac("sha256", SECRET)
.update(canonical)
.digest("base64");
const a = Buffer.from(expected);
const b = Buffer.from(req.headers["wm_sec.signature"] || "");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => {
if (!verifyPerformance(req, req.body)) {
return res.sendStatus(401);
}
res.sendStatus(200); // acknowledge within 3s
processQueue.add(JSON.parse(req.body)); // process asynchronously
});
The same canonical-string HMAC in Python:
import base64
import hashlib
import hmac
import os
SECRET = os.environ["WALMART_WEBHOOK_SECRET"].encode()
def verify_performance(method, path_and_query, timestamp, raw_body, signature):
body_hash = hashlib.sha256(raw_body).hexdigest()
canonical = "\n".join([method, path_and_query, timestamp, body_hash]).encode()
expected = base64.b64encode(hmac.new(SECRET, canonical, hashlib.sha256).digest()).decode()
return hmac.compare_digest(expected, signature or "")
Walmart webhook limitations and pain points
Two systems, and it's not the RSA scheme
The Problem: It's easy to reach for Walmart's SHA256WithRSA public-key signing, but that's for seller-to-Walmart outbound calls, not inbound verification. Inbound is either the credentials you set (general notifications) or the WM_SEC.SIGNATURE HMAC (performance webhooks).
Why It Happens: Walmart's docs cover both request-signing and webhook verification, and they're easy to conflate.
Workarounds:
- Confirm which system your integration targets, and verify with the credentials/HMAC path, not the RSA public-key path.
How Hookdeck Can Help: Hookdeck verifies the inbound scheme at the edge, so your application receives pre-verified events without you untangling Walmart's signing docs.
The canonical string must be exact
The Problem: The performance-webhook signature is over METHOD\nPATH_AND_QUERY\nTIMESTAMP\nSHA256_HEX(body). Any deviation (wrong path form, missing query, hashing a parsed body) fails verification.
Why It Happens: Walmart signs a canonical request representation, not just the body.
Workarounds:
- Reconstruct the canonical string exactly, hash the raw body, and compare in constant time.
How Hookdeck Can Help: Hookdeck handles the canonical-string verification at the edge, so your app doesn't reproduce it.
Replay window and deduplication
The Problem: There's a ~5-minute replay window (+2 min skew), and Walmart expects you to dedupe by delivery id over 7 days. Skipping either leaves you open to replays or double-processing.
Why It Happens: Walmart binds a timestamp and expects idempotent handling.
Workarounds:
- Reject stale timestamps and dedupe on the delivery id for 7 days.
How Hookdeck Can Help: Hookdeck verifies freshness and deduplicates deliveries at the edge, so replays and retries don't reach your app. See our guide to webhook idempotency.
The 3-second acknowledgement window
The Problem: You must return 2xx within 3 seconds, and general notifications retry only at 5/15/45 minutes. Slow processing risks the window and burns the small retry budget.
Why It Happens: Walmart caps the ack time and retries sparingly.
Workarounds:
- Verify, enqueue, and return 2xx immediately; process off a queue.
How Hookdeck Can Help: Hookdeck acknowledges Walmart within the window and durably queues events, decoupling the 3-second budget from your processing time.
Best practices
Verify the inbound scheme, not the RSA one
Check the authMethod credentials for general notifications, or the WM_SEC.SIGNATURE canonical-string HMAC for performance webhooks. Don't use the seller-outbound RSA scheme for inbound.
Reconstruct the canonical string exactly and use the raw body
Build METHOD\nPATH_AND_QUERY\nTIMESTAMP\nSHA256_HEX(rawBody) precisely and compare in constant time.
Enforce the replay window and dedupe
Reject stale timestamps and dedupe by delivery id over 7 days.
Acknowledge within 3 seconds, process asynchronously
Return 2xx immediately and defer work to a queue. See why to process webhooks asynchronously.
Make Walmart webhooks production-ready
Hookdeck verifies the inbound signature, deduplicates, and durably queues every seller event
Conclusion
Walmart Marketplace webhooks come in two systems: general notifications you authenticate with the credentials you set, and performance webhooks signed with a WM_SEC.SIGNATURE HMAC over a canonical METHOD/PATH/TIMESTAMP/SHA256(body) string. Neither is the RSA public-key scheme (that's seller-outbound). Verify the right one, reconstruct the canonical string exactly, enforce the replay window, dedupe, and acknowledge within 3 seconds.
Hookdeck verifies the inbound signature, deduplicates, and durably queues every event at the edge, so your app only ever processes verified, unique seller events.
Get started with Hookdeck for free and handle Walmart webhooks reliably in minutes.