Article

WooCommerce Webhooks Not Working? Trace the Order Handoff

Warehouse shelving and boxes representing the fulfillment process connected to online store orders

An order appears in WooCommerce, but the warehouse never receives it. The customer sees a completed checkout while your team is left asking where the handoff stopped.

I would investigate that gap as several separate stages: the right event occurs, WooCommerce attempts a delivery, the receiver accepts the request, and the receiving application completes its work. A green delivery response can answer one question without answering all four.

This guide covers outgoing WooCommerce webhooks used for fulfillment, accounting, CRM and other integrations. It is not a guide to incoming payment-provider callbacks. The scenarios are illustrative, not accounts of client incidents or tests I have performed on your store.

Start with the business action that is missing

Before changing a webhook, I would ask what should have happened. Was the warehouse supposed to create a shipment, the accounting service to update an invoice, or the CRM to update an existing contact?

Choose one affected order and record its ID, relevant status change, expected destination and timestamp with timezone. Ask the receiving team for the matching record or error. Avoid collecting whole customer records when a redacted identifier is enough.

Illustrative example: a store should send eligible paid orders to a fulfillment application. Order 4201 is visible in WooCommerce but absent from that application. “Webhook failed” is still only a hypothesis. The failure might be delivery, eligibility rules, field mapping or a downstream worker.

A useful incident note separates expected and observed behavior. It also identifies the owner on each side. Without an owner for the receiver, a store developer may be able to prove acceptance but not explain what happened afterward.

1. Check direction, topic, status and destination

WooCommerce’s webhook documentation describes the configuration under WooCommerce → Settings → Advanced → Webhooks. I would record the topic, status, delivery URL and webhook ID before editing anything. Active, paused and disabled states mean different things.

Check that the URL is the intended production receiver rather than an old staging endpoint. Use HTTPS and review any recent domain, firewall or deployment changes with the receiver’s maintainer. Do not send live order payloads to an arbitrary public request-capture service.

Then compare the configured topic with the required business event. An order being created does not, by itself, establish that the integration’s payment or fulfillment eligibility conditions are satisfied. I would define those conditions explicitly instead of treating every order notification as permission to ship.

If more than one webhook reaches the same service, document why. Two similar configurations can be intentional, but they can also explain duplicate processing or confusion about which delivery belongs to which subscription.

2. Trace one delivery instead of guessing from order status

The official guide points to WooCommerce → Status → Logs and the webhooks-delivery source. Find a delivery corresponding to the marked order event, then compare its time and response with the receiver’s logs.

ObservationWhat I would check next
No matching attempt is visibleTopic, status, event reproduction, background processing and logging availability
Connection error or timeoutDNS, TLS, network reachability and receiver response time
401 or 403 responseReceiver authentication, signature verification and access rules
404 or an unexpected HTML pageEndpoint path, deployment routing and accidental login or challenge pages
5xx responseReceiver application error and its correlation identifier
2xx response but missing business actionDurable receipt, queue processing, eligibility and downstream mapping

This table is a diagnostic starting point, not a guarantee that a particular status has only one cause. I would inspect the actual response and the corresponding receiver event. A status code alone does not prove that an invoice or shipment exists.

If no log appears, do not immediately conclude that no event occurred. Check logging configuration, retention and the time window. Also review the site’s background-processing health before creating more test events.

Illustrative order webhook diagnosis: confirm event, find delivery, inspect receiver acceptance, trace processing and verify business completion
Illustrative diagnosis: delivery acceptance and completed business processing are separate checks.

3. Verify authenticity using the original request body

The WooCommerce webhook API reference documents X-WC-Webhook-Signature as a base64-encoded HMAC-SHA256 signature of the payload. The receiving application should verify it using the configured secret and the original body bytes, not JSON that has been decoded and re-encoded.

Here is a small PHP verification fragment for an illustrative receiver. It assumes the receiver has already obtained the original body, signature header and its securely configured secret:

// Verification fragment only, not a complete public endpoint.
$expected = base64_encode(
    hash_hmac( 'sha256', $raw_body, $webhook_secret, true )
);

$signature_is_valid =
    is_string( $received_signature ) &&
    $received_signature !== '' &&
    hash_equals( $expected, $received_signature );

I would reject an invalid signature before business processing. This fragment does not implement routing, request-size limits, error handling, durable storage or duplicate protection. It is not a complete integration to paste into a live website.

For a mismatch, check the configured secret on both sides and whether middleware alters the body before verification. Handle secret rotation as a coordinated change. Do not solve a signature error by permanently disabling verification, and never publish the secret in a screenshot or shared error report.

