Ecommerce Webhooks: How to Receive Platform Events Reliably
How to handle ecommerce webhooks: architecture, event delivery, signature verification, retries, idempotency, duplicate and out-of-order events, failures and monitoring.
Quick answer
To handle ecommerce webhooks reliably, run a small endpoint that verifies the signature using the raw request body, stores or enqueues the event and responds within seconds, then process events asynchronously from a queue. Expect duplicates and out-of-order delivery: deduplicate by event ID, make processing idempotent and use timestamps or fetch current state before acting. Platforms retry failed deliveries for limited periods, so add reconciliation jobs to catch missed events, and monitor volumes, failures and lag.
Where This Fits
Webhooks are one entry point into an event-driven architecture. Processing usually happens through queues. Integration patterns more broadly are covered in API integration.
Webhook Architecture
| Component | Responsibility |
|---|---|
| Receiver endpoint | Verify signature, persist or enqueue, respond fast |
| Queue | Buffer events, enable retries and parallel processing |
| Workers | Process events idempotently, call downstream systems |
| Deduplication store | Record processed event IDs |
| Dead-letter queue | Hold events that keep failing, with alerts |
| Reconciliation job | Compare with platform API to catch missed events |
Signature Verification
Verify every request before trusting it. Compute an HMAC of the raw request body with the shared secret and compare it to the signature header using a constant-time comparison. Use the raw bytes, not a re-serialized JSON object, or verification will fail. Some providers, such as Stripe, include a timestamp in the signature to help reject replayed requests.
import crypto from "node:crypto";
export function isValid(rawBody: Buffer, header: string, secret: string) {
const digest = crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("base64");
const a = Buffer.from(digest);
const b = Buffer.from(header ?? "");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}Respond Fast, Process Later
Platforms expect a quick success response. If your endpoint calls the ERP, sends emails and updates inventory before responding, it will time out under load and trigger retries, causing duplicates. Acknowledge after verification and persistence, and let workers do the rest.
Losing or duplicating orders from webhooks?
ZSpace can rebuild your webhook handling with verification, queues, idempotency and reconciliation, and add the monitoring to prove it works.
Retries and Delivery Guarantees
Most platforms provide at-least-once delivery with retries for a limited period. Shopify, for example, retries failed deliveries several times over hours, and Stripe retries for up to three days in live mode, disabling endpoints that keep failing. After that, events can be lost, so your design must include reconciliation. Check each provider's current documentation for exact policies.
Idempotency and Duplicates
- Store processed event IDs (for example Shopify's webhook or event ID headers, Stripe's event ID)
- Skip events already processed
- Use idempotency keys when calling downstream APIs
- Design updates as 'set state to X' rather than 'add X' where possible
- Keep the deduplication record at least as long as the retry window
Out-of-Order Events
An 'order updated' event can arrive before 'order created', and an older update can follow a newer one. Compare timestamps or versions and ignore stale updates, or treat the webhook as a signal and fetch the current state from the API before acting. For sequences that must be processed in order per entity, queue by entity key.
Failures
| Failure | Handling |
|---|---|
| Invalid signature | Reject with 401, log and alert on spikes |
| Downstream system unavailable | Retry from queue with backoff |
| Bad data in payload | Dead-letter with details for investigation |
| Endpoint outage | Platform retries; reconciliation catches the rest |
| Endpoint disabled by provider | Alert, fix, re-enable and backfill |
Reconciliation
Schedule jobs that fetch recent orders, payments or products from the platform API and compare them with your records. Process anything missing through the same idempotent workers. Reconciliation turns webhook gaps from silent data loss into a short delay.
Security and Secrets
Store secrets in a secrets manager, use different secrets per environment, never log secrets or full sensitive payloads, restrict the endpoint to required methods and sizes, and rotate secrets as providers require.
Monitoring
- Deliveries received by type and source
- Signature failures
- Queue depth and processing latency
- Processing errors and dead-letter count
- Unexpected silence (no orders webhooks during trading hours)
- Reconciliation differences
Worked Example
An illustrative scenario, not a client case: a brand's order sync processes Shopify order webhooks synchronously, calling the ERP before responding. During a flash sale, the ERP slows, responses time out, the platform retries and some orders are created twice in the ERP. The team changes the endpoint to verify, enqueue and respond immediately, adds deduplication by webhook ID and an idempotency key on ERP calls, and runs an hourly reconciliation against the orders API.
Implementation Steps
- Build a minimal receiver: verify, persist, acknowledge
- Queue events and process with idempotent workers
- Store processed event IDs
- Handle out-of-order updates
- Add reconciliation against the platform API
- Monitor volumes, failures, lag and silence
Common Mistakes
- Processing synchronously before responding
- Verifying signatures against parsed JSON
- No deduplication
- Assuming in-order delivery
- No reconciliation
- Logging secrets or full customer payloads
Ready to make webhook integrations dependable?
Talk to ZSpace about integration engineering, Shopify app and webhook development and event-driven automation.
Conclusion
Reliable webhooks come down to verify, persist, acknowledge, process idempotently, handle order, reconcile and monitor. Related: event-driven architecture and queue architecture.
Common questions
An HTTP request a platform sends to your endpoint when something happens, such as an order being created, a payment succeeding or a product being updated, so your systems can react without polling.