# Volume Discounts — Reasoning & Recommendations

**Companion to:** [feature-design-guidelines.md](feature-design-guidelines.md), [bundle-concepts.md](bundle-concepts.md)
**Live preview:** PDP at https://demo.thecxlabs.com/v2/pdp.html · PLP at https://demo.thecxlabs.com/v2/plp.html · Cart at https://demo.thecxlabs.com/v2/cart.html
**Date:** May 2026

This document explains the volume-discount pattern for consumable supplies on USA Clean — how it works on the PDP, PLP, cart, and account surfaces, and how it maps to BigCommerce Stencil's native capabilities.

---

## TL;DR

Use BigCommerce's **native Bulk Pricing Rules** to drive volume discounts. Render a **3-tier table on the PDP** between price and ATC that highlights the active tier as the qty stepper changes. Show a small **"Bulk save"** pill on PLP cards for SKUs that have bulk rules configured. Show a **nudge callout on the cart row** when a buyer is one tier away from a savings break, plus a **summary savings line** that totals what they're saving across the cart.

The pattern is fully shippable in Stencil today — no app or replatform required.

| Phase | Surface | Effort |
|---|---|---|
| **Phase 1** _(Pilot)_ | Uniform 3-tier table on PDP, badge on PLP, nudge + summary on cart. Default tiers (1–5 / 6–11 / 12+, savings 0% / 5% / 15%) applied across all supplies. | **Low** — Stencil native; theme edits only |
| **Phase 2** _(Iterate)_ | Category-driven tier templates (paper bags vs. chemicals vs. batteries get different tier tables). Per-SKU overrides where merch sees demand patterns differ. | Low — admin config only |
| **Phase 3** _(Future)_ | Negotiated contract pricing per National Account ties into the same tier UI. Approval-flow integration: junior buyers see "Add 5 more to save 5% — request approval?" instead of just adding. | Higher — touches B2B Edition Customer Groups + Approval Workflows |

---

## Current state

USA Clean's consumable SKUs (vacuum bags, brushes, cleaning chemicals) are the highest-volume B2B reorder items. The current site shows base unit price only — there's no signal that buying in quantity costs less, even when the warehouse runs informal bulk pricing for known accounts.

Why this matters: B2B procurement buyers are *trained* to expect price breaks for volume. Hiding the tier is leaving margin on the table — buyers default to small-qty orders, then re-order more frequently than they need to. Surfacing the tier converts the qty-1 buyer into a qty-12 buyer in one decision.

---

## References

