Implementing BOGO (Buy One Get One) in WooCommerce: Lowest Item Free

“Buy One Get One” (BOGO) or “Buy Multiple, Get the Cheapest Free” are classic marketing strategies used to increase average order value. While WooCommerce doesn’t support these complex promotion rules out of the box, we can easily implement them using the powerful woocommerce_before_calculate_totals hook.

The “Cheapest Item Free” Logic

The goal is to scan the customer’s cart, identify the item with the lowest unit price, and then override its price to zero. This ensures the customer always gets the best deal based on your promotion rules.

add_action( 'woocommerce_before_calculate_totals', function ( $cart ) {
    // Prevent execution in admin or during AJAX (except checkout/cart updates)
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) return;

    // We need at least two items for "Buy X Get One"
    if ( count( $cart->get_cart() ) < 2 ) return;

    $min_price = PHP_FLOAT_MAX;
    $cheapest_item_key = '';

    // Step 1: Find the cheapest item in the cart
    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
        $item_price = $cart_item['data']->get_price();
        if ( $item_price <= $min_price ) {
            $min_price = $item_price;
            $cheapest_item_key = $cart_item_key;
        }
    }

    // Step 2: Set the cheapest item's price to 0
    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
        if ( $cheapest_item_key === $cart_item_key ) {
            $cart_item['data']->set_price( 0 );
            $cart_item['data']->set_sale_price( 0 );
        }
    }
}, 9999 );

Important Considerations

  • Quantity Handling: The basic code above applies the free discount to the entire line item of the cheapest product. If a customer has multiple quantities of the cheapest item, you might want to adjust the logic to only discount one unit.
  • Conflict with Coupons: Be sure to test this alongside other WooCommerce discounts or coupons to ensure the final total is calculated correctly.
  • Performance: Using a high priority (9999) ensures this logic runs after most other price manipulation plugins, providing consistent results.

By implementing this custom snippet, you can launch sophisticated sales campaigns without the need for heavy, expensive promotion plugins. You can further expand this to include “Buy 3 Get 1 Free” or role-based eligibility checks.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *