Early access
Port your subscription data from Paddle Classic to Paddle Billing
Map your product catalog and migrate your subscription data from Classic to Billing using screens in the dashboard. Available when you've built an integration with Paddle Billing.
After you've built an integration with Paddle Billing, use the dashboard to port subscription data from Paddle Classic to Paddle Billing. You can update records in your database, then turn off your Paddle Classic integration.
This guide walks through how to use the migration screens, and how to handle migrated data.
Access to migrations in the dashboard is limited to users who are part of our early access program. If you're interested in joining the program, read the testing overview guide and join the waitlist. We'll reach out when space is available if you meet the program requirements.
How it works
You can use screens in the Paddle dashboard to migrate data from Paddle Billing to Paddle Classic. It's a multistep process, with a final chance to review everything at the end.
You can run as many migrations as you want, choosing how many subscriptions you want to migrate each time.
Product catalog mapping
In the first step of migration, you can map plans in Paddle Classic with products in Paddle Billing.
You can map the same product to multiple plans. For example, you might have separate plans in Paddle Classic for monthly and annual pricing, which you could map to the same product in Paddle Billing.
For each plan that you map to a product, Paddle creates a new price for that product. You can review these on step two of the migration screen.
Price overrides in Paddle Classic and Paddle Billing can't be mapped one-to-one. If you have currency override prices in Paddle Classic, Paddle creates a new price in Paddle Billing for each override price.
By default, the new override prices are created as non-catalog prices. This means they're considered specific to the subscriptions that they're used on, and not presented in the dashboard or returned by the API by default.
Subscription selection
After you've mapped products and prices, you can choose which subscriptions you want to migrate.
We recommend choosing a small number of subscriptions for your first migration, so you can familiarize yourself with the process and check that your new Paddle Billing integration flows work correctly.
You can run as many migrations as you want, so you can go plan-by-plan, migrate a number at a time, or migrate all.
You can only migrate active subscriptions. Where subscriptions are past due, wait for dunning to complete then follow-up with another migration when subscriptions are active.
During migration
During a migration, Paddle creates new records in Paddle Billing and cancels the subscription in Paddle Classic. This is how the process works:
Prices imported
New prices are created in Paddle Billing for any mapped products.
Business data imported — optional
If a customer has a tax or VAT number, a business entity is created for the customer in Paddle Billing.
Subscriptions imported
A subscription entity is created in Paddle Billing for each subscription. It's linked to the customer, address, and business created earlier, and the products and prices mapped initially.
Subscription canceled in Paddle Classic
The subscription is canceled silently in Paddle Classic, with no disruption to the customer. If there's a problem importing a subscription to Paddle Billing, it's not canceled in Paddle Classic.
Post-migration
You can track the status of a migration in the dashboard. Paddle emails you when a migration is completed.
As part of the migration process, you need to create or update records in your database for the subscriptions you ported over. You can either:
Use webhooks — recommended
Listen for
customer.imported
,subscription.imported
, and other imported webhooks, then create records in your database.subscription_canceled
occurs in Paddle Classic.Create a database migration script
Export a list of migrated subscriptions from the dashboard, then use this to write a script to create records in your database.
As part of migration,
imported
events occur in place ofcreated
events. For example,customer.imported
occurs in place ofsubscription.created
.
In most cases, we recommend using webhooks because they contain all the information you need. You might like to create a database migration script if you're importing a large number of subscriptions that might overwhelm your webhook endpoint.
If you're using a migration script, you may need to make additional calls to the Paddle API to fetch the data you need.
Before you begin
Build an integration with Paddle Billing
Paddle Billing is built on an entirely new API, with new webhooks, Paddle.js library, and SDKs.
Before you can port your subscriptions from Paddle Classic to Paddle Billing, you'll need to build an integration with Paddle Billing so that you're ready to run subscriptions through Paddle Billing rather than Paddle Classic.
To learn more, see Reintegration checklist
Complete a transaction
You'll need to have at least one completed transaction on Paddle Billing to show that your integration is ready.
Make sure you've had one new customer signup through your Paddle Billing integration, or launch a checkout and take a payment through it yourself to verify that your Paddle Billing integration works correctly.
Subscribe to imported events — recommended
We recommend using webhooks to handle fulfilment and provisioning for subscription lifecycle events. Build a webhook handler function and set up a notification destination in Paddle.
If you're using webhooks to handle your post-migration workflow, subscribe to customer.imported
and subscription.imported
events.
To learn more, see Create or update notification destinations and Handle webhook delivery
You can use webhook simulator to check that your webhook endpoint and fulfilment workflows are working correctly.
Prepare your database
Create or update records in your database for new subscriptions in Paddle Billing.
To avoid data contamination, we recommend creating new tables in your database for subscription data rather than enriching existing records.
Customers can have more than one subscription in Paddle Billing, so we recommend creating a table for customer data and a separate table for subscription data, then relating them using the customer ID.
As part of the migration, customer.imported
occurs in Paddle Billing. You should store:
Description | Field name | Reason to store |
---|---|---|
Customer ID | customer.id | Used to identify a customer and relate to record in the subscription table. |
Email address | customer.email | Used to identify a customer. |
Classic reference | customer.import_meta.external_id | Used to match this subscription to a Paddle Classic user record. |
As part of the migration, subscription.imported
occurs in Paddle Billing. You should store:
Description | Field name | Reason to store |
---|---|---|
Customer ID | subscription.customer_id | Used to relate this record with a record in the customer table. |
Subscription ID | subscription.id | Used to identify this subscription and work with this subscription using the API. |
Subscription status | subscription.status | Used to limit or stop access when paused or canceled, or determine if a subscription is past due or trialing. |
Subscription items | subscription.items[].price.id , subscription.items[].quantity | Used to change items on a subscription as part of an upgrade or downgrade workflow. |
Subscription products | subscription.items[].price.product_id | Used to determine which features in your app a customer should have access to. |
Collection mode | subscription.collection_mode | Used to determine whether a subscription bills automatically or whether Paddle sends an invoice for charges that customers must pay manually. |
Scheduled change | subscription.scheduled_change | Used to determine whether a subscription is scheduled to pause or cancel. You can't change items on a subscription when there's a pending scheduled change. |
Classic reference | subscription.import_meta.external_id | Used to match this subscription to a Paddle Classic subscription record. |
As part of the migration subscription_canceled
occurs in Paddle Classic. We recommend marking records in your Paddle Classic tables as migrated to Paddle Billing at this point.
Migrate subscription data
Get started
Choose the Paddle Billing option in the toggle in the nav bar.
Go to Paddle > Migrate.
Click Get started.
You'll need to have at least one completed transaction to be able to start a migration.
Map products and prices
Use the drop-down to map plans in Classic to products in Billing. Paddle creates a new price for each plan against the product you select here.
Click Continue, then review prices.
Click Price details next to any price to update the name or description of a price. You can change other details later.
Click Continue.
Select subscriptions
Use the checkboxes to select subscriptions that you want to migrate. You can search, sort, and filter using the options at the top.
Click Continue.
We recommend selecting a small number of subscriptions for your first migration, so you can check your new integration works.
Review and start
Review the products and subscriptions you're migrating, then click Start migration.
Complete the final check by clicking Start migration.
Handle migrated subscriptions
Webhooks
If you built a post-migration workflow using customer.imported
and subscription.imported
events, you should check that:
- You received webhooks for imported events. Paddle automatically queues events that failed for retry, using an exponential backoff schedule. You can view logs in the Paddle dashboard or using the API.
- You processed webhooks successfully, and records are created in your database. You can export a list of subscriptions from Paddle > Migrate and check against your records.
- You're running subscriptions in Paddle Billing through your Paddle Billing integration.
When all your subscriptions are ported to Paddle Billing, you can safely remove your Paddle Classic integration.
Migration script
If you're using a database migration script to create and update records in your database, you should:
Toggle Paddle Billing in the nav bar, then export a list of subscriptions from Paddle > Migrate.
Write a database migration script to create or update records in your database.
Check that you're running subscriptions in Paddle Billing through your Paddle Billing integration.
When all your subscriptions are ported to Paddle Billing, you can safely remove your Paddle Classic integration.
Events
price.imported | Occurs during a migration when a price is created for a Paddle Classic plan. |
customer.imported | Occurs during a migration when a customer is created for a subscription. |
address.imported | Occurs during a migration when an address is created for a customer against a subscription. |
business.imported | Occurs during a migration when a business is created for a customer against a subscription. |
discount.imported | Occurs during a migration when a price is created for a Paddle Classic coupon. |
subscription.imported | Occurs during a migration when a subscription is ported from Paddle Classic to Paddle Billing. |
subscription_canceled
occurs in Paddle Classic after a subscription is imported to Paddle Billing.
Related pages
- Port your subscription data from Paddle Classic to Paddle Billing
- How it works
- Product catalog mapping
- Subscription selection
- During migration
- Post-migration
- Before you begin
- Build an integration with Paddle Billing
- Complete a transaction
- Subscribe to imported events — recommended
- Prepare your database
- Migrate subscription data
- Get started
- Map products and prices
- Select subscriptions
- Review and start
- Handle migrated subscriptions
- Webhooks
- Migration script
- Events
- Related pages