Skip to content

Using Tiers

This walkthrough goes from a fresh install to a working pricing table and a verified cart discount, then covers manual placement and the developer filters.

Open WooCommerce → Tiers and add bands in the Pricing tiers builder. There is no enable switch, saving at least one valid tier turns the discount on. Start with two or three breakpoints:

  • 5 units → 5% off
  • 10 units → 10% off
  • 25 units → 15% off

As you type, the live preview lists each band the way a shopper reads it. On save, rows with a non-positive quantity or a percentage outside 0-100 are dropped and the rest sort by quantity ascending. The deepest matching band always wins at cart time.

Pick a Table placement, product summary (default), before or after the add-to-cart form, the product meta area, or Only where I place it. Optionally set a Table heading and turn on the Savings column so the per-unit saving at each tier is spelled out.

Open a simple product with a regular price. The table renders at your chosen placement showing each quantity range (5, 9, 10, 24, 25+), the discount, and the resulting per-unit price; the deepest-discount row carries a Best value badge. The markup is plain server-rendered HTML with a <caption> and <th scope>, present as the page loads, no AJAX, no layout shift.

  1. Add the product below the first tier, the line uses the regular price.
  2. Raise the quantity to meet a tier, the line subtotal reflects that band’s discount off the regular price.
  3. Raise it to a higher tier, the deeper discount applies, not a stack of both.

If you turned on the Cart savings note, each discounted line shows You save {amount} beneath its subtotal. If totals look wrong, confirm the regular price is set and no other plugin is rewriting the line price for the same product.

Set Table placement to Only where I place it, then drop the table where you want it. The shortcode is [tiers_table]; it takes one attribute, product_id:

[tiers_table]
[tiers_table product_id="123"]

With no product_id (or 0), it uses the current product, so inside a product description or tab it renders that product’s table. Pass a product_id to show a specific product’s table anywhere, including a normal page or post.

In the block editor, insert the Volume pricing table block (category: WooCommerce). Its only control is a Product ID (0 = current product) field. The block is server-rendered, the editor shows a placeholder; the real table renders on the front end. Both paths share the same template, and both enqueue the table stylesheet on demand even outside single-product pages.

When a product has no valid tiers, the shortcode and block render nothing (empty string).

To vary tiers by product, role, or anything else, filter tiers_product_tiers. It receives the global tiers and the WC_Product, and runs both when building the table and when discounting the cart:

add_filter( 'tiers_product_tiers', function ( array $tiers, WC_Product $product ): array {
// Example: deeper tiers for a specific product.
if ( 123 === $product->get_id() ) {
return array(
array( 'min_qty' => 3, 'discount_percent' => 10.0, 'label' => '' ),
array( 'min_qty' => 6, 'discount_percent' => 20.0, 'label' => 'Wholesale' ),
);
}
return $tiers;
}, 10, 2 );

Each tier is an array of min_qty (int), discount_percent (float), label (string). This is the hook Tiers PRO uses for per-product and role-based pricing. See Configuration for the full hook list and the template override path.

Tiers rewrites the line-item price on woocommerce_before_calculate_totals (priority 25), before WooCommerce computes totals, so coupons apply on top of the tiered price and taxes are calculated on the discounted price by WooCommerce’s own logic. The table uses <th scope> and a <caption>, so screen readers announce the quantities and prices correctly.