Skip to content
Store slow, dated, or hard to edit? Request a Store Diagnostic
Running B2B on spreadsheets or email? Plan Your B2B Project
App & Plus Dev

Script-Based and Function-Based Discounts on Shopify Plus: What Changed

If your Shopify Plus store has custom discount logic that’s been quietly running since before 2022, tiered wholesale pricing, buy-X-get-Y rules, or customer-tag-based discounts, there’s a reasonable chance it’s still built on Shopify Scripts. And there’s an equally reasonable chance nobody on your team has looked closely at whether that’s a problem yet.

It is worth looking at. Shopify Scripts, the Ruby-based checkout customisation system that used to be the standard way Plus merchants built custom discount, shipping, and payment logic, has been deprecated in favour of Shopify Functions. This isn’t a cosmetic rename, it’s a different underlying architecture, and merchants still running Scripts are on borrowed time before Shopify enforces the migration on its own schedule rather than yours.

This post explains what actually changed, why it matters for merchants with legacy discount logic, and what a sensible migration path looks like.

What Shopify Scripts Were

Scripts let Plus merchants write custom Ruby code that ran at checkout to modify line item pricing, available shipping rates, or available payment methods, based on conditions the merchant defined, customer tags, cart contents, order value, and so on. They were powerful and flexible, but they had real structural limitations:

  • Scripts ran directly on Shopify’s checkout, written in a general-purpose scripting environment rather than a defined, sandboxed structure, which made them harder to test, harder to review for performance impact, and harder to keep secure at scale.
  • They were Plus-exclusive, with no path for smaller merchants to access similar customisation.
  • They were tightly coupled to the older checkout.liquid based checkout, which itself was on a deprecation path as Shopify moved toward Checkout Extensibility.

What Shopify Functions Are, and Why They Replaced Scripts

Functions are Shopify’s replacement approach to the same problem, custom checkout logic, but built on fundamentally different architecture:

  • Defined extension points. Instead of arbitrary code running anywhere in checkout, Functions plug into specific, well-defined points: product discounts, order discounts, shipping discounts, delivery customisation, payment customisation, and cart/checkout validation. This makes behaviour more predictable and easier for Shopify to guarantee performance and security around.
  • Compiled, sandboxed execution. Functions are typically written in languages that compile to WebAssembly (commonly JavaScript/TypeScript or Rust), which run in a tightly sandboxed, high-performance environment. This is part of why Shopify can offer stronger reliability guarantees than it could with open-ended Scripts.
  • Compatibility with Checkout Extensibility. Functions are designed to work with Shopify’s current checkout extension model, rather than the legacy checkout.liquid approach that Scripts depended on. If your store is still relying on Scripts, there’s a real chance you’re also carrying other legacy checkout customisations that need the same migration attention.
  • Broader access over time. Where Scripts were Plus-only, Shopify has progressively made certain Function types available more broadly, reflecting a general platform shift toward Functions as the standard mechanism rather than a Plus-exclusive perk.

Why This Isn’t Just a “Nice to Have Someday” Migration

A few reasons this deserves real priority rather than sitting on a someday list:

  1. Scripts are on a deprecation timeline Shopify controls, not you. Merchants who wait for a forced cutover typically end up doing an urgent, unplanned migration under time pressure, which is a worse outcome than a planned one on your own schedule.
  2. Checkout Extensibility migration and Scripts migration are connected. If your store hasn’t fully moved off checkout.liquid customisations, discount Scripts are frequently tangled up with other legacy checkout code that also needs attention. Treating it as one project rather than piecemeal fixes is usually more efficient.
  3. Functions genuinely behave differently in edge cases, so a like-for-like “just port the logic across” migration needs proper testing, a discount rule that worked correctly in Scripts can produce a subtly different result in a Function if the rewritten logic doesn’t account for how cart line item data is structured differently in the Functions input schema.

What the Migration Actually Involves

For a Plus merchant with legacy discount Scripts, a realistic migration sequence looks like this:

  1. Audit every active Script, not just the obvious ones. Scripts can exist for line item discounts, shipping discounts, and payment gateway customisation separately, check all three categories, since it’s common for merchants to remember the discount Script but forget a shipping or payment Script was also deployed years ago.
  2. Document the exact business logic in plain language for each Script, what conditions trigger it, what it changes, and any edge cases (excluded products, minimum thresholds, tag-based eligibility) the original developer may not have documented.
  3. Map each Script to the correct Function extension point, a line item discount Script generally maps to a product or order discount Function; a shipping Script maps to a shipping discount or delivery customisation Function.
  4. Rebuild the logic as a Function, typically in JavaScript/TypeScript or Rust, using Shopify’s CLI and local testing tools.
  5. Test extensively on a development store, specifically checking edge cases: empty carts, single-item carts, carts mixing eligible and ineligible products, and customers who qualify for multiple discount conditions at once.
  6. Run the Function in parallel where possible, or at minimum do a controlled cutover with close monitoring immediately after activation, since discount and shipping logic errors are highly visible to customers in real time.
  7. Decommission the old Script only once the Function has been verified in production for a reasonable period.

This is meaningfully more involved than a typical app configuration change, because it touches checkout, the part of the store where bugs are most expensive and most visible. It sits squarely in the kind of work we do as part of Shopify Plus development, since it requires both an understanding of the legacy Scripts environment and current Functions architecture, plus the checkout-testing discipline to migrate it without breaking pricing or shipping for real customers mid-transaction.

