What “migrating” actually means
Nothing moves off Stripe. Specifically:- Your existing Stripe customers keep paying through the same Stripe subscriptions they’re already on.
- Charges, invoices, and payouts continue exactly as before.
- Stripe remains authoritative for products, prices, customers, and subscriptions.
Before you start
You’ll need:- A BillingOS organization with Stripe connected (OAuth, production).
- The BillingOS products you want to map your Stripe products to. Create them under Products in the dashboard first — the import wizard will ask you to match Stripe products → BOS products.
Step 1 — Run the import wizard
Open Settings → Import Data
Once Stripe is connected, you’ll see a new Import Data tab in your organization settings.
Map products
For each Stripe product, choose the BillingOS product it corresponds to. The wizard shows the count of active subscriptions per Stripe product so you can prioritize the important ones.
Subscriptions whose Stripe product isn’t mapped will be skipped. You can re-run the import later after adding missing mappings — all imports are idempotent.
Step 2 — Pass email when you create session tokens
This is the trick that makes everything “just work” for your existing customers. When your backend creates a session token, pass the user’s email along with their ID:
Step 3 — Resolve “stuck” customers (if any)
After the import completes, BillingOS classifies un-bound customers into two buckets:Pending
Customers with a unique email. They’ll auto-bind on first SDK session. No action required.
Needs attention
Customers with no email, or sharing an email with another customer in Stripe. These need a one-time manual bind.
Bulk-resolving from your backend
For larger sets, use the Node SDK to script the binding:What happens next
Once a customer is bound (auto via email, or manually), the following work for them with no extra code:- Portal — they can view their current plan, update payment method, cancel
- Checkout — they can upgrade or downgrade through the BillingOS pricing table
- Feature gates —
useFeature("api_calls")returns the right entitlement - Usage tracking —
useTrackUsagerecords consumption against their subscription
Re-running the import
The import is fully idempotent. Re-run it any time you:- Add new Stripe products and need to map them
- Have new customers in Stripe that weren’t imported on the first pass
- Migrate from another billing tool that ends up creating Stripe customers outside BillingOS
FAQ
Do I need to change anything in my app to keep my existing customers paying?
Do I need to change anything in my app to keep my existing customers paying?
No. Their subscriptions stay on Stripe and continue charging exactly as before. The only code change is passing
email to createSessionToken so they auto-bind on first session.What about inactive or canceled Stripe subscriptions?
What about inactive or canceled Stripe subscriptions?
The import only ingests active-ish subscriptions (
active, trialing, past_due, unpaid). Canceled and incomplete-expired subscriptions are skipped to keep the BillingOS state clean.Can I import customers from multiple Stripe accounts into one BillingOS organization?
Can I import customers from multiple Stripe accounts into one BillingOS organization?
Not in v1. The import flow assumes a single connected Stripe Connect account per organization.
What if I have customers using a free plan that doesn't exist in Stripe?
What if I have customers using a free plan that doesn't exist in Stripe?
The import only mirrors customers that exist in your Stripe account. Free-tier users that you track outside Stripe (e.g., in your own database) keep working as before — they’ll get a BillingOS customer record the first time they hit your app with the SDK.
Will my customers see any disruption during the import?
Will my customers see any disruption during the import?
No. Imports happen in the background and don’t touch their Stripe subscriptions. There’s no double-charge, no payment retry, no email — your customers won’t know anything happened.