Native Shopify can give a customer a set price like "4 for GBP 10" one time, but it does not re-trigger that deal for each additional set. So a customer who buys 8 of a GBP 3.49 item does not pay GBP 20. They pay GBP 23.96, because Shopify applies the fixed discount to a single set of four and charges full price for the rest. A true repeating multibuy, where every complete set of four re-prices to GBP 10, needs a discount that recalculates per set. On Shopify that means a discount built on Shopify Functions, not the native discount builder or a fake bundle product.
This guide explains what native discounts actually do with set pricing, why the deal stops after one set, the fake bundle-product workaround merchants reach for and why it hurts more than it helps, how a Functions-based discount recalculates the price for every set, and a full worked example (4 for GBP 10, 8 for GBP 20, 12 for GBP 30) with the exact math laid side by side.
Can Shopify do "4 for GBP 10, 8 for GBP 20" natively?
Partly, and the partly is the whole problem. You can create a native discount that makes four items cost GBP 10. What you cannot create natively is a deal where the same GBP 10 set price recurs on its own for every additional group of four in the cart. Shopify's built-in discount types apply a fixed amount or a percentage a set number of times, not a repeating "each complete set re-prices to GBP 10" rule.
This is a real, recurring merchant question. On the Shopify Community, a merchant trying to run "4 for GBP 10, 8 for GBP 20" across a 600-product collection reported that native discounts price the total once, so eight items came to GBP 23.96 instead of the GBP 20 they wanted, and asked how to make each additional set re-trigger the deal. The answer they got was that native discounts cannot do repeating set pricing, and the workaround suggested was to build a fake "bundle product" priced at GBP 10. We will come back to why that workaround is a trap.
The short version: native Shopify is fine for a one-off set price on a fixed quantity. It falls apart the moment the customer buys more than one set and expects the deal to keep applying.
IMAGE PLACEHOLDER (Image 1): One set versus every set
Suggested visual: A clean 16:9 diagram on a white background. Left side labeled "Native Shopify" shows a cart of 8 items with only the first group of 4 boxed in violet and priced GBP 10, the remaining 4 at full price, total GBP 23.96 in red. Right side labeled "Repeating multibuy" shows the same 8 items split into two violet boxes of 4, each priced GBP 10, total GBP 20 in green. Minimal flat vector, brand colors violet and gold, sans-serif labels, no photography.
What is a repeating multibuy deal?
A multibuy deal sets a price for a group of items rather than a price per item. "3 for 2," "2 for GBP 5," and "4 for GBP 10" are all multibuy deals. A repeating multibuy is one where the group price applies again, automatically, every time the customer adds another complete group. Four items cost GBP 10, eight cost GBP 20, twelve cost GBP 30, and so on, with the deal recalculating for each completed set.
The word that matters is "per set." The customer is not getting a flat amount off their order and they are not getting a percentage off every unit. They are getting a fixed price for each complete bundle of a set size, with any leftover items that do not complete a set charged at their normal price. That per-set recalculation is exactly the behavior native Shopify does not have, and it is the behavior a Functions-based discount adds back.
Why "per set" is harder than it looks
To price a cart correctly, the discount engine has to count how many complete sets are in the cart at the moment of checkout, apply the set price to each one, and then decide what to do with the remainder. A cart of six items is one complete set of four at GBP 10 plus two loose items at full price. A cart of eight is two sets at GBP 20 flat. That count changes every time the shopper adjusts a quantity, and it has to be recomputed server-side so the number on the cart page is the number they are actually charged. Native discounts do not recompute a set count this way, which is the root of the "8 for 23.96" surprise.
Why does native Shopify only discount one set?
Native Shopify has two discount types that look like they could do multibuy, and both stop short in different ways.
Amount off products applies the fixed discount once
The closest native fit for "4 for GBP 10" is an "Amount off products" discount with a minimum quantity of four and a fixed amount off calibrated to bring four items down to GBP 10. According to the Shopify Help Center, amount off product discounts take a fixed value or a percentage off the qualifying items. The trouble is that the fixed value is applied to the qualifying line items as one deduction, not re-triggered for each additional set. If four of a GBP 3.49 item need GBP 3.96 knocked off to reach GBP 10, Shopify subtracts that GBP 3.96 one time. Add four more items and Shopify does not subtract a second GBP 3.96. The customer gets one set price and full price on everything after it. That is precisely how eight items land at GBP 23.96 rather than GBP 20.
Buy X Get Y is about extra items, not a set total
The other candidate is a "Buy X Get Y" discount. Per Shopify's developer documentation, a Buy X Get Y discount is defined by what the customer buys (a prerequisite quantity of items) and what they then get (a quantity of items at a discounted price or for free). It is built to hand the shopper additional discounted units, for example "buy 3, get 1 free." It is not built to express "these four items together cost GBP 10." You cannot phrase a fixed set total in the buy/get model, because the model discounts the "get" items, it does not re-price the whole group to a flat number. Buy X Get Y also carries other native limits merchants hit, including a cap on eligible products, which we cover in a separate piece on the 100-product Buy X Get Y limit.
So the native builder gives you a set price that fires once (amount off products) or an extra-item mechanic that cannot express a set total at all (Buy X Get Y). Neither recalculates per set, and that is not a bug you can configure your way out of. It is the boundary of what the native types are designed to do.
The fake bundle-product workaround (and why it backfires)
The most common no-app workaround, and the one suggested in that Community thread, is to create a new product that represents the set. You make a "4-pack" product, set its price to GBP 10, and sell that. On the surface it works: the customer adds one "4-pack" and pays GBP 10, adds two and pays GBP 20. The set price repeats because each unit of the fake product is already priced as a set.
It backfires in several expensive ways.
- Inventory goes out of sync. Unless you wire the bundle to its component products through Shopify's native Bundles feature or a bundling app, selling one "4-pack" does not decrement the stock of the four real items inside it. You end up maintaining two inventory realities that drift apart.
- Customers cannot buy the quantities they want. A real multibuy lets someone buy 5 or 7 units and get one set priced plus loose items at full price. A fake bundle product forces purchases in multiples of the set size. Want six? You cannot, you get four or eight.
- It does not scale across a collection. The merchant in the Community thread wanted the deal across 600 products with mix-and-match sets. A fake bundle product needs a separate SKU for every combination customers might want, which is impossible past a handful of items. Mix-and-match across a large collection is exactly what a bundle product cannot represent.
- It pollutes merchandising and analytics. The bundle shows up as its own product in search, collections, and reports. Your per-item sales data now hides inside "4-pack" line items, and customers browsing the real product page see a different price than the bundle, which is confusing.
- Variants multiply. If the underlying products have sizes or colors, every variant combination inside the set needs to exist on the bundle product, and the variant count explodes fast.
The workaround trades a pricing problem for an inventory, catalog, and reporting problem. For a single hero product with no variants it can limp along. For a real catalog it is not maintainable.
How a Functions-based discount recalculates per set
The reliable way to run a repeating multibuy is a discount that runs as code inside Shopify's own checkout pipeline, using Shopify Functions. Instead of a fixed deduction applied once, the discount reads the cart at checkout time, counts how many complete sets of the set size are present, applies the set price to each complete set, and leaves any remainder at its normal price. Because it recomputes on every cart change and runs server-side, the price is recalculated for every set and the cart total matches the checkout total.
Here is the logic in plain English for a "4 for GBP 10" deal on an item that normally costs GBP 3.49:
- Count the eligible units in the cart. Say the customer has 10.
- Divide by the set size of four. That is two complete sets (8 units) with a remainder of 2.
- Price the two complete sets at GBP 10 each, for GBP 20.
- Charge the remaining 2 units at the normal GBP 3.49 each, for GBP 6.98.
- Cart total: GBP 26.98, computed the same way on the cart page, the checkout, and in Shop Pay.
Every step is deterministic and repeats as the set count grows. Twelve units is three sets at GBP 30 with no remainder. Because the calculation lives in a Function rather than in theme JavaScript, accelerated checkouts like Shop Pay, Apple Pay, and Google Pay, which skip the cart page, still get the identical price. This is the same reason server-side discounts avoid the cart-versus-checkout mismatch we cover in how discount stacking works in Shopify.
IMAGE PLACEHOLDER (Image 2): Counting complete sets at checkout
Suggested visual: A 16:9 flow diagram. Step boxes left to right, connected by gold arrows: "Cart has 10 units" then "Divide by set size 4" then "2 complete sets + 2 remainder" then "2 sets priced GBP 10 each = GBP 20" then "2 loose units at GBP 3.49 = GBP 6.98" then a green total card "GBP 26.98, same everywhere". Clean flat vector, violet boxes with gold arrows, monospace numbers, white background, no photography.
Worked example: 4 for GBP 10, 8 for GBP 20, 12 for GBP 30
Let us make the difference concrete with a single product that normally sells for GBP 3.49. The deal is "4 for GBP 10," which means each complete set of four should re-price to GBP 10 no matter how many sets the customer buys. To hit GBP 10 for a set of four (normally GBP 13.96), the deal needs to take GBP 3.96 off each complete set.
The table below shows the same carts three ways: full price with no deal, native Shopify applying the fixed discount once, and a repeating multibuy that recalculates per set.
Read the 8-unit row. Full price is GBP 27.92. Native subtracts the single GBP 3.96 set discount and stops, landing at GBP 23.96, the exact figure the Community merchant reported. The repeating multibuy subtracts GBP 3.96 twice, once for each complete set, and lands at GBP 20.00. By 12 units the gap widens to GBP 7.92, because native has still only applied one set discount while the multibuy has applied three.
Notice the 6-unit row is identical for native and multibuy at GBP 16.98, because there is only one complete set either way (one set of four at GBP 10, plus two loose units at GBP 3.49). The two approaches diverge only once a second set completes. That is the tell: if your promotion never sells more than one set per order, native is enough. If customers routinely buy multiples, native quietly overcharges them the moment they cross into a second set, and every merchant who runs this deal eventually gets the "why is my 8-pack not GBP 20" support ticket.
How to set up a repeating multibuy, step by step
Whether you use native discounts for a single-set deal or a Functions-based app for a true repeating one, the setup thinking is the same. Here is the reliable sequence.
1. Write the deal as set size, set price, and remainder rule
Nail down three numbers before you touch any settings: the set size (4), the set price (GBP 10), and what happens to leftover units that do not complete a set (charged at normal price is the usual and fairest choice). If you cannot state the deal in those terms, you do not yet have a multibuy, you have something else.
2. Decide what counts as "the same product"
A multibuy has to know which cart units count toward a set. Is it four of one exact variant, four of any variant of one product (mix sizes freely), or four drawn from a hand-picked group of related products? This "counting" choice is the difference between a clean deal and one that either never triggers or triggers off unrelated items. Stackable calls these per_variant, per_product, and per_group counting, and it is the same decision behind per-product volume discounts.
3. Choose your mechanism honestly
For a one-set-only promotion, a native "Amount off products" discount with a minimum quantity is genuinely fine, and free. For a repeating deal, or a deal that spans a collection with mix-and-match, use a discount app built on Shopify Functions so the price recalculates per set. Do not reach for the fake bundle product unless you have a single no-variant hero product and no intention of scaling it.
4. Set combinability deliberately
Decide whether this multibuy should stack with anything else. A multibuy is a product-class discount, so it can combine with an order discount or free shipping (different classes) if you turn combining on, but it will not stack with another product discount on the same item. Set this on purpose rather than discovering it at checkout.
5. Test a second set, not just the first
This is the step that catches the native shortfall. Do not test with a cart of four and call it done, because four looks correct in every approach. Test with eight and twelve, place a draft or test order, and read the checkout summary line by line. If the total is GBP 23.96 instead of GBP 20 on eight units, your deal is applying once, not per set. Then test a non-multiple like six to confirm leftover units are charged correctly.
6. Verify accelerated checkout
Run the eight-unit cart through Shop Pay. A native or Functions-based discount prices it identically because the math is server-side. A theme-script "deal" is where accelerated checkouts silently drop the discount, so this is your last line of defense before customers find the gap for you.
IMAGE PLACEHOLDER (Image 3): Test the second set
Suggested visual: A 16:9 product screenshot mockup of a Shopify checkout order summary in clean Polaris styling. Show a cart of 8 identical items with a line reading "Multibuy: 4 for GBP 10 applied x2" and an order total of GBP 20.00 highlighted in violet, with a small green checkmark badge reading "Recalculated per set." Reference the docs/screenshot-manifest.md slot for a checkout summary capture to swap in the real screen later. Brand accent violet, no photography.
Run repeating multibuy reliably with Stackable
If you want a set price that actually re-triggers for every set, without a fake bundle product and without hand-checking test orders, this is what Stackable is built for, and it stays inside Shopify's real rules.
- The multibuy math runs in a Shopify Function, so the set price recalculates per complete set and the cart page, checkout, and Shop Pay all compute the identical total from one engine. Eight units come to GBP 20, not GBP 23.96, everywhere.
- You choose what counts as "the same product" with per_variant, per_product, or per_group counting, so a set can be four of one exact variant, four of any size of one product, or four drawn from a hand-picked group, without pooling your whole catalog.
- Repeat logic is built in, so the deal keeps applying as quantity grows instead of firing once. It is the same per-set recalculation behind Stackable's BOGO and Buy X Get Y offers.
- Stackable never changes your product prices. The multibuy exists only as a checkout adjustment, so there is no fake bundle SKU in your catalog, your inventory stays accurate, and uninstalling leaves your products exactly as they were.
Install Stackable free and confirm your 8-for-20 deal charges GBP 20 in the cart, at checkout, and in Shop Pay at usestackable.com/pricing.
The bottom line
- Native Shopify can price one set at "4 for GBP 10," but it applies the fixed discount once, so eight units come to GBP 23.96 instead of GBP 20 and the deal stops after the first set.
- Buy X Get Y cannot express a set total either; it discounts extra "get" items rather than re-pricing a whole group to a flat number.
- A repeating multibuy recalculates per set: it counts complete sets in the cart, prices each at the set price, and charges leftover units at normal price.
- The fake bundle-product workaround forces buying in multiples, breaks inventory and analytics, and cannot do mix-and-match across a collection. Avoid it beyond a single simple product.
- A discount built on Shopify Functions recalculates per set server-side, so the cart, checkout, and Shop Pay all show the same total.
- Always test a cart with two or more sets (eight and twelve units), not just one, because a single set looks correct in every approach and hides the shortfall.
- Tools like Stackable run the multibuy in a Function with per-product counting and repeat logic, so 8 for GBP 20 charges GBP 20 without a fake product in your catalog.
Related articles
- Per-product counting explained: choose exactly what counts as "the same product" for every quantity-based deal.
- Shopify quantity breaks and tiered pricing: count one product's variants, not the whole collection, and hold the price from cart to checkout.
- BOGO and Buy X Get Y with repeat logic: the same per-set recalculation applied to buy-and-get offers, past the 100-product cap.
- Per-product volume discounts in Shopify: tier by the same product, not the whole collection.
- Shopify's 100-product limit on Buy X Get Y: why native Buy X Get Y caps out and how to run 3-for-2 storewide.
- How discount stacking works in Shopify: why native only applies the highest discount, and how classes combine.
- Stackable pricing: plans, the free tier, and what each includes.



