LUCENTCOMMERCEGET A FREE STORE AUDITFREE AUDIT

SUBSCRIPTIONS · MIGRATION · INTEGRATIONS · 21 JULY 2026 · 8 MIN READ

Migrating subscriptions between platforms

You cannot move a subscription. You move a plan definition, a payment credential and a schedule, and only one of those three can actually stop you.

A wholesale order form beside its negotiated price list

Stop thinking of it as moving subscribers. A subscription is three separable things — a plan definition, a stored payment credential and a billing schedule with history attached — and they migrate by different routes. Plans you rebuild. Schedules you import as subscription contracts. The payment credential is the one that can genuinely block the project, because card data cannot be exported: either the gateway vault transfers, or every customer has to re-authorise, and the difference between those two outcomes is most of your churn risk.

IN SHORT

  • Card details cannot be exported from one platform to another; what moves is either a gateway vault transfer or a token reference, never the number.
  • Shopify's customerPaymentMethodRemoteCreate mutation imports payment methods from external gateways — Shopify documents Stripe, Authorize.Net and Braintree — by associating a remote reference with a customer.
  • That import is asynchronous: Shopify states the returned payment method may be incomplete and directs you to poll the customerPaymentMethod query until details are available or the method is revoked.
  • subscriptionContractCreate requires customerId, currencyCode, nextBillingDate and a contract object carrying status, paymentMethodId, billingPolicy and deliveryPolicy.
  • That mutation is documented as deprecated in favour of the SubscriptionContractCalculation API and its calculate-poll-commit flow, so confirm which flow applies before anyone writes code.
  • Cycle counts, prepaid balances, tenure-based discounts and queued changes are where migrations actually fail, because none of them is a field in the target model.
  • Migrate by billing-date cohort with the old platform's billing frozen. Two engines pointed at one customer is a double charge, which is the only unrecoverable failure on this list.

Three things wearing one name

A "subscription" in a merchant's head is one object. In two systems it is three, and pulling them apart is what makes the project estimable.

The plan. Shopify calls this a selling plan: the delivery, pricing and billing policies attached to products. It is configuration, it is small, and you rebuild it rather than migrating it. This is also the moment to stop reproducing plans nobody has bought since 2023 — a migration is the cheapest catalogue rationalisation you will ever get.

The contract. The agreement between one customer and you: which variants, how often, at what price, next billing on what date, shipping to where. Shopify models this as a subscription contract, and the documentation describes contracts moving through active, paused, failed, cancelled and expired states. This part is a data import and it is tractable.

The credential. The stored means of taking money. This is the one that decides whether the project is a fortnight of engineering or a customer communications campaign, and it is the one that never appears on the first plan.

The credential problem, which you should solve first

Card numbers are not yours to move. They live in a gateway vault under someone's PCI scope, and no reputable platform will hand you a spreadsheet of them. What can move is a reference, and which references are available depends entirely on a fact about your old setup that is worth establishing before anything else: whose gateway was billing your subscribers?

If you keep the gateway, you keep the vault. This is the good case. Shopify's customerPaymentMethodRemoteCreate mutation exists precisely for it — it imports payment methods from external gateways and associates them with a Shopify customer record, and Shopify names Stripe, Authorize.Net and Braintree as the gateways it covers. You are moving a pointer, not a card, and the customer is never asked to do anything.

If you are leaving the gateway, you need a vault transfer. Gateways do run PCI-compliant vault migrations between one another, but they are a commercial and operational process with lead times, not an API call. Start it before you scope the build, because the answer sometimes comes back "not for your card mix" and that changes the project rather than delaying it.

If the old platform was the merchant of record, assume you are starting again. Where the subscription platform held the merchant relationship rather than you, the credentials are theirs. Every subscriber has to re-authorise, and that is not a migration, it is a re-acquisition campaign with a migration attached. Know this on day one and budget for the churn honestly rather than discovering it at cutover.

One implementation detail that catches people: the remote import is asynchronous. Shopify is explicit that the returned payment method may be incomplete at first and instructs you to "use the customerPaymentMethod query to retrieve the payment method status until all details are available or the payment method is revoked." That means the migration is a job with a reconciliation pass, not a script that prints a success count. Anything left incomplete when you reconcile is a contract that will fail its first billing attempt.

What a contract import actually needs

Once credentials exist in Shopify, the contracts follow. The documented input to subscriptionContractCreate is a useful checklist because every field is something you must have extracted correctly from the old system: customerId, currencyCode and nextBillingDate are required at the top level, and the contract object carries status, paymentMethodId, billingPolicy, deliveryPolicy, deliveryPrice and deliveryMethod. The scope is write_own_subscription_contracts, alongside the manage_orders_information permission.

Two things follow from reading that list carefully.

The first is that nextBillingDate is the field carrying all the risk. It is the difference between a customer's next box arriving on time and it arriving twice, or not at all. Extract it, do not derive it — recomputing "every 30 days from the start date" against a contract that has been paused twice and skipped once will produce a date that is plausible and wrong, and plausible-and-wrong is precisely the kind of error that survives review.

The second is a versioning check to do before estimating. Shopify's documentation marks subscriptionContractCreate and its draft-based flow as deprecated in favour of the SubscriptionContractCalculation API, which uses a calculate-poll-commit pattern instead. Whether your migration writes the old flow or the new one depends on the API version your app targets, and the two are different enough that finding out mid-build costs real days. Read the current reference for your version rather than a tutorial, this one included.

The scopes themselves are worth a conversation with both vendors. They are named read_own_subscription_contracts and write_own_subscription_contracts, and what an app can observe across a store during a parallel run is exactly what determines whether you can verify the migration from inside Shopify or have to reconcile against exports. Ask both sides before you design the verification step.

The fields that have nowhere to go

