Every subscription programme we inherit arrives with the same story attached. It launched well. Sign-ups were strong for two quarters. Then the active subscriber count flattened, billing tickets started arriving faster than the team could answer them, and nobody could explain where the leak was. The founder assumes retention and goes looking for a better email flow.
It is almost never a retention problem. It is an architecture problem that only becomes visible at scale.
Subscriptions are the one part of a Shopify build where a decision made in week two determines whether the programme is still viable in year two. A one-off product page can be redesigned in a sprint. A selling plan structure that has fifteen thousand live contracts attached to it cannot. The data model is load-bearing, and once subscribers are sitting on top of it, your options narrow to migration projects that cost more than the original build.
Australia’s subscription commerce market reached roughly USD 7.9 billion in 2025 and is forecast to keep compounding, which will pull a lot of DTC brands into recurring revenue whether they planned for it or not. The brands that still have healthy subscription revenue in 2028 will be the ones who treated it as a systems build rather than an app install.
This article is about the build decisions. Not whether subscriptions are a good idea, and not which app has the nicest dashboard. The decisions that are expensive to reverse.
The three APIs your programme actually runs on
Whatever app sits on the front of your subscription programme, it is orchestrating three Shopify primitives underneath. Understanding them is the difference between choosing an app and being chosen by one.
The Selling Plan API extends the product model so a variant can be sold on a recurring basis. A selling plan describes a single purchase option: deliver every 30 days, 10 per cent off. Selling plans live inside selling plan groups, and groups are attached to products or variants. This is your catalogue layer.
The Subscription Contract API represents one subscriber’s ongoing agreement. Which lines, which cadence, which delivery method, which discounts, what happens next billing cycle. This is your customer layer.
The Customer Payment Method API holds the vaulted payment credential that recurring charges are drawn against. This is the layer nobody thinks about until they try to change apps, at which point it becomes the only layer that matters.
The critical thing to internalise is that these are Shopify objects, not app objects. Selling plans and contracts belong to your store. The subscriber portal, dunning sequence, retry logic, analytics and merchandising rules belong to the app. That split is the most useful lens for evaluating a vendor, because it tells you exactly what you keep if you leave and what you rebuild.
Build artefact: the ownership map

Before any subscription build starts, we fill this in with the client. It takes twenty minutes and it has prevented more bad vendor decisions than any feature comparison spreadsheet.
| Layer | Owned by | Portable if you switch apps? |
|---|---|---|
| Selling plans and groups | Shopify | Yes, but the new app usually recreates them |
| Subscription contracts | Shopify | Yes, readable via Admin API |
| Vaulted payment methods | Shopify (Shopify Payments) or the gateway | Only if the vault is Shopify’s |
| Subscriber portal UI | App | No |
| Dunning and retry logic | App | No |
| Swap, skip and gift rules | App | No |
| Subscription analytics history | App | Usually export only |
Read the third column carefully. If payment methods are vaulted with a third party gateway rather than Shopify Payments, switching apps means asking every subscriber to re-enter their card. On a base of 8,000 subscribers, expect to lose a meaningful slice permanently. We have seen brands abandon a necessary platform change entirely because of this one row.
Selling plan modelling: the decisions that lock you in
Most subscription programmes are modelled in an afternoon by whoever installed the app. The default is one group per product with two or three delivery intervals, and it works fine at 200 subscribers.
It stops working when the merchandising team wants a prepaid six-month plan at a different discount, a gift plan that does not auto-renew, a founding-member tier that must keep its original pricing forever, and a bundle that draws from three SKUs. Those are four different structural requirements, and retrofitting them onto contracts that already exist is where the cost lands.
The structure we build toward looks like this. Groups are organised by commercial intent, not by product.
Group: replenishment-standard
Plan: every-30-days (10% off, no commitment)
Plan: every-60-days (10% off, no commitment)
Plan: every-90-days (10% off, no commitment)
Group: prepaid-commitment
Plan: prepaid-3-cycles (18% off, billed once, 3 deliveries)
Plan: prepaid-6-cycles (25% off, billed once, 6 deliveries)
Group: founding-member (closed to new sign-ups)
Plan: legacy-monthly (20% off, grandfathered pricing)
Three properties of that structure are doing real work. Groups can be closed to new sign-ups without touching existing contracts, which is how you honour grandfathered pricing without a spreadsheet of exceptions. Prepaid and pay-as-you-go are separated, because they have different billing policies and different cancellation semantics and mixing them into one group produces portal states that are impossible to explain to a customer. And the naming is intent-based, which means when finance asks what founding members are worth, the answer is one query rather than an archaeology project.
A fourth decision worth making deliberately: whether the discount lives on the selling plan or comes from a Shopify Function. Selling plan discounts are simple and visible in the contract. Function-based pricing is far more flexible, particularly for tiered or volume-dependent subscription pricing, and it composes with the rest of your cart transform and bundling logic. The wrong answer is both, applied inconsistently across groups, which is what we find about half the time.
The 2026 API change most brands have not costed
On 27 July 2026 Shopify shipped the SubscriptionContractCalculation object into early access on the 2026-10 release candidate. It is the successor to SubscriptionDraft, the object every subscription app currently uses to create and edit contracts.

