Send WooCommerce Orders to Google Sheets Automatically with n8n
Someone on your team copies every new WooCommerce order into a Google Sheet for fulfilment, accounting or a weekly report. It's tedious, and it's easy to get wrong. With n8n, an open-source automation tool, you can send each new order to a sheet automatically, in real time, in about 20 minutes. Here's the full setup, plus the details that usually trip people up.
What you need
- A WooCommerce store you have admin access to.
- An n8n instance that's reachable from the internet: n8n Cloud, or self-hosted on a VPS with a domain. A local install on
localhostwon't work for live orders, because WooCommerce has to be able to send data to it. - A Google account with a spreadsheet for the orders.
Step 1: Prepare the Google Sheet
Create a sheet with a header row. n8n maps data to columns by these names:
Order ID | Date | Status | Customer | Email | Phone | Items | Total | Currency | Payment method | Shipping country
Keep the header row exactly as you want it, since renaming columns later means re-mapping them in n8n.
Step 2: Create WooCommerce API keys
- In WordPress, go to WooCommerce → Settings → Advanced → REST API and click Add key.
- Description: "n8n". User: an admin account. Permissions: Read/Write. The trigger needs write access to create its webhook in WooCommerce.
- Copy the Consumer key and Consumer secret. The secret is only shown once.
In n8n, go to Credentials → Add credential → WooCommerce API, and paste the keys plus your store URL (e.g. https://example.com).
Step 3: Add the WooCommerce Trigger
- Create a new workflow and add a WooCommerce Trigger node.
- Select your WooCommerce credential and set Event to
order.created. - Click Listen for test event, then place a test order on your store (a 100% coupon or a cheap test product works well).
n8n receives the full order as JSON. You'll see fields like id, status, billing, line_items and total. When you activate the workflow, n8n registers the webhook in WooCommerce automatically. You'll see it under WooCommerce → Settings → Advanced → Webhooks.
Step 4: Add the Google Sheets node
- Add a Google Sheets node after the trigger, with the operation Append Row (newer n8n versions also offer Append or Update Row, covered below).
- Connect your Google account, then pick the spreadsheet and sheet.
- Set the mapping mode to Map each column manually. n8n reads your header row and shows one field per column.
Fill in each column with an expression. Click a field, switch to Expression, and paste:
Order ID {{ $json.id }}
Date {{ $json.date_created }}
Status {{ $json.status }}
Customer {{ $json.billing.first_name }} {{ $json.billing.last_name }}
Email {{ $json.billing.email }}
Phone {{ $json.billing.phone }}
Items {{ $json.line_items.map(i => i.name + ' × ' + i.quantity).join(', ') }}
Total {{ $json.total }}
Currency {{ $json.currency }}
Payment method {{ $json.payment_method_title }}
Shipping country {{ $json.shipping.country }}
The Items expression turns the list of products into one readable cell, like Blue Mug × 2, Teapot × 1. Run the node once to check the row appears correctly, then click Activate on the workflow.
Keep the sheet updated when order status changes
order.created fires once, when the order is placed. Often it's still "pending" or "processing" at that point. To keep the Status column current:
- Create a second workflow, or add a second trigger, with the event
order.updated. - Use the Google Sheets operation Append or Update Row, with Order ID as the column to match on.
Existing rows get updated in place, and orders that somehow weren't added yet get appended. You can use this same setup for the main workflow too, so a retried webhook never creates duplicate rows.
Only send some orders
Add an If or Filter node between the trigger and Google Sheets. Examples:
- Only paid orders:
{{ $json.status }}is one ofprocessingorcompleted. - Only one country:
{{ $json.shipping.country }}equalsCA. - Only large orders:
{{ Number($json.total) }}is larger than500.
The Number() matters there: WooCommerce sends totals as strings like "129.00".
Troubleshooting
The trigger never receives orders
- Check the webhook in WooCommerce (Settings → Advanced → Webhooks). If its status is "Disabled", WooCommerce turned it off after repeated delivery failures. Fix the cause, then set it back to "Active".
- Check that n8n's public URL is set. On self-hosted n8n, the
WEBHOOK_URLenvironment variable must be your public HTTPS URL. Otherwise n8n registers alocalhostaddress that WooCommerce can't reach. - Check for a firewall in front of n8n. A Cloudflare challenge or basic auth on the n8n domain blocks WooCommerce's requests.
- Check WP-Cron. WooCommerce sends webhooks through its background queue, so if WP-Cron isn't running, webhooks are delayed or never sent. See fixing WP-Cron and Action Scheduler.
It works in testing but not when activated
n8n uses a different webhook URL for "Listen for test event" than for the active workflow. After activating, place another test order and check the workflow's Executions list. If nothing appears there, delete the webhook in WooCommerce and deactivate and reactivate the workflow, so n8n re-registers it with the production URL.
Beyond Google Sheets
Once the trigger works, the same workflow can do much more with each order: post high-value orders to Slack, create a task in your fulfilment tool, add the customer to your email platform, or send a summary to an AI model that tags the order for your team. The pattern stays the same: trigger, filter, transform, send.
Written by
Sameer Hussain, Senior Shopify & WordPress Engineer
Top Rated on Upwork and the Shopify & WordPress engineer at Inceptus Digital. Short on time, or not comfortable editing code? Send me your URL and the error on Upwork and I'll tell you how I'd fix it before you commit.
Need Custom Engineering or Growth Systems?
Our team helps ambitious brands build bespoke software, AI integrations, and high-conversion platforms.