In short: Shopify Scripts stopped running on 30 June 2026, so historical orders are the only record of what a Script charged. Calibrate a Ruby shim on them, compare it with the ported Function over many test carts, then confirm a sample in real checkouts.
Shopify Scripts stopped running on 30 June 2026, so every Shopify Plus store that discounted with a line item Script has had to replace it, either with an app or with a discount Function of its own. If your Function was written by translating the Ruby line by line, the story is probably familiar: the Function deploys, the tests that came with it pass, and the discount looked right on the handful of carts someone tried before launch.
None of that shows the port gives the discounts the Script gave. A discount that is one cent out on a few hundred orders a week, a promotion that now refuses to stack with a discount code it used to stack with, or a threshold that is now measured against a different subtotal will not show up in a test written to match the port's own code. This guide explains how to collect that evidence: whether an app or a custom Function suits each Script, what to use as the reference now that the Scripts runtime has gone, how to build the carts to compare, where Scripts and Functions are designed to behave differently, and how to keep the check independent of whoever wrote the port. It describes Shopify's documentation as checked in October 2026, when the current Function API version was 2026-10.[1]
What happened to Shopify Scripts on 30 June 2026?
Shopify's developer changelog set out the final dates on 9 April 2026: editing and publishing new Scripts would stop on 15 April, and on 30 June "All Shopify Scripts will cease to execute entirely."[2] The help centre now says it in the past tense: any Scripts still published "have been deactivated and no longer work."[3]
Two things from the Scripts era are still worth collecting before anything else.
The Scripts report. Shopify's help centre still describes a Shopify Scripts customizations report, reached from the Script Editor app, that lists the customisations that were active before 30 June. It groups them into payment gateways, shipping and product discounts, links each one to its source file, and suggests either an existing app built on Functions or a Functions API guide. It can be exported as a CSV file.[3] Export it and keep it with the migration, because it is the store's own inventory of what has to be matched.
The Script source. The Ruby is the closest thing left to a specification. Scripts used "a limited version of the Ruby programming language", could not make web requests or database calls, and could not use time or random numbers.[4][5] That makes the old logic easier to reason about than most legacy code, but it does not make it a complete description of what customers were charged, for reasons covered below.
Scripts were available only on Shopify Plus.[6] Functions reach further: stores on any plan can use public App Store apps that contain Functions, but only Plus stores can use custom apps that contain them.[7] A store that ported its own Script into its own app is therefore still a Plus store running a custom app, which is the case this guide assumes.
What replaces each Shopify Script in Functions?
Shopify does not publish one general mapping table. The help centre puts the recommendation for each Script inside the store's own report instead.[3] The Function API pages make the broad mapping clear enough.
| What the Script did | Where it lives now | What to watch |
|---|---|---|
| Line item discounts and price reductions | Discount Function API, product and order classes | The Function proposes discounts; Shopify decides how they combine |
| Overriding a line item's displayed price, title or image | Cart Transform API (lineUpdate) |
Only Plus and development stores can use apps with lineUpdate |
| Shipping discounts | Discount Function API, delivery target | One shipping discount per order |
| Renaming, hiding or sorting shipping methods | Delivery Customization API | Separate Function from the discount |
| Renaming, hiding or reordering payment methods | Payment Customization API | Separate Function |
| Rejecting a discount code with a message | Discount Function API, enteredDiscountCodesReject |
Only when the Function backs an automatic discount |
The Discount Function API lets one Function apply savings across the product, order and shipping classes, which Shopify's changelog describes as "a use case historically supported by Shopify Scripts".[8][1] Changing the price a line shows, rather than discounting it, belongs to the Cart Transform API, and only development stores or Plus stores can use apps with lineUpdate operations.[9] Shipping and payment changes have their own Function APIs, and only one shipping discount can apply to an order.[10][11][12] A code rejection, which a Script did with a single method call, now needs a discount Function that backs an automatic discount.[13][1]
Some Script methods have no counterpart that I could find in the current Function APIs: change_properties, which rewrote a line item's properties, and split, which divided one line into two.[13] If a Script relied on either, the port is a redesign, not a translation, and parity testing should treat those carts as a separate decision for the business owner.
Should you use an app or build a custom Function?
Shopify's help centre gives two routes for each customisation in the Scripts report, and says they can be combined: install an existing app built on Functions, or build your own solution with Functions.[3] The report can list recommended apps for a customisation. It says some customisations can be recreated by installing an existing app, while others might need a manual rebuild from a Functions API guide.[3] Five questions decide which route a given Script should take.
- Do the default discounts already cover it? Shopify describes apps as the way to create discount types beyond its default ones, for example a single discount that carries more than one saving.[14] Check what a default discount with the right combination settings can do before you build or install anything.
- Which plan will it run on? Stores on any plan can use public apps that contain Functions, but only stores on Shopify Plus can use custom apps that contain them.[7]
- Is the Script ordinary or unusual? A Script that maps to one documented discount type is the natural candidate for an existing app. A Script that relies on
change_propertiesorsplit, for which I found no counterpart, or that packs several promotions into one file, is more likely to need a custom Function or a redesign.[13] - Who maintains it? Shopify releases a new API version every quarter, Function APIs are among the versioned ones, and each stable version is supported for a minimum of 12 months.[15] Shopify deprecated its earlier product, order and shipping discount Function APIs as of version 2025-04, and a Function using them had to move to the unified Discount Function API before version 2026-04, so a custom Function needs an owner who reads the changelog.[16] A Function also declares its own API version in its extension configuration, and the Function API schema can change between versions, so it needs its own check at each upgrade.[17] The iLogr guide to the 2026-10 release lists what to look at.[18] With an app, that work belongs to its developer, and so does the timing of any change in its behaviour.
- Who builds it? Custom apps created in the Shopify admin do not support Shopify App Bridge, so a custom Functions-based app has to be created in the Dev Dashboard and then connected to the store.[3] Shopify's help centre says app developers and Shopify Partners can build custom apps for a store.[19]
Either route needs the same test. An installed app has no source to compare with the shim, but historical orders, the cart corpus and the development-store checkout all test its behaviour unchanged. The first questions to put to its developer are the ones the rest of this guide keeps returning to: how it rounds, which currency it works in, and how it combines with other discounts.
Shopify Scripts vs Functions: why can a faithful port charge differently?
A line item Script and a discount Function can look alike line by line. They run in very different models, and a translation that copies the logic faithfully can still charge different amounts. These are the differences that matter most for discounts.
A Script changed prices; a Function proposes discounts. A line item Script changed line prices directly, for example with change_line_price, and ran again each time an item was added, removed or changed.[13][4] A discount Function returns candidates with a selection strategy, and Shopify decides what applies. Shopify's reference says that discount Functions run concurrently "and have no knowledge of each other", and that a Function's candidate combines with other discounts according to the combination rules set on the discount node.[1] Part of the behaviour that used to be in the Ruby is now in configuration, outside the code you are reading.
Script discounts ignored combination settings. The help centre lists "Discounts added to an order using the Scripts API" among the discounts that always apply, regardless of the combination settings of other discounts on the order.[12] A Function-based discount has no such privilege. Discounts do not combine unless each one is configured to, and when discounts cannot be combined, Shopify applies the best discount for the customer's cart.[12] A Script promotion that always stacked with a staff code can quietly become a promotion that competes with it.
The subtotal moved. Scripts saw the cart subtotal after line item changes but before discount codes, and the help centre says Scripts "can't access post-discount totals or automatic discounts."[13][5] With native discount combinations, product discounts apply first, order discounts apply to the revised subtotal, and shipping discounts apply last. Two percentage order discounts are both calculated on the original subtotal, and percentage discounts are applied before fixed amounts.[12] A Script's spend threshold therefore read one specific subtotal. In the port, keep the subtotal used to decide eligibility separate from the subtotal Shopify later uses to calculate an order discount. The application order alone does not establish what the Function's threshold check sees: record the input field and target used, then test the rule with other eligible discounts in checkout.[1][12]
The currency moved. Scripts ran in the store's currency: amounts were converted to it before the Script ran and converted back to the customer's currency afterwards.[20] Functions work the other way round. Their input gives money in the customer's displayed currency, their output must be in the customer's currency, and the input offers presentmentCurrencyRate for converting between the two.[21] A ported rule that hard-codes "10 off" or "over 100" now means ten or a hundred of whatever currency the customer sees, unless the port converts it.
Allocation is explicit. In a discount Function, a fixed amount is applied once across the entitled items unless appliesToEachItem is true, and a target with no quantity applies to the full quantity of the matching line.[1] A Script that reduced each line's line_price might have applied a fixed reduction per line, a reduction per unit multiplied by quantity, or a percentage of the line total. Inspect that calculation before choosing appliesToEachItem, and include a line with quantity greater than one in the corpus.[13][1]
The first match is a strategy. If a Script looped through promotions and stopped at the first one that applied, the Function has to express that as a selection strategy: product discounts can use FIRST, MAXIMUM or ALL, and order discounts FIRST or MAXIMUM.[1] The wrong one gives the right answer for every cart with a single eligible promotion and the wrong answer for the rest.
The limits are different. A Function runs inside fixed limits, among them 11 million instructions, 128 kB of input and 20 kB of output for carts of up to 200 lines, with the limits scaling up for larger carts.[17] A Function can fail by raising an exception, exceeding memory or time limits, or returning output that does not match its schema.[22] A port that is correct on a ten-line cart may still fail on the largest carts the store sees.