The change is architectural rather than cosmetic. The old draft workflow required a dozen or more stateful mutations to edit one contract: create the draft, add a line, update the line, remove a line, add a discount, apply a code, update delivery, commit. The new model replaces that with a stateless calculate, poll, commit lifecycle that runs through the same checkout engine that powers Checkout, draft orders and subscription billing attempts.
1. CALCULATE
subscriptionContractUpdateCalculate()
→ returns SubscriptionContractCalculationPending
2. POLL
query subscriptionContractCalculation
or subscribe to:
subscription_contract_calculations/succeed
subscription_contract_calculations/fail
→ SubscriptionContractCalculationSuccess | Failure
3. COMMIT
subscriptionContractCalculationCommit()
→ contract persisted
Two consequences matter for anyone planning a build this half.
First, pricing, tax and Function output for contract edits are now calculated server-side by the same engine as checkout, and returned as an immutable preview before anything persists. That closes a long-standing class of bug where the price a subscriber saw when they edited their plan did not match what they were eventually charged. If your team has ever fielded a ticket that begins “I was quoted”, this is the fix.
Second, it makes capabilities possible that the drafts API simply could not support: bundle products inside contracts, cart transform and delivery customisation Functions applying to recurring orders, and tax alignment with what the subscriber actually sees.
The practical guidance for merchants is narrower than the excitement suggests. SubscriptionDraft will be deprecated once the new API is generally available on 2026-10, but it will keep working. Both APIs will coexist and migration can be incremental. Shopify’s own advice is not to build production integrations until 2026-10 is stable.
So the action for a brand right now is not to migrate. It is to ask your subscription vendor a direct question and write down the answer: what is your timeline for supporting the calculation API, and will bundles-in-contracts and Function-based delivery customisation be available to us when it lands? A vendor who cannot answer that in August 2026 is a vendor whose roadmap you are about to inherit.
The product page is where subscription programmes leak
The subscription widget on a product page is usually the least engineered part of the whole programme, and it is where conversion is won or lost. Three failure patterns account for most of what we find in audits.
The widget renders after the fold has already settled. App-injected subscription selectors frequently load via a script that runs late, which pushes the add-to-cart button down the page after the customer has already looked at it. On mobile that is a measurable conversion loss and a Cumulative Layout Shift penalty at the same time. The fix is reserving the vertical space in the theme before the widget mounts, which costs one CSS rule and is skipped almost universally.
Variant changes do not propagate to the selling plan. If a customer picks the 1kg size after selecting the fortnightly plan, a naive widget can leave a selling plan attached to a variant it was never valid for. The result is either a silent failure at add-to-cart or, worse, a contract created against the wrong variant. Any subscription widget shipped by us has to survive a variant-switch test in QA before it goes near production.
The default selection is chosen by instinct rather than data. Whether the page defaults to one-time purchase or to subscribe-and-save materially changes both sign-up rate and early churn. Defaulting to subscription lifts sign-ups and also lifts the number of subscribers who cancel in cycle two because they did not fully register what they had agreed to. That is not a copy problem. It is a decision about which number you are optimising, and it should be made explicitly and then tested.
Build artefact: the subscription PDP checklist
- Vertical space reserved for the widget before it mounts, no layout shift on load
- Variant switch re-validates available selling plans and clears invalid selections
- Selling plan ID present in the add-to-cart payload, verified in the network tab, not assumed
- Price display shows the recurring price and the saving, both derived from the selling plan rather than hardcoded
- Delivery cadence written in plain language with the first delivery date stated
- Cancellation terms visible before add-to-cart, not buried in the FAQ
- Widget renders correctly with JavaScript throttled to a mid-range Android device
- Selling plan survives the cart, the checkout and a browser back-button round trip
That last item catches more bugs than the rest combined.
Involuntary churn is an engineering problem wearing a marketing costume
Somewhere between 20 and 40 per cent of subscription cancellations are involuntary. The customer did not decide to leave. Their card expired, or the charge was declined for insufficient funds, and the recovery sequence was not good enough to bring them back. Across the subscription economy, failed payments account for an estimated USD 440 billion a year in lost revenue, and insufficient funds alone drive roughly 34 per cent of failed recurring charges, with expired cards accounting for another 15 per cent.

