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.
Opens WPIDE on
Code
$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 add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.