Where does a WooCommerce store keep its orders?
In more places than one query can reach. A legacy store keeps the order header in the WordPress posts table and everything else — totals, customer details, payment fields — as key-value rows in the post-meta table. Line items sit in their own WooCommerce tables, and refunds are separate order records attached to the original.
Stores on High-Performance Order Storage (HPOS) work differently: orders live in dedicated order tables with real columns, addresses in their own table, and operational fields separated out. HPOS is the default for new stores, existing stores can be migrated, and many run compatibility mode with both sets of tables kept in sync. That is three possible layouts behind the same admin screen, which is exactly why a generic connector cannot promise you a correct revenue number.
Where each part of a WooCommerce order lives, by storage mode
| Part of the order |
Legacy post storage |
HPOS storage |
| Order header & status |
wp_posts row, type shop_order, status in post_status |
wp_wc_orders row with status, currency and totals as columns |
| Totals, tax & payment fields |
wp_postmeta keys such as _order_total and _order_tax |
Columns on wp_wc_orders plus wp_wc_order_operational_data |
| Billing & shipping address |
Further wp_postmeta keys, one row per field |
wp_wc_order_addresses, one row per address type |
| Line items (product, tax, shipping, coupon, fee) |
wp_woocommerce_order_items, split by order_item_type |
Unchanged — same order-items tables |
| Quantity, product & variation IDs, line totals |
wp_woocommerce_order_itemmeta, key-value again |
Unchanged — same item-meta table |
| Refunds |
Child shop_order_refund post linked to the parent order |
Child row in wp_wc_orders carrying the parent order ID |
| Custom plugin data |
wp_postmeta, mixed in with core keys |
wp_wc_orders_meta |
Table prefixes are not always wp_, and multisite installs repeat the whole set per site. We read the prefix and the storage mode from your install rather than assuming, which is the first thing we check on a scoping call.
Why does a naive extract report the wrong revenue?
Because most of the traps are invisible in a row count. Four cause nearly every wrong number we are asked to fix: unmapped statuses, refunds counted twice or not at all, non-product line items added into product sales, and variable products collapsed to their parent. None of them throw an error; they just quietly change the total.
The line-item table is the sharpest edge. Product rows, tax rows, shipping rows, fee rows and coupon rows all live in the same table, distinguished only by a type column. Sum the amounts without filtering and shipping income and tax become product revenue. Ignore the coupon rows and your discounts vanish from the margin story. Add the fact that amounts are stored as text and need explicit typing, and you have a report that is close enough to look right and wrong enough to be dangerous.
Which order statuses count as a sale?
Your call, made once and written down. Most stores treat completed and processing orders as revenue, exclude pending, cancelled and failed, and handle refunds through the refund records rather than by removing the original order. Draft checkouts never count. We agree the mapping with you before building the measures.
WooCommerce prefixes its statuses with wc-, and plugins for subscriptions, wholesale, pre-orders or shipping add their own. If nobody enumerates them, a custom status simply falls outside your filter and the orders disappear from the dashboard. We list every status present in your data, show you the order and value counts behind each, and make the mapping a documented table in the model — so when the number is questioned, there is an answer rather than an argument.
How do you connect WooCommerce to Power BI?
There is no first-party WooCommerce connector in Power BI. Three routes work, and the right one depends on your hosting, your order volume, and whether your host will grant database access. We test the route during scoping and write the choice into your estimate before spending an hour of your block.
Three ways to get WooCommerce data into Power BI
| Route |
How it works |
Best fit |
Watch out for |
| Read-only database account |
Power BI's MySQL connector against a scoped user, usually through the on-premises data gateway |
Stores with database access and real order history |
Host restrictions, gateway setup, and queries that must stay off the production load |
| WooCommerce REST API v3 |
Consumer key and secret against the store's wc/v3 endpoints, paged through Power Query |
Managed hosting where no database access is offered |
Page-size caps mean thousands of requests on a large store, so refreshes get slow |
| Staged copy |
Orders landed into a small SQL database or warehouse first, then modeled from there |
High-volume stores, multisite, or several stores reporting together |
One more moving part to maintain — worth it once API paging becomes the bottleneck |
Microsoft documents both entry points we use. WordPress runs on MySQL, so the MySQL database connector (opens in new tab) is the cleanest path when your host allows a read-only account, and because the store is self-hosted it normally reaches Power BI through the on-premises data gateway (opens in new tab). Where no database access exists, the REST API is reached with the Web connector (opens in new tab), authenticated with a consumer key and secret over HTTPS. We are not affiliated with WooCommerce, Automattic or Microsoft; we use documented interfaces only. If a staged copy is the right answer, our SQL Server Power BI dashboard work covers that side, and the measure layer is described on our Power BI data modeling and DAX page.
What does a WooCommerce dashboard cost?
You buy prepaid Flex hours that never expire: Starter 20h at $125/hr ($2,500), Growth 40h at $115/hr ($4,600), or Power 80h at $100/hr ($8,000), with hourly work from $100/hr. A first orders-and-margin build typically fits inside one block. No project minimum, no retainer — refill only when you're ready.
Traditional Power BI firms charge $175–250/hr, set project minimums, want $10K+ to start, let unused hours expire, and don't begin for 4–6 weeks. Flex Support flips that: $100–125/hr, no minimums, banked hours that never expire, and a start this week. You buy a block, send your request, and we reply with a scope and hours estimate before any work — hours deduct only for approved builds. See how prepaid Flex hours work or our affordable Power BI consulting page for the full pricing comparison. Compared with a per-store monthly connector subscription, a one-off build you own has a fixed cost and no renewal.
How fast is delivery, and how does refresh work?
Most builds ship in 3–5 business days after you approve the scope estimate. We publish to your workspace, set scheduled refresh, and configure incremental refresh where the order history is long — so the dashboard updates itself instead of waiting on someone to rerun an export.
Microsoft's published data refresh limits (opens in new tab) allow up to eight scheduled refreshes per day on Power BI Pro, with more on higher capacities. Most stores settle on a morning refresh and one in the afternoon. We monitor it, fix the breakage when a plugin update or a host migration changes something underneath, and do that from your banked hours — the maintenance a driver licence leaves entirely to you.
Who is this build for?
Stores running WooCommerce on their own hosting, where reporting has outgrown the built-in analytics screens and a spreadsheet is doing the reconciliation. It also fits WordPress agencies whose clients keep asking for reporting the agency does not want to build, and finance leads who need store numbers that tie to the ledger.
If your storefront is hosted rather than self-hosted, the equivalent build is our Shopify Power BI sales dashboard — same delivery model, different data path. Selling on marketplaces too? Power BI for Amazon sellers covers per-ASIN profit and FBA inventory, and Power BI dashboards for ecommerce brands is the multi-channel version that blends store, marketplace and ad data into CAC, MER and contribution margin per SKU. Brands that also trade through physical stores should start with Power BI for retail, and if those stores ring sales on Square, our Square Power BI dashboard page sets out the API split, the gross-to-net sales unstacking and the payout-to-bank reconciliation for that side. To put traffic and conversion next to orders, see our GA4 Power BI marketing dashboard page; to tie net sales back to the books, QuickBooks Power BI dashboards. Contact is form-only — send your request and we'll reply with a scope estimate within one business day.