Importing your Historical Purchases
Choosing Your Import Path
Importing existing purchase data to RevenueCat can be done server-side, or client-side. A server side migration is preferable whenever possible because it ensures that all subscriptions will be recorded in RevenueCat regardless of any in-app activity.
Do you have all of the raw base64 Apple receipts, StoreKit 2 signed transactions and/or Google / Amazon purchase tokens saved in your database?
Server Side Data Import
A server side import involves sending all of the Apple receipts and/or purchase tokens to RevenueCat via the POST /receipts
REST API endpoint. This will create the customer in RevenueCat, RevenueCat will validate the receipt and keep the subscription up-to-date. Ideally, you set up forwarding of new receipts/tokens first before sending any historic ones. RevenueCat will automatically deduplicate them.
This is the quickest way to get your existing subscribers into RevenueCat. See the API reference for more details.
Afterwards, the purchase data will be up to date in charts, customer lists, REST API etc., and if any of your customers open the version of the app containing the RevenueCat SDK their subscription status will automatically be synced.
If you are aiming to import very large volumes of historical data, please contact RevenueCat support to start a bulk data import process.
Google Play receipts that have been expired for more than 90 days ago can't be imported, and only the current status can be retrieved from each receipt. This means that historical data won't be presented accurately in Charts. To fill the gaps in historical data, you can use Google Historical Imports.
Client-side (SDK) Data Import
A client-side data migration is a technique to sync existing purchases with RevenueCat when the app is first launched. It requires integrating the RevenueCat SDK in your app.
The RevenueCat SDK will automatically detect new transactions and sends them to RevenueCat. However, when migrating from an older system, you need to tell the RevenueCat SDK to sync to ensure we are tracking your subscribers correctly. Keep in mind that with a client-side migration RevenueCat will only ever "see" customers that open the latest version of the app containing RevenueCat and sync their purchases.
The way to do this is: if your existing in-app purchase code knows that the customer has pre-existing purchases, but RevenueCat does not, then programmatically sync purchases.
See the following pseudo example.
- Swift
const isSubscribedInOldSystem = oldTracking.isSubscribed()
const isSubscribedInRevenueCat = !customerInfo.entitlements.active.isEmpty
// If the old system says we have a subscription, but RevenueCat does not
if (isSubscribedInOldSystem && !isSubscribedInRevenueCat)
{
// Tell Purchases to syncPurchases.
// This will sync the user's receipt with RevenueCat.
Purchases.shared.syncPurchases { (customerInfo, error) in }
}
When a customer launches with the first version containing RevenueCat it will trigger a sync. Once the sync is complete, it won't be triggered again.
It's okay to trigger a sync once per subscriber programmatically the first time they open a version of your app containing RevenueCat. You should not call this programmatically on every app launch for every user. This can increase latency in your app and can unintentionally alias customers together.