Shopify Discount Functions Explained (2026 Guide)

Shopify discount functions replaced Scripts as the only way to build custom discount logic on Shopify. Here's how they work, what changed, and what breaks when a membership discount meets a promo code.

A merchant messaged us in June with a simple question: why did a customer's VIP discount and a site-wide promo code both apply to the same product, stacking into a price that lost money on the order. The answer had nothing to do with a bug. It had to do with how Shopify discount functions decide which discount wins when two of them want the same line item, and almost nobody reads that part of the documentation until it costs them money.

Shopify discount functions are server-side WebAssembly modules that calculate and apply discounts during cart and checkout, replacing the Ruby-based Shopify Scripts that shut down for good on June 30, 2026. A function receives cart data as structured input, runs custom logic against it, and returns a list of operations Shopify executes at checkout: apply 10% off this line, discount the whole order by $25, knock 50% off Express Shipping. The function itself lives inside an app. Merchants never touch code; they see a new discount type in the same Discounts page they've always used.

That distinction matters more than it sounds. Scripts ran inline in the Shopify admin's Script Editor, wrote in Ruby, and only worked on Shopify Plus. Discount functions are compiled ahead of time, distributed through an app, and available to every plan (Basic, Shopify, Advanced, and Plus) the moment a merchant installs an app that contains one. A custom, private function still requires Plus, but a public app built on the Discount Function API works everywhere.

What Do Shopify Discount Functions Actually Do?

A discount function is a small program that decides, in under 5 milliseconds, whether a discount applies to a cart and how much it's worth. Shopify's own developer docs put a hard number on that speed target, and it's not marketing. Functions run inside the checkout request itself, so a slow function means a slow checkout. There are three discount classes a single function can touch: product, order, and shipping. One function can reduce a product's price, knock a flat amount off the order subtotal, and discount the delivery fee all in the same execution.

Under the hood, a function is built with the Shopify CLI, written in Rust or JavaScript, and compiled to WebAssembly before it ever reaches a live store. It reads a GraphQL input (cart lines, customer tags, quantities, metafields) and returns a "FunctionRunResult" telling Shopify exactly which lines to discount and by how much. Nothing about that logic is visible to the shopper beyond the discount message they see at checkout, like "Member price applied."


How Are Shopify Functions Different From Shopify Scripts?

Scripts gave a single Ruby program full control over the entire cart in one pass; functions run as isolated, independent modules that never see each other. That's the single biggest behavior change merchants hit during migration, and it's the reason the VIP-discount-plus-promo-code scenario above turned into a support ticket.

With Scripts, a developer could write one program that checked ten conditions in sequence and applied a loyalty discount, a promo code, and a shipping override all in one coherent block of logic. With functions, each discount is its own separate extension. Shopify can run up to 25 discount functions on a single store at once, and none of them know the others exist.

Two different settings are easy to mix up here, and mixing them up is exactly what causes the surprise. Inside a single function, "discountApplicationStrategy" (FIRST, MAXIMUM OR ALL) decides which of that function's own candidate discounts get applied, useful when one function's logic could discount several lines at once. Whether two entirely separate discounts, say a VIP membership discount and a promo code from a different app, combine on the same order is a different setting entirely: "combinesWith" configured on each discount. If both discounts allow combination, both apply. If they don't, Shopify's engine automatically picks whichever single discount is worth more to the customer.



Shopify Scripts

Shopify Functions

Language

Ruby

Rust or JavaScript, compiled to WebAssembly

Where it lives

Script Editor, Shopify admin

Distributed as an app

Plan availability

Shopify Plus only

All plans, via public apps

Multiple discounts

One script sees the whole cart

Isolated functions, combined via strategy rules

Status

Deprecated, stopped executing June 30, 2026

Current standard

Why Discount Stacking Behaves Differently Now

A store credit or membership discount that used to stack cleanly with a promo code under Scripts can now lose to it, cancel it out, or apply on top of it depending entirely on how the discount node is configured. This is the part of the migration nobody wrote about at length, and it's exactly where retention programs get exposed.