What do you test the port against without the Scripts runtime?
Parity testing compares the new Function with something. Since 30 June there is no Scripts runtime to compare it with, so the first decision is what stands in for it. There are three candidates, and they answer different questions.
Historical orders are the only record of what the real runtime did. A discount created by a Script is recorded on the order as a ScriptDiscountApplication, which keeps the title "as defined by the Script", the value, the allocation method and the target selection.[23] The amounts actually taken off each line are held separately, as discount allocations in both shop and presentment currencies.[24] Those orders are real evidence, but they have limits. Every order placed before 30 June is now more than 60 days old, and the Admin API only returns the last 60 days of orders by default; older orders need the read_all_orders scope, which Shopify must approve.[25] Orders also cover only the carts that customers completed, so the unusual carts are under-represented, and an order does not necessarily record every input the Script read, such as a customer tag that has changed since.
A reference implementation of the Ruby, often called a shim, can answer any cart. It means running the old Script source in ordinary Ruby, with stand-in versions of the cart, line item and Money objects the Scripts API provided. It is the most useful tool in the whole exercise, because it lets you feed the old logic carts that nobody ever ordered. It is also the easiest one to over-trust, and this needs saying plainly: a Ruby shim is not the Scripts runtime. The stand-in objects are your reconstruction. The Scripts API reference documents Money in cents and documents multiplying a Money by a number, but I found no statement of how a fractional cent was rounded.[13] The runtime also converted currency before and after the Script ran.[20] When the Function and the shim agree on the tested carts, that is evidence that the Function matches your reconstruction for those cases. It does not establish agreement on untested carts or prove that it matches what Shopify charged.
The business rule is the third reference. Someone decided what the promotion was meant to do. Where the Script did something else, the business owner should decide whether to keep the old behaviour or fix it now, and the decision should be written down.
The three work together. Calibrate the shim first, by rebuilding the carts of a sample of historical orders, running them through the shim and comparing the result with the recorded allocations. Only when the shim reproduces those orders, to the cent or within a tolerance you agreed before running it, use it to judge carts that never existed. Every disagreement between shim and order is a finding about the shim, or about the order data, not about the Function.
Which carts should a discount parity test cover?
The corpus of test carts decides what the comparison can find. A corpus of tidy carts with round prices will report perfect parity for a port that is wrong in production. Build it from two sources.
Hand-picked edge cases, one or more per rule in the Script:
- thresholds exactly at, one cent below and one cent above each spend or quantity limit
- prices that do not divide cleanly, such as three units of 9.99 with 15% off, or a fixed amount spread over three items
- the same product on several lines, which line item properties can cause, and a mix of eligible and ineligible lines
- each customer condition the Script checked, such as tags, and a guest checkout
- no discount code, then a product code, an order code, a shipping code and a code the Script used to reject
- the store currency and at least one other presentment currency, with the conversion rate the Function will see
- the largest cart the store has seen, and one above 200 lines, for the limits
Generated carts, built from random combinations of products, quantities, prices, customers, codes and currencies. Generate them from a recorded seed, so that a failing cart can be rebuilt exactly, and keep every failing cart as a permanent case.
Shopify's testing guide shows the format that makes this practical. Each fixture holds the Function's export name, its target, an input that matches the Function's input query, and the expected output, and an integration test compiles the Function to WebAssembly and runs it against every fixture in the folder.[26] The same input, translated into the shape your shim expects, is what you feed the shim.
How do you test a discount Function against the old Script?
First, the compiled Function against the shim, offline. Shopify CLI's app function run executes the Function once with a JSON input, so you can test logic locally against known or logged inputs, and the integration test helpers run the compiled module and, from version 1.1.0, report the instruction count.[26] Use the compiled WebAssembly for the parity run, not unit tests alone: Shopify notes that unit tests do not run in WebAssembly, "which in rare cases might cause different results than what's found in production."[26] The shim produces new line prices and the Function produces discount candidates, so compare the shim's intended reductions with the Function's candidates, including their targets, quantities, values and selection strategies. If the harness calculates per-line amounts or totals from those candidates, label them as modelled amounts and record its assumptions about selection, combination, rounding and allocation. Confirm Shopify's final amounts separately in checkout.[1][26]
Second, the whole checkout, on a development store. Combination settings, other automatic discounts, discount codes, the order in which discount classes apply, and currency conversion all happen after the Function returns, so only a real checkout shows the final amount. Take a sample that includes every class of difference the offline run found, every rounding case and every stacking case, and record the totals a checkout actually shows. While app dev is running, the CLI writes a log file for each Function execution on the development store, and app function replay re-runs the Function with a logged input.[26] Those log files can become fixtures directly.[26]
Third, production. Function runs are visible in the Dev Dashboard, for production stores as well as development stores.[26] Shopify describes Functions as deterministic: given the same input, they always return the same output.[22] When a customer reports a wrong discount, retrieve the logged input and output using the required access scopes or staff or collaborator access to the store, and preserve the Function build that produced them. Replay that input against the same build to reproduce the Function output; investigate the final checkout amount separately. Add the case to the corpus with an independently reviewed expectation before writing the fix.[22][26]
Sort every difference into one of three groups:
- a defect in the port, to be fixed
- an accepted platform difference, such as stacking that now follows combination settings, written down and signed off
- a Script behaviour that is deliberately not carried over, signed off by the business owner
Anything left unsorted is not parity; it is an open question.
Field note: a test with Shopify's own template. To see how easily a faithful-looking port drifts, Shopify's own Rust template for the Discount Function API, as published in its function-examples repository on 9 December 2025, was compiled and run with Shopify's function-runner 9.2.2 in a throwaway container, with no store and no Shopify account involved.[27][28] The template gives 20% off the cart line with the highest subtotal, chosen with Rust's max_by. Beside it ran a Ruby shim of an equivalent Script, written for the test, which chooses that line with Ruby's max_by. Across 300 seeded random carts built from a 12-product catalogue, the two picked different lines in 14 carts, and all 14 were carts where two lines tied for the highest subtotal. Rust's documentation says of max_by: "If several elements are equally maximum, the last element is returned."[29] Ruby 2.6.10, in the same test, returned the first. Every candidate carried the same 20%, so a test that checked only the discount value would have passed. Which line the real Scripts runtime picked on a tie is something the shim cannot tell you, because it is ordinary Ruby rather than Shopify's sandbox; only historical orders with tied lines can. The same runs counted 98,553 instructions for a 10-line cart, 1,452,787 for 200 lines and 3,588,583 for 500, against a limit of 11 million for carts of up to 200 lines.[17]

