Change Prices of Items added to Cart in WooCommerce
Sometimes we have to recalculate product prices and their totals when products are already added to the cart depending on some 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.
1 2 3 4 5 6 7
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).

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
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).
add_action( 'woocommerce_before_calculate_totals', 'misha_recalculate_price' ); function misha_recalculate_price( $cart_object ) { if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;add_action( 'woocommerce_before_calculate_totals', 'misha_recalculate_price' ); function misha_recalculate_price( $cart_object ) { if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return; // 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.