Register your interest: Tag @Cody, get an agent
BlogResources

How to connect WooCommerce to Google Sheets when it is a WordPress site

WooCommerce lives on hosting you control, which changes everything about the export. Authentication, order statuses that are plugin-defined, and not taking the shop down with a report.

Isha MagguIsha Maggu11 min read

Summarize with AI

How to connect WooCommerce to Google Sheets when it is a WordPress site
On this page

The thing that separates WooCommerce from a hosted store platform is that the server is yours. There is no vendor absorbing the load of your reporting queries, no team keeping the API consistent between versions, and no guarantee that the plugin somebody installed last month has not changed what an order looks like.

That shapes the export in ways a hosted platform's does not. The constraints are your hosting, your plugins, and your version — and getting those right matters more than anything about the spreadsheet.

What we'll cover

It runs on your server

Your reporting query competes with customers. An export pulling thousands of orders during a busy hour is load on the same machine serving the shop.

Shared hosting has hard limits, and a request that takes too long is killed by the host rather than returning an error you can interpret.

A security plugin may block you. Rate limiting and firewall rules applied to the site apply to your export too, frequently without a useful message.

Caching plugins can serve stale responses to API requests depending on configuration, which produces an export that is subtly out of date.

Your version is whatever you last updated to, and the API's behaviour differs between versions in ways the documentation assumes you know.

The practical consequences: schedule the export off-peak, page in modest batches, and test against your own installation rather than trusting general documentation.

Authentication, which depends on your setup

REST API keys are generated in WooCommerce with read or read-write permissions, and read is all a report needs.

Key-based authentication over HTTPS is the normal route, and it requires the site to actually be on HTTPS, which is worth confirming rather than assuming.

Some hosting strips authorization headers, which produces a confusing authentication failure that is nothing to do with your credentials. The workaround differs per host.

Application passwords are a WordPress-level alternative that some setups prefer.

Create a dedicated key rather than reusing one, so it can be revoked without affecting anything else, and so the access log attributes requests to it.

Test the connection before building anything, because this step fails more often on WooCommerce than on hosted platforms and the failure is rarely self-explanatory.

Building it with CodeWords

CodeWords connects to more than 3,000 integrations, and the connection is made once and reused.

  1. Open CodeWords and start a new automation.
  2. Describe what should happen in plain language to Cody, the automation builder: which orders, which fields, how often, and which sheet.
  3. Authorize the connection with a read-only WooCommerce API key, plus access to the target spreadsheet.
  4. Describe the exceptions: a request that times out, an order with a status you have not seen, a plugin field that is missing.
  5. Run it against a staging copy of the site if you have one, and off-peak against production if you do not.

You describe the outcome; Cody builds it, connects it, and deploys it. The free plan covers light use, with Pro at $39 per month and Business at $100 per month as usage grows; details are on the pricing page.

Order statuses are not fixed

WooCommerce ships with a standard set — pending, processing, on hold, completed, cancelled, refunded, failed — and plugins add their own.

A subscription plugin, a shipping plugin, or a payment gateway may each introduce statuses, and an export that assumes the standard set will meet them.

Report unknown statuses rather than dropping those orders or bucketing them as "other", because that is how a whole category of orders vanishes from a report.

Statuses mean different things per shop. On hold is a payment problem on one shop and a stock problem on another, so document what yours mean alongside the sheet.

Decide which statuses count as revenue and say so in the sheet, because that single decision is why an export disagrees with whatever the shop owner expects.

Refunds are partly separate. A partially refunded order still has its original total, so a revenue figure needs the refunds subtracted deliberately.

Line items and the grain decision

One row per order keeps counting sensible and loses the product detail.

One row per line item gives you product-level analysis and means the order total appears once per line, so anybody summing it double-counts badly.

Say which grain the sheet uses, prominently, since this is the single most common cause of a wrong total from an ecommerce export.

If you need both, use two sheets rather than one sheet with a flag, because somebody will filter the flag wrongly.

Product names change. A line item stores the name at the time of sale, which is correct historically and means the same product appears under several names over time — match on product identifier if you are grouping.

Meta fields, where plugins put things

Plugins store their data in order meta, and that is where the interesting fields often are — delivery slots, gift messages, custom checkout fields, subscription references.

Meta keys are not documented in any central place; they are whatever each plugin chose, and finding them means inspecting an order.

Keys can change when a plugin updates, which breaks an export that depends on one with no warning.

Some meta is internal and meaningless outside the plugin, so exporting everything produces columns of noise.

