Unity

Instructions for installing Purchases SDK for Unity

What is RevenueCat?

RevenueCat provides a backend and a wrapper around StoreKit and Google Play Billing to make implementing in-app purchases and subscriptions easy. With our SDK, you can build and manage your app business on any platform without having to maintain IAP infrastructure. You can read more about how RevenueCat fits into your app or you can sign up free to start building.

Installation

Import the Purchases Unity package

Download the latest version of Purchases.unitypackage.

Import the downloaded unitypackage to your Unity project. Make sure the PlayServiceResolver and the ExternalDependencyManager folders are also added. These folders will install the EDM4U plugin, which will add all the Android and iOS dependencies automatically when building your project.
If you're running purchases-unity v3.5.1 or later, also make sure that the RevenueCatPostInstall script is added, since it will set up StoreKit for iOS and prevent issues when uploading builds to App Store Connect in Unity 2020.

🚧

ExternalDependencyManager plugin

Make sure the ExternalDependencyManager is properly installed. Otherwise our plugin will not be able to compile. If you don't see the option under the Assets menu after restarting the editor, try reinstalling the RevenueCat plugin or manually importing the EDM4U plugin.

📘

Android InAppBillingService in versions of purchases-unity < 2.3.0

If using the RevenueCat plugin older than 2.3.0 alongside Unity IAP or other plugin that includes the Android InAppBillingService class, or you are getting Duplicate class com.android.vending.billing.IInAppBillingService please update to the latest Unity SDK or see the legacy install instructions

Create a GameObject with the Purchases behavior

The Purchases package will include a MonoBehavior called Purchases. This will be your access point to RevenueCat from inside Unity. It should be instantiated once and kept as a singleton. You can use properties to configure your API Key, app user ID (if you have one), and product identifiers you want to fetch.

The Purchases behavior is configured with your RevenueCat API key and the product identifiers you want to fetch.The Purchases behavior is configured with your RevenueCat API key and the product identifiers you want to fetch.

The Purchases behavior is configured with your RevenueCat API key and the product identifiers you want to fetch.

Link StoreKit

On iOS, add StoreKit.framework to Linked Frameworks and Libraries in Xcode.

Subclass Purchases.Listener MonoBehavior

The Purchases behavior takes one additional parameter, a GameObject with a Purchases.Listener component. This will be where you handle purchase events, and updated subscriber information from RevenueCat. Here is a simple example:

using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

public class PurchasesListener : Purchases.UpdatedPurchaserInfoListener
{
  
  private void Start()
    {
        CreateButton("Restore Purchases", RestoreClicked, 100);

        CreateButton("Do Other Stuff", DoOtherStuff, 300);

        var purchases = GetComponent<Purchases>();
        purchases.SetDebugLogsEnabled(true);
        purchases.GetOfferings((offerings, error) =>
        {
            if (error != null)
            {
                LogError(error);
            }
            else
            {
               var package = offerings.Current.Monhtly;
               if (package == null) continue;
                    var label = package.PackageType + " " + package.Product.priceString;
                    CreateButton(label, () => ButtonClicked(package), 500);
                }
            }
        });
    }
  
    void ButtonClicked(Purchases.Package package)
    {
        Purchases purchases = GetComponent<Purchases>();
        purchases.PurchasePackage(package, (productIdentifier, purchaserInfo, userCancelled, error) =>
        {
            if (!userCancelled)
            {
                if (error != null)
                {
                    LogError(error);
                }
                else
                {
                    DisplayPurchaserInfo(purchaserInfo);
                }
            } else
            {
                Debug.Log("Subtester: User cancelled, don't show an error");
            }
        });
    }
    
    void DoOtherStuff()
    {
        var purchases = GetComponent<Purchases>();
        var data = new AdjustData
        {
            adid = "test",
            network = "network",
            adgroup = "adgroup",
            campaign = "campaign",
            creative = "creative",
            clickLabel = "clickLabel",
            trackerName = "trackerName",
            trackerToken = "trackerToken"
        };

        purchases.AddAttributionData(JsonUtility.ToJson(data), Purchases.AttributionNetwork.ADJUST);
        
        purchases.GetPurchaserInfo((info, error) =>
        {
            Debug.Log("purchaser info " + info.ActiveSubscriptions);
            if (error != null) {
                LogError(error);
            }
        });
        
        Debug.Log("user ID " + purchases.GetAppUserId());
    }

    void RestoreClicked()
    {
        var purchases = GetComponent<Purchases>();
        purchases.RestoreTransactions((purchaserInfo, error) =>
        {
            if (error != null)
            {
                LogError(error);
            }
            else
            {
                DisplayPurchaserInfo(purchaserInfo);
            }
        });
    }

    
    public override void PurchaserInfoReceived(Purchases.PurchaserInfo purchaserInfo)
    {
        DisplayPurchaserInfo(purchaserInfo);
    }
    
    private void logError(Purchases.Error error)
    {
        Debug.Log("Subtester: " + JsonUtility.ToJson(error));
    }


    private void DisplayPurchaserInfo(Purchases.PurchaserInfo purchaserInfo)
    {
        // Show purchaser info on screen
    }
}

Proguard rules

If you have enabled Minify in Unity, make sure to add these custom rules to your Assets/Plugins/Android/proguard-user.txt and enable the Custom Proguard File setting in Publishing Settings:

-keep class com.revenuecat.** { *; }

Installation with Unity IAP side by side

❗️

Unity IAP doesn't work with version 3.3.0+ of the purchases plugin

Make sure to use version 3.2.0 of our plugin. Due to incompatibilities with the version of BillingClient used by Unity IAP, the latest versions of the plugin won't work alongside Unity IAP until Unity IAP gets updated to BillingClient 4.x.x.

❗️

Follow this instruction if using RevenueCat alongside Unity IAP 2.2.0+, other plugin that includes the Android InAppBillingService class, or for some other reason you get an error regarding duplicated classes.

If using RevenueCat alongside Unity IAP 2.2.0+ or other plugin that includes the Android BillingClient library you will be getting an error when compiling that warns about some BillingClient classes being duplicated.

The easiest way to remove the error would be to tell Gradle to not include the billingclient library that Unity IAP is already including.

In order to do that, make sure you have Custom Main Gradle Template selected in the Android Player Settings... That should create a mainTemplate.gradle inside the Assets/Plugins/Android.

Modify the mainTemplate.gradle to include the following at the end of the dependencies block:

dependencies {
    ...
    
    // ** ADD THIS **
    configurations.all {
        exclude group: 'com.android.billingclient', module: 'billing'
    }
}

Perform a clean up of the resolved dependencies using the Assets/External Dependency Manager/Android Resolver/Delete Resolved Libraries menu. This will cleanup the previously downloaded .aars in Assets/Plugins/Android. Otherwise you could end up with duplicated classes errors.

Also make sure to perform a resolve, so External Dependency Manager adds the right dependencies to the generated build.gradle.

Next Steps


Did this page help you?