Discover how to apply a recursive discount in WooCommerce such as ‘Buy 2 Get 1 Free’, to offer customers additional value for their purchases. So with this approach, you can allow customers to receive an additional product at a discounted price.
Moreover, it is possible to apply the recursive bogo rule for the same product. But here in this guide, we will explore how to implement recursive discounts using two different products, where A represents the main product and B denotes the free product.
Solution: Implement ‘Buy 2 Get 1 Free’ Recursive Discount in WooCommerce
The code is designed to implement a “Buy N Get N/2” discount logic for the automatically added product according to the following criteria:
Buy 2 Parent Product and get 1 Free Product at a discount.
Buy 4 Parent Product and get 2 Free Product at a discount.
Buy 6 Parent Product and get 3 Free Product Price at a discount and so on.
add_action('woocommerce_cart_calculate_fees', 'ts_discount_and_free_product_based_on_quantity', 10, 1); add_action('woocommerce_before_calculate_totals', 'ts_set_free_product_price_to_zero'); function ts_discount_and_free_product_based_on_quantity($cart) { if (is_admin() && !defined('DOING_AJAX')) return; $parent_product_id = 54; $free_product_id = 917; // Get the price of the specified products $parent_product_price = wc_get_product($parent_product_id)->get_price(); $free_product_price = wc_get_product($free_product_id)->get_price(); // Initialize the discount amount based on the quantity of the parent product $parent_quantity = 0; // Check if the parent product is in the cart foreach ($cart->get_cart() as $cart_item) { if ($cart_item['product_id'] == $parent_product_id) { $parent_quantity = $cart_item['quantity']; // Check if the parent quantity is an even number (2, 4, 6, 8, ...) if ($parent_quantity % 2 == 0) { // Calculate the number of times the discount should be applied based on the parent product quantity $discount_applications = $parent_quantity / 2; // Calculate the total discounted price $discounted_price = $discount_applications * $free_product_price; // If the discount is applied, display a custom notice if ($discounted_price > 0) { wc_clear_notices(); wc_add_notice(sprintf( __("Congratulations! Buy %d, get %d free product(s).", 'your-text-domain'), $parent_quantity, $discount_applications ), 'success'); // Add a custom fee for the discounted amount $cart->add_fee(__("Discount for Free Product"), -$discounted_price, true); // Check if the free product is not already in the cart $free_product_cart_id = WC()->cart->generate_cart_id($free_product_id); $free_product_in_cart = WC()->cart->find_product_in_cart($free_product_cart_id); // If the free product is not in the cart, add it if (!$free_product_in_cart) { WC()->cart->add_to_cart($free_product_id); } } } // Adjust the price of the parent product in the cart item $cart_item['data']->set_price($parent_product_price); break; // Exit the loop after finding the parent product } } // Check if the free product is in the cart $free_product_in_cart = WC()->cart->find_product_in_cart($free_product_id); // Loop through cart items foreach ($cart->get_cart() as $cart_item) { // Check if the current item is the parent product if ($cart_item['product_id'] == $parent_product_id) { // Adjust the price of the parent product in the cart item $cart_item['data']->set_price($parent_product_price); break; // Exit the loop after finding the parent product } } // Adjust the price of the free product after subtotal calculation if ($free_product_in_cart) { foreach ($cart->get_cart() as $cart_item_key => $cart_item) { if ($cart_item['product_id'] == $free_product_id) { // Modify the item price to include the original price with strikethrough $original_price = wc_get_product($free_product_id)->get_regular_price(); $cart_item['data']->set_price($original_price); break; } } } } function ts_set_free_product_price_to_zero($cart) { if (is_admin() && !defined('DOING_AJAX')) return; $free_product_id = 917; // Loop through cart items foreach ($cart->get_cart() as $cart_item_key => $cart_item) { if ($cart_item['product_id'] == $free_product_id) { // Set the price of the free product to 0 $cart_item['data']->set_price(0); break; // Exit the loop after finding the free product } } } // Function to modify cart item price to include original price with strikethrough function ts_modify_cart_item_price($price, $cart_item, $cart_item_key) { $free_product_id = 917; // Product ID of the free product $original_price = wc_get_product($free_product_id)->get_regular_price(); if ($cart_item['product_id'] == $free_product_id) { // Modify the item price to include the original price with strikethrough $price = sprintf( '<del>%s</del> %s', wc_price($original_price), // Format the original price $price // Keep the current price ); } return $price; } add_filter('woocommerce_cart_item_price', 'ts_modify_cart_item_price', 10, 3);
This to the shop owners who are running or planning to run BOGO offers on their WooCommerce store…
BOGO deals are great for increasing your sales, but have you thought about which offers are bringing you more revenue and which offers are not performing that great?
Don’t just set a BOGO deal, track the revenue generated by your deals in real-time with the Flexi BOGO for WooCommerce plugin.
Output
When the specified parent product A is added to the cart, and based on the quantity of the parent product the code provides a discount on the free product B. When there are 2 units of the parent product in the cart, the free product is automatically added to the cart with a discount equivalent to 1 unit of the free product.
Also, the user gets a notice about the discount, and if the above-mentioned conditions are met, the free product is added to the cart with the calculated discount.
To increase your store’s average order value, consider implementing dynamic bulk WooCommerce discount tiers based on quantity. This strategy can effectively optimize pricing based on selected quantity tiers.