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
purchaseFromAppStore productId: string
purchaseFromGooglePlay productId: string, basePlanId?: string, offerId?: string
restorePurchases None

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);

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.