Contracts import cleanly. What does not import is everything the old platform accumulated around them, and this is where migrations are actually lost — not in a failed mutation but in a customer emailing to ask why their loyalty discount vanished.

Inventory the following before agreeing a scope, because each one is either a build, a business decision, or an apology:

  • Cycle count. "You have had eleven deliveries" drives tenure discounts, gift milestones and churn models. It is history, not state, and the target has no field for it. Usually it becomes a metafield, which means something has to keep counting it afterwards.
  • Prepaid and credit balances. A subscriber who paid for twelve months up front holds a liability you owe them. This needs an explicit design, and it needs finance in the room.
  • Tenure-based pricing ladders. Ten per cent off from month three, fifteen from month twelve. If the old platform computed this at billing time, the new one must reproduce the ladder exactly or you are silently repricing your most loyal customers.
  • Queued changes. A swap, a skip or an address change scheduled for next cycle sits in the old platform as a pending instruction. Nothing about a contract import moves it, and it is invisible in an export of current state.
  • One-off add-ons attached to the next delivery, which have the same problem for the same reason.
  • Cancellation and pause reasons, which are the only retention data you have and are worth exporting to a warehouse even if they land nowhere in the new system.

Cutover, and the one unrecoverable mistake

Everything else on this page is recoverable. Charging a customer twice in one week is not — it is a refund, a support ticket, a chargeback risk and, for a subscription business, an immediate cancellation. So the cutover rule is absolute: at no point may two billing engines hold a live credential for the same subscriber. Freeze billing on the old platform before you import the first contract, and verify the freeze rather than trusting a toggle.

Given that constraint, cohort by billing date. Take the subscribers billing furthest out first, migrate them, and let them bill on the new platform while the near-term cohorts are still running on the old one. Each cohort gives you a real billing run against real credentials before the next one moves, and the blast radius of a bad assumption is one week of subscribers rather than the whole base.

Two other things belong in the plan. Rehearse the whole extract-transform-load against a copy first, with the billing step pointed at nothing, and compare counts and totals field by field — a dry run that only proves the script completes has proved nothing. And decide in advance what a failed first billing attempt means: a natural rate of decline exists on any book of subscriptions, so you need the old platform's baseline failure rate to hand, or you will spend cutover week unable to tell a broken import from a Tuesday.

Where re-authorisation is unavoidable, Shopify provides customerPaymentMethodSendUpdateEmail, which sends the customer a link to update a vaulted payment method and is documented for exactly the expiring-or-declined case. It is a good tool and a bad plan: use it to recover the tail, not to move the base. Sequence the emails so the ask arrives close to a delivery the customer is looking forward to, not three weeks before anything happens.

When we would tell you to stay put

A subscription migration asks every one of your best customers to notice you. That is the cost, and it is not on the quote. Against it, two reasons people give for moving, only one of which survives.

"The platform is too expensive." Usually not worth it. Model the fee difference over two years against the engineering, the vault transfer, the churn from any cohort that has to re-authorise, and the support load. For most mid-market books the saving arrives in year three, assuming nothing goes wrong, and something goes wrong. If the only complaint is the invoice, go and negotiate the invoice.

"We cannot build the thing the business needs." This one is worth it. A platform that cannot express your bundle logic, cannot offer the pause-and-swap behaviour that keeps people subscribed, or cannot be integrated with the ERP is blocking revenue rather than costing money, and no negotiation fixes that. Migrate deliberately, cohort by cohort, with the credential question answered before anything else is scoped.

And a third, quieter case: if you are migrating the storefront anyway, migrate the subscriptions at a different time. Doing both in one weekend means that when a billing run looks wrong you will not know whether the cause is the contracts, the catalogue or the theme. Separate the variables. The calendar is the cheapest risk control available.

Questions this raises

Can you transfer saved credit cards between subscription platforms?

Not as card numbers. Either you keep the same gateway and move a reference — Shopify documents customerPaymentMethodRemoteCreate for importing payment methods from Stripe, Authorize.Net and Braintree — or the two gateways run a PCI-compliant vault transfer, which is a commercial process with lead times. Failing both, every subscriber re-authorises.

How long does a subscription migration take?

The contract import is the small part. The schedule is set by the credential route: a same-gateway reference import is a matter of weeks, a gateway vault transfer adds the gateway's own lead time, and a full re-authorisation is a customer campaign measured in months with a churn cost attached. Establish which one you are in before estimating anything else.

What data does a Shopify subscription contract need?

The documented subscriptionContractCreate input requires customerId, currencyCode and nextBillingDate, plus a contract object carrying status, paymentMethodId, billingPolicy, deliveryPolicy, deliveryPrice and deliveryMethod. Note that Shopify marks this mutation deprecated in favour of the SubscriptionContractCalculation API, so check the reference for your API version.

What happens to a subscriber's history when you migrate?

It does not come with the contract. Cycle counts, prepaid balances, tenure discount ladders and queued skips or swaps have no field in the target model and must each be handled deliberately — usually as metafields plus logic, sometimes as a business decision to honour something manually. This is where most migrations go wrong.

Can you run both subscription platforms in parallel?

You can run them side by side for different cohorts, and you should. What you must never do is leave two billing engines holding a live credential for the same subscriber — a double charge is the only failure on this list you cannot quietly fix. Freeze billing on the old platform and verify the freeze before importing anything.

Should we migrate subscriptions and the storefront at the same time?

No. If a billing run looks wrong during a combined cutover you will not know whether the cause is the contracts, the catalogue or the theme. Separate them by several weeks so each has its own baseline. It costs nothing and it is the most effective risk control on the project.

NEXT STEP

Free store audit

A senior Shopify engineer reviews your storefront, theme performance and checkout, then sends a prioritised list of fixes.