PurchaseController

A protocol for handling Superwall's subscription-related logic with your own purchase implementation.

This protocol is not required. By default, Superwall handles all subscription-related logic automatically.

When implementing PurchaseController, you must manually update subscriptionStatus whenever the user's entitlements change.

Purpose

Use this protocol only if you want complete control over purchase handling, such as when using RevenueCat, another third-party purchase framework, or your own external billing flow.

Signature

public protocol PurchaseController: AnyObject {
  @MainActor
  func purchase(product: StoreProduct) async -> PurchaseResult
  
  @MainActor
  func restorePurchases() async -> RestorationResult
}

Parameters

Prop

Type

Returns / State

  • purchase() returns a PurchaseResult (.purchased, .failed(Error), or .cancelled)
  • restorePurchases() returns a RestorationResult (.restored or .failed(Error?))

When using a PurchaseController, you must also manage subscriptionStatus yourself.

Handling Products

  • For App Store-backed products, use product.sk1Product or product.sk2Product, or pass the product into your existing purchase SDK.
  • For custom products introduced in 4.15.0, Superwall will call your purchase controller with a StoreProduct that has no StoreKit backing product. In that case, use product.productIdentifier in your external billing system and return the matching PurchaseResult.
  • Do not call Superwall.shared.purchase(product) for custom products. That helper is for StoreKit-backed purchases only.

Usage

For implementation examples and detailed guidance, see Using RevenueCat.

This is commonly used with RevenueCat, StoreKit 2, or other third-party purchase frameworks where you want to maintain your existing purchase logic.

How is this guide?

On this page