One of the highest-stakes projects I have led was migrating live e-commerce orders from WooCommerce into the Patient Platform and Brello while handing active subscription billing to Stripe. For this healthcare product, a missed renewal could mean a patient’s medication subscription lapses. Nobody could see an interruption. Not one customer.
This post is the playbook I wish I’d had at the start. The patterns generalize to any live billing migration, whatever the systems involved.
Rule zero: the old system stays authoritative until proven otherwise
The single biggest mistake in billing migrations is flipping authority too early. Until the moment of cutover, WooCommerce remained the source of truth, while the new application and billing records were shadows being validated against it.
That means running both in parallel and comparing outputs, not for a day but for full billing cycles. Subscriptions have temporal behavior that only shows up when a renewal actually fires. A migration validated only against static data will pass every test and then fail on the first renewal that hits an edge case: a paused subscription, a mid-cycle plan change, or a card that expired during the migration window.
Backfill history, don’t just port state
It is tempting to migrate only current state: active subscriptions, current plans, and next billing dates. Resist it. Support teams, refund flows, and dispute processes all reach into history. If a customer disputes a charge from four months before the migration, someone needs to trace it in the new application platform.
Our approach was to backfill historical orders as first-class records in the Patient Platform and Brello, linked to their WooCommerce originals with a stable cross-reference ID. That last part matters more than it looks. During the messy weeks after cutover, the ability to hop from a record in the new application platform to its ancestor in WooCommerce turns a support nightmare into a lookup.
Active-order linking is the hard part
Historical backfills are mechanical. The genuinely hard problem is active subscriptions: an order that exists in WooCommerce, has a renewal scheduled, and must be linked to a live Stripe subscription at the right moment with the right state.
The pattern that worked:
- Freeze windows, per cohort. Never migrate everything at once. Slice by renewal date and migrate each cohort during its quietest window, right after a renewal fires, when the subscription has the longest runway before the next event.
- Idempotent creation. Every migration script must be safe to run twice. Partial failures will happen, and the recovery path should be “run it again,” not an archaeological dig.
- Suppress, then verify, then release. After creating the subscription in Stripe, the WooCommerce renewal does not get deleted. It gets suppressed (renewals disabled) and retained as evidence. Deleting the fallback before validating the replacement is how you turn a bug into an outage.
Reconciliation is a permanent fixture, not a phase
We built a reconciliation job that compared the two systems continuously: every active subscription, its next billing date, its amount, and its payment method status. Any divergence raised a flag before the customer’s renewal date arrived. That converts silent billing failures into tickets you handle proactively.
My rule of thumb: the reconciliation tooling should outlive the migration by at least one full billing cycle of every plan you offer. Annual plans mean a year.
The cutover should be boring
If the parallel run is validated, the backfills are linked, and reconciliation is green, then cutover day is a non-event: a configuration change, not a launch. That is the goal. The drama budget for a billing migration should be spent entirely in the preparation, so the moment itself has none left.
Ours was boring. The patients never knew. That’s what success looks like in this kind of work: nothing visible happened at all.
The reliability instincts behind this migration started much earlier. Read Building a telehealth startup: 5 engineering lessons from Medsi for the product and architecture lessons that carried forward.

