Making Purchases

Process a transaction with Apple or Google

When it comes time to make a purchase, Purchases SDK has a simple method, purchasePackage, that takes a package from the fetched Offering and purchases the underlying product with Apple, Google, or Amazon.

Purchases.shared.purchasePackage(package) { (transaction, purchaserInfo, error, userCancelled) in
  if purchaserInfo.entitlements["your_entitlement_id"]?.isActive == true {
    // Unlock that great "pro" content              
  }
}
[[RCPurchases sharedPurchases] purchasePackage:package withCompletionBlock:^(SKPaymentTransaction *transaction, RCPurchaserInfo *purchaserInfo, NSError *error, BOOL cancelled) {
  if (purchaserInfo.entitlements[@"your_entitlement_id"].isActive) {
    // Unlock that great "pro" content
  }
}];
Purchases.sharedInstance.purchasePackageWith(
  this,
  aPackage,
  onError = { error, userCancelled -> /* No purchase */ },
  onSuccess = { product, purchaserInfo ->
    if (purchaserInfo.entitlements["my_entitlement_identifier"]?.isActive == true) {
    // Unlock that great "pro" content
  }
})
Purchases.getSharedInstance().purchasePackage(
    this,
    aPackage,
    new MakePurchaseListener() {
        @Override
        public void onCompleted(@NonNull Purchase purchase, @NonNull PurchaserInfo purchaserInfo) {
            if (purchaserInfo.getEntitlements().get("my_entitlement_identifier").isActive()) {
              // Unlock that great "pro" content
            }
        }

        @Override
        public void onError(@NonNull PurchasesError error, Boolean userCancelled) {
          // No purchase
        }
    }
);
try {
  PurchaserInfo purchaserInfo = await Purchases.purchasePackage(package);
  if (purchaserInfo.entitlements.all["my_entitlement_identifier"].isActive) {
    // Unlock that great "pro" content
  }
} on PlatformException catch (e) {
  var errorCode = PurchasesErrorHelper.getErrorCode(e);
  if (errorCode != PurchasesErrorCode.purchaseCancelledError) {
    showError(e);             
  }
}
// Using Offerings/Packages
try {
  const {purchaserInfo, productIdentifier} = await Purchases.purchasePackage(package);
  if (typeof purchaserInfo.entitlements.active.my_entitlement_identifier !== "undefined") {
    // Unlock that great "pro" content
  }
} catch (e) {
  if (!e.userCancelled) {
    showError(e);
  }
}

// -----
// If you are NOT using Offerings/Packages:
await Purchases.purchaseProduct("product_id");

// Or, optionally provide the product type as the third parameter
// Defaults to PURCHASE_TYPE.SUBS
await Purchases.purchaseProduct("product_id", null, Purchases.PURCHASE_TYPE.INAPP);
Purchases.purchasePackage(package, ({ productIdentifier, purchaserInfo }) => {
    if (typeof purchaserInfo.entitlements.active.my_entitlement_identifier !== "undefined") {
      // Unlock that great "pro" content
    }
  },
  ({error, userCancelled}) => {
    // Error making purchase
  }
);

// Note: if you are using purchaseProduct to purchase Android In-app products, an optional third parameter needs to be provided when calling purchaseProduct. You can use the package system to avoid this.

Purchases.purchaseProduct("product_id", ({ productIdentifier, purchaserInfo }) => {
}, ({error, userCancelled}) => {
    // Error making purchase
}, null, Purchases.PURCHASE_TYPE.INAPP);
Purchases purchases = GetComponent<Purchases>();
purchases.PurchasePackage(package, (productIdentifier, purchaserInfo, userCancelled, error) =>
{
  if (purchaserInfo.Entitlements.Active.ContainsKey("my_entitlement_identifier")) {
    // Unlock that great "pro" content
  }
});

The purchasePackage completion block will contain an updated PurchaserInfo object if successful, along with some details about the transaction.

If the error object is present, then the purchase failed. See our guide on Error Handling for the specific error types.

The userCancelled boolean is a helper for handling user cancellation errors. There will still be an error object if the user cancels, but you can optionally check the boolean instead of unwrapping the error completely.

🚧

Warning: Automatic Transaction Finishing/Acknowledgement/Consumption

Transactions (new and previous transactions that are synced) will be automatically finished (acknowledged in Android), and will be made available through the RevenueCat SDK / Dashboard / ETL Exports.

You can use observer mode if you don't wish to have transactions finished automatically, but you will have to make sure that you finish them yourself.

Next Steps