# PurchaseController

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

**Deprecated SDK**  
We strongly recommend migrating to the new [Superwall Expo SDK](/content/docs/expo/index.html), see our [migration guide](/content/docs/expo/guides/migrating-react-native/index.html) for details.

## [Purpose](/content/docs/react-native/sdk-reference/PurchaseController#purpose/index.html)

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](/content/docs/react-native/sdk-reference/PurchaseController#signature/index.html)

```
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](/content/docs/react-native/sdk-reference/PurchaseController#methods/index.html)

| Prop                        | Type                                                                               |
|-----------------------------|------------------------------------------------------------------------------------|
| `purchaseFromAppStore`     | productId: string                                                                  |
| `purchaseFromGooglePlay`   | productId: string, basePlanId?: string, offerId?: string                         |
| `restorePurchases`         | None                                                                              |

## [Usage](/content/docs/react-native/sdk-reference/PurchaseController#usage/index.html)

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](/content/docs/react-native/sdk-reference/PurchaseController#important-notes/index.html)

- When using a `PurchaseController`, you must call [`setSubscriptionStatus()`](/content/docs/react-native/sdk-reference/subscriptionStatus/index.html) 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.
