WP SITES

3085 Coded Tutorials & 288 Plugins

Buy This Product Get These Products Free WooCommerce

Swap out the product ids to suit your own requirements. If the main product is added to cart, the 2 free products are also added to cart and the price changes too free.

If the main product is removed from cart, the price of the 2 free products changes back to the original price.

If 1 or more of the free products are added to cart and then the main product is added to cart, the free products price changes to free.

On their own, the free products are not free.

add_action('woocommerce_before_calculate_totals', 'custom_buy_one_get_two_free', 10, 1);

function custom_buy_one_get_two_free($cart) {
    if (is_admin() && !defined('DOING_AJAX')) {
        return;
    }

    // Define the main product (the one that triggers the free items)
    $main_product_id = 3372; // Replace with the actual product ID

    // Define the free products
    $free_products = [
        3311, // Replace with the first free product ID
        3312  // Replace with the second free product ID
    ];

    // Check if the main product is in the cart
    $main_product_in_cart = false;
    foreach ($cart->get_cart() as $cart_item) {
        if ($cart_item['product_id'] == $main_product_id) {
            $main_product_in_cart = true;
            break;
        }
    }

    // Handle free products
    foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
        $product_id = $cart_item['product_id'];

        if (in_array($product_id, $free_products)) {
            if ($main_product_in_cart) {
                // If the product was bought at full price, make it free
                if (!isset($cart_item['custom_free_item'])) {
                    $cart_item['custom_price_backup'] = $cart_item['data']->get_price(); // Store original price
                    $cart_item['custom_free_item'] = true; // Mark as free
                }
                // Ensure price is set to zero
                $cart_item['data']->set_price(0);
            } else {
                // Restore original price if main product is removed
                if (isset($cart_item['custom_free_item']) && isset($cart_item['custom_price_backup'])) {
                    $cart_item['data']->set_price($cart_item['custom_price_backup']); // Restore price
                    unset($cart_item['custom_free_item'], $cart_item['custom_price_backup']);
                }
            }
        }
    }

    // Auto-add free products if missing when main product is added
    if ($main_product_in_cart) {
        foreach ($free_products as $free_product_id) {
            $product_in_cart = false;
            foreach ($cart->get_cart() as $cart_item) {
                if ($cart_item['product_id'] == $free_product_id) {
                    $product_in_cart = true;
                    break;
                }
            }
            if (!$product_in_cart) {
                // Add product with a custom free flag
                $cart_item_key = $cart->add_to_cart($free_product_id, 1);
                if ($cart_item_key) {
                    $cart->get_cart()[$cart_item_key]['custom_free_item'] = true;
                }
            }
        }
    }
}

Add the code to your child themes functions file or code snippets plugin.

Leave a Reply

New Plugins