Skip to content

Controlled discounts on sale items

The sale-items lock is all-or-nothing: past your threshold, the code dies. That’s right for many stores — but it costs you the customer who abandons when their code “doesn’t work.” There’s a middle path: let codes work on sale items, at a rate you chose. Full-price items get the real discount; marked-down items get a token one. The double-dip becomes a controlled, priced-in dip.

All items 20% off. Sale items 5% off. One code.

The customer’s code always works — you just decided in advance what it’s worth on each kind of item.

Everything happens inside one PromoLock discount, using cart groups’ Sale status filter — no collections, no product tagging, no maintenance. An item counts as “on sale” when its price is below its compare-at price, and the groups sort the cart automatically at checkout.

  1. In Discounts, create your discount (code or automatic).
  2. The step everyone misses: in the right rail under Margin guards, set On-sale items to Shopify default. It ships as No discount, and while it’s on that setting, sale items are dropped before your offer ever sees them — the Sale status filter doesn’t even appear in the group editor, because it would do nothing. (Not Sale or code: that option nets the code against the markdown, so your 5% would usually come out to $0.)
  3. Open the group manager (Create/Manage groups from any product discount) and create two groups:
    • Group Full-price items: turn on Filters → tick Sale statusOnly full-price items.
    • Group Sale items: same, but Only items on sale. Leave both groups’ catalog selection empty — the filter alone splits the whole cart cleanly, and every item lands in exactly one group.
  4. In the offer, add two Product discounts: Percentage off 20 aimed at Full-price items, and Percentage off 5 aimed at Sale items.
  5. Cap it: Cap total discount in Margin guards still applies across both rates — set it, and even a cart full of everything has a ceiling.

Because the split is computed from live prices at checkout, it maintains itself: mark a product down and it moves to the 5% side; restore the price and it moves back. Nothing to update, ever.

If two groups and two rates is more policy than you want, the On-sale items guard has a middle option of its own: Sale or code — whichever saves more, not both. The code keeps working on sale items, but the markdown the sale already gave counts toward it, so a sale item only gets the part of the code that beats its sale. A 20% code on a $10 item marked down to $7 gives nothing extra (the sale was already worth more); a 50% code takes it to $5. Full-price items get the full 20% as usual.

The difference from the two-rate setup: Sale or code guarantees a sale item never costs you more than the code’s headline rate off the original price, while the two-rate discount pays a fixed, smaller rate on top of the sale. Pick Sale or code when the promise you want to keep is “20% off, full stop”; pick the two rates when you want sale items to always get something for the code.

Retire the blunt instruments for this policy

Section titled “Retire the blunt instruments for this policy”
  • Don’t run the Controller’s Lock Discount Usage On Sale Items alongside this — that lock blocks all codes on sale-heavy carts, including your two-rate one. This strategy replaces the lock; pick one policy or the other.
  • Old ungoverned codes should be retired or blocked so the two-rate discount is the path customers actually take.
Situation Better policy
Sale prices are final — codes shouldn’t touch them, full stop Sale-items lock
Codes are part of your brand and blocking them costs conversions Two-rate discount (this page)
Deep clearance where even 5% hurts Keep the lock — or set the sale-side rate to a symbolic 1–2%

After a few weeks, open Analytics → Sale-item discounts. Loss on sale items won’t be zero under this policy — that’s the point, the 5% is planned — but the line should be small, flat, and boring. If it climbs, some other code is reaching sale items ungoverned; the top-discounts list will name it.

  • Leaving On-sale items on No discount. The symptom: sale items get no discount at all, the Sale status filter is nowhere to be found, and support tickets say “code doesn’t work.”
  • Only creating the sale-items group. Without the full-price group’s filter, the 20% side would target the whole cart — sale items included. Two filtered groups, one rate each, no overlap.
  • Leaving other codes combinable. The two-rate discount prices in the dip — a second code stacking on top un-prices it. Keep the stacking lock on and this discount’s Combines with flags off.
  • Stale compare-at prices. An item whose compare-at was left above its price after a “sale” ended still counts as on sale and gets the 5% rate. Clearing compare-at when a markdown ends keeps the split honest.