---
title: "WooCommerce n8n Integration: Trigger Node vs Webhook"
description: "WooCommerce to n8n: why the WooCommerce Trigger makes one attempt, answers 200 before the workflow runs, and fires on every order save, and what to use instead."
url: "https://wpwebhooks.org/blog/woocommerce-n8n-webhook/"
date: "2026-10-17"
---

# WooCommerce n8n Integration: Trigger Node vs Webhook

**TL;DR:** n8n's WooCommerce Trigger node is a thin wrapper around WooCommerce's own webhooks, and inherits all of their delivery behaviour.

-   WooCommerce makes **one delivery attempt** per event. There is no retry.
-   The trigger answers 200 **before your workflow runs**, so a failure in a later node never reaches WooCommerce.
-   There is no "order completed" event, only `order.updated`, which fires on every order save.
-   A 301 or 302 from the n8n URL is **counted as a successful delivery**, and the redirect is not followed.
-   For orders that must arrive, post a queued webhook to a Webhook node that responds when the last node finishes. A failed workflow then returns 500 and the delivery is retried.

/ Trigger node

## How does the n8n WooCommerce Trigger node work?

It registers a webhook in your store and listens on it. The node's [credential](https://docs.n8n.io/integrations/builtin/credentials/woocommerce) is a WooCommerce REST API consumer key and secret with **Read/Write** permission. When you publish the workflow, the node calls `POST /webhooks` on your store with three values: the workflow's production URL as `delivery_url`, the event you picked as `topic`, and a generated `secret`. Unpublish the workflow and it deletes that webhook again. You can see it under _WooCommerce → Settings → Advanced → Webhooks_ while the workflow is live.