Common Discount Patterns That Need Careful Rebuilding

Some specific patterns worth flagging because they’re common causes of subtle bugs during migration:

  • Percentage-off tiers based on cumulative cart quantity across multiple product variants, the Functions input schema groups cart data differently than Scripts did, so quantity-summing logic needs to be rewritten carefully, not just translated line by line.
  • Stacking rules between automatic discounts and discount codes, Shopify’s discount combination rules (combinesWith settings) work differently under Functions and need explicit configuration, rather than relying on whatever Scripts happened to do implicitly.
  • Customer-tag-based eligibility checks, confirm the Function actually has access to the customer data it needs at the relevant extension point; not every Function type receives full customer object data by default.

Performance and Reliability Differences Worth Understanding

Beyond the architectural change, merchants who’ve migrated report a genuine difference in how Functions behave in production compared to Scripts, and it’s worth understanding why before you migrate, not just accepting it as a vague claim:

  • Functions run in a sandboxed WebAssembly environment with defined resource limits, which means Shopify can guarantee execution speed and reliability in a way that was harder to promise with open-ended Ruby Scripts running arbitrary logic. In practice, this generally translates to more consistent checkout performance, particularly under high traffic like BFCM, when discount and shipping logic needs to evaluate reliably for every single checkout without adding meaningful delay.
  • Functions have a clearer, more constrained input/output contract. Scripts could technically access and manipulate a broad range of checkout data in flexible ways, which was powerful but also made it harder to predict exactly what a given Script would do in an edge case nobody tested for. Functions’ defined schema makes behaviour more predictable and testable, at the cost of some of that open-ended flexibility.
  • Error handling is more structured. A failing Script could, in some cases, cause unpredictable checkout behaviour. Functions are designed with clearer failure modes, generally either not applying the intended discount/change or falling back to a default behaviour, rather than the checkout process encountering the kind of undefined behaviour that could occur with legacy Scripts.

This isn’t a purely technical detail, it’s directly relevant to how much testing confidence you can have once the migration is done, and it’s part of why the migration is worth treating as a proper project rather than a quick like-for-like port.

Auditing Your Store the Right Way

If you’re not certain what’s currently running, here’s a practical way to check rather than guessing:

  1. Check your Shopify admin’s discount and automatic discount settings for anything referencing a Script or custom app that isn’t a recognisable third-party app you remember installing.
  2. Ask whoever built your original custom checkout logic (an in-house developer, a previous agency, or a freelancer) directly whether Scripts were used, and request documentation if any exists.
  3. Review your Partner or development store’s app and extension list for any Script-related entries that might not be obvious from the merchant-facing admin alone.
  4. If in doubt, request a technical audit rather than assuming your store is clear, Scripts can be quietly running in the background for years without anyone on the current team being aware they exist, particularly after staff or agency changes.

When Should You Prioritise This?

If any of the following apply, this migration should move up your priority list rather than waiting:

  • You’re not certain whether your store still has active Scripts running (worth a direct audit rather than assuming)
  • You’re planning any other Plus-level replatforming or theme work, since bundling the Scripts migration into a broader technical project is usually more efficient than doing it in isolation
  • Your discount logic is business-critical (wholesale tiering, high-value BOGO campaigns) and a forced, rushed migration would be genuinely disruptive

FAQ

Are Shopify Scripts completely shut off now?
Shopify has been actively deprecating Scripts in favour of Functions, with migration guidance and timelines communicated to affected merchants. If you’re unsure of your store’s current status, check directly in your Shopify admin or with your development team rather than assuming Scripts still work exactly as before.

Can I just copy my Script code into a Function?
No, Scripts and Functions use fundamentally different languages, execution models, and data input structures. The business logic can be preserved, but the code itself needs to be rebuilt for the Functions framework, not ported directly.

Will migrating from Scripts to Functions change how my discounts look to customers?
It shouldn’t, if the migration is done correctly, the goal is identical behaviour from the customer’s perspective, just running on new infrastructure. This is exactly why thorough edge-case testing before cutover matters; customers should notice nothing changed.

Do I need Shopify Plus to use Functions?
Certain Function types were originally Plus-exclusive but Shopify has broadened access to some Function categories over time. Check current plan-level availability for the specific extension type you need before assuming it requires Plus.

How urgent is this if my Scripts still seem to be working fine?
“Still working” isn’t the same as “safe long-term” on a platform actively deprecating the underlying system. The safer approach is a planned migration on your own timeline rather than waiting for Shopify to force the issue, which tends to happen with less notice than merchants would like.

Not Sure What’s Running on Your Checkout?

If you’re not confident whether your store still depends on legacy Scripts, or you want a clear migration plan before Shopify forces the issue, book a call and we’ll help you audit what’s actually there.

Niraj Raut
Written by Niraj Raut SEO Manager

Niraj Raut is the SEO Manager and co-founder at Nexly. He helps Australian Shopify and Shopify Plus brands earn durable organic growth through technical SEO, search-led store architecture and content that ranks. He writes about what actually moves rankings for ecommerce.

Connect on LinkedIn
Have a Shopify project? Chat with us, takes 30 seconds.