Shopify Scripts stopped running on June 30, 2026. If your Plus store still had Ruby Scripts handling discounts, payment logic, shipping rules, or checkout behavior, those rules are silent now. You will see it as wrong discounts, shipping logic that no longer applies, or payment methods that used to hide and no longer do. Below is how we inventory what the Scripts did, decide where each rule belongs now, and rebuild it with Shopify Functions and the newer discount combination support.
One update makes this easier. Shopify's 2026-04 GraphQL Admin API added support for applying multiple product discounts to a single cart line, and Shopify said outright that it shipped this to help merchants finish migrating Scripts before the June 30, 2026 sunset.
Shopify Scripts and storefront ScriptTag are separate systems with separate deadlines. Apps that inject storefront JavaScript through ScriptTag now need the October 2026 ScriptTag migration checklist.
The short answer
Do not migrate Scripts by copying the code line for line. Write down the business rules first: edge cases, exclusions, app dependencies, and what finance expects to see in reports. Only then decide which parts belong in Shopify Functions, discount combinations, checkout extensions, app configuration, or a plain native Shopify setup.
Why discount scripts are hard to replace
Most Scripts were written years ago to fix something urgent. Bundle pricing, VIP discounts, wholesale rules, region-specific offers, free gift logic, subscription exclusions, payment hiding, shipping changes, custom B2B behavior. The code did its job for long enough that nobody on the merchant team remembers every rule it contained, and now that it has stopped, the only record of those rules is the code itself.
- ✓Rules that only apply to certain tags, collections, markets, or customer groups
- ✓Scripts that depend on cart attributes or line item properties set by the theme
- ✓Discounts deliberately blocked from combining with subscriptions or sale items
- ✓Reporting or finance expectations that are nowhere in the code
- ✓Overlap with apps that have changed since the script was written
- ✓Checkout behavior that now needs Functions, checkout UI extensions, or native settings
What the new multiple-discount support changes
Real stores stack logic. A customer qualifies for a campaign discount and a product-specific discount at the same time, or a bundle has to coexist with a membership offer. Multiple product discounts on one cart line make those migrations practical where they were awkward before. It still does not translate old Ruby behavior into a correct Function setup for you; someone has to read the Script and decide what it was actually doing.
Not every Script deserves a direct migration
Copying old logic onto a new platform without asking whether the rule is still useful is where migrations go wrong. Plenty of Scripts were workarounds for limitations Shopify has since fixed, and a native discount, a shipping setting, Shopify Flow, or a narrower app will cover them. The ones that still earn their keep and need deterministic checkout behavior should become Functions.
- ✓Keep it native when Shopify settings or native discounts can handle the rule cleanly
- ✓Use Flow when the logic is operational and does not need to run inside checkout
- ✓Use an app when the rule belongs to a mature category such as subscriptions, loyalty, or complex promotions
- ✓Use Shopify Functions when the rule must execute reliably in the checkout path
- ✓Retire it when nobody can explain why the rule exists
- ✓Discount logic: bundles, thresholds, VIP rules, customer tags, subscription interactions, and market-specific promotions
- ✓Shipping logic: free shipping thresholds, rate hiding, regional rules, product exclusions, and carrier-rate cleanup
- ✓Payment logic: payment method hiding, B2B rules, risk-based conditions, and regional payment preferences
- ✓Cart assumptions: line item properties, gift cards, subscriptions, bundles, and app-created items
Migration checklist
- ✓Export every active and inactive Script and label what each one did in plain English
- ✓List every customer tag, product tag, collection, market, selling plan, and cart attribute the logic reads
- ✓Build test carts for the top revenue scenarios and for the weird edge cases
- ✓Map each rule to Shopify Functions, native discounts, discount combinations, checkout extensions, shipping settings, or app logic
- ✓Test stacking, subscription exclusions, sale products, gift cards, draft orders, B2B customers, and international markets
- ✓Check analytics and finance reporting after the migration as well as storefront behavior
- ✓Freeze promo changes close to launch so the migration target stops moving
Blocking checkout is no longer something to assume
If a validation rule used to live in a Script, check this before you rebuild it as a UI extension. Checkout UI extensions that support blocking now default to non-blocking unless the merchant explicitly allows it. Shopify's own recommendation for custom checkout validation is a validation Function, because Functions run on every supported checkout.
So if a rule has to stop a checkout, put it in a validation Function. Use the UI extension to explain to the shopper why they were stopped, and treat it as a display layer rather than the thing enforcing the rule.
How Thought Bulb approaches it
We start by turning the old Script behavior into a rules document a merchant can read. Then we build a test matrix, pick the implementation surface for each rule, migrate the logic, and verify the carts that matter. We are aiming for discount behavior the merchant can understand, operate, and trust now that Scripts are gone, which is a different target from a tidier version of the old code.
"A discount migration is a business-rule migration first and a code migration second."
— Thought Bulb
Shopify's April 2026 changelog has the details on the multiple product discount update for merchants migrating Scripts.
Read Shopify's discount update →If a discount, shipping, or payment rule went quiet after the Scripts sunset, we can work out what the old logic did and rebuild it as Functions before your next campaign.
Plan a Shopify Scripts migration →



