Get notified when WooCommerce disables a webhook: a plugin you can build today
· 4 min read
WooCommerce webhooks connect your store to Zapier, HubSpot, inventory feeds, and anything else that needs to know when an order lands or a product changes. When a delivery fails repeatedly, WooCommerce disables the webhook automatically. Five or more consecutive non-2xx responses from the receiving endpoint is the threshold. The webhook stops queuing jobs. Orders placed after that moment send nothing.
Nothing alerts you. Action Scheduler marks each job complete regardless of whether the webhook fired. The WooCommerce dashboard shows no warning. You find out when your Zapier automation stops running, when a customer asks why their order never appeared in your CRM, or when you happen to scroll through the webhooks list.
A notification plugin solves the lag. When a webhook transitions to disabled, you get an email with the webhook name, the delivery URL, the current failure count, and a direct link to the edit screen. A reset button on the webhooks screen clears the failure counter and re-enables the webhook once you have fixed the underlying issue.
What one build gives you
- Hourly cron check that detects webhooks newly disabled since the previous run
- Email alert with webhook name, delivery URL, failure count, and a direct link to the edit screen
- Admin notice on the WooCommerce webhooks screen listing all currently disabled webhooks
- A per-webhook Reset action that clears the failure counter and re-enables the webhook
What it does not do
- Retrying failed deliveries or replaying missed webhook payloads
- Diagnosing the cause of delivery failures, which is in WooCommerce status logs
- Automatic re-enabling without admin action
- Per-webhook notification addresses: all alerts go to the site admin email
- Real-time detection on every failed delivery: the check runs on an hourly schedule
The prompt
Loads into the composer so you can edit it first. Nothing is built, and nothing is charged, until you send it.
Build a WordPress plugin called WooCommerce Webhook Monitor. Plugin Name: WooCommerce Webhook Monitor. Description: Sends an admin email when WooCommerce automatically disables a webhook due to consecutive delivery failures, and adds a reset option to the webhooks screen. Requires WooCommerce. Single PHP file. No dependencies beyond WordPress core and WooCommerce. Check that WooCommerce is active at plugins_loaded using is_plugin_active('woocommerce/woocommerce.php'). If WooCommerce is not active, add an admin_notices callback that displays a dismissible warning notice and return early from the rest of the setup. On plugin activation (register_activation_hook), do two things. First, call wc_get_webhooks(['status' => 'disabled']) to get currently disabled webhook objects, extract their IDs using array_map and get_id(), and save the result as a JSON-encoded array in the WordPress option wc_webhook_monitor_known_disabled. Second, schedule a recurring cron event named wc_webhook_monitor_check using wp_schedule_event(time(), 'hourly', 'wc_webhook_monitor_check') only if one is not already scheduled. On plugin deactivation (register_deactivation_hook), call wp_clear_scheduled_hook('wc_webhook_monitor_check') and delete_option('wc_webhook_monitor_known_disabled'). Hook the cron callback to the action wc_webhook_monitor_check. In the callback: call wc_get_webhooks(['status' => 'disabled']) to get the current list of disabled webhook objects. Extract IDs into an array. Read the option wc_webhook_monitor_known_disabled and json_decode it, defaulting to an empty array if missing or null. Find the IDs present in the current list but absent from the stored list — these are newly disabled since the last run. For each newly disabled ID, find the corresponding webhook object in the current results. Build a notification email: to get_option('admin_email'), subject '[' . get_bloginfo('name') . '] WooCommerce webhook disabled: ' . $webhook->get_name(), body including the webhook name, delivery URL ($webhook->get_delivery_url()), current failure count ($webhook->get_failure_count()), and a direct link to the webhook edit page built with admin_url('admin.php?page=wc-settings&tab=advanced§ion=webhooks&edit-webhook=' . $webhook->get_id()). Send with wp_mail. After processing, update the option wc_webhook_monitor_known_disabled with json_encode of the full current list of disabled IDs. Add an admin_notices hook. Check whether the current admin page is the WooCommerce webhooks screen by verifying is_admin() is true and that $_GET contains page=wc-settings, tab=advanced, and section=webhooks. If those conditions are met, call wc_get_webhooks(['status' => 'disabled']) to get disabled webhook objects. If there are any, output a div with class notice notice-warning. Print a paragraph stating that the following webhooks have been disabled by WooCommerce due to delivery failures. For each disabled webhook, output its name and delivery URL followed by a Reset link. Build the Reset link URL using wp_nonce_url(admin_url('admin-post.php?action=wc_webhook_monitor_reset&webhook_id=' . $webhook->get_id()), 'reset_webhook_' . $webhook->get_id()). If $_GET contains wc_webhook_reset set to 1, also output a separate dismissible notice div with class notice notice-success confirming the webhook was reset and re-enabled. Register the admin-post handler using add_action('admin_post_wc_webhook_monitor_reset', ...). In the callback: read webhook_id from $_GET using absint. Verify the nonce using check_admin_referer('reset_webhook_' . $webhook_id). Verify the current user has manage_woocommerce capability using current_user_can, and wp_die if not. Load the webhook using new WC_Webhook($webhook_id). Call $webhook->set_failure_count(0). Call $webhook->set_status('active'). Call $webhook->save(). Read the stored option, decode it, remove this ID from the array using array_filter, re-encode and update the option. Redirect to admin_url('admin.php?page=wc-settings&tab=advanced§ion=webhooks&wc_webhook_reset=1') using wp_safe_redirect followed by exit.
How WooCommerce handles delivery failures
WooCommerce tracks a failure counter per webhook. Each non-2xx response from the endpoint increments it. Once the counter passes the threshold, WooCommerce sets the webhook status to disabled and stops queuing further deliveries. A brief outage on the receiving end is enough to trigger it.
Re-enabling is not enough on its own. Editing the webhook and setting the status back to active does not reset the failure counter. WooCommerce evaluates the count on the next delivery attempt, so one more failed request disables it again immediately. You need to both fix the endpoint and clear the counter before the webhook will stay active.
What the plugin does
Once installed, a background task runs every hour. It fetches all webhooks with status disabled, compares that list to the one stored from the previous run, and sends a notification email for any webhook that transitioned since the last check. If an integration broke an hour ago, you know within the hour rather than whenever someone notices the data is missing.
The notification email goes to the site admin address. It names the webhook, its delivery URL, and the current failure count, and includes a direct link to the webhook edit screen so you can get there in one click.
On the WooCommerce webhooks screen, the plugin adds an admin notice listing any currently disabled webhooks. Each entry has a Reset link. Clicking it sets the failure count to zero, sets the webhook status back to active, and returns you to the same screen. Use it only after fixing the endpoint, because resetting before that will re-disable the webhook on the next delivery attempt.
- Hourly background check for webhooks newly disabled since the previous run
- Email to the admin address with webhook name, delivery URL, failure count, and a direct edit link
- Admin notice on the webhooks screen listing every disabled webhook
- A per-webhook Reset action that clears the failure count and re-enables it
What the plugin does not do
The plugin does not retry failed deliveries. WooCommerce handles retries natively before disabling the webhook, and re-queuing them after the fact raises questions about duplicate processing on the receiving end.
It does not diagnose why the delivery failed. WooCommerce logs individual delivery attempts under WooCommerce, Status, Logs. The log entries include the full request payload and the response code, which is usually enough to identify the cause: an expired token, a changed endpoint URL, or a receiving service that was down.
It does not automatically re-enable webhooks without your input. The failure happened for a reason, and re-enabling silently before that reason is resolved would just disable it again.
Extending the plugin
The default sends every notification to the admin email set under Settings, General. If you want alerts to go to a developer or integration address instead, ask Steem to add a notification address field under WooCommerce, Settings, Advanced.
If an hourly check is too slow for integrations that matter, ask for a version that hooks directly into each delivery attempt and fires the alert on the failure that crosses the threshold, rather than waiting for the next scheduled run.
Questions
- How quickly will I be notified when a webhook is disabled?
Within one hour. The plugin checks for newly disabled webhooks on an hourly cron schedule. If you need faster detection, ask Steem to add a hook that fires on each individual delivery failure instead.
- Does resetting the failure count fix the underlying problem?
No. Resetting clears the counter and re-enables the webhook. If the delivery endpoint is still returning errors, WooCommerce will disable the webhook again on the next attempt. Fix the endpoint first: check that the URL is correct, the API token is valid, and the receiving service is responding.
- Will I get a new notification every hour if the webhook stays disabled?
No. The plugin tracks which webhooks were already known to be disabled and only emails you when a webhook transitions from active to disabled. You get one email per incident, not one per hourly check.
- Can I send the alert to a different email address?
Not by default. All alerts go to the WordPress admin email set under Settings, General. Ask Steem to add a notification address field to the plugin settings.
- Does this work with all WooCommerce webhook topics?
Yes. The plugin monitors all webhooks regardless of topic. Any webhook that WooCommerce disables due to delivery failures will trigger the notification.
The prompt
Loads into the composer so you can edit it first. Nothing is built, and nothing is charged, until you send it.
Build a WordPress plugin called WooCommerce Webhook Monitor. Plugin Name: WooCommerce Webhook Monitor. Description: Sends an admin email when WooCommerce automatically disables a webhook due to consecutive delivery failures, and adds a reset option to the webhooks screen. Requires WooCommerce. Single PHP file. No dependencies beyond WordPress core and WooCommerce. Check that WooCommerce is active at plugins_loaded using is_plugin_active('woocommerce/woocommerce.php'). If WooCommerce is not active, add an admin_notices callback that displays a dismissible warning notice and return early from the rest of the setup. On plugin activation (register_activation_hook), do two things. First, call wc_get_webhooks(['status' => 'disabled']) to get currently disabled webhook objects, extract their IDs using array_map and get_id(), and save the result as a JSON-encoded array in the WordPress option wc_webhook_monitor_known_disabled. Second, schedule a recurring cron event named wc_webhook_monitor_check using wp_schedule_event(time(), 'hourly', 'wc_webhook_monitor_check') only if one is not already scheduled. On plugin deactivation (register_deactivation_hook), call wp_clear_scheduled_hook('wc_webhook_monitor_check') and delete_option('wc_webhook_monitor_known_disabled'). Hook the cron callback to the action wc_webhook_monitor_check. In the callback: call wc_get_webhooks(['status' => 'disabled']) to get the current list of disabled webhook objects. Extract IDs into an array. Read the option wc_webhook_monitor_known_disabled and json_decode it, defaulting to an empty array if missing or null. Find the IDs present in the current list but absent from the stored list — these are newly disabled since the last run. For each newly disabled ID, find the corresponding webhook object in the current results. Build a notification email: to get_option('admin_email'), subject '[' . get_bloginfo('name') . '] WooCommerce webhook disabled: ' . $webhook->get_name(), body including the webhook name, delivery URL ($webhook->get_delivery_url()), current failure count ($webhook->get_failure_count()), and a direct link to the webhook edit page built with admin_url('admin.php?page=wc-settings&tab=advanced§ion=webhooks&edit-webhook=' . $webhook->get_id()). Send with wp_mail. After processing, update the option wc_webhook_monitor_known_disabled with json_encode of the full current list of disabled IDs. Add an admin_notices hook. Check whether the current admin page is the WooCommerce webhooks screen by verifying is_admin() is true and that $_GET contains page=wc-settings, tab=advanced, and section=webhooks. If those conditions are met, call wc_get_webhooks(['status' => 'disabled']) to get disabled webhook objects. If there are any, output a div with class notice notice-warning. Print a paragraph stating that the following webhooks have been disabled by WooCommerce due to delivery failures. For each disabled webhook, output its name and delivery URL followed by a Reset link. Build the Reset link URL using wp_nonce_url(admin_url('admin-post.php?action=wc_webhook_monitor_reset&webhook_id=' . $webhook->get_id()), 'reset_webhook_' . $webhook->get_id()). If $_GET contains wc_webhook_reset set to 1, also output a separate dismissible notice div with class notice notice-success confirming the webhook was reset and re-enabled. Register the admin-post handler using add_action('admin_post_wc_webhook_monitor_reset', ...). In the callback: read webhook_id from $_GET using absint. Verify the nonce using check_admin_referer('reset_webhook_' . $webhook_id). Verify the current user has manage_woocommerce capability using current_user_can, and wp_die if not. Load the webhook using new WC_Webhook($webhook_id). Call $webhook->set_failure_count(0). Call $webhook->set_status('active'). Call $webhook->save(). Read the stored option, decode it, remove this ID from the array using array_filter, re-encode and update the option. Redirect to admin_url('admin.php?page=wc-settings&tab=advanced§ion=webhooks&wc_webhook_reset=1') using wp_safe_redirect followed by exit.
Steem