Get Product (or Variation) by SKU
In this tutorial, I will show you how to get a product or a product variation object in WooCommerce if you only know its SKU. When we just need to get a product object by ID, we use the wc_get_product() function – super-easy, right? But if we only have an SKU, it is going to be a little bit more interesting.
So, I am going to show you four different ways how you can obtain a product object from its SKU, we are going to do it both the WooCommerce way (with WP_Product_Query and wc_get_product_id_by_sku() function) and the WordPress way (with WP_Query). Also, I will show you how to do it when you interact with the WooCommerce REST API.
Get Product by SKU with WC_Product_Query
$query = new WC_Product_Query( array(
'sku' => 'MISHA-123',
) );
$products = $query->get_products();
$product = reset( $products );
// let's print the product price for example
echo $product->get_price();
// or product ID
echo $product->get_id();It can also be achieved with the wc_get_products() function.
$products = wc_get_products( array( 'sku' => 'MISH-123' ) );
$product = reset( $products );In all the above examples I am using the reset() PHP function to get the first element of an array. So it is sort of similar to using $products[0]. At the same time, it means that in case duplicate SKUs are allowed on your WooCommerce store, this method will also work.
But there is one thing – the examples above won’t work with product variations! So, please continue to read this article to find out how to deal with them.
Get Product or Variation ID by SKU with wc_get_product_id_by_sku()
Here it is. Function wc_get_product_id_by_sku() is a universal solution that allows you to get an ID of either a product or a product variation by its SKU.
// Get a product ID by SKU in WooCommerce
$product_id = wc_get_product_id_by_sku( 'MISH-123' );
if( $product_id ) {
$product = wc_get_product( $product_id );
} else {
echo 'Neither a product nor a variation has been found.';
}For variations:
// Get a variation ID by SKU in WooCommerce
$variation_id = wc_get_product_id_by_sku( 'MISH-234' );
if( $variation_id ) {
$variation = wc_get_product_object( 'variation', $variation_id );
}By the way, it is not necessary to use the wc_get_product_object() for product variations, wc_get_product() is also fine.
Get Product by SKU with WP_Query
Yes, we can also use standard WordPress classes and functions to work with WooCommerce products, however, you need to keep in mind the following two things:
- Whenever possible I recommend you stick to the WooCommerce functions and classes, because, in the good case, you can bypass caching or some performance optimization by WooCommerce, in the worst case – one day your code will stop working (a good example is HPOS orders).
- SKU of products is just a custom field of a custom post type, which is stored in the
wp_postmetatable under_skukey.
Now, straight to the code:
$products = new WP_Query(
array(
'post_type' => array(
'product', // if you only need get products by SKU
'product_variation', // if you need to get variations as well
),
'meta_query' => array(
array(
'key' => '_sku',
'value' => 'MISH-123',
)
),
)
);
while( $products->have_posts() ) : $products->the_post();
$product = wc_get_product( $products->post->ID );
echo $product->get_price();
endwhile;Do you see now how weird and much more complicated this solution is? Even if we replace the WP_Query class with the get_posts() function it doesn’t make things much better.
But let’s look on the bright side, it works perfectly with both products and product variations.
$products = get_posts(
array(
'post_type' => array( 'product', 'product_variation' ),
'meta_query' => array(
array(
'key' => '_sku',
'value' => 'MISH-123',
)
),
)
);
$post = reset( $products );
$product = wc_get_product( $post->ID );
echo $product->get_price();Get Product by SKU in WooCommerce REST API
Last but not least, let’s talk about getting a product by SKU while working with WooCommerce REST API.
That’s exactly the way my Simple WP Crossposting plugin works when you set a product connection type by SKU in the plugin settings:

Long story short when we want to get products by SKU via the WooCommerce REST API we need to use the /wc/v3/products endpoint and provide sku argument to it.
Example:
$sku = 'MISH-123';
$request = wp_remote_get(
add_query_arg( 'sku', $sku, 'https://your-website/wp-json/wc/v3/products' ),
array(
'headers' => array(
'Authorization' => 'Basic ' . base64_encode( "$key:$secret" )
)
)
);
if( 'OK' === wp_remote_retrieve_response_message( $request ) ) {
$products = json_decode( wp_remote_retrieve_body( $request ) );
if( $products ) {
$product = reset( $products );
echo "We found a product with ID {$product->id}";
} else {
echo 'No products with this specific SKU have been found';
}
}For $key and $secret here you can use an application password or create a consumer key and consumer secret in the WooCommerce settings.
It is not necessary to use the WordPress HTTP API as I do in the example above, you can also use official WooCommerce JS and PHP libraries.
Misha Rudrastyh
Hey guys and welcome to my website. For more than 15 years I've been doing my best to share with you some superb WordPress guides and tips for free.
Need some developer help? Contact me
Thank you for this rundown of retrieving Products by SKU. In the plugin I developed that extends WooCommerce, I tried get_posts() and WP_Query, but in the end settled on
wc_get_product_id_by_sku()for many of the reasons you mentioned here.However, I have an issue.
wc_get_product_id_by_sku()only returns a single ID. It turns out that a number of translation plugins work by creating duplicate posts, and thus duplicate SKUs. I need to be able to update all products with the same SKU, some of which are variations. Any suggestions on how to do this? My current idea, which I don’t like, is to take the code fromget_product_id_by_sku()copy it to my plugin and remove the “LIMIT 1” from the SQL.Translation plugins are also using tons of functions with custom SQL queries. So I think that there is nothing wrong if you decide to use a query like this:
Unfortunately, you can’t modify the original function with the
woocommerce_get_product_id_by_skuhook because it requires you to pass an integer value as a result. But we may want to pass an array if we have multiple products.