RevenueCat

Build With RevenueCat

Build a customized mobile subscription business with RevenueCat. We do the heavy lifting of normalizing subscribers from any source and maintain a single source of truth for subscription status, so you can get back to building your app.

RevenueCat is a powerful, secure, reliable, and free to use in-app purchase server with global support. All you need to get started is an API key.

App User IDs

How RevenueCat handles user identity

This section assumes you've followed our Quickstart section of our Getting Started guide to install and configure our SDK.

RevenueCat provides a source of truth for a subscriber's status across different platforms. To do this, each subscriber has an App User ID that uniquely identifies them within your application.

Random App User ID

If you don't provide an App User ID when instantiating the Purchases SDK, RevenueCat will create a new random App User ID for you and cache it on the device.

In the event that the user deletes and reinstalls the app, this random App User ID will be unrecoverable and a new random App User ID will be generated. Restoring in-app purchases will recover any subscriptions and alias the new and old random App User IDs together.

Provided App User ID

Setting your own App User ID will allow you to reference users in the RevenueCat dashboard, via the API, as well as in the webhooks and other integrations.

Using an externally managed App User ID also provides a mechanism by which to restore purchases in a few scenarios:

  • When a user deletes and reinstalls your app - using the same App User ID will ensure they still haves access to subscriptions previously started.
  • When the user logs in on multiple devices - you can honor a subscription that was purchased on one device across any other platform.

Set App User ID on instantiation

If you have your own App User IDs, you can pass those on instantiation to Purchases.

Purchases.configure(withAPIKey: "my_api_key", appUserID: "my_app_user_id")
[RCPurchases configureWithAPIKey:@"my_api_key" appUserID:@"my_app_user_id"];
Purchases.configure(this, "my_api_key", "my_app_user_id")
Purchases.configure(this, "my_api_key", "my_app_user_id");

Convert Random App User ID to Provided App User ID

If you don't have an App User ID on instantiation, you can set it later through the identify() method. Using identify() will clear any caches and re-fetch info for that user.

It's usually preferable to wait until you have your User ID to initialize Purchases. However, you can use .identify() a user logs out, and you need to sign in a new user.

Purchases.shared.identify("my_app_user_id") { (purchaserInfo, error) in
    
    // New user set with purchaserInfo from my_app_user_id
}
[[RCPurchases sharedPurchases] identify:@"my_app_user_id" completionBlock:^(RCPurchaserInfo *purchaserInfo, NSError *error) {
    
    // New user set with purchaserInfo from my_app_user_id
}];
Purchases.sharedInstance.identify("my_app_user_id") { ReceivePurchaserInfoListener { purchaserInfo, error ->
  // New user set with purchaserInfo from my_app_user_id
}
Purchases.getSharedInstance().identify("my_app_user_id", new ReceivePurchaserInfoListener() {
	@Override
	public void onReceived(@android.support.annotation.Nullable PurchaserInfo purchaserInfo, @android.support.annotation.Nullable PurchasesError error) {
		// New user set with purchaserInfo from my_app_user_id
	}
});

App User IDs Should Not Be Guessable

RevenueCat provides subscription status via the public API, having App User IDs that are easily guessed is not good. It is recommended to use a non-guessable psuedo-random ID that isn't made public inside your app.

For App User IDs generated by RevenueCat, we use a UUID.

Don't set emails as App User IDs

For the above reason, and GDPR compliance, we don't recommend using email addresses as App User IDs

Aliases

Aliases are a way for RevenueCat to attach multiple App User IDs to a single subscriber. This is useful when a user has multiple devices and you are relying on random App User IDs or when a user makes a purchase before logging in. For example:

Alias 1 and 2 both reference the same subscriber and the same subscriptions.

Alias 1 and 2 both reference the same subscriber and the same subscriptions.

There are two ways that aliases are created:

  • Restoring purchases
  • Calling createAlias

Restoring Purchases

Restoring purchases is a mechanism by which your user can restore their in-app purchases, reactivating any content that had previously been purchased from the same store account (Apple or Google).

If two different App User IDs try to restore transactions from the same underlying store account (Apple or Google) RevenueCat will create an alias between the two App User IDs and count them as the same user going forward.

This is a common if your app does not have accounts and is relying on RevenueCat's random App User IDs.

Purchases.shared.restoreTransactions { (purchaserInfo, error) in
    //... check purchaserInfo to see if entitlement is now active
}
[[RCPurchases sharedPurchases] restoreTransactionsWithCompletionBlock:^(RCPurchaserInfo *purchaserInfo, NSError *error) {
    //... check purchaserInfo to see if entitlement is now active
}];
Purchases.sharedInstance.restorePurchases(ReceivePurchaserInfoListener { purchaserInfo, error ->
	//... check purchaserInfo to see if entitlement is now active
})
Purchases.getSharedInstance().restorePurchases(new ReceivePurchaserInfoListener() {
	@Override
	public void onReceived(@android.support.annotation.Nullable PurchaserInfo purchaserInfo, @android.support.annotation.Nullable PurchasesError error) {
    //... check purchaserInfo to see if entitlement is now active 	
  }
});

Restoring purchases for logged in users

If you've provided your own App User ID, calling restoreTransactions could alias the logged in user to another generated App User ID that has made a purchase on the same device.

Allow Sharing App or Play Store Accounts

By default, RevenueCat will not let you reuse an App or Play Store account that already has an active subscription. If you set allowSharingAppStoreAccount = True the SDK will be permissive in accepting shared accounts, creating aliases as needed.

By default allowSharingAppStoreAccount is True for RevenueCat random App User IDs but must be enabled manually if you want to allow permissive sharing for your own App User IDs.

Manually Creating Aliases

Sometimes, it is useful to manually create an alias. This is most often used when an app allows users to purchase before logging in.

To do this, you can call the createAlias() method on Purchases.

Purchases.shared.createAlias("my_app_user_id") { (purchaserInfo, error) in
            
    // my_app_user_id added as an alias for current user
}
[[RCPurchases sharedPurchases] createAlias:@"my_app_user_id" completionBlock:^(RCPurchaserInfo *purchaserInfo, NSError *error) {
    
    // my_app_user_id added as an alias for current user
}];
Purchases.sharedInstance.createAlias("my_app_user_id", ReceivePurchaserInfoListener { purchaserInfo, error ->
  // my_app_user_id added as an alias for current user
})
Purchases.getSharedInstance().createAlias("my_app_user_id", new ReceivePurchaserInfoListener() {
  @Override
  public void onReceived(@Nullable PurchaserInfo purchaserInfo, @Nullable PurchasesError error) {
    // my_app_user_id added as an alias for current user
  }
});

This is great if a user makes a purchase with a generated App User ID, that you later want to link to a provided App User ID. For example:

  1. User opens the app, Purchases is instantiated without an App User ID therefore generating a random App User ID
  2. User purchases a subscription, attaching the subscription to the generated ID
  3. User creates an account
  4. Developer calls createAlias(newAppUserID) to link the previous purchase to newAppUserID in RevenueCat

Now the subscriber can be referenced in the Purchases SDK or the REST API by using the developer specified App User ID.

Logging Out

When a user logs out you can call the reset() method on Purchases to reset the App User ID to a new generated App User ID. This sets you up with a new anonymous user for the logged out state.

Logging out will reset the account sharing preference

Calling reset() will set allowSharingStoreAccount to True, be sure to set this back if needed.

Next Steps