How to Connect WooCommerce to Google Sheets Automatically
Which of the three spreadsheets you are actually asking for, how the webhook wiring works, and the four failures that turn one order into five rows.
“Can you get our orders into a Google Sheet automatically?” is one of the most common automation requests there is, and it is almost never the actual question. The actual question is hiding one level down: who needs to see this, and what are they going to do with it? Three different people ask for the same spreadsheet for three different reasons, and each one wants a different sheet.
So this is both the how and the why: how to wire WooCommerce to Google Sheets so it keeps working, and which of the three versions you are actually asking for.
First, which sheet is this
- A window for people without WordPress access. A bookkeeper, a warehouse, a partner, a client. They need to read orders and never touch WooCommerce. This version is read-only, carries the minimum, and is the easiest of the three.
- A working surface. Someone ticks things off, adds a tracking number, notes which supplier an item came from. The sheet is not a copy here — it is where work happens, and it holds columns WooCommerce has never heard of. This version is the one people underestimate.
- Reporting. Somebody wants pivot tables and a chart. This one usually should not be a live sync at all — a daily or weekly summary export is smaller, faster and far less fragile than a row-per-order feed that has to stay correct forever.
Ask which one before building anything. Version one takes an afternoon. Version two is a real project. Version three is often a different tool entirely.
How the connection actually works
WooCommerce can fire a webhook when an order is created or updated. That webhook posts the whole order as JSON to a URL you control — in my builds, an n8n workflow — which reshapes it and writes a row to Google Sheets.
You will also see the alternative: poll the WooCommerce REST API every few minutes and look for anything new. Both are legitimate and they fail differently. A webhook is instant and cheap but silent when it goes wrong — if your endpoint is down for an hour, WooCommerce retries a few times and then gives up, and the orders from that hour simply never arrive. Polling is slower and noisier but self-healing, because the next run picks up whatever it missed. Webhook vs polling vs schedule goes through how to choose, and for order data the answer is often both: webhooks for speed, plus a nightly reconciliation pass that fills in anything the webhooks dropped.
Set the webhook up in WooCommerce under Settings → Advanced → Webhooks. Use order.updated rather than only order.created, because the interesting part of an order — paid, shipped, refunded — happens after it is created.
The four things that break it
1. Appending instead of matching
This is the big one. If your workflow appends a row every time a webhook fires, one order becomes five rows: created, paid, processing, shipped, completed. Webhooks are also retried, so a slow response can duplicate a row that already arrived correctly.
The fix is to make the order ID the key: look up the row, update it if it exists, append only if it does not. In n8n that is a lookup step before the write, and it is the difference between a sheet you can trust and a sheet somebody rebuilds by hand every month. The general principle — the same message arriving twice must not produce two outcomes — is the first thing I check in any workflow, and it is covered properly in error handling for automations.
2. Line items do not fit in a row
An order has one customer and several products. A spreadsheet row has neither. You have three options and they are not interchangeable:
- One row per order, with the items flattened into a single cell (
2 x Blue Mug, 1 x Teapot). Readable, useless for maths. Right for version one. - One row per line item, repeating the order details on each. Ugly to read, correct for any product-level analysis. Right for version three.
- Two sheets — orders and items — joined by order ID. Correct, and more than most people want to maintain.
Choose deliberately. Changing your mind later means rebuilding the sheet and everything anyone has built on top of it.
3. Editing the sheet does nothing
Someone will change an order status in the spreadsheet and assume WooCommerce got the message. It did not. The sync is one-way, and to whoever is looking at the sheet that is invisible.
Two ways to handle it. Either protect the synced columns so they are read-only and put the editable ones (notes, tracking, ticked-off status) to the right of them — that is version two done properly. Or build a genuine write-back, where changing a specific column updates the order through the API. The second is doable and I do build it, but it doubles the project and introduces every conflict problem that comes with two systems believing they are in charge. Most shops need the first.
4. Sheets has limits, and you will find them
Google Sheets is a spreadsheet pretending to be a database and it stops pretending somewhere around the tens of thousands of rows — slow to open, slow to write, and eventually refusing. The Sheets API also has per-minute write quotas, which a busy Friday will hit if every status change is its own API call. Batch the writes, and add a retry with backoff for the quota errors, which are temporary by nature.
If the sheet is heading for six figures of rows, stop and move the destination — a real database, or BigQuery if the point is reporting. Keeping a spreadsheet past its limit is how a working automation turns into a daily complaint.
The part nobody mentions: it is customer data
That sheet will contain names, email addresses, phone numbers and delivery addresses. The moment it exists, it is a copy of your customer database living in someone’s Google Drive, and it inherits none of WooCommerce’s access control.
- Never share it by link. “Anyone with the link can view” on a sheet of customer addresses is a data breach waiting for someone to forward an email.
- Carry the minimum. Fulfilment needs an address; a bookkeeper does not. Reporting needs almost no personal data at all.
- Delete old rows. Your store has a retention policy, or should. The sheet is outside it unless you write a step that trims rows past a certain age — and a deletion request that clears WooCommerce but leaves the spreadsheet has not been honoured.
That last point is the one that catches people. Any copy of personal data is a copy you now have to look after.
When not to do this at all
If the only reason is that somebody cannot get into WooCommerce, the cheaper answer is a WordPress user account with a limited role. Five minutes, no moving parts, no second copy of customer data to protect.
And if the real goal is a number on a dashboard once a week, a scheduled summary beats a live feed every time. Fewer rows, fewer failure modes, and nobody notices if it runs four minutes late. Deciding what to automate first is mostly this question asked repeatedly: what is the smallest thing that removes the actual annoyance?
What it costs
A one-way order feed — webhook in, matched write out, error alerts, nightly reconciliation — is a single workflow and starts at $600, usually live in three to five days. Add a working surface with protected columns, editable extras and write-back for one or two fields and it is $1,800-tier work. Prices are on the pricing page, and both include 30 days of support after launch.
I build these on n8n, running in your own accounts on your own API credentials, and hand over the exported workflow and a runbook. If the store itself needs work rather than the spreadsheet, that is WooCommerce development, and the wider view of what is worth automating in a shop is in automation for eCommerce stores.
Book a free intro call and bring the three questions: who reads it, what do they do with it, and what happens today when they do not have it.
Key takeaways
- Decide which sheet you are building first: a read-only window, a working surface, or reporting. They are three different projects.
- Match on order ID, never append blindly. One order must not become five rows, and a retried webhook must not duplicate one.
- Webhooks for speed, a nightly reconciliation pass for the ones that silently never arrived.
- Editing the sheet does not change the order. Protect the synced columns so nobody learns that the hard way.
- The sheet is a copy of your customer data. Never share by link, carry the minimum, and trim old rows.