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

How to Apply a BOGO Rule as ‘Buy 2 Get 1’ Recursive Discount in WooCommerce?

The recursive BOGO rule will enable customers to get more value for their money by receiving an additional product at a discounted price. 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);

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.

How to Apply a BOGO Rule as 'Buy 2 Get 1' Recursive Discount in WooCommerce? - Tyche Softwares

Similarly, you can also implement BOGO bulk discount tiers that will tie the discounts to a quantity range. Check out here on how to add dynamic bulk WooCommerce discount tiers based on quantity.

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

Share It:

Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x