Reliable Webhook Processing in NestJS: Signatures, Idempotency, Retries & Queues
Build reliable NestJS webhooks for SaaS payments and integrations using signature verification, idempotency, durable inboxes, queues, retries, and observability.
- NestJS
- Webhooks
- SaaS
- Security
- Queues

Webhooks are untrusted, duplicated, and out of order by design. A payment provider can retry the same event, deliver it late, or time out while your NestJS API successfully processes it. Treating a webhook like an ordinary controller request is how SaaS products double-activate subscriptions and lose billing events.
A reliable webhook pipeline verifies the raw payload, records the event durably, responds quickly, and processes business logic asynchronously. Idempotency makes retries safe; queues and observability make failures recoverable.
Why webhook controllers fail in production
- Providers retry when your response is slow—even if your database transaction succeeded
- Duplicate events can issue two refunds, send two invoices, or provision the same tenant twice
- Events may arrive out of order, such as subscription updates before the creation event
- A provider outage or your deployment can create a burst that overwhelms synchronous handlers
- Without an event ledger, support cannot prove what arrived or what failed

The reliable NestJS webhook flow
- Capture the raw request body — signature verification must use the exact bytes the provider signed
- Verify authenticity — validate HMAC or provider signatures before parsing or trusting any field
- Claim the event idempotently — insert the provider event id behind a unique constraint
- Persist the payload — store an inbox record with provider, type, timestamps, and processing status
- Acknowledge quickly — return the required 2xx response before expensive business logic begins
- Enqueue processing — hand the inbox id to BullMQ, RabbitMQ, or another durable worker pipeline
- Record the outcome — mark processed, retrying, or dead-lettered with a useful error trail
Signature verification comes before JSON
Many providers sign the raw body plus a timestamp. If middleware parses and re-serializes JSON first, byte-level differences can invalidate the signature. Configure NestJS to expose the raw body only for webhook routes, verify against the provider secret, enforce timestamp tolerance, and reject invalid signatures with no side effects.
Idempotency: make duplicate delivery harmless
- Place a unique database constraint on `(provider, event_id)`; do not rely on an in-memory check
- Perform the event claim and state transition in a transaction
- Make downstream operations idempotent too—for example, upsert subscription state by provider id
- Store the provider event timestamp and version so stale events cannot overwrite newer state
- Return success for an already accepted event instead of processing it again
Exactly-once delivery is a promise the network cannot keep; idempotent processing is the guarantee your application can provide.
Retries, backoff, and dead-letter handling
- Retry transient failures with exponential backoff and jitter
- Do not retry permanent errors such as an unknown event schema forever
- Move exhausted events to a dead-letter state that operators can inspect and replay
- Cap concurrency so a delivery burst does not exhaust PostgreSQL or downstream APIs
- Preserve correlation ids from intake through every worker attempt
Webhook observability checklist
- Count received, verified, duplicated, processed, retried, and dead-lettered events
- Track processing lag from provider timestamp to successful completion
- Alert on signature failures, queue depth, oldest unprocessed event, and dead-letter growth
- Expose a secure internal event viewer for support and operations
- Redact secrets and sensitive payment data from logs and traces
Multi-tenant SaaS considerations
- Resolve the tenant from trusted provider metadata or an internal mapping—not an unsigned payload field
- Apply the tenant context before updating subscriptions, entitlements, or audit records
- Partition worker concurrency so one tenant's integration burst cannot starve others
- Store provider-account-to-tenant mappings with strict uniqueness and audit history
What production-ready looks like
The endpoint verifies and stores an event in milliseconds, duplicates become no-ops, workers retry transient failures, dead letters are visible, and every subscription change has an audit trail. Explore Cyber Infoware products or contact us to choose a reliable NestJS SaaS foundation.
Explore Cyber Infoware packages
Production NestJS SaaS foundations with commercial licensing — pick the architecture that matches your team.
- NestJS Microservice Starter Kit
Production NestJS microservices — API gateway, Keycloak SSO, RabbitMQ, Docker, Kubernetes, and Terraform.
- Enterprise SaaS Microservices Boilerplate
Full multi-tenant SaaS control plane as NestJS microservices — service-per-DB, billing, audit, notifications.
- Multi-Tenant SaaS Boilerplate
Best-seller NestJS multi-tenant SaaS boilerplate — one API, per-tenant databases, billing, and Keycloak SSO.