Discount based on item quantity count for a category in WooCommerce cart
You are not using the correct hook and there are some missing things. Try the following:
add_action( 'woocommerce_before_calculate_totals', 'discounted_cart_item_price', 20, 1 );
function discounted_cart_item_price( $cart ){
// Not for wholesaler user role
if ( ( is_admin() && ! defined( 'DOING_AJAX' ) ) || current_user_can('wholesaler') )
return;
// Required since Woocommerce version 3.2 for cart items properties changes
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// HERE set your product categories in the array (can be IDs, slugs or names)
$categories = array('surfacing-adhesives');
$categories = array('t-shirts');
// Initializing
$found = false;
$count = 0;
// 1st Loop: get category items count
foreach ( WC()->cart->get_cart() as $cart_item ) {
// If product categories is found
if ( has_term( $categories, 'product_cat', $cart_item['product_id'] ) ) {
$count += $cart_item['quantity'];
}
}
// Applying discount
if ( $count >= 10 ) {
// Discount calculation (Drop the per item qty price)
$price = $count >= 20 ? 5 : 10;
// 2nd Loop: Set discounted price
foreach ( WC()->cart->get_cart() as $cart_item ) {
// If product categories is found
if ( has_term( $categories, 'product_cat', $cart_item['product_id'] ) ) {
$cart_item['data']->set_price( $price );
}
}
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works. Woocommerce percentage discount per item based on quantity
The following will make a percentage discount based on item quantity:
add_action( 'woocommerce_cart_calculate_fees','cart_quantity_discount' );
function cart_quantity_discount( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$discount = 0; // Initializing
$percent = 10; // Percentage
// Loop through cat items
foreach ( $cart->get_cart() as $cart_item ) {
$subtotal = $cart_item['line_total'];
// Calculation by Item based on quantity
if( $cart_item['quantity'] > 17 ) {
$discount += $cart_item['line_total'] * $percent / 100;
}
}
if( $discount > 0 ) {
$cart->add_fee( __( "Item quantity discount", "woocommerce" ), -$discount, true );
}
}
Code goes on functions.php file of your active child theme (or active theme). It should works. Cart item discount based on quantity in Woocommerce 3
The code will apply a cart item discount based on the cart item quantity. In this code example, it will apply a discount of 5% on the cart item, when the quatity is equal or more than 2 (two).Since woocommerce version 3+ the linked answer code doesn't work. It needs something different and can even be done in a better way.
The cart item unit price displayed is always the real product price. The discount will be effective and displayed on the cart item subtotal.
Additionally the product name will be appended with a discount mention.
The code:
add_filter('woocommerce_add_cart_item_data', 'add_items_default_price_as_custom_data', 20, 3 );
function add_items_default_price_as_custom_data( $cart_item_data, $product_id, $variation_id ){
$product_id = $variation_id > 0 ? $variation_id : $product_id;
## ----- YOUR SETTING ----- ##
$discount_percentage = 5; // Discount (5%)
// The WC_Product Object
$product = wc_get_product($product_id);
// Only for non on sale products
if( ! $product->is_on_sale() ){
$price = (float) $product->get_price();
// Set the Product default base price as custom cart item data
$cart_item_data['base_price'] = $price;
// Set the Product discounted price as custom cart item data
$cart_item_data['new_price'] = $price * (100 - $discount_percentage) / 100;
// Set the percentage as custom cart item data
$cart_item_data['percentage'] = $discount_percentage;
}
return $cart_item_data;
}
// Display the product original price
add_filter('woocommerce_cart_item_price', 'display_cart_items_default_price', 20, 3 );
function display_cart_items_default_price( $product_price, $cart_item, $cart_item_key ){
if( isset($cart_item['base_price']) ) {
$product = $cart_item['data'];
$product_price = wc_price( wc_get_price_to_display( $product, array( 'price' => $cart_item['base_price'] ) ) );
}
return $product_price;
}
// Display the product name with the discount percentage
add_filter( 'woocommerce_cart_item_name', 'append_percetage_to_item_name', 20, 3 );
function append_percetage_to_item_name( $product_name, $cart_item, $cart_item_key ){
if( isset($cart_item['percentage']) && isset($cart_item['base_price']) ) {
if( $cart_item['data']->get_price() != $cart_item['base_price'] )
$product_name .= ' <em>(' . $cart_item['percentage'] . '% discounted)</em>';
}
return $product_name;
}
add_action( 'woocommerce_before_calculate_totals', 'custom_discounted_cart_item_price', 20, 1 );
function custom_discounted_cart_item_price( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
## ----- YOUR SETTING ----- ##
$targeted_qty = 2; // Targeted quantity
// Loop through cart items
foreach ( $cart->get_cart() as $cart_item ) {
// For item quantity of 2 or more
if( $cart_item['quantity'] >= $targeted_qty && isset($cart_item['new_price']) ){
// Set cart item discounted price
$cart_item['data']->set_price($cart_item['new_price']);
}
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.Newest similar: Cart item quantity progressive percentage discount in Woocommerce 3To display the discounted product price instead of the original product price, just remove
woocommerce_cart_item_price()
function (and hook)…
Cart bulk quantity discount for specific product tag IDs in WooCommerce
To apply a discount based on product tag IDs, you can use WC_Product::get_tag_ids(), and then compare it.
I have provided an extra piece of code via the woocommerce_cart_item_price
hook, which will allow you to strikethrough the original price and show the new price next to it
So you get:
// Used to calculate totals
function action_woocommerce_before_calculate_totals( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// Set Tag IDs
$tag_id_1 = 326;
$tag_id_2 = 327;
// Tag ID 1
// 15% discount above 10 units
$tag_id_1_threshold_1 = 10;
$tag_id_1_discount_1 = 0.15;
// 20% discount above 25 units
$tag_id_1_threshold_2 = 25;
$tag_id_1_discount_2 = 0.20;
// Tag ID 2
// 20% discount above 10 units
$tag_id_2_threshold_1 = 10;
$tag_id_2_discount_1 = 0.20;
// 35% discount above 25 units
$tag_id_2_threshold_2 = 25;
$tag_id_2_discount_2 = 0.35;
// Loop through cart items
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
// Get price
$price = $cart_item['data']->get_price();
// Get quantity
$quantity = $cart_item['quantity'];
// Get product tag ID's
$tag_ids = $cart_item['data']->get_tag_ids();
// Check for tag ID
if ( in_array ( $tag_id_1, $tag_ids ) ) {
// Compare
if ( $quantity >= $tag_id_1_threshold_1 && $quantity < $tag_id_1_threshold_2 ) {
$discount = $tag_id_1_discount_1;
} elseif ( $quantity >= $tag_id_1_threshold_2 ) {
$discount = $tag_id_1_discount_2;
}
} elseif ( in_array ( $tag_id_2, $tag_ids ) ) {
// Compare
if ( $quantity >= $tag_id_2_threshold_1 && $quantity < $tag_id_2_threshold_2 ) {
$discount = $tag_id_2_discount_1;
} elseif ( $quantity >= $tag_id_2_threshold_2 ) {
$discount = $tag_id_2_discount_2;
}
}
// Isset & NOT empty
if ( isset( $discount ) && ! empty( $discount ) ) {
// Set new price
$cart_item['data']->set_price( $price * ( 1 - $discount ) );
// Reset
$discount = '';
}
}
}
add_action( 'woocommerce_before_calculate_totals', 'action_woocommerce_before_calculate_totals', 10, 1 );
// Strikethrough the original price
function filter_woocommerce_cart_item_price( $price_html, $cart_item, $cart_item_key ) {
// Get the product object
$product = $cart_item['data'];
// Is a WC product
if ( is_a( $product, 'WC_Product' ) ) {
// Get reqular price
$regular_price = $product->get_regular_price();
// New price
$new_price = $cart_item['data']->get_price();
// NOT empty and NOT equal
if ( ! empty ( $regular_price ) && $regular_price != $new_price ) {
// Output
$price_html = '<del>' . wc_price( $regular_price ) . '</del> <ins>' . wc_price( $new_price ) . '</ins>';
}
}
return $price_html;
}
add_filter( 'woocommerce_cart_item_price', 'filter_woocommerce_cart_item_price', 10, 3 );
Cart item quantity progressive percentage discount in Woocommerce 3
You can do it by cart item quantity or globally based on cart items count:
1) By cart item quantity:
// Utility function that give the discount percentage based on quantity argument
function get_discount_percent( $quantity ){
if( $quantity < 9 )
$percent = 0; // 0 % ( quantity from 1 to 8 )
elseif( $quantity >= 9 && $quantity < 13 )
$percent = 5; // 5 % ( quantity from 9 to 12 )
else
$percent = 10; // 10 % ( quantity up to 13 )
return $percent;
}
add_filter('woocommerce_add_cart_item_data', 'add_items_default_price_as_custom_data', 20, 3 );
function add_items_default_price_as_custom_data( $cart_item_data, $product_id, $variation_id ){
$product_id = $variation_id > 0 ? $variation_id : $product_id;
## ----- YOUR SETTING ----- ##
$percent_1 = 5; // Discount (5%)
$percent_2 = 10; // Discount (10%)
// The WC_Product Object
$product = wc_get_product($product_id);
$price = (float) $product->get_price();
// Set the Product default base price as custom cart item data
$cart_item_data['discount'][0] = $price;
// Set the Product discounted price of 5% as custom cart item data
$cart_item_data['discount'][$percent_1] = $price * (100 - $percent_1) / 100;
// Set the Product discounted price of 10% as custom cart item data
$cart_item_data['discount'][$percent_2] = $price * (100 - $percent_2) / 100;
return $cart_item_data;
}
// Display the product original price
add_filter('woocommerce_cart_item_price', 'display_cart_items_default_price', 20, 3 );
function display_cart_items_default_price( $product_price, $cart_item, $cart_item_key ){
if( isset($cart_item['discount'][0]) ) {
$product = $cart_item['data'];
$product_price = wc_price( wc_get_price_to_display( $product, array( 'price' => $cart_item['discount'][0] ) ) );
}
return $product_price;
}
// Display the product name with the discount percentage
add_filter( 'woocommerce_cart_item_name', 'append_percetage_to_item_name', 20, 3 );
function append_percetage_to_item_name( $product_name, $cart_item, $cart_item_key ){
// get the percent based on quantity
$percent = get_discount_percent($cart_item['quantity']);
if( isset($cart_item['discount'][$percent]) && isset($cart_item['discount'][0]) ) {
if( $cart_item['data']->get_price() != $cart_item['discount'][0] )
$product_name .= ' <em>(' . $percent . '% discounted)</em>';
}
return $product_name;
}
add_action( 'woocommerce_before_calculate_totals', 'set_custom_discount_cart_item_price', 25, 1 );
function set_custom_discount_cart_item_price( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
foreach( $cart->get_cart() as $cart_item ){
// get the percent based on quantity
$percentage = get_discount_percent($cart_item['quantity']);
// For items non on sale set a discount based on quantity as defined in
if( $percentage != 0 && isset($cart_item['discount'][$percentage]) && ! $cart_item['data']->is_on_sale() ) {
$cart_item['data']->set_price($cart_item['discount'][$percentage]);
}
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.2) Globally on cart item count (for non on sale products):
// Utility function that give the discount percentage based on quantity argument
function get_discount_percent( $quantity ){
if( $quantity < 9 )
$percent = 0; // 0 % ( quantity from 1 to 8 )
elseif( $quantity >= 9 && $quantity < 13 )
$percent = 5; // 5 % ( quantity from 9 to 12 )
else
$percent = 10; // 10 % ( quantity up to 13 )
return $percent;
}
// Utility function that count cart items that are not on sale
function get_non_on_sale_cart_items_count(){
$items_count = 0;
foreach( WC()->cart->get_cart() as $cart_item ){
if( ! $cart_item['data']->is_on_sale() ){
$items_count += $cart_item['quantity'];
}
}
return $items_count;
}
add_filter('woocommerce_add_cart_item_data', 'add_items_default_price_as_custom_data', 20, 3 );
function add_items_default_price_as_custom_data( $cart_item_data, $product_id, $variation_id ){
$product_id = $variation_id > 0 ? $variation_id : $product_id;
## ----- YOUR SETTING ----- ##
$percent_1 = 5; // Discount (5%)
$percent_2 = 10; // Discount (10%)
// The WC_Product Object
$product = wc_get_product($product_id);
$price = (float) $product->get_price();
// Set the Product default base price as custom cart item data
$cart_item_data['discount'][0] = $price;
// Set the Product discounted price of 5% as custom cart item data
$cart_item_data['discount'][$percent_1] = $price * (100 - $percent_1) / 100;
// Set the Product discounted price of 10% as custom cart item data
$cart_item_data['discount'][$percent_2] = $price * (100 - $percent_2) / 100;
return $cart_item_data;
}
// Display the product original price
add_filter('woocommerce_cart_item_price', 'display_cart_items_default_price', 20, 3 );
function display_cart_items_default_price( $product_price, $cart_item, $cart_item_key ){
if( isset($cart_item['discount'][0]) ) {
$product = $cart_item['data'];
$product_price = wc_price( wc_get_price_to_display( $product, array( 'price' => $cart_item['discount'][0] ) ) );
}
return $product_price;
}
// Display the product name with the discount percentage
add_filter( 'woocommerce_cart_item_name', 'append_percetage_to_item_name', 20, 3 );
function append_percetage_to_item_name( $product_name, $cart_item, $cart_item_key ){
// Get cart items count
$items_count = get_non_on_sale_cart_items_count();
// get the percent based on quantity
$percent = get_discount_percent($items_count);
if( isset($cart_item['discount'][$percent]) && isset($cart_item['discount'][0]) ) {
if( $cart_item['data']->get_price() != $cart_item['discount'][0] )
$product_name .= ' <em>(' . $percent . '% discounted)</em>';
elseif ( $cart_item['data']->is_on_sale() && $percent != 0 ){
$product_name .= ' <em>(Item on sale)</em>';
}
}
return $product_name;
}
// Change cart item price
add_action( 'woocommerce_before_calculate_totals', 'set_custom_discount_cart_item_price', 25, 1 );
function set_custom_discount_cart_item_price( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// Get cart items count
$items_count = get_non_on_sale_cart_items_count();
// get the percent based on quantity
$percentage = get_discount_percent($items_count);
foreach( $cart->get_cart() as $cart_item ){
// For items non on sale set a discount based on quantity as defined in
if( $percentage != 0 && isset($cart_item['discount'][$percentage]) && ! $cart_item['data']->is_on_sale() ) {
$cart_item['data']->set_price($cart_item['discount'][$percentage]);
}
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.Here below, in this example, the third item is on sale, so the real count is10 + 1 = 11
items and then the discount for11
items is5%
:
Adding a discount by cart items conditionally based on the item quantity
Yes this is also possible, making a custom calculation for each cart item and replacing individually their price (matching your conditions and calculations), using a custom function hooked inThis code will not work in Woocommerce 3+…
See: Cart item discount based on quantity in Woocommerce 3:
woocommerce_before_calculate_totals
action hook.This is the code:
add_action( 'woocommerce_before_calculate_totals', 'custom_discounted_cart_item_price', 10, 1 );
function custom_discounted_cart_item_price( $cart_object ) {
$discount_applied = false;
// Set Here your targeted quantity discount
$t_qty = 12;
// Iterating through each item in cart
foreach ( $cart_object->get_cart() as $item_values ) {
## Get cart item data
$item_id = $item_values['data']->id; // Product ID
$item_qty = $item_values['quantity']; // Item quantity
$original_price = $item_values['data']->price; // Product original price
// Getting the object
$product = new WC_Product( $item_id );
// CALCULATION FOR EACH ITEM
// when quantity is up to the targetted quantity and product is not on sale
if( $item_qty >= $t_qty && !$product->is_on_sale() ){
for($j = $t_qty, $loops = 0; $j <= $item_qty; $j += $t_qty, $loops++);
$modulo_qty = $item_qty % $t_qty; // The remaining non discounted items
$item_discounted_price = $original_price * 0.9; // Discount of 10 percent
$total_discounted_items_price = $loops * $t_qty * $item_discounted_price;
$total_normal_items_price = $modulo_qty * $original_price;
// Calculating the new item price
$new_item_price = ($total_discounted_items_price + $total_normal_items_price) / $item_qty;
// Setting the new price item
$item_values['data']->price = $new_item_price;
$discount_applied = true;
}
}
// Optionally display a message for that discount
if ( $discount_applied )
wc_add_notice( __( 'A quantity discount has been applied on some cart items.', 'my_theme_slug' ), 'success' );
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.This make exactly the discount that you are expecting separately for each item in cart (based on it's quantity) and not for items that are in sale. But you will not get any label (text) indicating a discount in the line items of cart.
Optionally I display a notice when a discount is applied to some cart items…
This code is tested and works.
Related Topics
Symfony 3.1.5 Warning: Sessionhandler::Read(): Session Data File Is Not Created by Your Uid
The Behaviour of the or Operator in PHP
Regex to Conditionally Replace Twitter Hashtags with Hyperlinks
Difference Between Directoryiterator and Filesystemiterator
How to Call Curl_Setopt with Curlopt_Httpheader Multiple Times to Set Multiple Headers
Speeding Up Large Numbers of MySQL Updates and Inserts
How to Use Session Variables in Wordpress
PHP Readfile() and Large Files
How to Select a MySQL Database to Use with Pdo in PHP
A Better Way to Replace Emoticons in PHP
How to Resize and Convert an Uploaded Image to a Png Using Gd
PHP Dom Textcontent VS Nodevalue
Pdo_Sqlite Driver Not Present.. What to Do
Wordpress Paginate_Links - How to Use It