The [node](https://docs.n8n.io/integrations/builtin/trigger-nodes/n8n-nodes-base.woocommercetrigger) offers twelve events: created, updated and deleted for coupons, customers, orders and products. On every request it checks the `X-WC-Webhook-Signature` header, an HMAC-SHA256 of the raw body keyed with that secret and base64-encoded. A request with a wrong signature gets `401 Unauthorized` and never starts the workflow.¹

Everything after that is WooCommerce's delivery code, not n8n's, and that is where the surprises are.

/ Events

## Why is there no "order completed" event in the n8n trigger?

Because WooCommerce has none. Its webhook topics are resource-level. In [`class-wc-webhook.php`](https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/includes/class-wc-webhook.php), `order.updated` is wired to three hooks: `woocommerce_update_order`, `woocommerce_order_refunded` and `woocommerce_order_refund_deleted`. The first one fires every time the order object is saved.

An order is saved many times in its life. The payment gateway saves it, the status change saves it, a shipping plugin adding a tracking number saves it, an admin editing the address saves it. Each save is a separate delivery and a separate n8n execution. If the workflow should run when an order is completed, you add an IF node on `status === 'completed'`, and it still runs again for every later save of that completed order. The tracking-number update next week sends the thank-you email a second time.

So a workflow on `order.updated` needs its own record of which orders it has already handled. The trigger cannot give you that.

FIG 01 — Two ways into n8n: one attempt and a 200 before the workflow runs, or a queue that sees the workflow fail

/ Downtime

## What happens to WooCommerce webhooks when n8n is down?

The order is delivered once and lost. WooCommerce collects webhooks during the request and hands them to Action Scheduler as a `woocommerce_deliver_webhook_async` job, so the shopper does not wait. The job makes a single POST with a 60-second timeout. If n8n is restarting, the request fails, the failure counter goes up, and that is the end of that order's delivery. Nothing schedules a second attempt.

The counter decides when WooCommerce gives up on the webhook entirely. The check runs _before_ the increment and compares against `woocommerce_max_webhook_delivery_failures`, which defaults to 5:

-   Failures 1 to 6 raise the counter from 0 to 6, because each check sees 0, 1, 2, 3, 4 and then 5, and 5 is not greater than 5.
-   Failure 7 sees 6 > 5 and sets the webhook's status to **disabled**.

So seven failed orders in a row, a busy hour during a long n8n outage, switch the integration off. A single successful delivery resets the counter to zero. There is an action for the disable, `woocommerce_webhook_disabled_due_delivery_failures`, but nobody is notified unless you hook it. Republishing the workflow registers a fresh webhook, because the node only looks for active ones, and leaves the disabled one behind in the list.

/ Redirects

## Why does a redirect count as a successful WooCommerce webhook delivery?

Because the success check is `>= 200 && < 303`, a 2xx, 301 or 302, and the request is sent with `redirection` set to 0. WooCommerce gets the 301, does not follow it, counts the delivery as a success and resets the failure counter.

This bites when the n8n instance sits behind a proxy that redirects `http` to `https`, or adds a trailing slash, and `WEBHOOK_URL` was set to the other form. n8n registers that URL with WooCommerce, every order "succeeds", and no execution ever appears. Open the webhook in WooCommerce and check that the delivery URL is exactly the one n8n's Webhook panel shows.

/ Response

## Does a 200 from n8n mean the workflow ran?

Not with the WooCommerce Trigger. The node is hard-wired to respond _on receipt_: once the signature checks out, n8n answers 200 and then starts the workflow. If the CRM node three steps later fails, WooCommerce has already logged a success. The only record of that order is a failed execution in n8n's list, which n8n keeps according to its execution pruning settings.

The core [Webhook node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.webhook) lets you choose. Set _Respond_ to _When Last Node Finishes_ and the response waits for the workflow. In n8n's webhook handler, a run that ends in an error returns **500** with the message `Error in workflow`.² Now the sender can tell a delivered order from a lost one, provided the sender retries.

| Concern | WooCommerce Trigger node | Webhook Actions + Webhook node |
| --- | --- | --- |
| Setup inside n8n | Pick an event, add a REST key. Nothing to configure in WordPress | More work: a webhook in wp-admin, a trigger hook, field mapping |
| Which event | order.updated on every save, filtered in n8n | One hook, such as woocommerce\_order\_status\_completed, so the workflow runs once per transition |
| n8n down or restarting | One attempt, then the order is lost | Retried with exponential backoff, five attempts by default |
| Workflow fails after receipt | WooCommerce already saw 200 | The 500 from When Last Node Finishes is retried |
| Repeated failures | Webhook disabled on the seventh, silently | Each delivery fails on its own; failure notifications by email, Slack and more |
| Finding a lost order | WooCommerce logs, if any | Delivery log with request, response and every attempt; replay after the fix |
| Duplicate protection | Build it in n8n | A UUID in event.id that stays the same across retries |

try\_it

Seeing it run beats reading about it. The live preview boots a throwaway WordPress with Webhook Actions already installed and demo deliveries sitting in the log — no signup, nothing left on your machine afterwards.

[Try the live preview →](https://playground.wordpress.net/?blueprint-url=https://wpwebhooks.org/blueprint.json) [Install plugin](https://downloads.wordpress.org/plugin/flowsystems-webhook-actions.zip)

/ Timeouts

## How long can the n8n workflow take before the sender gives up?

As long as the sender's timeout, which is the one setting this pattern depends on. With _When Last Node Finishes_, the HTTP request stays open for the whole workflow. If the workflow calls three APIs at about 1.5 seconds each, that is 3 × 1.5 = 4.5 seconds, close to a 5-second client timeout. A timeout counts as a failure and is retried, but n8n did not stop: the workflow finishes, and the retry runs it a second time.

Two ways out. Raise the timeout to cover the slowest realistic run; [`fswa_http_timeout`](https://wpwebhooks.org/docs/fswa-http-timeout/) is a one-line filter. Or keep the workflow short and hand the slow part to a second workflow. Either way, plan for the duplicate, because a retry after a timeout is the normal case, not an edge case.

PHP — raise the delivery timeout for slow workflows

```
add_filter( 'fswa_http_timeout', function ( $seconds ) {
    return 30;   // the workflow's slowest run, plus headroom
} );
```

/ Duplicates

## How do you stop an n8n workflow from processing the same order twice?

Check for the result, not the delivery. n8n's [Remove Duplicates](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.removeduplicates) node has a _Remove Items Processed in Previous Executions_ operation, and an event id looks like the natural key. The catch is in the node's source: it calls `checkProcessedAndRecord`, so the id is recorded **when the node checks it**, not when the workflow succeeds. Put it at the start, let a later node fail, and the retry of that order is dropped as a duplicate. The retry you set up to recover the order is the one thing that never gets through.

Use it only right before a step that cannot fail halfway, or skip it and look up the effect instead. Before creating an invoice, search for one carrying the order number. Before sending an email, check a sent flag you wrote back to the order. A lookup sees what actually happened, so it gives the right answer on the first run and on the fifth.

The [n8n WordPress trigger article](https://wpwebhooks.org/blog/n8n-wordpress-trigger/) covers the polling alternative and when it is the better fit. For WooCommerce specifically, the same delivery pattern feeds accounting: the [WooCommerce to Xero](https://wpwebhooks.org/blog/woocommerce-xero-integration/) article builds an invoice workflow on it.

/ Exposure

## What does n8n not protect you from?

**A public URL.** A Webhook node with no authentication runs for anyone who finds the address. Set _Authentication_ to _Header Auth_ and send the same header from WordPress. It costs one credential on each side, and the WooCommerce Trigger's signature check gave you the equivalent for free, which is easy to forget when you switch.

**Test URLs in production.** The test URL works only while the editor is listening. A store pointed at it delivers into nothing as soon as the tab closes. Use the production URL, which is registered when the workflow is published.

**The 16 MB ceiling.** The Webhook node rejects payloads over 16 MB by default. A WooCommerce order is far below that, but an order with hundreds of line items and their full meta can grow, so send the fields you use rather than the whole object.

**A forgotten REST key.** The trigger's key has write access to the whole store. If you move to a pushed webhook, revoke it under _WooCommerce → Settings → Advanced → REST API_.

/Footnotes

¹ Node behaviour from the source of [WooCommerceTrigger.node.ts](https://github.com/n8n-io/n8n/blob/master/packages/nodes-base/nodes/WooCommerce/WooCommerceTrigger.node.ts), read 2026-10-22. WooCommerce delivery, retry and disable logic from `class-wc-webhook.php` and `wc-webhook-functions.php` on trunk, read the same day.

² Response handling in n8n's [webhook-helpers.ts](https://github.com/n8n-io/n8n/blob/master/packages/cli/src/webhooks/webhook-helpers.ts), read 2026-10-22.

## Structured data

```json
{"@context":"https://schema.org","@type":"Article","headline":"WooCommerce n8n Integration: Trigger Node vs Webhook","description":"WooCommerce to n8n: why the WooCommerce Trigger makes one attempt, answers 200 before the workflow runs, and fires on every order save, and what to use instead.","datePublished":"2026-10-17","dateModified":"2026-10-17","author":{"@type":"Person","name":"Mateusz Skorupa","url":"https://wpwebhooks.org/about/"},"publisher":{"@type":"Organization","name":"WP Webhooks","url":"https://wpwebhooks.org"},"url":"https://wpwebhooks.org/blog/woocommerce-n8n-webhook/","image":"https://wpwebhooks.org/og_image.jpg","keywords":["n8n woocommerce","woocommerce n8n","n8n woocommerce trigger","woocommerce webhook n8n","woocommerce webhook disabled","woocommerce webhook retry"]}

{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"WP Webhooks","item":"https://wpwebhooks.org/"},{"@type":"ListItem","position":2,"name":"Blog","item":"https://wpwebhooks.org/blog/"},{"@type":"ListItem","position":3,"name":"WooCommerce n8n Integration: Trigger Node vs Webhook","item":"https://wpwebhooks.org/blog/woocommerce-n8n-webhook/"}]}

{"@context":"https://schema.org","@type":"FAQPage","mainEntity":[{"@type":"Question","name":"How does the n8n WooCommerce Trigger node connect to my store?","acceptedAnswer":{"@type":"Answer","text":"It uses a WooCommerce REST API key with Read/Write permission. When you publish the workflow, the node creates a webhook in WooCommerce with the workflow URL, the chosen topic and a generated secret, and deletes it when you unpublish. Incoming requests are checked against the X-WC-Webhook-Signature header."}},{"@type":"Question","name":"Does WooCommerce retry a failed webhook delivery?","acceptedAnswer":{"@type":"Answer","text":"No. WooCommerce sends each webhook once, in the background through Action Scheduler, with a 60 second timeout. A failure only increases a counter. With the default threshold of 5, the webhook is set to disabled on the seventh consecutive failure, and one success resets the counter."}},{"@type":"Question","name":"Why is there no order completed event in the n8n WooCommerce Trigger?","acceptedAnswer":{"@type":"Answer","text":"WooCommerce webhook topics are per resource. order.updated fires on woocommerce_update_order, which runs every time the order is saved, plus refunds. To act on completed orders you filter on the status in n8n, and the workflow still runs again for later saves of the same order."}},{"@type":"Question","name":"Why does my WooCommerce webhook show success but n8n never runs?","acceptedAnswer":{"@type":"Answer","text":"WooCommerce counts 2xx, 301 and 302 as success and does not follow redirects. If the delivery URL redirects, for example from http to https or to a trailing slash, every delivery is marked successful and nothing reaches n8n. Make the URL in WooCommerce exactly match the one n8n shows."}},{"@type":"Question","name":"How do I make n8n return an error when the workflow fails?","acceptedAnswer":{"@type":"Answer","text":"Use the Webhook node and set Respond to When Last Node Finishes. If the run ends in an error, n8n answers 500 with Error in workflow, so a sender that retries will try again. The WooCommerce Trigger node always answers on receipt, before the workflow runs."}}]}

{"@context":"https://schema.org","@type":"ImageObject","contentUrl":"https://wpwebhooks.org/diagrams/woocommerce-n8n-webhook.png","caption":"FIG 01 — Two ways into n8n: one attempt and a 200 before the workflow runs, or a queue that sees the workflow fail","description":"Left path: a WooCommerce webhook registered by the n8n WooCommerce Trigger node posts the order once. The trigger answers 200 as soon as the signature checks out, before the workflow runs, so a later node failure never reaches WooCommerce, and WooCommerce does not retry anyway. Right path: a queued webhook posts to an n8n Webhook node set to respond when the last node finishes. A workflow error returns 500 Error in workflow, so the queue retries with backoff, and the event id lets the workflow skip an event it already handled.","encodingFormat":"image/png","creator":{"@type":"Organization","name":"WP Webhooks","url":"https://wpwebhooks.org/"},"copyrightHolder":{"@type":"Organization","name":"Flow Systems","url":"https://flowsystems.pl/"},"copyrightNotice":"© Flow Systems","creditText":"WP Webhooks","license":"https://creativecommons.org/licenses/by/4.0/","acquireLicensePage":"https://wpwebhooks.org/image-license/"}
```
