Black Friday & Cyber Monday SUPER SALE ALL WEEK:
Grab 40% OFF on plugins
Days
Hours
Minutes
Seconds

How can I implement “Buy 1 Get 2 free” action in WooCommerce?

How can I implement "Buy 1 Get 2 free" action in WooCommerce? | tychesoftwares.com

One thing E-commerce store owners know is that the customers love offers and discounts on the products. E-commerce store owners give various offers on various products to customers, now & then. It increases the sales for the products and makes the customer happy.

Many stores give offers such as “Buy 1 Get 1 Free”, where when you buy a certain product, you get the second product free of cost. This is a good marketing technique. People love these kinds of offers.

With WooCommerce becoming a popular E-commerce platform for the store owners, it would be great if we could create an offer like this in WooCommerce.

In this post, we will take a look at 5 different ways in which you can give a discount or products for free if a particular product is present in the cart.

1. Give 50% discount on 2nd product if a product from selected category is in cart:

Let’s start with a simple example. We will see how to give 50% discount on the second product if a product of a certain category is present in the cart. In our case, we have product ‘T-shirt’ with the category ‘Get 2’. If this product is present in the cart then we will give 50% discount on the second product present in the cart.

We will use the WooCommerce hook called ‘woocommerce_cart_calculate_fees’. This action hook can be used to modify the cart prices. Let’s take a look at the code –

add_action('woocommerce_cart_calculate_fees', 'ts_add_custom_discount', 10, 1 );
function ts_add_custom_discount( $wc_cart ){
    $discount = 0;
    $product_ids = array();
	$in_cart = false;

	foreach ( $wc_cart->get_cart() as $cart_item_key => $cart_item ) {
		$cart_product = $cart_item['data'];
		if ( has_term( 'get2', 'product_cat', $cart_product->get_id() ) ) {
			$in_cart = true;
		}else {
			$product_ids[] = $cart_product->get_id();
		}

	}

	if( $in_cart ) {
		$count_ids = count($product_ids);

		if( $count_ids >= 1 ) { 
		   foreach( $product_ids as $id ) {
			    
				$product = wc_get_product( $id );
				$price = $product->get_price();
				$discount -= ($price * 50) /100; //apply 50% discount on the other product
		   }
	   }

	} 

    if( $discount != 0 ){
        $wc_cart->add_fee( 'Discount', $discount, true  );
        # Note: Last argument in add_fee() method is related to applying the tax or not to the discount (true or false)
    }
}

We loop through the products in the cart. If the product has the category ‘Get 2’, then we set the flag $in_cart to true. Otherwise, we add the product id in an array to be used later.

If the product of the category ‘Get 2’ is present in the cart and there are other products in the cart, then we apply a 50% discount on the other product. This discount is applied using a function called ‘add_fee’ of the WC_Cart class.

Here is a screenshot of the cart page –

Buy 1 Get 2 Free in WooCommerce

Criteria: T-shirt product from ‘Get 2’ category is in cart
Result: 50% discount is applied on product Hoodie

2. Give 50% discount on 2nd product if a specific product is in cart:

If we want to apply the discount only if a specific product is present, we can do it in a similar way. In the above example, we checked for the category. In this example, we will check for the product id.

The product ‘T-shirt’ has the ID – 2216. We will check if a product of ID 2216 is present in the cart or not. If it is present, then we will apply the discount.

add_action('woocommerce_cart_calculate_fees', 'ts_add_custom_discount', 10, 1 );
function ts_add_custom_discount( $wc_cart ){
    $discount = 0;
    $product_ids = array();
    $product_id = 2216;
	$in_cart = false;
	foreach ( $wc_cart->get_cart() as $cart_item_key => $cart_item ) {
		$cart_product = $cart_item['data'];
		if ( $cart_product->get_id() == $product_id ) {
			$in_cart = true;
		}else {
			$product_ids[] = $cart_product->get_id();
		}
	}
	if( $in_cart ) {
		$count_ids = count($product_ids);
		if( $count_ids >= 1 ) { 
		   foreach( $product_ids as $id ) {
			    
				$product = wc_get_product( $id );
				$price = $product->get_price();
				$discount -= ($price * 50) /100; //apply 50% discount on the other product
		   }
	   }
	} 
    if( $discount != 0 ){
        $wc_cart->add_fee( 'Discount', $discount, true  );
        # Note: Last argument in add_fee() method is related to applying the tax or not to the discount (true or false)
    }
}

Criteria: T-shirt product with ID 2216 is in cart
Result: 50% discount is applied on product Hoodie

3. Give 100% discount on 2nd product if a product from selected category is in cart:

Now, if we want to apply a discount of 100% on the second product, we just need to modify the calculations for the $discount variable. The rest of the code will be same –

$discount -= ($price * 100) /100;

Here is the screenshot –

Buy 1 Get 2 Free in WooCommerce

As you can see, the product ‘Hoodie’ is now free for the customer.

Criteria: T-shirt product from ‘Get 2’ category is in cart
Result: 100% discount is applied on product Hoodie