Think about a typical VIP setup: a member gets an automatic 15% discount on every order, funded by their subscription. A marketing team runs a 20% off sitewide promo for a flash sale. Under the old Scripts model, a developer decided explicitly how those two combined, usually the better one won, applied cleanly, end of story. Under functions, if the VIP discount and the promo code are both configured to allow combination ("combinesWith"), both apply together, which can stack into a bigger discount than anyone intended. If either one is set to not combine with the other, Shopify's engine picks whichever single discount saves the customer more, which is exactly how a 20% flash-sale code can silently outrank a 15% VIP discount that was supposed to be the store's best offer.

Store credit sits outside this problem entirely, which is worth calling out because it's a common point of confusion. Store credit isn't a discount function at all. It's applied as a payment method at the order level, after every discount has already been calculated. That's a structural difference worth understanding before assuming a credit-based membership program needs to fight for position in the discount stack the way a percentage-off VIP discount does.



Where Merchants Get This Wrong

The most common mistake is treating discount functions like Scripts with new syntax, when the actual mental model is closer to running several independent programs that each need to be told explicitly how to coexist. A few patterns show up repeatedly:

  1. Configuring a loyalty or membership discount and a promotional discount as separate product-level functions, then being surprised when only one applies to a shared line item.

  2. Building a function that queries large product collections on every run, which can time out or fail outright on collections with thousands of products. Functions have fixed resource limits, and a poorly scoped query burns through them fast.

  3. Writing functions in JavaScript for a store with big carts, when Shopify's own guidance is that Rust handles large cart volume more reliably because of its lower memory overhead.

  4. Assuming the migration is a code-only project and skipping the business decision of which discount should actually win when two now-isolated functions both want the same customer.

Do You Need a Developer to Build a Discount Function?

Not for standard use cases. Tiered pricing, BOGO, free-gift-with-purchase, and shipping promos are all available through App Store apps already built on the Discount Function API, with no code required. Custom stacking logic tied to a specific membership model, or rules no app already covers, is where a private function and a developer earn their keep. For a Shopify Plus store running something as specific as store-credit-funded membership pricing sitting alongside promotional discounts, that's usually not a five-minute app install. It's a deliberate decision about combination strategy, tested against real carts before it goes live.

For everything short of that, a visual editor closes the gap between "needs a function" and "needs a developer." Subscribfy's Flowly: Discount Functions is a free app, launched on the Shopify App Store in July 2026, that turns product, order, and shipping discount logic into a node-based canvas: connect an Initial node to a Branch for your conditions, then to a Rule node that pairs an action with a target. One shared Shopify Function reads every rule a merchant builds and applies it at checkout, so adding a new discount is a configuration change, not a new function to deploy. When more than one candidate matches, a selection strategy decides the winner: First or All across every discount class, plus Maximum and Minimum on product discounts specifically, for picking the biggest or smallest eligible saving. It's built for exactly the merchants who read this far and want the combination-strategy problem solved without hiring for it.

FAQ

What is the difference between a discount code and a discount function?

A discount code is what a customer types in; a discount function is the logic that decides what happens once a discount, code-based or automatic, is triggered. A single function can power either kind.

Can I still use Shopify Scripts in 2026?

No. Shopify Scripts stopped executing entirely on June 30, 2026, and merchants who hadn't migrated by then lost that checkout logic without warning.

Do non-Plus stores get access to discount functions?

Yes. Any store on any plan can install a public app from the Shopify App Store that contains a discount function. Custom, privately built functions still require Shopify Plus.

How many discount functions can run on one store?

Up to 25 discount functions can be active on a single store, all running concurrently and independently of each other.

Why did my VIP discount stop stacking with a promo code after migrating from Scripts?

Because discount functions don't share awareness of each other the way a single Script did. Whether two separate discounts combine is controlled by "combinesWith", a setting on each discount, not by the FIRST/MAXIMUM/ALL strategy (that setting only governs candidates inside one function). If the discounts aren't set to combine, Shopify automatically applies whichever single discount is worth more to the customer.


Image

Book a meeting with our sales team now!

Create predictable revenue from the customers you already have.