How to add Buy 3 get 1 free coupon in WooCommerce

If you wanted to add this functionality to WooCommerce you probably discovered that the official WooCommerce Dynamic Pricing plugin doesn’t support it. Or maybe you tried Pricing Deals for WooCommerce and after 7 hours figuring out how it works you discovered that the coupon solution is not AJAX and it needs a manual refresh by the customer. Unacceptable.
You’re in luck since I will share a custom solution for you that can be adapted to your needs. With this coupon, you can buy one get one free, buy 3 get one free, or buy as many as you want and get the cheapest product in the carefree.
Add this code in your functions.php file to get buy 3 get one free (the cheapest). You will need 4 products in the cart for this to work. The 4th product is free.

// Hook before calculate fees - "Buy 3 get 1 free" coupon
add_action('woocommerce_cart_calculate_fees' , 'buy3_coupon');

 * Add discount for "Buy 3 get 1 free" coupon  
 * @param WC_Cart $cart

function buy3_coupon( WC_Cart $cart ){

	// return if cart has less than 4 items
	if( $cart->cart_contents_count < 4 ) return;
	$match = false;
	$applied_coupons = $cart->get_applied_coupons();	
	// check if the coupon is "buy 3 get 1 free" with custom field
	foreach ($applied_coupons as $coupon_code) {
		$coupon = get_page_by_title($coupon_code, OBJECT, 'shop_coupon');
		if (get_field('buy_3_get_1_coupon', $coupon->ID)) {
			$match = true;

	// return if no coupon matches
	if (!$match) return;
	// loop through the items in cart to find the cheapest
	foreach ( $cart->get_cart() as $cart_item_key => $values ) {
		$_product = $values['data'];
		$price = $_product->get_price_including_tax();
		for ($i = 1; $i <= $values['quantity']; $i++) {
			$product_price[] = $price;
	sort($product_price, SORT_NUMERIC);
	$free_items = floor($cart->cart_contents_count/4);

	$discount_amount = 0;
	for ($i = 1; $i <= $free_items; $i++) {
		$discount_amount += array_shift($product_price);

	$cart->add_fee( 'Coupon deal: Buy 3 get 1 for free', -$discount_amount);


Add the coupon in WooCommerce

Add the coupon and ensure the sum is set to 0.
add buy 3 get one free coupon woocommerce
Under usage restrictions click Check this box if the coupon cannot be used in conjunction with other coupons and click Exclude sale items. These are optional.
add coupon usage restrictions
Go test the coupon

buy 3 get one free coupon cart woocommerce

Note: We do not provide support and customizations for this code. If you need help with updates and custom work please post this project for our partners


10 Responses

  1. wow just what I needed.
    we have a set of 5 products that when you buy 3 you get the fourth free.
    I’m just having a little trouble getting it to apply automaicially
    I added it to the child theme functions php. it doesn’t automatically apply to the products sofar, but works if I add it to the coupon field.
    But it’s a great solution. I was about to get the plugins above glad you wrote this!

  2. Hey Mark,
    I’m glad it’s been helpful to you. Yes this solution is tied to the coupons usage.

  3. Hi Lucian,
    I set the coupon to apply to 5 specific product ids. But when I add 4 of those products to the cart it doesn’t automatically trigger the coupon.
    But it should, right?

  4. The coupon needs to be added manually by the customer. The discounts are applied automatically. This is a coupon based solution

  5. Hi thanks for this!
    I have made an offer ‘Buy 4 get an additional free’
    Therefore when a customer adds 5 items to the basket and puts the code in it should deduct the 5th cheapest item, i have changed the coding manually but cant get it to work, may i have help with this one please?

  6. You’ll want to play with the number from this code:
    // return if cart has less than 4 items
    if( $cart->cart_contents_count < 3 ){ return; } then adjust the wording here: $cart->add_fee( ‘Coupon deal: Buy 3 get 1 for free’, -$cheapest);

  7. Hi, I was looking for this a long time and I followed your steps. But I’m a bit panicked now. Everything works great , you get the discount in the cart but in the checkout, the original price is charged. Newsletter has been sent out to customers and they observed this error and contacted us. Any suggestions please? I’m desperate
    Best regards

  8. This code is purposed to give away the cheapest product off. The 50% discount would require another logic.

Comments are closed.