Secure your WooCommerce webhooks: verify signatures, rotate secrets and test safely

Practical checks and a safe rollout pattern so your store only acts on real WooCommerce deliveries, rejects replays and rotates secrets without downtime.

Start by assuming any webhook delivery you receive could be forged until you prove otherwise. The quickest win is to verify the signature WooCommerce sends, make handlers idempotent, and test a short dual-secret rollout in staging before you change production. That prevents spoofed updates, accidental duplicate processing and interruptions during secret rotation.

In this guide

Inventory your webhooks

Open WordPress admin → WooCommerce → Settings → Advanced → Webhooks and list every webhook that has a Delivery URL, Secret and status. Alternatively use the REST Webhooks resource to export IDs and delivery URLs. Record: webhook ID, Delivery URL, Secret presence (not value), status and any recent failure notes. That inventory tells you which receivers to update and where to run tests. See WooCommerce’s webhook docs for the UI and resource details: WooCommerce webhooks documentation and the REST API webhooks resource WooCommerce REST API webhooks.

Confirm WooCommerce sends a signature

Send a test delivery to a request logger you control (for example a private HTTP endpoint that records raw headers and body). Check the recorded request for the following headers described in the official docs: X-WC-Webhook-Signature and X-WC-Webhook-Delivery-ID. The X-WC-Webhook-Signature is a base64-encoded HMAC-SHA256 of the raw request body using the webhook Secret. The API docs show the delivery headers to expect: REST API webhooks and the admin-focused webhook guide explains where to trigger and inspect deliveries: WooCommerce webhooks docs.

Verify the signature on the receiver

On your receiver endpoint do these things before you act on the payload:

  • Read the raw request body exactly as delivered (not a parsed JSON string) and compute HMAC-SHA256(body, secret).
  • Base64-encode the computed HMAC and compare it, with a timing-safe comparison, to the X-WC-Webhook-Signature header value.
  • If verification fails, log the full failure (header values, webhook ID if present, remote IP) and return a non-2xx HTTP status so WooCommerce will retry according to its retry rules. Do not process the payload on failures.

Here’s a compact verification pseudo-example you can copy into a developer ticket or use as a review checklist (readers implement in the language their receiver uses):

raw_body = read_raw_request_body()
signature_header = request.headers['X-WC-Webhook-Signature']
secret = lookup_secret_for_webhook(webhook_id_or_url)
computed_hmac = base64_encode(HMAC_SHA256(raw_body, secret))
# Python example: import hmac, hashlib, base64
# base64.b64encode(hmac.new(secret, raw_body, hashlib.sha256).digest())
if timing_safe_equals(computed_hmac, signature_header):
    enqueue_or_process_payload(raw_body)
else:
    log_verification_failure(webhook_id, signature_header, computed_hmac)
    return 400

Replay protection and idempotency

WooCommerce does not publish a signed timestamp/nonce in its webhook headers in core documentation, so you should not rely on a built-in replay-protection header. Instead:

  • Use X-WC-Webhook-Delivery-ID (or another unique ID in the payload) to detect duplicate deliveries. Persist recent delivery IDs in a short-lived dedup store (for example an in-memory cache with TTL or a small database table) and reject duplicates.
  • Make your processing idempotent: ensure repeated processing of the same delivery ID or payload has no harmful side effects (for example update inventory to the supplied value rather than add/subtract, or use database upserts keyed by order/external ID).

These steps stop replayed or retried deliveries from creating duplicate orders, repeated stock adjustments or duplicate notifications.

Enforce HTTPS and TLS best practices

Only use https:// delivery URLs. Confirm your receiver uses modern TLS settings and HSTS at the hosting or CDN layer. WordPress’ administration TLS guidance is a useful reference for why HTTPS matters for admin endpoints and callbacks: WordPress HTTPS guidance. For capability-like webhook URLs and sensitive endpoints, the W3C capability-URLs note reinforces using secure scheme and transport: W3C capability URLs.

If you need IP-based allowlisting, verify whether your host or CDN publishes sender IP ranges; WooCommerce core doesn’t document a fixed origin IP list. Implement IP allowlisting only via a documented firewall, proxy or host feature and treat it as an additional layer, not a replacement for signature verification.

Rotate webhook secrets safely

WooCommerce’s admin UI shows a Secret field for each webhook. There is no built-in dual-secret automatic acceptance window in core, so you must plan rotation as an operator. A safe rollout pattern:

  1. Staging: deploy receiver code that accepts both old and new secrets (check webhook delivery ID or source) and logs which secret verified each delivery.
  2. Staging: update the webhook Secret in WooCommerce (admin UI or REST API) and trigger test deliveries until you see deliveries signed with the new secret.
  3. Production: repeat the same dual-acceptance deployment pattern, update the production webhook Secret, confirm deliveries, then remove acceptance of the old secret after you have observed successful deliveries for a reasonable overlap window you choose for your risk profile.
  4. Document the steps and keep an emergency rollback plan (revert the webhook Secret or redeploy the receiver to accept the previous secret) in case an outage occurs.

Because the platform doesn’t provide an automated rotation workflow, test the procedure and timing that suits your business. See the webhook admin and API docs for where to set the Secret: WooCommerce webhooks documentation and WooCommerce REST API webhooks.

Operational safeguards and practical tests

Operational items to implement now:

  • Separate logs for verification failures and for successful deliveries (include webhook ID, delivery ID, and which secret matched during rotation).
  • Short processing handlers that validate and enqueue work; perform heavy work in background jobs so your receiver responds quickly and avoids timeouts.
  • Alerting on spikes of verification failures (possible compromise or misconfiguration) and on many retries for the same webhook (downstream failure).

Practical tests you can run yourself (each test is observable):

  1. Signature presence test: point a webhook to a request-logger endpoint, trigger an event, and confirm X-WC-Webhook-Signature and X-WC-Webhook-Delivery-ID are present in the recorded request.
  2. Verification test: implement HMAC verification in staging. Send a valid webhook and confirm the receiver processes it. Modify the body or signature and confirm the receiver rejects it and logs a verification failure.
  3. Replay test: capture a valid delivery (headers and body), resend the same HTTP request to your receiver and confirm your dedup/idempotency logic rejects or safely ignores the duplicate delivery.
  4. Rotation test: in staging deploy dual-secret acceptance, set a new secret in WooCommerce, verify deliveries switch to the new signature, then stop accepting the old secret and confirm deliveries still succeed under the single new secret.

Fictional example

Fictional example: A toy shop used a webhook to post stock updates to its marketplace connector. They added HMAC-SHA256 verification comparing the computed base64 HMAC to X-WC-Webhook-Signature, kept a 48-hour dedup cache keyed by X-WC-Webhook-Delivery-ID, and tested secret rotation in staging by accepting both secrets during the swap. During production rotation they updated the webhook Secret in WooCommerce, watched deliveries sign with the new secret for an hour, and then removed support for the old secret. (This example is illustrative and fictional.)

Finish by choosing one immediate action: either run the signature-presence test (step 1 under Practical tests) for one webhook you control, or deploy a staging verification endpoint and complete the verification test there. Both show you quickly whether your store and receiver are speaking the same verification language.

Related guides: Use WooCommerce webhooks to keep inventory synchronized with marketplaces and Configure and test WooCommerce order and low‑stock emails.

Sources: WooCommerce webhooks documentation, WooCommerce REST API webhooks, WordPress HTTPS guidance, W3C capability URLs.