Your WooCommerce webhook is not firing. Here is the order to check things in.
A webhook that stops is rarely broken in the way it looks broken. WooCommerce fires it, something at the other end times out, WooCommerce marks the webhook disabled after five failures, and from then on nothing happens at all — silently, with no email and nothing on any screen you normally look at. Most of the time the integration was fine and the receiver was asleep.
First: WooCommerce disabled it and did not tell you
WooCommerce counts consecutive delivery failures. After five it sets the webhook’s status to disabled and stops trying. This is sensible — it stops a dead endpoint generating traffic forever — but nothing announces it. Go to WooCommerce → Settings → Advanced → Webhooks and look at the status column before you debug anything else. If it says Disabled, that is your answer, and re-enabling it does not resend what was missed.
Second: was it ever actually sent?
WooCommerce delivers webhooks through the scheduled-action queue, not during the request that triggered them. So the order completes, the customer sees their thank-you page, and the delivery is a separate job that runs afterwards. If Action Scheduler is stuck — a common state on shops with a large backlog, or where WP-Cron never runs because the site gets no traffic — the webhook is not failing. It is queued, and queued looks exactly like nothing happening.
Check WooCommerce → Status → Scheduled Actions, filter to Pending, and look for actions named woocommerce_deliver_webhook_async. A pile of them with dates in the past is a cron problem, not a webhook problem, and the fix is a real system cron hitting wp-cron.php rather than anything to do with the integration.
Third: what the other end actually said
WooCommerce treats any response outside 2xx as a failure, and it keeps only the last delivery per webhook. That is enough to tell you the endpoint returned 500 once; it is not enough to tell you it has been returning 500 all week, or that it returned 200 for nine orders and timed out on the tenth. The pattern is the diagnosis, and the pattern is what WooCommerce throws away.
A timeout is worth separating from a rejection. Five seconds is the default, and a receiver that does real work before replying — writing to a CRM, calling another API — will exceed it under load while being perfectly healthy. Those deliveries are lost, the order is fine, and nothing in the shop indicates a gap.
Retrying, rather than hoping
The behaviour you want is unglamorous: when a delivery fails, try again after a minute, then after a few minutes, then after an hour, and keep the whole history so you can see whether it eventually landed. That is what every payment provider does to you, and it is what a shop sending its own orders somewhere should do too.
Before you blame the plugin at the other end
Two things account for most reports. A staging site cloned from production keeps the same webhooks and starts delivering real orders to somebody’s live endpoint — check that first if deliveries doubled. And a security plugin or a host’s firewall will block outbound POSTs to an address it does not recognise, which looks identical to the receiver being down, except the receiver never saw a request at all.
