In WooCommerce, finding all orders that include a specific product can be trickier than it sounds—especially with the new High-Performance Order Storage (HPOS) system. Since HPOS replaces the old posts and postmeta tables with custom ones, direct database queries are no longer the recommended approach. Instead, we should rely on the official CRUD functions and helpers like wc_get_orders().
Unfortunately, the official documentation doesn’t cover this particular use case at all. There’s no example showing how to fetch orders that contain a given product, which leaves many developers guessing or resorting to outdated SQL queries.
In this snippet, you’ll see a clean, efficient way to retrieve WooCommerce orders based on a product ID using wc_get_orders(). It’s fully compatible with HPOS, safe to use in any environment, and easy to adapt.

PHP Snippet: Get WooCommerce Orders by Product ID / Product Name
The idea for this helper function came from a great discussion with Olli Kousa from parvus.fi in the Business Bloomer Club Slack channel. While exploring how WooCommerce’s backend order search works, he discovered the internal logic that makes it possible to locate orders by product ID—and it turns out it works beautifully.
What follows is a simple helper function that builds on that concept. It’s not a standalone solution, so you’ll need to include it inside your own custom function or plugin code to make it work. The result is an array of order IDs that contain the specific product you’re searching for, using wc_get_orders() under the hood for full HPOS compatibility.
This approach keeps your code future-proof, clean, and entirely within the WooCommerce API—no raw SQL or legacy table lookups required.
/**
* @snippet Get order IDs that contain product ID @ WooCommerce
* @tutorial https://businessbloomer.com/woocommerce-customization
* @author Rodolfo Melogli, Business Bloomer
* @compatible WooCommerce 10
* @community Join https://businessbloomer.com/club/
*/
$product_id = 123456; // OR GET IT DYNAMICALLY!
$product = wc_get_product( $product_id );
$args = [
'status' => wc_get_is_paid_statuses(),
'limit' => -1,
'type' => 'shop_order',
'return' => 'ids',
's' => $product->get_name(), // WE SEARCH BY PRODUCT NAME
'search_filter' => 'products',
];
$order_ids = wc_get_orders( $args ); // HERE ARE YOUR ORDER IDS
This snippet retrieves all paid WooCommerce orders that include a specific product name.
First, it defines the product ID and loads the product object. Then, it prepares the query arguments for wc_get_orders(): only paid orders are included, the result returns order IDs, and the product name is used as the search keyword with the “products” search filter. Finally, wc_get_orders() runs the search and returns an array of matching order IDs.
This approach is fully compatible with HPOS and mirrors WooCommerce’s own admin order search logic—clean, efficient, and no direct database access needed.
While testing on my dev site, with 35,000 orders, the query took about 0.0069s to find 25 matching orders.








