Woocommerce Cart Quantity Base Discount

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

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

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.

Sample Image


To display the discounted product price instead of the original product price, just remove woocommerce_cart_item_price() function (and hook)

Newest similar: Cart item quantity progressive percentage discount in Woocommerce 3

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

Sample Image

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.

Sample Image


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 is 10 + 1 = 11 items and then the discount for 11 items is 5%:

Sample Image

Adding a discount by cart items conditionally based on the item quantity

This code will not work in Woocommerce 3+

See: Cart item discount based on quantity in Woocommerce 3:

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 in 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' );
}

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…

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

This code is tested and works.



Related Topics



Leave a reply



Submit