Pick the handful you need, name them readably, and report when one goes missing rather than producing an empty column.

Not taking the shop down with a report

Schedule off-peak, which for most shops is the early hours in their main market's timezone.

Page in modest batches rather than requesting large pages, since a big page is a long-running request and long-running requests are what hosting kills.

Export incrementally using a modified-since filter rather than pulling everything every time.

Back off on errors rather than retrying immediately, particularly on timeouts, which usually mean the server is busy.

Watch the site's response times around your scheduled run, at least once, to confirm the export is not what somebody complains about later.

Tax, shipping, and the totals that never quite add up

Ecommerce order totals are assembled from several parts, and an export that treats them casually produces a figure nobody can reconcile.

Decide whether your revenue figure includes tax. Both answers are defensible and they differ by a lot, so the sheet must say which.

Shipping is revenue to some businesses and a pass-through to others, and the accounting treatment differs accordingly.

Discounts apply at order and at line level, so a line item's price may not reflect what was actually paid for it.

Multi-currency shops store both the order currency and a converted value where a plugin provides one, and mixing them silently is how a total ends up meaningless.

Fees and refunds are separate records attached to the order, not adjustments to its total, so both need handling deliberately.

Reconcile against the payment provider rather than against the shop's own dashboard. The gateway knows what money arrived, which is the figure that matters when the two disagree.

Making it survive

Filter by modified date and store the cursor durably, so each run is small.

Make writes idempotent, matching on order identifier rather than appending blindly.

Handle the timeout as a normal case, with a retry and a smaller page size, since it is the most common failure here.

Report unknown statuses and missing meta fields rather than silently dropping.

Report the outcome. Orders exported, rows written, requests retried, and anything skipped.

Limits worth knowing about

Your hosting sets the real limits, including request timeouts and any rate limiting applied by security plugins.

Pagination behaviour and available filters vary by WooCommerce version, so check against your own installation.

Sheets has a cell limit, which a line-item export of a busy shop reaches within a year.

Meta field availability depends on plugins, and nothing guarantees a key exists after an update.

Deleted orders may not appear, and orders moved to trash behave differently from deleted ones.

What to set up first

An incremental daily export of completed orders at one row per order, filtered on modified date, running off-peak, with unknown statuses reported rather than dropped. It is small, it does not strain the site, and it gives you a durable history that the shop's own reporting does not keep in a form anybody can filter.

Two habits make the difference. Use a modified-since filter from the first version, since a full export becomes impractical faster than you expect on shared hosting. And write which statuses you counted as revenue into the sheet, because that is the number the shop owner will compare against their own and the difference is always definitional.

Frequently asked questions

Why does the export time out?

Because your hosting killed a long-running request, which is the most common WooCommerce integration failure. Use smaller pages, filter incrementally, run off-peak, and back off rather than retrying immediately.

Why does authentication fail with correct credentials?

Some hosting strips authorization headers, which looks exactly like a credential problem and is not. It is worth checking with your host early, because the workaround differs and nothing in the error says so.

Why are there order statuses I do not recognise?

Plugins add their own. Report unknown statuses rather than dropping those orders or bucketing them as "other", since that is how a whole category disappears from a report without anybody noticing.

One row per order or per line item?

Per order for counting and revenue, per line item for product analysis — and say which in the sheet. A line-item sheet where somebody sums the order total double-counts badly, and it is the commonest cause of a wrong ecommerce figure.

Where do plugin fields live?

In order meta, under keys each plugin chose and which are documented nowhere central. Inspect an order to find them, export only the handful you need, and report when one disappears after an update.

Why does my revenue figure disagree with the shop's?

Which statuses you counted, and whether refunds were subtracted. Both are decisions rather than facts, so write them into the sheet — the difference is almost always definitional rather than a data problem.

Will the export slow the shop down?

It can, because it runs on the same server. Schedule off-peak, page modestly, export incrementally, and check the site's response times around a run at least once so you find out before a customer does.

Should revenue include tax and shipping?

Both answers are defensible and they differ substantially, so the sheet must state which it used. This, along with which statuses count, accounts for nearly every "the export does not match" conversation.

What should the export reconcile against?

The payment provider, not the shop dashboard. The gateway knows what money actually arrived, and when the two disagree it is the figure that matters — usually because of refunds, fees, or orders in an unexpected status.

Get started today

Your first workflow is free to build.

Describe what you need. Cody handles the build, the connections, and the deployment.