Quantity Price Breaks With a Price Table
Lowers the unit price when a customer buys more of the same product, for example 5% off from 10 units, and shows a price-break table on the product page.
Opens WPIDE on
Code
$wpide_qty_tiers = array(
'tiers' => array( 10 => 5, 25 => 10, 50 => 15 ), // Minimum quantity => percent off.
'products' => array(), // Product IDs, empty for all.
);
$wpide_tier_percent = function ( $qty ) use ( $wpide_qty_tiers ) {
$percent = 0;
foreach ( $wpide_qty_tiers['tiers'] as $min => $off ) {
if ( $qty >= $min ) {
$percent = $off;
}
}
return $percent;
};
$wpide_tier_applies = function ( $product_id ) use ( $wpide_qty_tiers ) {
return empty( $wpide_qty_tiers['products'] ) || in_array( (int) $product_id, array_map( 'intval', $wpide_qty_tiers['products'] ), true );
};
add_action( 'woocommerce_before_calculate_totals', function ( $cart ) use ( $wpide_tier_percent, $wpide_tier_applies ) {
static $base_prices = null;
if ( is_admin() && ! wp_doing_ajax() ) {
return;
}
$base_prices = $base_prices ?: new SplObjectStorage(); // Original prices, so repeated totals runs never stack.
foreach ( $cart->get_cart() as $item ) {
if ( ! $wpide_tier_applies( $item['product_id'] ) ) {
continue;
}
if ( ! $base_prices->contains( $item['data'] ) ) {
$base_prices[ $item['data'] ] = (float) $item['data']->get_price( 'edit' );
}
$base = $base_prices[ $item['data'] ];
$percent = $wpide_tier_percent( (int) $item['quantity'] );
$item['data']->set_price( $percent ? round( $base * ( 100 - $percent ) / 100, wc_get_price_decimals() ) : $base );
}
}, 20 );
add_action( 'woocommerce_single_product_summary', function () use ( $wpide_qty_tiers, $wpide_tier_applies ) {
global $product;
if ( ! $product instanceof WC_Product || ! $product->is_purchasable() || '' === $product->get_price() || ! $wpide_tier_applies( $product->get_id() ) ) {
return;
}
$price = (float) wc_get_price_to_display( $product );
echo '<table class="wpide-price-tiers shop_table"><thead><tr><th>' . esc_html( 'Quantity' ) . '</th><th>' . esc_html( 'Price each' ) . '</th></tr></thead><tbody>';
foreach ( $wpide_qty_tiers['tiers'] as $min => $off ) {
printf( '<tr><td>%s+</td><td>%s <small>(-%s%%)</small></td></tr>', esc_html( $min ), wp_kses_post( wc_price( $price * ( 100 - $off ) / 100 ) ), esc_html( $off ) );
}
echo '</tbody></table>';
}, 25 );
Notes
Tiers apply per cart line; list product IDs in 'products' to limit them, or leave it empty for every product.
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.