Change Prices of Items added to Cart in WooCommerce

Luckily the Cart Object allows to do cool stuff and create any condition.

First off all let me show you a very simple example, where we just set the custom price for all products in cart.

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 );

My today’s task is the following: When a customer adds to the cart a certain amount (3 for example) of products of a specific category (ID 25), these products will receive 50% discount. But this shouldn’t affect Lambo product (with ID 12345).

WooCommerce: 50% discount to a specific product category when selected a certain amount of products
Cart totals are outside the image on the last frame, but trust me, cart totals was updated.

add_action( 'woocommerce_before_calculate_totals', 'misha_recalculate_price' );
function misha_recalculate_price( $cart_object ) {

	if ( is_admin() && ! defined( 'DOING_AJAX' ) )

	// you can always print_r() your object and look what's inside
	//print_r( $cart_object ); exit;
	// it is our quantity of products in specific product category
	$quantity = 0;
	// $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( 25, $value['data']->get_category_ids() ) && $value['product_id'] != 12345 ) {
			// if yes, count its quantity
			$quantity += $value['quantity'];

	// change prices
	if( $quantity > 3 ) {
		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( 25, $value['data']->get_category_ids() ) && $value['product_id'] != 12345 ) {
				$newprice = $value['data']->get_regular_price() / 2;
				// in case the product is already on sale and it is much cheeper with its own discount
				if( $value['data']->get_sale_price() > $newprice )
					$value['data']->set_price( $newprice );

If you’re wondering where I found all those methods like set_price(), get_category_ids(), look at the Abstract Product Object, you can find it in WooCommerce plugin directory in /includes/abstracts/abstract-wc-product.php. 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.

If you cart in WooCommerce is custom coded and our hook doesn’t apply to it, use WC()->cart->calculate_totals().

P.S. While working with woocommerce_before_calculate_totals action hook, be careful with plugins that affect cart prices too, like YITH Dynamic Pricing and Discounts.

Misha Rudrastyh

Misha Rudrastyh

I develop websites since 2008, so it is total of 14 years of experience, oh my gosh. Most of all I love love love to create websites with WordPress and Gutenberg, some ideas and thoughts I share throughout my blog.

Need some developer help? Contact me

Follow me on Twitter