### Grainger volume pricing
Grainger surfaces "Save when you buy in quantity" on supplies. Their tier table is per-SKU, edited in admin, rendered as a small inline tier list under the price. Tier is computed live as the qty input changes. ([Grainger PDP example: respirator filters](https://www.grainger.com/category/safety-respiratory-protection-respirator-cartridges-filters))

### Amazon Business "Quantity Discounts"
Amazon Business shows quantity discount tables on PDPs for Business Prime customers. Same pattern: 3–5 tiers, live-highlight active tier as qty changes, "you saved $X" surfaced at checkout. ([Amazon Business — Quantity discounts](https://business.amazon.com/en/discover-more/blog/quantity-discount))

### McMaster-Carr volume pricing
McMaster shows price-per-quantity inline under each product's add-to-cart row. The pattern is minimalist: a tiny table with no fanfare — appropriate for engineers who already know what they want. ([McMaster — bulk pricing example](https://www.mcmaster.com/screws/cap-screws/))

### HD Supply tier pricing
HD Supply embeds tier pricing in their B2B-Edition-style account model — pricing is contract-driven per Company, surfaced inline on the PDP for logged-in users with that contract assignment.

---

## What BigCommerce Stencil gives us

**Native Bulk Pricing Rules** — directly addresses this feature without any apps or custom code.

- **Admin config:** Settings → Products → [Product] → Pricing → Bulk Pricing Rules. Each product supports unlimited tier rules: define qty range + price type (fixed / % off / $ off).
- **Stencil rendering:** stock cart and product templates iterate `{{#each product.bulk_discount_rates}}` to render the tier table. Available in `templates/components/products/`.
- **Cart engine:** BC computes the applicable rate per line item automatically at cart and checkout — the UI shows the savings; the cart engine is the source of truth.
- **API:** [`/v3/catalog/products/{product_id}/bulk-pricing-rules`](https://developer.bigcommerce.com/docs/rest-management/catalog/product-bulk-pricing-rules) for programmatic management.

Bulk Pricing Rules also play nicely with:
- **Customer Group pricing** — National Account customers can see different tiers than retail (B2B Edition feature).
- **Promotions API** — coupons stack on top of bulk pricing when configured.

**Sources:** [BC Help: Bulk Pricing](https://support.bigcommerce.com/s/article/Bulk-Pricing), [BC Dev: Bulk Pricing Rules API](https://developer.bigcommerce.com/docs/rest-management/catalog/product-bulk-pricing-rules).

---

## Stencil limitations

- **No native "you're N away from the next tier" nudge** on the cart page. Stock cart template just renders the line at the applicable rate. The nudge in this prototype is a custom JS read of the qty + tier rules. **Custom theme JS required.**
- **No native cart-summary "you saved $X with volume discount" line.** Stock cart shows subtotal + promotions; bulk-pricing savings are baked into the line price, not surfaced separately. We compute and show it via theme template logic.
- **PLP card badges for "this product has bulk pricing"** aren't a native field — but `product.bulk_discount_rates` is queryable in the PLP iteration loop, so we can render a badge whenever the rates array is non-empty. Theme edit.
- **No native UI for category-driven tier defaults.** Each product's bulk rules are set per-SKU. Phase 2's "tier templates" would be admin-side automation (a backend script that applies the same rules to all SKUs in a category) — not a Stencil feature.
- **Approval workflows** (Phase 3) intersect with B2B Edition. The volume nudge could route through "request approval if over budget" — that's a custom integration with B2B Edition's Approval API.

---

## App marketplace shortlist

| App | What it does | Worth it now? |
|---|---|:---:|
| **(Native) Bulk Pricing Rules** | Built into BC core — qty tiers, %/$ off, per-SKU config. | ✅ Use this. |
| **[Discounts by Customer Group](https://www.bigcommerce.com/apps/discount-customer-groups/)** | Tier discounts gated by customer group. Useful for National Account contract pricing in Phase 3. | Maybe — B2B Edition Customer Groups + native Bulk Pricing already cover most of this. |
| **[Better Bulk Discounts](https://www.bigcommerce.com/apps/better-bulk-discounts/)** | Wraps native Bulk Pricing Rules with a slicker admin UI. | Skip — doesn't add capability, only smoother admin. Wait for Phase 2 if merch finds admin painful. |
| **Generic countdown / urgency apps** | "Add 5 more to save 5%" countdown overlays. | Skip — visually foreign; we build the nudge in Caster to match the system. |

---

## Caster impact

**New tokens** (none — uses existing amber + accent tokens for the "save" affordance).

**New pattern: `.volume-pricing` block**
- 3-tier inline table — qty range, price, savings label
- Active tier highlight (`is-active` class) driven by the qty stepper
- Pairs with the `.pdp-price` block above and `.pdp-atc` below
- Currently inline in `v2/pdp.html`; promote to Caster `/patterns/` when a second consumer arrives (cart-row qty editor, or quote line items)

**New badge: `.pill--volume`** (PDP pills row) and **`.product-card__badge-volume`** (PLP card badges)
- Amber surface, dark-amber text, with a small cube icon
- Indicates "this product has bulk pricing available"
- Add to Caster's `/primitives/pill.html` showcase as the `--volume` variant

**New cart pattern: `.cart-row__nudge`**
- Dashed amber callout under the row meta
- "Add N more to save X%" with an inline "Add N →" action
- Promote to Caster when the second cart-style consumer arrives

**New summary line: `.summary__savings`**
- Single success-tinted strip under the grand total
- "Contract pricing applied · You're saving $X"
- Useful pattern for any savings surface (volume + coupon + contract)

**Downstream impact:** the volume pill is now part of the pills row on the PDP; teams adding new PDP variants should consider whether their SKU has volume pricing and include the pill accordingly. Same for PLP cards — the badge is "show iff `product.bulk_discount_rates.length > 0`."

---

## Phased recommendation

### Phase 1 — Ship uniform default tiers

Apply a single **uniform tier rule across all consumable SKUs**: 1–5 base, 6–11 saves 5%, 12+ saves 15%. Admin config; no code.

Render the tier table on every PDP. Add the badge on every PLP card. Add the cart nudge logic to the theme JS.

**What "winning" looks like:** measurable shift in average order qty for consumables, repeat-order frequency drops (buyers order larger less often), no measurable impact on cart abandonment.

### Phase 2 — Category-driven tiers (data-gated)

Different categories warrant different tier tables. Paper bags are bought in cases of 10 (no need for 24-unit tier); batteries are bought 1–2 at a time (24+ tier irrelevant); chemicals are bought by the gallon (different qty scale entirely).

**Trigger:** when merch has 1–2 months of Phase 1 data showing which tiers convert and which sit unused per category, group SKUs into tier templates: "Bags & Filters template," "Chemicals 1-gal template," "Batteries template." Three or four templates cover the catalog.

Per-SKU overrides for outliers (the 4-pack SKU has different tier breaks than the single-unit SKU).

### Phase 3 — Contract pricing + approval flows

National Account customers have negotiated contract prices baked in via B2B Edition Customer Groups. The tier UI shows their contract tiers — different from retail.

For accounts with **spending approval workflows**, the cart nudge changes:
- Retail / single-buyer: "Add 5 more to save 5% — Add 5 →"
- Approval-gated buyer: "Adding 5 more saves 5% — Tom needs to approve."

**Trigger:** when sales reports show the top 10 National Accounts asking for their own price breaks beyond what the public tiers offer, and when 3+ accounts have Approval Workflows configured.

---

## Implementation notes

### Stencil theme edits required (Phase 1)

1. **PDP price block** — add `volume-pricing` partial under `templates/components/products/`. Iterates `product.bulk_discount_rates`, renders the 3-tier table, includes JS for live-highlighting the active tier as qty changes.
2. **PLP card** — extend `templates/components/products/card.html` to check `{{#if product.bulk_discount_rates.length}}` and render the volume badge.
3. **Cart row** — extend `templates/components/cart/content.html` to compute "qty until next tier" for each line item, render the dashed amber nudge.
4. **Cart summary** — extend the summary partial to sum (`line.list_price - line.sale_price`) across all lines with bulk pricing applied, render as the savings strip.

### Analytics

Track:
- Tier conversion: distribution of cart qty across tier ranges, before vs. after launch.
- Nudge engagement: % of "Add N more" clicks vs. impressions per SKU.
- AOV shift on PDPs with bulk pricing vs. control.
- Repeat-order cadence on volume-purchased SKUs (should lengthen — fewer, larger orders).

### Accessibility

- Tier table is a real `<table>` with `<caption>` and `<th>` headers when shipped (the prototype uses a CSS grid for the visual; production should use semantic table markup for screen readers).
- Active-tier change announces via an `aria-live="polite"` region: "Quantity 6 — Tier 2 active, save 5%."
- The "Bulk save" pill on PLP cards has an explicit text label, not icon-only.
- The cart nudge's "Add 5 →" link is a real button with `aria-label="Add 5 more units of [product name] to qualify for the 5% volume discount"`.

### Performance

`product.bulk_discount_rates` is included in the standard product API response — no extra request. The PLP card badge logic adds zero network cost; the PDP tier table is a small DOM addition (~3 rows). Live-tier highlighting is a single event listener on the qty stepper.

---

## Catalyst / replatform candidacy

**Phase 1 ships well in Stencil.** Bulk Pricing Rules is one of BC's strongest native features; the tier UI is a straightforward theme edit.

**Phase 3 starts to feel headless.** The interaction between volume pricing + contract pricing + approval workflows is a multi-system orchestration: catalog price, customer-group price, B2B Edition approval queue, cart engine. Stencil templates can do it but the logic becomes spaghetti at the partial level. **Phase 3 is a forcing function for Catalyst** — the React storefront can express the conditional UI cleanly (different nudge for different roles + groups) and call the BC APIs server-side.

**Recommendation:** ship Phase 1 + Phase 2 in Stencil. When Phase 3 work begins, treat it as the first piece of a Catalyst replatform rather than further Stencil-template surgery.

---

## Sources

- [BC Help — Bulk Pricing Rules](https://support.bigcommerce.com/s/article/Bulk-Pricing)
- [BC Dev — Bulk Pricing Rules API](https://developer.bigcommerce.com/docs/rest-management/catalog/product-bulk-pricing-rules)
- [BC Help — Customer Groups](https://support.bigcommerce.com/s/article/Customer-Groups)
- [BC Stencil — product template reference](https://developer.bigcommerce.com/docs/storefront/stencil/themes/product)
- [Amazon Business — Quantity discounts blog](https://business.amazon.com/en/discover-more/blog/quantity-discount)
- [Grainger PDP example — bulk-priced respirator filters](https://www.grainger.com/category/safety-respiratory-protection-respirator-cartridges-filters)
- [McMaster-Carr — bulk pricing pattern](https://www.mcmaster.com/screws/cap-screws/)
- [feature-design-guidelines.md](feature-design-guidelines.md) — operating manual that drove this brief
- [bundle-concepts.md](bundle-concepts.md) — the cart-engine + Promotions API discussion overlaps with this brief
