# Shopify Tiered Discounts in 2026: Buy More, Save More with Functions

By [Eoin Villarin](https://amvprosox.com/about). Published 2026-11-15. Canonical: https://amvprosox.com/blog/shopify-tiered-discounts-discount-function

> How to create tiered quantity discounts on Shopify after Scripts were retired: built-in options, discount apps and a working JavaScript Discount Function with metafield tiers.

## How do I create tiered discounts on Shopify?

Create tiered quantity discounts on Shopify with a Shopify Function built on the Discount Function API, or with a Functions-powered discount app from the Shopify App Store. The Function counts cart quantity, picks the matching tier and returns a productDiscountsAdd operation. Public apps work on any plan; custom apps with Functions need Shopify Plus.

**Key takeaways**

- Shopify Scripts stopped running on June 30, 2026, so tiered discounts now need Shopify Functions.
- Product and order discounts use the cart.lines.discounts.generate.run target.
- Store the tiers as JSON in the $app function-configuration metafield so they change without a deploy.
- Public discount apps work on any plan; custom apps with Functions require Shopify Plus.
- Show the tier table on the product page so customers see the saving before the cart.

To create tiered quantity discounts on Shopify in 2026 (for example buy 3 save 10%, buy 5 save 15%, buy 10 save 20%), use a Shopify Function built on the Discount Function API, or a Functions-powered discount app from the Shopify App Store. Shopify Scripts used to do this on Shopify Plus, but they stopped running on June 30, 2026. Below is the no-code route, the limits of Shopify's built-in automatic discounts, and a working JavaScript Function you can adapt, with tiers stored in a metafield so marketing can change them without a deploy.

## Three ways to do tiered discounts on Shopify

| Method | Plan | Effort | Limits |
| --- | --- | --- | --- |
| Built-in automatic discounts (one per tier) | Any | Minutes | Each discount has one minimum; several tiers depend on discount combination settings and can stack or conflict |
| Functions-powered discount app | Any | An hour | Monthly app fee, rules limited to the app's settings |
| Custom app with a Discount Function | Shopify Plus for custom apps | 1 to 5 days | Development and maintenance; full control |

For one or two simple tiers, try the built-in automatic discounts first. For several tiers, customer-tag rules, collection rules or anything your store relied on Scripts for, use a Function.

![Reusable shopping tote bag printed with Rotterdam 010 on a shop display](https://amvprosox.com/api/img/1794711546853-ahsnaz)
*Volume tiers lift average order value on products people buy in multiples. Photo: Donald Trung Quoc Don, CC BY-SA 4.0, via Wikimedia Commons*

## How the Discount Function API works

- A Function is a small WebAssembly module that Shopify runs during cart and checkout. You can write it in JavaScript or Rust; Shopify recommends Rust for large carts.

- Product and order discounts use the target `cart.lines.discounts.generate.run`. Shipping discounts use `cart.delivery-options.discounts.generate.run`.

- The Function returns operations such as `productDiscountsAdd`, `orderDiscountsAdd` or `deliveryDiscountsAdd`.

- The discount's classes (`PRODUCT`, `ORDER`, `SHIPPING`) arrive in the input, so one Function can check what it is allowed to apply.

- Settings live in a metafield on the discount (namespace `$app`, key `function-configuration`), read as JSON.

## Step 1: Generate the Function

```
shopify app init
cd your-app
shopify app generate extension --template discount --name tiered-discount
```

Choose JavaScript when the CLI asks for a language. The generator creates the extension folder with a TOML config, an input query and a run function.

## Step 2: The input query

```
query CartInput {
  cart {
    lines {
      id
      quantity
    }
  }
  discount {
    discountClasses
    metafield(namespace: "$app", key: "function-configuration") {
      jsonValue
    }
  }
}
```

## Step 3: The run function

```
import { DiscountClass, ProductDiscountSelectionStrategy } from '../generated/api';

const DEFAULT_TIERS = [
  { min: 3, percent: 10 },
  { min: 5, percent: 15 },
  { min: 10, percent: 20 },
];

export function cartLinesDiscountsGenerateRun(input) {
  if (!input.cart.lines.length) {
    return { operations: [] };
  }
  if (!input.discount.discountClasses.includes(DiscountClass.Product)) {
    return { operations: [] };
  }
  const config = input.discount.metafield?.jsonValue;
  const tiers = Array.isArray(config?.tiers) && config.tiers.length ? config.tiers : DEFAULT_TIERS;
  const totalQuantity = input.cart.lines.reduce((sum, line) => sum + line.quantity, 0);
  const tier = [...tiers].sort((a, b) => b.min - a.min).find((t) => totalQuantity >= t.min);
  if (!tier) {
    return { operations: [] };
  }
  return {
    operations: [
      {
        productDiscountsAdd: {
          selectionStrategy: ProductDiscountSelectionStrategy.First,
          candidates: [
            {
              message: `${tier.percent}% off ${tier.min}+ items`,
              targets: input.cart.lines.map((line) => ({ cartLine: { id: line.id } })),
              value: { percentage: { value: String(tier.percent) } },
            },
          ],
        },
      },
    ],
  };
}
```

Notes: percentage values are Decimals and must be sent as strings. To limit the discount to one collection, add `merchandise` with `inAnyCollection` to the input query and filter the lines before counting.

## Step 4: Deploy and create the discount

- Run `shopify app dev` to test on a development store, then `shopify app deploy`.

- Create an automatic app discount that uses your Function (for example with the `discountAutomaticAppCreate` Admin API mutation), set its discount class to product, and save the tiers JSON in the `$app` / `function-configuration` metafield:

```
{"tiers":[{"min":3,"percent":10},{"min":5,"percent":15},{"min":10,"percent":20}]}
```

- Set the discount's combination rules (with product, order and shipping discounts) to match your promo policy.

- Test carts with 2, 3, 5 and 10 items, mixed products, a discount code on top, and different markets.

## Show the tiers on the product page

Customers only buy more if they can see the deal. Add a small tier table under the price ("3+ save 10%, 5+ save 15%, 10+ save 20%") using a theme app block or a metafield in your theme, and show the saving in the cart. Keep the table text the same as the Function's tiers so the cart never disagrees with the product page.

![Shopify sign on an office building directory board](https://amvprosox.com/api/img/1794710852715-fanj0i)
*Discount Functions run inside Shopify's checkout, so they work with Checkout Extensibility and Shop Pay. Photo: Raysonho @ Open Grid Scheduler / Grid Engine, CC0, via Wikimedia Commons*

## Common problems

- **Discount does not apply:** the discount is not active, its class does not include product, or the Function returned no operations (check the Function run logs in the Partner Dashboard or in `shopify app dev`).

- **Stacking with codes:** discount combination settings decide whether a code applies on top. Set them deliberately.

- **Wrong tier:** make sure you count quantity across the right lines (all lines, one collection, or one product).

- **Large carts:** very large carts can hit Function limits in JavaScript; Rust is faster if you see failures.

## Need it built?

I build Shopify Functions, discount apps and Checkout UI extensions for Shopify and Shopify Plus stores. If your tiered pricing stopped working when Scripts were retired, read [Shopify Scripts stopped working: how to fix it](https://amvprosox.com/blog/shopify-scripts-stopped-working-functions-fix) or see my [Shopify development services](https://amvprosox.com/shopify-development).

## Frequently asked questions

### Can Shopify do tiered discounts without an app?

Partly. You can create one automatic discount per tier with a minimum quantity, but several tiers rely on discount combination settings and can behave unpredictably. A Function or Functions-powered app gives reliable tiers.

### Do I need Shopify Plus for tiered discounts?

No. Public discount apps that use Shopify Functions work on any plan. Only a custom app with your own Function requires Shopify Plus.

### What replaced Shopify Scripts for tiered pricing?

The Discount Function API. Product and order discounts use the cart.lines.discounts.generate.run target and return productDiscountsAdd or orderDiscountsAdd operations.

### Can I change discount tiers without redeploying?

Yes. Store the tiers as JSON in the discount's function-configuration metafield and read it in the Function input.

### Can tiered discounts apply to one collection only?

Yes. Query each line's merchandise with inAnyCollection and only count and discount the lines in that collection.

### Should I write Shopify Functions in JavaScript or Rust?

JavaScript is quicker to write and fine for most stores. Shopify recommends Rust for performance, especially with large carts.

## Sources

- [Shopify.dev: Discount Function API](https://shopify.dev/docs/api/functions/latest/discount)

- [Shopify.dev: About Shopify Functions](https://shopify.dev/docs/apps/build/functions)

- [Shopify developer changelog: Shopify Scripts will be deprecated on June 30, 2026](https://shopify.dev/changelog/shopify-scripts-will-be-deprecated-on-june-30-2026)

- [Shopify.dev: Migrating from Shopify Scripts](https://shopify.dev/docs/apps/build/functions/migrating-from-shopify-scripts)