A valid signature supports authenticity and integrity; it does not establish that this business action has never been processed before. Duplicate handling needs its own design.

4. Make receiver acceptance meaningful

If I maintain the receiver, I would define exactly what a success response means. For work that takes time, one useful design is to verify the request, persist an accepted event durably, enqueue processing and then respond promptly. The worker’s completion or failure is tracked separately.

The important word is durably. Sending a success response and then keeping the only copy of the job in process memory creates an avoidable loss window if that process exits.

I would also decide what happens when durable storage or queue insertion fails. Do not acknowledge work as safely accepted when it has nowhere reliable to go. The appropriate response and recovery behavior need to be designed with the sender’s actual delivery behavior, not assumed.

This adds operational responsibility: queue monitoring, failed-job inspection, retention and a recovery procedure. A simple low-volume integration may not need elaborate infrastructure, but it still needs an honest definition of receipt and completion.

5. Prevent duplicate actions without dropping legitimate updates

I would assume a recovery action might cause the same business information to arrive again. Before replaying anything, ask whether another shipment, invoice or notification would be created.

A blanket “ignore this order ID after the first message” rule can be wrong for an update integration. Later changes to that order may be legitimate. Define deduplication around the business operation and event semantics, then make the underlying write safe under concurrent requests.

For the fictional fulfillment example, I would maintain a link between the WooCommerce order and the receiving fulfillment record. A repeated create request should not create a second shipment. A later approved address change needs a separate rule rather than being silently discarded.

I would test duplicates, overlapping workers and out-of-order changes on staging with synthetic data. Where an event’s freshness matters, define how the receiver obtains and compares the authoritative current state. Do not use an arrival timestamp as proof that the payload is the newest business state.

6. Recover missing work deliberately

WooCommerce can disable outgoing webhooks after consecutive delivery failures. Its merchant and API documentation differ in their wording about the exact cutoff, so I would confirm the installed release and any custom failure-threshold filter rather than promise a fixed retry schedule.

Re-enabling a configuration is not evidence that missing business actions have been recovered. First repair and test the cause. Then establish the affected interval and compare eligible WooCommerce orders with records in the receiving system.

I would prepare a reconciliation list: order ID, expected action, receiver record, current outcome and approved recovery action. Separate “not received” from “received but processing failed” so the team does not replay work that already completed.

Run a small controlled recovery sample, confirm the result with the destination owner and only then expand. Keep an audit trail and pause if duplicates or unexplained state changes appear. Do not repeatedly toggle a failing webhook as a substitute for that investigation.

7. Verify the full handoff on staging

My WordPress staging guide covers preparation. For an integration test, I would explicitly identify which receiver, credentials and data are safe for the test environment.

  • The intended event produces the expected notification.
  • The receiver rejects an invalid signature and accepts a valid marked test.
  • Receipt is recorded durably before success is acknowledged.
  • The downstream action completes with the correct field mapping.
  • A repeated event does not repeat a one-time business action.
  • A receiver or worker failure is visible and recoverable.
  • Historical orders and missing optional values are handled as agreed.
  • The responsible team can reconcile sender and receiver records.

If a custom field is part of the handoff, the Checkout Block custom-fields guide explains how I would verify the saved value and its destination. For custom order access, include an HPOS compatibility review.

Use AI to organize evidence, not to invent a diagnosis

I would ask AI to turn a redacted event timeline into questions: which stage lacks evidence, which timestamps use different timezones, and which recovery actions could duplicate work? Use fictional payloads or carefully minimized technical excerpts, not customer names, addresses or secrets.

I would verify suggested API behavior against official documentation and the installed code. A generated explanation cannot confirm that a warehouse processed an order. That needs a record from the warehouse system.

A good handover names the event, acceptance rule, duplicate strategy, monitoring owner and reconciliation procedure. That makes the integration easier to maintain after the original developer is no longer looking at it daily.

If your store or agency has an order integration that misses updates or creates duplicates, send me a brief description of the sender, receiver and missing action. I can help define a focused investigation and a safer recovery plan.

Official technical references reviewed on October 16, 2026. Featured stock photograph: Alberto Rodríguez on Unsplash. The diagram, code fragment and fulfillment scenario are illustrative, not client evidence or live test results.

Need help fixing this on your website?

Need help fixing this on your website? Chat with me on WhatsApp.

Explore relevant services

Chat on WhatsApp

Need help with a website project?

Chat on WhatsApp