Promotions are where most Shopify stores accumulate their debt. The first campaign needs a discount that the native tools cannot express, so an app goes in. The next one needs something slightly different, so a second app goes in, or the first one gets a workaround. Two years later there are four apps, a spreadsheet explaining which one to use, and a developer on call every time marketing wants to run a sale.
Intelligent Change needed the opposite. The brand behind the Five Minute Journal runs seasonal campaigns, bundles and tiered offers across a catalogue that sells in several regions, and the team needed to run them without development support each time. That requirement decided the architecture.
Why Functions
Shopify Functions are the mechanism Plus stores use to change how checkout calculates discounts, shipping and payment options. Unlike an app's discount, a Function runs inside Shopify's own pricing pipeline, so it applies at the same moment and with the same reliability as a native discount. Unlike Scripts, which they replaced, Functions work with the current checkout and with checkout extensibility.
The practical difference for a merchant is that the logic is yours. It is written once, deployed as part of an app you own, and configured through the discounts interface the team already uses. There is no monthly subscription for the privilege of running a tiered discount, and no third party between your pricing rules and your checkout.
What was built
The pricing logic on Intelligent Change's store handles the shapes of promotion the team actually runs.
Tiered discounts. Buy more, save more, with the tiers set by the team in the discount configuration rather than in code. A Function reads the cart, works out which tier applies and returns the discount. Changing the thresholds for a campaign is a configuration change, not a deployment.
Bundles. Intelligent Change sells products that belong together, and bundling them at a price is a core part of how they sell. The bundle logic identifies qualifying combinations in the cart and applies the bundle price, so the customer sees the right number on the cart and at checkout without any client-side trickery.
Campaign switching. Promotions have start and end dates, and the team runs several a year. Because the logic lives in discounts the team controls, a campaign can be scheduled, activated and retired without touching the theme.
The theme's job is presentation: showing the tier a customer is about to reach, making the bundle saving visible on the product page, and keeping the cart honest about what will be charged. The Function's job is the number. Keeping those responsibilities separate is what makes the whole thing maintainable.
What it looks like for the team
The point of all of this is a marketing team that can move. When a campaign idea comes up, the question is no longer whether the store can do it. It is which discount to configure and when to switch it on. The design and the product pages were built to carry campaign messaging, so the promotion looks like part of the brand rather than a banner bolted on top.
That matters more for a brand like Intelligent Change than for most. The products are about intention and care, and a store that felt hacked together for a sale would undermine them.
The rest of the build
The store was built from scratch on Shopify Plus over twelve weeks, designed around the product photography and the brand's editorial feel. Internationalisation was part of the scope from the start, since the audience shops across several regions, and the pricing logic works per market rather than assuming one currency.
If you are still on Scripts
Shopify Scripts are being retired, and every Plus store still relying on them for discount, shipping or payment logic has a migration ahead. The good news is that the migration is also the opportunity to do what Intelligent Change did: replace a tangle of app-driven promotions with logic you own, configured by the people who run the campaigns.
Scripts to Functions migration has its own page, including what usually survives the move and what does not.
Related service: Scripts to Functions



