# Buy 3, Get the Cheapest One Free

> Runs a "buy X, get one free" deal automatically: for every set of items in the cart, the cheapest one is discounted to zero, shown as a line in the totals.

- Type: PHP
- Runs: Run everywhere
- Category: [WooCommerce](https://wpide.com/library/category/woocommerce/)
- Requires: WooCommerce
- Tags: woocommerce, discounts, bogo, promotion
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/woo-buy-x-get-cheapest-free/

## Code

```php
$wpide_bogo = array(
    'group'      => 3,       // Every 3rd item is free (buy 2 get 1 = 3).
    'categories' => array(), // Category slugs, empty for all products.
    'label'      => 'Buy 2, get 1 free',
);

$wpide_bogo_prices = function ( $cart ) use ( $wpide_bogo ) {
    $prices = array();

    foreach ( $cart->get_cart() as $item ) {
        if ( $wpide_bogo['categories'] && ! has_term( $wpide_bogo['categories'], 'product_cat', $item['product_id'] ) ) {
            continue;
        }

        $unit = (float) wc_get_price_excluding_tax( $item['data'] );

        for ( $i = 0; $i < (int) $item['quantity']; $i++ ) {
            $prices[] = $unit;
        }
    }

    sort( $prices );

    return $prices;
};

add_action( 'woocommerce_cart_calculate_fees', function ( $cart ) use ( $wpide_bogo, $wpide_bogo_prices ) {
    if ( is_admin() && ! wp_doing_ajax() ) {
        return;
    }

    $prices = $wpide_bogo_prices( $cart );
    $free   = (int) floor( count( $prices ) / max( 1, $wpide_bogo['group'] ) );

    if ( $free > 0 ) {
        $cart->add_fee( $wpide_bogo['label'], -array_sum( array_slice( $prices, 0, $free ) ), true );
    }
} );

add_action( 'woocommerce_before_cart', function () use ( $wpide_bogo, $wpide_bogo_prices ) {
    $count = count( $wpide_bogo_prices( WC()->cart ) );
    $left  = $wpide_bogo['group'] - ( $count % $wpide_bogo['group'] );

    if ( $count > 0 && $left > 0 && $left < $wpide_bogo['group'] ) {
        wc_print_notice( sprintf( 'Add %1$d more qualifying item(s) to get one free (%2$s).', $left, esc_html( $wpide_bogo['label'] ) ), 'notice' );
    }
} );
```

## Notes

Set the group size and optional categories at the top; a cart notice tells shoppers how many more items unlock the next free one.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Buy 3, Get the Cheapest One Free" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
