Override Product Prices in Cart
In this tutorial I will show you how we can override prices of the products that are already in the Cart with the help of woocommerce_before_calculate_totals
action hook and cart object.
Here we are going to deal with products that have already been added to cart, if you would like to add products to the cart with a custom price, I can recommend you this example.
Below we are going to set the same price ($10) for every product in the cart programmatically.
add_action( 'woocommerce_before_calculate_totals', 'misha_recalc_price' );
function misha_recalc_price( $cart_object ) {
foreach ( $cart_object->get_cart() as $hash => $value ) {
$value[ 'data' ]->set_price( 10 );
}
}
Example. Change Product Price Based on Quantity
Now it is time to do something a little bit more interesting. The idea is when a customer adds a certain quantity of a specific product from a specific category (ID 25) to the cart, these products will get 50% off. But it should never affect a Wizard hat product (ID 12345).

/**
* Change Product Prices Programmatically Based on Quantity
*
* @author Misha Rudrastyh
* @link https://rudrastyh.com/woocommerce/change-product-prices-in-cart.html#based-on-qty
*/
add_action( 'woocommerce_before_calculate_totals', 'misha_recalculate_price' );
function misha_recalculate_price( $cart_object ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
return;
}
$product_category_id = 25;
$product_id_to_exclude = 12345;
// it is our quantity of products in specific product category
$quantity = 0;
// you can always print_r() your object and look what's inside
// print_r( $cart_object ); exit;
// $hash = cart item unique hash
// $value = cart item data
foreach ( $cart_object->get_cart() as $hash => $value ) {
// check if the product is in a specific category and check if its ID isn't 12345
if( in_array( $product_category_id, $value[ 'data' ]->get_category_ids() ) && $value[ 'product_id' ] !== $product_id_to_exclude ) {
// if yes, count its quantity
$quantity += $value[ 'quantity' ];
}
}
// change prices
if( 3 < $quantity ) {
foreach ( $cart_object->get_cart() as $hash => $value ) {
// I want to make discounts only for products in category with ID 25
// and I never want to make discount for the product with ID 12345
if( in_array( $product_category_id, $value[ 'data' ]->get_category_ids() ) && $value[ 'product_id' ] !== $product_id_to_exclude ) {
$newprice = $value[ 'data' ]->get_price() / 2;
$value[ 'data' ]->set_price( $newprice );
}
}
}
}
If you’re wondering where I’ve found all those methods like set_price()
, get_category_ids()
, look at the WC_Product
object, you can find it in WooCommerce plugin directory in /includes/abstracts/abstract-wc-product.php
or in the documentation. And by the way, variations don’t have categories.
If you read my blog and still don’t know where to insert this type of code, it is sad. Try your current theme functions.php
then.

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
So how do you exclude the calculations for product addons
I mean, the function works great but I’m using product addons and it modifies the prices for those as well.
Hey,
Try to use a higher priority for the
woocommerce_before_calculate_totals
hook.Please how to make it work when the product is variable. I set the category ID but it only works on simple product. Is there a workaround for variable products?
Let me clarify, that
set_price()
method works perfectly for both simple and variable products.If you want to check if your variable product is in a certain category, let’s say with ID=25, your condition can look like this:
Hi.
Does your snippet update items’ prices via ajax by changing their values in cart rows or not?
Hi Alessandro,
I’m not sure that I understand you question.
My snippet doesn’t make any AJAX stuff, it hooks the price in PHP, server-side. But if affects everything in your WooCommerce store – the popup cart, the cart and checkout pages.
Thank you Misha, that hook and your example works well.
I have also tried to use a POSTed value from a hidden input on the cart page to :
– update that custom cart meta ( created and assigned successfully in add to cart )
– modify the price using this value and the set_price method you show
It is via AJAX, so I did this hooked at woocommerce_before_calculate_totals:
No errors and the logs are as expected until I dump out the cart, and it has the old price. And the ‘unit_price’ property is also not updated.
I would like to achieve pretty much what WooCommerce does with the $quantity variable when updated.
Try to replace this line
foreach ( $cart_object as $key => $value) {
with this oneforeach ( $cart_object->get_cart() as $key => $value ) {
Thanks for the fast response.
Yes, wrong code … I had fixed it ( and was assigning unit_price not calculated_price ) … but still not much success.
Anyhow, I tidied it up and just did this :
Should work but doesn’t – until I just hardcode the POST.
Perhaps I should use this hook : woocommerce_update_cart_action_cart_updated to modify the cart object with my custom POST variables ( similar to $quantity above in that form handler update function ).
Then let calculate totals do its job? Any advice on hooks or how to handle POST var s in this situation would be appreciated.
Hmmm… maybe somehow with order items.
Good day
===
I need something like this : if total amount in the cart is less than 2000 => then amount should be updated + 15%
===
If total amount in the cart is above 2000 => nothing updated
===
Could you help me
Hey,
First of all let’s try to get the cart amount with this code:
Once you did it, you can just add the cart discount with this condition:
somecouponname15
is the coupon created in admin area with 15% discount.Would it be possible to modify this code for it to allow let’s say a sales person to adjust the final price of a product. So le’ts say they found the item cheaper on amazon. My sales could do the shop as customer and then adjust the price to match what was on amazon but without changing the product price itself so that other customers still pay regular price?
Hi Jesse,
Mmmm… Sorry but I don’t get why you need it 🙃 So a sales person adjusted the price and nobody but he/she can buy the product with the adjusted price, correct?
Basically what I have done is added an input field to the cart – that gets the current price of the product.
<input type="number" id="cart_custom" name="cart_custom" value="'.$cart_price.'" >
What I would like to happen is that the sales person could change that Value hit the update button and the cart total would then use the NEW Price that was changed in the input field for the calculations.
Here is the code i have so far.. but what keeps happening if i add 2 items and i change the value of the second item… they both change but when i change the value of just the first item.. NOTHING happens…
Hi,
Working on that kind of bulk discount, with your method the ajax display of cart (ie : mini-cart) was not displaying the correct prices.
So, I’m applying the rules only on that filter “woocommerce_get_cart_contents” which is now working like a charm on page cart/orders and mini-cart.
Hi, i want to ask you how change price of subscription cart quantity, because i cant do that with this code.
I am using woocommerce subscription product.
Hi Misha,
I wanted to know the added value to use the following lines because there are not in the very first example you gave ?
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
Hi Misha,
Can you please answer ?
I am interested to know !
Thanks in advance.
Hi Benji,
These two lines prevent the code from being executed where it shouldn’t be. I do not have specific examples though.