PurchaseController

An abstract class that defines the contract for a purchase controller.

Deprecated SDK

We strongly recommend migrating to the new Superwall Expo SDK, see our migration guide for details.

Purpose

Abstract class that defines the contract for a purchase controller. This is used for custom purchase handling when you want to manage all subscription-related logic yourself.

Signature

export abstract class PurchaseController {
  abstract purchaseFromAppStore(productId: string): Promise<PurchaseResult>;
  abstract purchaseFromGooglePlay(
    productId: string,
    basePlanId?: string,
    offerId?: string,
  ): Promise<PurchaseResult>;
  abstract restorePurchases(): Promise<RestorationResult>;
}

Methods

Prop

Type

Usage

Implement the PurchaseController class:

import {
  PurchaseController,
  PurchaseResult,
  RestorationResult,
  PurchaseResultCancelled,
  PurchaseResultFailed,
  PurchaseResultPurchased,
} from "@superwall/react-native-superwall";

class MyPurchaseController extends PurchaseController {
  async purchaseFromAppStore(productId: string): Promise<PurchaseResult> {
    try {
      // Your iOS purchase logic here
      // For example, using RevenueCat:
      const purchase = await Purchases.purchaseProduct(productId);

      if (purchase.customerInfo.entitlements.active["pro"]) {
        return new PurchaseResultPurchased();
      } else {
        return new PurchaseResultFailed("Purchase completed but entitlement not active");
      }
    } catch (error) {
      if (error.userCancelled) {
        return new PurchaseResultCancelled();
      }
      return new PurchaseResultFailed(error.message);
    }
  }

  async purchaseFromGooglePlay(
    productId: string,
    basePlanId?: string,
    offerId?: string,
  ): Promise<PurchaseResult> {
    try {
      // Your Android purchase logic here
      // For example, using RevenueCat:
      const purchase = await Purchases.purchaseProduct(productId);

      if (purchase.customerInfo.entitlements.active["pro"]) {
        return new PurchaseResultPurchased();
      } else {
        return new PurchaseResultFailed("Purchase completed but entitlement not active");
      }
    } catch (error) {
      if (error.userCancelled) {
        return new PurchaseResultCancelled();
      }
      return new PurchaseResultFailed(error.message);
    }
  }

  async restorePurchases(): Promise<RestorationResult> {
    try {
      // Your restore logic here
      // For example, using RevenueCat:
      const customerInfo = await Purchases.restorePurchases();

      if (customerInfo.entitlements.active["pro"]) {
        return RestorationResult.restored();
      } else {
        return RestorationResult.failed("No active subscription found");
      }
    } catch (error) {
      return RestorationResult.failed(error.message);
    }
  }
}

Configure Superwall with your purchase controller:

await Superwall.configure({
  apiKey: "pk_your_api_key",
  purchaseController: new MyPurchaseController(),
});

Important Notes

  • When using a PurchaseController, you must call setSubscriptionStatus() whenever the user's entitlements change.
  • The purchase controller is responsible for handling all purchase and restore logic.
  • You can use third-party services like RevenueCat, Stripe, or your own backend to handle purchases.

How is this guide?

On this page