Move Existing Subscriptions to Shopify App Pricing: Two Paths
No7 Engineering Team
Growth Architecture Unit

Shopify has opened a path for apps that bill with the Billing API to bring existing subscriptions onto Shopify App Pricing without asking merchants to approve the charge again. The Shopify changelog entry adds a migration tool in the Partner Dashboard and shopify app subscription-migrations commands in Shopify CLI. Each subscription moves at its next billing cycle or renewal, later if the terms change.
Shopify App Pricing is Shopify's hosted billing for apps. Shopify serves the plan selection page and runs recurring charges, usage-based pricing, free trials, proration and price updates, as the Shopify App Pricing overview describes.
Who this affects
The change applies to apps that currently bill merchants through the Billing API and want those subscriptions on Shopify App Pricing. Apps already on Shopify App Pricing are not affected. You do not have to change how your app bills before you start. Existing Billing API subscriptions keep billing through the Billing API until the tooling moves them, per the migration API guide.
Which subscriptions can the Dashboard move, and which need the CLI?
Both paths start in the Partner Dashboard, where you draft and test the App Pricing plans. Only the move itself differs. The migration guide draws the line at one rule: the Dashboard tool moves a subscription when its recurring price, currency and billing interval match exactly one public plan. Everything else goes through the CLI. One exclusion applies to both paths: a subscription with an active discount cannot move until the discount ends.
Which tool moves what
| Subscription | Tool | Why |
|---|---|---|
| Simple subscription that pairs with a public plan | Partner Dashboard | Rows group subscriptions by charge name, price, currency and interval; one click moves a row. |
| Usage-based subscriptions | Shopify CLI | The Dashboard tool moves simple subscriptions only, and the target plan needs events, meters and usage prices set up first. |
| Price adjustments | Shopify CLI | The current price does not match the target plan, so the Dashboard cannot pair them. |
| Moves to a private plan | Shopify CLI | The Dashboard maps subscriptions to public plans only; the CLI accepts public or private targets. |
You can have up to eight public plans and unlimited private plans. To keep the Dashboard path open, keep exactly one public plan for each price, currency and interval combination your existing subscriptions pay. Shopify drafts plans from your manual plans but skips plans above the limits and does not copy usage configuration.
The CLI handles the complex cases: it lists subscriptions with status and effective date, schedules moves in bulk from a CSV, and cancels pending moves, Dashboard ones included. The migration guide says the commands are available in the nightly build of Shopify CLI (npm install -g @shopify/cli@nightly); check with shopify version after installing. For the CLI itself, see our guide to Shopify CLI 4 engineering migration.
How to move existing subscriptions to Shopify App Pricing in six steps
- Review the draft plans. In the Partner Dashboard, open your app's pricing content and review the App Pricing plans Shopify generated from your manual plans. Complete every plan marked Action needed, add usage configuration to usage-based plans, and add any plan Shopify skipped.
- Test on a development store. Open your app on a development store in your Partner organisation, subscribe to a draft plan, and complete the approval and redirect. If you bill on usage, check that both your Billing API and App Events integrations work.
- Enable Shopify App Pricing. Confirm every Action needed status is resolved, with no more than eight public plans and no more than one free public plan without usage charges. Then tick the readiness box and click Enable Shopify App Pricing. From that point new subscriptions use your App Pricing plans; existing ones keep billing through the Billing API until you move them, so keep that integration running, usage records included.
- Move the simple subscriptions in the Dashboard. In Review and assign new plans, each row shows the plan it will move to. Untick any rows you want to keep on the Billing API, then click Move selected to Shopify app pricing, review the summary and click Move selected to confirm.
- Schedule the rest with the CLI. Run
shopify app subscription-migrations list --status UNSCHEDULEDto list the eligible subscriptions (add--jsonfor machine-readable output). That list is an inventory, not schedule input. Build a schedule CSV with one row per shop and the columnsshop_id,target_plan_handle,price_behaviorandnotification, per the CLI migration guide.price_behavioris the decision that matters.HONOR_BILLING_PRICEkeeps the existing price;PLAN_PRICEapplies the target plan's price, and a price change triggers the notice and delay rules below.notificationisWHEN_REQUIREDorOPT_OUT. Submit it withshopify app subscription-migrations schedule --input migrations.csv --watch: the CLI validates the whole file, splits it into batches of at most 250 shops and returns one operation ID per batch. Save every operation ID; you need them to check status or cancel unprocessed work. The Partner Dashboard account you use needs the Manage app listings permission. - Confirm the moves land. Run
shopify app subscription-migrations status --id <operation-id> --jsonand read every per-shop result code (a COMPLETED operation can still hold failed shops) (INELIGIBLE,INVALID_PLAN,BLOCKEDand the rest) before treating a batch as done. Then check that subscriptions move on schedule and bill correctly under Shopify App Pricing before you expand the migration to more stores.
When the change takes effect, and what merchants see
A move is scheduled, not immediate. Each subscription changes at the start of its next billing cycle, or when an annual plan renews. One rule from the migration guide matters for planning. If the move changes billing terms (the recurring fee, usage charges or spending limit), or you send an opt-out notice, the merchant gets at least 30 days before the change. In that case a subscription less than 30 days from its next cycle stays on current terms for one more period, which for an annual plan is another year. To see each store's status and effective date, use the CLI list command.
If the terms change, Shopify emails the store owner when the move is scheduled, comparing the current and new terms and giving the date. If nothing changes, Shopify sends no email unless you request an opt-out notice through the CLI. A merchant who does not want the change can cancel the app subscription before it takes effect, which also cancels the move.
Cancelling a scheduled move
You can cancel a scheduled move with the CLI before it takes effect, including moves made in the Partner Dashboard. The documented sequence is short. Export the scheduled rows with shopify app subscription-migrations list --status SCHEDULED > scheduled.csv. Create a CSV with only a shop_id column for the stores you want to keep on the Billing API. Then run shopify app subscription-migrations unschedule --input <file> --watch. A cancelled subscription that qualifies for the Dashboard reappears there, so you can move it later. Per the migration guide, Shopify does not email merchants about a cancellation, so tell anyone who already received a notice. Once a subscription has changed to its new plan, the move cannot be undone.
Checking subscription state before and after the switch
The Active Subscription API in the Partner API returns both Billing API and Shopify App Pricing subscriptions. It can therefore check subscription status before and after the switch. The query below is abridged from the one the Shopify App Pricing docs publish; the full version adds tiered prices, discounts, usage and pending updates. The activeSubscription reference notes that the API client needs the Manage apps permission and that custom and private apps are not supported by the query.
query ActiveSubscription($appId: ID!, $shopId: ID!) { activeSubscription(appId: $appId, shopId: $shopId) { billingPeriod cancelAtEndOfCycle trialEndsAt currentBillingCycle { startTime endTime } items { handle description price { __typename active currency ... on FlatRatePrice { amount } } } } }Use the response to reconcile your own entitlement records. The item handles show the current subscription items. After a move, request the legacySubscriptionId field (not in the abridged query above; see the activeSubscription reference) to read the original AppSubscription ID. For a scheduled move's effective date, use the CLI list command rather than reading it off the billing cycle. Keep your internal records; the query is a check, not a replacement for them.
What changes in your code
Per the migration guide, Shopify App Pricing does not send the Billing API webhooks. Read the URL redirect parameters after a merchant selects a plan, and query the Partner API for changes that happen outside a redirect. The one exception is the moment of the move: the merchant's Billing API AppSubscription keeps its status, takes the new recurring price and interval, loses its capped amount and triggers an APP_SUBSCRIPTIONS_UPDATE webhook. After that, the Active Subscription API returns the subscription with legacySubscriptionId set, the CLI list shows it as MIGRATED, and usage for it is reported with the App Events API, not Billing API usage records. If your handlers key on Billing API webhook topics or legacy plan names, map old names and new plan handles to the same entitlement tiers before you schedule anything. Remove the Billing API subscription path only when no Billing API subscriptions remain that you intend to keep billing; one-time purchases that grant access stay on currentAppInstallation.
Usage-based apps have the most work: the guide requires the App Events API alongside the new plan setup before those subscriptions can move. For the engineering cost side, see our breakdown of Shopify custom app development cost. For what a public app launch involves once billing is in place, see our note on Anchor Loyalty's Shopify App Store launch.
What to do this week
Open the pricing content for your app in the Partner Dashboard and count the plans marked Action needed; that is the work before you can enable App Pricing. Once enabled, the Review and assign new plans rows show what the Dashboard can move, and the CLI list shows the rest.
Then decide on timing. Annual plans move at renewal, and a terms change adds at least 30 days' notice, or a full extra year for an annual plan within 30 days of renewal. If you bill on usage, put the App Events work first. For help scoping that migration, review our Shopify development services.
Frequently Asked Questions
The questions buyers and engineers ask us most about this topic.
Can the Partner Dashboard tool move usage-based subscriptions?
No. The Dashboard tool moves a subscription when its price, currency and interval match one public plan. Usage-based subscriptions, price adjustments and moves to private plans go through the shopify app subscription-migrations commands in Shopify CLI.
When does a moved subscription switch to Shopify App Pricing?
When its next billing cycle begins, or at the next renewal for annual plans. If the move changes billing terms or you send an opt-out notice, the merchant gets at least 30 days, and a subscription less than 30 days from its next cycle stays on current terms for one more period.
Can a scheduled move be cancelled?
Yes, with Shopify CLI before it takes effect, including moves made in the Partner Dashboard: list the scheduled subscriptions, put the shop IDs to keep in a CSV, and run the unschedule command. A merchant can also cancel the app subscription before the change, which cancels the move.