Here is what that means in Australian dollars for a mid-sized DTC brand. A store with 6,000 active subscribers at an average order value of $65 AUD on a monthly cycle is billing roughly $390,000 AUD a month. If 6 per cent of those charges fail and you recover half of them, you are writing off about $11,700 AUD every month, or $140,000 AUD a year. Lifting recovery from 50 per cent to 75 per cent is worth around $70,000 AUD annually, and it requires no new customers, no additional ad spend and no discount.
The recovery levers are well understood and they stack. Smart retry logic on its own recovers something like 40 per cent of failed charges. A card-updater service adds around 25 per cent. Dunning email sequences contribute a further 15 to 20 per cent on top. Combined properly, well-run programmes recover 70 to 85 per cent of failed payments, and merchants implementing structured dunning commonly see payment-related churn drop 30 to 50 per cent within the first month.
The timing detail that gets missed: dunning recovers the most in the first 72 hours and decays sharply after two weeks. A sequence that sends its first email on day three has already given away most of its value.
Build artefact: the retry and dunning ladder
| Timing | System action | Customer-facing action |
|---|---|---|
| T+0 | Charge fails, decline code captured and logged | None yet, avoid alarming on a soft decline |
| T+2 hours | Retry once if decline code is retryable | None |
| T+24 hours | Retry with card updater result if available | Email one, plain text, direct card-update link |
| T+72 hours | Retry | SMS, short, single link |
| T+7 days | Retry | Email two, states what happens if unresolved |
| T+14 days | Final retry | Email three, final notice with pause option offered |
| T+21 days | Contract paused, not cancelled | Win-back enters the lifecycle flow |
Pausing rather than cancelling at the end of the ladder is deliberate. A paused contract retains the delivery schedule and line items, so reactivation is a single click. A cancelled contract requires the customer to rebuild their order, and most of them will not.
Two engineering requirements sit underneath this table. Decline codes must be captured and stored, because retrying a hard decline like “stolen card” is wasted work and can trigger gateway penalties, while retrying “insufficient funds” on payday is genuinely effective. And billing attempt outcomes must be observable, which means the subscription_billing_attempts webhooks need to be consumed reliably rather than assumed. That is the same delivery-guarantee problem we cover in detail in our piece on building reliable Shopify webhook consumers, and subscriptions is where the cost of getting it wrong compounds fastest.
Migrating between subscription apps without losing the base
At some point most brands change subscription vendor. Pricing changes, the roadmap stalls, or the programme outgrows the tool. This is the highest-risk project in the subscription lifecycle and it is routinely under-scoped.
The order of operations that works:
- Establish payment method portability first. Before anything else, confirm where the payment credentials are vaulted. Shopify Payments vaulting means contracts can be recreated against existing payment methods. A third-party gateway vault usually means they cannot, and that single fact determines whether the migration is a technical project or a customer communications campaign.
- Export the contract state, not the app’s dashboard view. Pull contracts from the Admin API: lines, quantities, selling plan, delivery policy, next billing date, discounts. The app’s CSV export is a summary, and summaries lose the fields you need.
- Rebuild selling plan groups in the target app before touching contracts. Contracts reference selling plans. Getting the catalogue layer right first prevents a class of orphaned-reference errors that are painful to unwind.
- Migrate in cohorts, ordered by next billing date. Move the subscribers billing furthest out first. That gives the longest window to catch problems before anyone is charged incorrectly.
- Run a billing reconciliation for two full cycles. Compare expected charges against actual charges for every migrated cohort. Discrepancies almost always show up in cycle two, not cycle one, because cycle one often inherits a scheduled charge from the old system.
- Keep the old app installed and read-only until reconciliation passes. Uninstalling early destroys your comparison baseline.
The reconciliation step is the one clients push back on because it extends the project. It is also the one that has caught every serious migration defect we have encountered. Two cycles of reconciliation on a 6,000-subscriber base is a few days of analyst time against a six-figure AUD revenue risk.
The edge cases that surface at scale
Shop Pay. Subscription apps require specific changes to be compatible with Shop Pay, and compatibility is not automatic. Given how much of Australian mobile checkout runs through accelerated wallets, an incompatible subscription widget quietly removes the fastest checkout path for the customers most likely to convert. Test it explicitly.
Point of sale. Selling a subscription in a physical store requires the app to build a POS UI extension that uses the Cart API to attach selling plans to products. Most apps do not have one. If your retail team has been promised the ability to sign customers up in-store, verify that capability exists before it appears in a launch plan.
Markets and multi-currency. Subscription pricing across markets needs deliberate handling, because a contract created in one currency does not gracefully follow a customer who relocates. Decide up front whether you support cross-market subscription changes or whether the answer is a supported cancel-and-resubscribe path.
B2B. Subscription contracts now extend to wholesale customers with their own pricing, terms and delivery schedules, which pairs with company-level payment terms on B2B accounts. Recurring wholesale replenishment is one of the more under-exploited configurations available on Shopify right now.
Accounting. Prepaid plans create a deferred revenue obligation. Cash arrives in month one, revenue is recognised across six deliveries. If your Shopify to Xero integration treats a prepaid subscription order like a normal sale, your P&L is wrong from the first month, and the error grows with the programme.
What to instrument before launch
A subscription programme without observability is a programme where the first signal of a problem is an angry customer. The minimum instrumentation we ship with:
- Billing attempt success rate, tracked daily, alerting on a drop of more than two percentage points
- Decline code distribution, so a gateway or BIN-range issue is visible as a pattern rather than as noise
- Active contract count by selling plan group, which surfaces a broken PDP widget within hours instead of at month end
- Cycle-two churn tracked separately from overall churn, because it measures expectation-setting rather than product satisfaction
- Recovery rate on failed payments, the single number that tells you whether the dunning ladder is earning its keep
- Webhook processing lag and failure count on subscription topics
Five of those six are trivial to build and are missing from the majority of stores we audit.
How We Do It at Insiteful
We treat a subscription programme as a systems build with a commercial model attached, not as an app install with some styling on top.
Every subscription engagement starts with the ownership map above, filled in with the client’s actual vendor and gateway, because that table determines what is reversible. If payment methods are vaulted outside Shopify Payments, we say so on day one and price the consequences into the plan rather than discovering them in month eight.
We model selling plan groups by commercial intent before a single line of theme code is written, and we deliberately include the plans the merchandising team has not asked for yet. Adding a closed founding-member group at build time costs nothing. Adding it after four thousand contracts exist costs a project.
The PDP widget is built into the theme rather than left as an app injection wherever the vendor allows it, for the same reasons we build the rest of the front end natively. It removes a render-blocking third-party script, it eliminates the layout shift, and it means the subscription selector is styled by the same design system as everything else. That is consistent with how we approach the whole stack, which we have written about in our case for a native Shopify stack over headless.
Dunning is configured against the ladder above and then measured, not set once and forgotten. We report recovery rate alongside the acquisition metrics in the monthly review, because for a mature subscription programme it is usually the higher-leverage number.
And where a client’s requirements genuinely exceed what any subscription app supports, we build against the Shopify APIs directly. That is a real decision with real ongoing cost, and we are honest about when it is not warranted. Most brands should use an app. The ones who should not are usually running unusual billing logic, complex bundle composition inside contracts, or a subscriber experience that is itself the product. Our view on when to cross that line is set out in our guide to building custom Shopify apps.
Across roughly 200 Shopify builds a year, the pattern is consistent. Subscription programmes do not fail because the offer was wrong. They fail because the data model could not absorb the second year of decisions, or because a fixable payment failure was allowed to look like a customer choosing to leave.
Where to start
If you already have a subscription programme running, the highest-value hour you can spend this week is pulling three numbers: your billing attempt success rate, your failed payment recovery rate, and your cycle-two churn. If nobody in the business can produce them, that is the finding.
If you are planning a programme, resolve the payment vault question and the selling plan structure before you choose an app. Those two decisions constrain everything that follows, and they are the two most commonly made by default.
If you want a second set of eyes on either, our build assessment covers the subscription architecture alongside the rest of the stack. We will tell you plainly whether the foundation you have will hold the programme you are planning.