Updating Product Stock Programmatically
Since I’ve been working a lot lately with synchronising product stock quantities between multiple WooCommerce stores or within a WordPress Multisite network, I can share with you some interesting insights how it is working.
CRUD-objects vs Updating Product Meta Directly
Trying to update product stock using update_post_meta() function
Let’s begin with the thing that product stock information is stored in the post meta wp_postmeta
table for now. WooCommerce has plans to move on to a custom database table, but it is just their plans in the future.
The meta keys used:
_manage_stock
– whether stock managemant is turned on or not._stock
– product stock quantity (stock management is on)._stock_status
–instock
,outofstock
etc (stock management is off).
So, when you find those values in the database, the first thing that may come to your mind is to do something like this:
$product_id = 123;
update_post_meta( $product_id, '_manage_stock', 'yes' ); // yes or no
update_post_meta( $product_id, '_stock', 100 );
update_post_meta( $product_id, '_stock_status', 'instock' );
And it is actually working without even refreshing the caches:

But this method doesn’t work properly with product variations. Using WC_Product_Variable::sync()
or wc_delete_product_transients()
doesn’t help.
set_stock_status() and set_stock_quantity() methods of WC_Product
But the most correct way to update product stock data is to use CRUD layers of course.
$product_id = 123;
$product = wc_get_product( $product_id ); // object of WC_Product class
// for variations
// $product = wc_get_product_object( 'variation', $product_id );
$product->set_manage_stock( true ); // true/false
$product->set_stock_quantity( 100 );
// $product->set_stock_status( 'instock' );
// always
$product->save();
In this case you don’t even need to use set_stock_status()
method because WooCommerce will figure it out itself that this specific product is in stock now.
Using WooCommerce REST API
$product_id = 123;
wp_remote_request(
"https://YOUR STORE/wp-json/wc/v3/products/{$product_id}",
array(
'method' => 'PUT',
'headers' => array(
'Authorization' => 'Basic ' . base64_encode( "$login:$pwd" )
),
'body' => array(
'manage_stock' => true,
//'stock_status' => 'instock',
'stock_quantity' => 100,
)
)
);
If you don’t know where to get $login
and $pwd
values, please read this.
In order to make it work for product variations just change the endpoint to /wp-json/wc/v3/products/{$product_id}/variations/{$variation_id}
.

Misha Rudrastyh
Hey guys and welcome to my website. For more than 10 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