How do you test Shopify Functions discount rounding and stacking?
These two areas produce most of the differences that survive an ordinary test run, and both depend on behaviour that Shopify does not fully document.
Rounding. Shopify's Function API reference describes percentage and fixed discount values, but I found no complete rounding and allocation specification there.[1] A Shopify staff response dated 12 February 2026 does describe percentage discounts as calculated per unit and illustrates rounding down: two units priced at $46.99 with 10% off receive $4.69 off each, leaving $84.60.[30] In the same thread, that per-unit calculation is described as replacing an earlier one based on the total line quantity, and a later staff reply about the notice given says "in this case we incorrectly assessed the severity of this change."[30] That response does not specify every fixed-amount or allocation case, so use it to inform the corpus and confirm the results in development-store checkouts, and rerun that checkout sample from time to time rather than only at launch. The Scripts side is no better documented, as noted above. Even the help centre's own example of a proportional split, a $50 discount across a $50 item and a $100 item, gives $16.50 and $33.50 rather than an exact one-to-two division.[31] So use the documented behaviour where available and verify expected amounts against observation: the historical orders for the Script, and development-store checkouts for the Function. Agree the tolerance before running anything. One workable choice is that the total discount must match to the cent, while one line may differ by a cent where an amount is split; whatever the choice, write it down, so a later reviewer does not decide it after seeing the results.
Stacking. Build a small matrix for each ported discount: on its own; with a product code, an order code and a shipping code; with each other automatic discount the store runs; and with the codes the Script used to reject. Then compare each cell with the Script era. Expect differences, because Script discounts always applied and Function discounts follow combination settings. The help centre also notes that line item and shipping Scripts that read the cart's discounts "aren't compatible with discount combinations".[5] On Plus, product discounts can be configured to combine on the same line item using matching tags, and stores can have at most 25 active automatic discounts; Shopify's Function reference also caps active discount Functions at 25 per store.[12][1] A Script that encoded several promotions in one file may become several discounts that must each be configured to combine, and that configuration is part of what the parity test checks.
How do you keep the parity check independent of the port?
The usual risk in a port is that whoever writes the Function also decides whether it matches, using tests written from the same reading of the Script. Then the code and the test share one misunderstanding of Money, rounding or stacking, and every test passes. A few rules keep the verdict independent:
- Give whoever writes the port the Script source, the report entry and the written business rule, and ask for a list of every assumption made about
Money, rounding, currency and stacking. - Keep the corpus and its expected outputs under a different owner from the Function. The author may propose new cases; a second person adds them.
- Never change an expected output to make a test pass. A changed expectation is a triage decision with a named owner.
- Have someone other than the shim's author check its calibration against historical orders, because the shim is the part most likely to share the port's misunderstanding.
- Keep combination settings and discount configuration under their own change control; they are store settings, not code, and the Function's result depends on them.[12]
The corpus is a data asset: versioned, reviewed and grown from real failures.
Does the Function's language or configuration change the test?
Rust or JavaScript. Shopify recommends Rust when a Function belongs to a public app, handles many line items or is computationally complex, and calls JavaScript "a good starting point" for prototyping; JavaScript is interpreted, so each line costs many more WebAssembly instructions.[32][33] A port that starts in JavaScript and is later rewritten in Rust is a second port, so run the same corpus again after it.
Configuration. If a Script hard-coded its thresholds and product lists, the Function can read them instead from metafields on the discount that owns it, and since API version 2026-04 all Functions can read app-owned metaobjects.[34][35] Moving constants into configuration is a good change, but it adds inputs, so the corpus should include each configuration the store will use.
What should a parity report record?
The output of all this should be a short report kept in the repository with the Function, so the next change can run it again. It should record:
- the Script source and the exported Shopify Scripts customizations report
- the shim version, and its calibration result against a stated number of historical orders
- the corpus: its seed, its size and its hand-picked cases
- the Function build, its language and its highest instruction count on the largest cart
- the tolerance agreed before the run
- every difference, in its group, with the person who signed off each accepted difference
- the combination settings on each discount, and the development-store checkout sample with its totals
A report like that turns "the port matches" into a claim someone can check.
Summary
- Scripts stopped running on 30 June 2026. Export the Shopify Scripts customizations report and keep the Script source before anything else.
- Decide per Script between an app and a custom Function on plan, how unusual the Script was, and who will maintain it. Either route needs the same behaviour test.
- Discount Functions propose discounts; Shopify combines, orders and allocates them. Stacking, subtotals, currency and allocation can all differ from the Script even when the logic is translated faithfully.
- Historical orders are the only record of the real Scripts runtime, and every one is now older than the Admin API's default 60-day window.
- A Ruby shim lets you test any cart, but it is not the Scripts runtime. Calibrate it against orders before trusting it.
- Compare the compiled Function with the shim over hand-picked and generated carts, then check a sample of real checkouts on a development store.
- Keep the corpus and expected outputs under a different owner from the person who wrote the port, and give every accepted difference a named owner.
References
Numbers in square brackets in the text link to these sources.
- Shopify Function API reference: Discount (API version 2026-10) (opens in a new tab).Used for: the API version, selection strategies, combination behaviour, fixed-amount allocation and the 25-Function limit.
- Shopify developer changelog: Shopify Scripts will be deprecated on June 30, 2026 (9 April 2026) (opens in a new tab).Used for: the final Scripts dates: editing stopped on 15 April 2026 and execution on 30 June 2026.
- Shopify Help Center: Transitioning from Shopify Scripts to Shopify Functions (opens in a new tab).Used for: the Shopify Scripts customizations report, its CSV export, the two routes, and the Dev Dashboard rule.
- Shopify Help Center: Shopify Scripts and the Script Editor app (opens in a new tab).Used for: what Scripts were: limited Ruby, no web requests, and a run on each cart change.
- Shopify Help Center: Shopify Scripts requirements and limitations (opens in a new tab).Used for: Script limitations: no post-discount totals and no support for discount combinations.
- Shopify Help Center: International pricing, Discounts (opens in a new tab).Used for: that Scripts were available only on the Shopify Plus plan.
- Shopify developer documentation: About Shopify Functions (opens in a new tab).Used for: which plans can use public apps and custom apps that contain Functions.
- Shopify developer changelog: Introducing the new Discount Function API (21 May 2025) (opens in a new tab).Used for: the unified Discount Function API and its link to what Scripts did.
- Shopify Function API reference: Cart Transform (opens in a new tab).Used for: that changing a line price belongs to Cart Transform, with its Plus restriction.
- Shopify Function API reference: Delivery Customization (opens in a new tab).Used for: where shipping method changes now live.
- Shopify Function API reference: Payment Customization (opens in a new tab).Used for: where payment method changes now live.
- Shopify Help Center: Combining discounts (opens in a new tab).Used for: how discounts combine, the order they apply in and which discounts always apply.
- Shopify Help Center: Shopify Scripts API reference (opens in a new tab).Used for: the Scripts API methods, Money in cents, and the methods with no Function counterpart.
- Shopify Help Center: Creating discounts with apps (opens in a new tab).Used for: apps as the route to discount types beyond the default ones.
- Shopify developer documentation: API versioning (opens in a new tab).Used for: the quarterly release schedule and the 12-month support window.
- Shopify developer changelog: Deprecation of Product, Order, and Shipping Discount Function APIs (21 May 2025) (opens in a new tab).Used for: the deprecated product, order and shipping discount Function APIs and their deadline.
- Shopify developer documentation: Function APIs (resource limits and execution order) (opens in a new tab).Used for: Function limits, versioning, API schema changes and execution order.
- iLogr: Shopify API 2026-10: What Changed, Who Is Affected and How to Upgrade From 2026-07.Used for: what to check on a Function when upgrading to API version 2026-10.
- Shopify Help Center: Customizing your checkout and customer accounts with apps (opens in a new tab).Used for: that app developers and Shopify Partners can build custom apps for a store.
- Shopify Help Center: Scripts for multiple currencies (opens in a new tab).Used for: that Scripts ran in the store currency, converted before and after.
- Shopify developer documentation: Localization practices for Shopify Functions (opens in a new tab).Used for: Function input and output in the customer currency, and the conversion rate.
- Shopify developer documentation: Monitoring and handling errors in production (opens in a new tab).Used for: how Functions fail, and that they are deterministic.
- Shopify GraphQL Admin API reference: ScriptDiscountApplication (opens in a new tab).Used for: how an order records a discount that a Script created.
- Shopify GraphQL Admin API reference: DiscountAllocation (opens in a new tab).Used for: the amounts taken off each line, in shop and presentment currency.
- Shopify developer documentation: Access scopes (read_all_orders) (opens in a new tab).Used for: the default 60-day order window and the approval needed for older orders.
- Shopify developer documentation: Test and debug Shopify Functions (opens in a new tab).Used for: fixtures, local runs, instruction counts, logs and replay for Functions.
- Shopify function-examples on GitHub: Rust template for the Discount Function API (commit of 9 December 2025) (opens in a new tab).Used for: the Rust discount template used in the field note.
- Shopify function-runner on GitHub: release 9.2.2 (4 August 2026) (opens in a new tab).Used for: the function-runner version used to run that template.
- Rust standard library documentation: Iterator::max_by (opens in a new tab).Used for: that Rust returns the last of equal maximum elements.
- Shopify Developer Community: Inconsistent Cents Rounding on Discounts Across Different Stores (Shopify staff replies of 12 February and 23 March 2026) (opens in a new tab).Used for: Shopify staff on per-unit percentage discounts rounded down, and the notice given.
- Shopify Help Center: Amount off discounts (opens in a new tab).Used for: the proportional split example of 16.50 and 33.50 dollars.
- Shopify developer documentation: Language considerations for Shopify Functions (opens in a new tab).Used for: when Shopify recommends Rust, and JavaScript as a starting point.
- Shopify developer documentation: Optimize instruction counts (opens in a new tab).Used for: why JavaScript costs more instructions per line.
- Shopify developer documentation: Metafields for input queries (opens in a new tab).Used for: reading thresholds and lists from metafields on the discount.
- Shopify developer changelog: Metaobject access in Shopify Functions (1 April 2026) (opens in a new tab).Used for: app-owned metaobject access in Functions from API version 2026-04.