4. Give 100% discount on only first 2 products in cart, if a product from selected category is in cart:

There is still something missing, though. There is no limit to the number of products on which the discount will be applied. All the other products, except the one with the category ‘Get 2’, will be free.

That is not what we want. We want only 2 products to be free. We will add a counter which will apply the discount for only the first 2 products in the cart.

add_action('woocommerce_cart_calculate_fees', 'ts_add_custom_discount', 10, 1 );
function ts_add_custom_discount( $wc_cart ){
    $discount = 0;
    $product_ids = array();
	$in_cart = false;
	foreach ( $wc_cart->get_cart() as $cart_item_key => $cart_item ) {
		$cart_product = $cart_item['data'];
		if ( has_term( 'get2', 'product_cat', $cart_product->get_id() ) ) {
			$in_cart = true;
		}else {
			$product_ids[] = $cart_product->get_id();
		}
	}
	if( $in_cart ) {
		$count_ids = count($product_ids);
    $count = 0;
		if( $count_ids >= 1 ) { 
		   foreach( $product_ids as $id ) {
			  if( $count >= 2 ) {
					break;
				}
				$product = wc_get_product( $id );
				$price = $product->get_price();
				$discount -= ($price * 100) /100; //apply 100% discount on the other product
         $count++;
		   }
	   }
	} 
    if( $discount != 0 ){
        $wc_cart->add_fee( 'Discount', $discount, true  );
        # Note: Last argument in add_fee() method is related to applying the tax or not to the discount (true or false)
    }
}
	

In the above example, we have a variable called $count. We increment this variable after each iteration and if its value is 2 or greater than 2 then we break the loop.

Our cart page now applies discount on only first two products –

Buy 1 Get 2 Free in WooCommerce

Criteria: T-shirt product from ‘Get 2’ category is in cart
Result: 100% discount is applied on product Hoodie & Jacket

5. Give 100% discount on only first 2 products with the lowest prices, if a product from selected category is in cart:

Now, what if you want to apply the discount on only the two products having the lowest prices in the cart. Well, you can do that too. Let’s look at the example –

add_action('woocommerce_cart_calculate_fees', 'ts_add_custom_discount', 10, 1 );
function ts_add_custom_discount( $wc_cart ){
    $discount = 0;
	$product_ids = array();
	$item_prices = array();
	$in_cart = false;

	foreach ( $wc_cart->get_cart() as $cart_item_key => $cart_item ) {
		$cart_product = $cart_item['data'];
		if ( has_term( 'get2', 'product_cat', $cart_product->get_id() ) ) {
			$in_cart = true;
		}else {
			$product_ids[] = $cart_product->get_id();
			$item_prices[$cart_product->get_id()] = $cart_product->get_price();
		}

	}

	if( $in_cart ) {
		$count_ids = count($product_ids);
		asort( $item_prices ); //Sort the prices from lowest to highest
		
		$count = 0;
		if( $count_ids >= 1 ) { 
		   foreach( $item_prices as $id => $price ) {
			    if( $count >= 2 ) {
					break;
				}
				//$product = wc_get_product( $id );
				//$price = $product->get_price();
				$discount -= ($price * 100) /100;
				$count++;
		   }
	   }

	} 

    if( $discount != 0 ){
        $wc_cart->add_fee( 'Discount', $discount, true  );
        # Note: Last argument in add_fee() method is related to applying the tax or not to the discount (true or false)
    }
}

Here, we created an associative array having the product ids and their prices. Then, we sort this array based on prices from lowest to highest. So, the first 2 products having the lowest prices will be free to the customers.

Here is the screenshot of the Cart page –

Buy 1 Get 2 Free in WooCommerce

In this example, the products ‘Hoodie’ & ‘Cap’ will be free of cost as they are the ones with the lowest prices.

Criteria: T-shirt product from ‘Get 2’ category is in cart
Result: 100% discount is applied on product Hoodie & Cap


These were just some basic examples to show how we can offer discounts on various products to customers. There are many more ways and methods to offer discounts. Some other ways we can apply discounts on products is based on certain conditions – i.e if it is of a specific category, it has a specific tag, or if it of a certain product type etc.

If you have any more interesting ideas, please share them with us.

Browse more in: Code Snippets, WooCommerce How Tos, WooCommerce Tutorials

Share It:

Subscribe
Notify of
3 Comments
Newest
Oldest
Inline Feedbacks
View all comments
5 years ago

Hi Rashmi It is great and done the simplest , bet way. Thanks for the code. I have couple of help questions if you can help please. 1. in the 2nd point above ; (Give 50% discount on 2nd product if a specific product is in cart) When we add a product, the 50% discount is added as suggested. If I add another product in the cart (say product 3) after that, then again 50% is added to the new product, (product 3) where as I want to to give discount only one time to any product customer wants. Is… Read more »

5 years ago

It’s an awesome explanation with code implementation!

3
0
Would love your thoughts, please comment.x
()
x