Where data is stored
WooCommerce stores data in the WordPress database: partly in the standard tables, partly in its own. You need to know the tables to understand what is going on, but data should always be read and changed through the shop's classes and functions, not with database queries.
What lives where
| Data | Where |
|---|---|
| Products | The wp_posts table, post type product |
| Product properties (price, SKU) | wp_postmeta and the lookup table wp_wc_product_meta_lookup |
| Categories, tags, attributes | The product_cat, product_tag, pa_... taxonomies |
| Orders | Dedicated tables wp_wc_orders, wp_wc_order_addresses, wp_wc_orders_meta |
| Order items | wp_woocommerce_order_items |
| Customers | WordPress users with the customer role |
| Settings | The wp_options table, woocommerce_... keys |
A post type is how WordPress keeps different entities in one table: posts, pages, products. A taxonomy is a way to group posts: categories and tags.
HPOS
Orders used to be rows in wp_posts too. Now they live in separate tables — this mode is called HPOS (High-Performance Order Storage). In new shops it is on from the start. You can check it in WooCommerce → Settings → Advanced → Features, the Order data storage block.
There is one practical consequence: orders are handled only through wc_get_order() and the order object's methods. get_post_meta() and WP_Query do not see orders.
The shop object
The WC() function returns the main WooCommerce object. It gives access to the cart, the customer and the session of the current visitor:
$count = WC()->cart->get_cart_contents_count();
$country = WC()->customer->get_billing_country();
$version = WC()->version;The first line returns the number of items in the cart, the second the customer's country, the third the plugin version. The cart and the customer exist only on site pages: in the admin panel and in background jobs WC()->cart is null.
Access functions
Other data is reached through functions with the wc_ prefix:
| Function | What it returns |
|---|---|
wc_get_product($id) | A product object |
wc_get_products($args) | A list of products |
wc_get_order($id) | An order object |
wc_get_orders($args) | A list of orders |
wc_price(19.9) | A price with the currency as HTML |
wc_get_page_permalink('cart') | The address of a shop page |
Each of them is covered in the following lessons.
Trying things without a plugin
While you have no plugin of your own, code is convenient to test in the WP-CLI console:
wp eval 'echo wc_get_product(12)->get_name();'The command runs PHP code inside a loaded WordPress and prints the name of the product with ID 12. The ID is visible in the Products list when you hover over a row.
Common mistake
Data is read with an SQL query: SELECT meta_value FROM wp_postmeta WHERE meta_key = '_price'. The table structure changes between versions — this already happened to orders with the move to HPOS — and such code stops working after an update. WooCommerce objects and functions hide the storage and stay the same.