Skip to main content
This page documents all classes, methods, properties, and types available in WhopIAP.
Looking for guides? See Build a Paywall or Check Entitlements.

WhopIAP

The main class for managing in-app purchases. An @Observable class that can be used with SwiftUI’s environment system or accessed via the shared singleton.
@MainActor @Observable
public class WhopIAP

shared

The shared singleton instance of the SDK.
static var shared: WhopIAP
Example:
import WhopPayments

@State private var iap = WhopIAP.shared

configure(companyID:productIDs:apiKey:)

Configures and initializes the SDK. Call this once at app startup. Returns the configured instance.
static func configure(
    companyID: String,
    productIDs: [String],
    apiKey: String
) async throws -> WhopIAP
Parameters:
ParameterTypeDescription
companyIDStringYour Whop company ID (starts with biz_)
productIDs[String]Array of product IDs to manage (starts with prod_)
apiKeyStringYour API key from the Developer Settings
Returns: The configured WhopIAP instance Example:
iap = try await WhopIAP.configure(
    companyID: "biz_xxxxxxxxxxxxxx",
    productIDs: ["prod_xxxxxxxxxxxxxx"],
    apiKey: "your_api_key_here"
)

isInitialized

Indicates whether the SDK has finished initializing.
var isInitialized: Bool { get }
Example:
if iap.isInitialized {
    // SDK ready to use
}

deviceId

The unique device identifier managed by the SDK. Persists across app launches using the iOS Keychain.
var deviceId: String { get }

appUserId

The current logged-in user ID, or nil if no user is logged in.
var appUserId: String? { get }

plans

Array of available subscription plans for the configured products.
var plans: [WhopIAPPlan] { get }
Example:
ForEach(iap.plans) { plan in
    Text(plan.title ?? "Plan")
}

memberships

Array of active memberships for the current user or device.
var memberships: [WhopIAPMembership] { get }

hasAccess(to:)

Checks if the user has access to a specific product.
func hasAccess(to productId: String) -> Bool
Parameters:
ParameterTypeDescription
productIdStringThe product ID to check (starts with prod_)
Returns: true if the user has an active membership for the product
The product ID must be included in the productIDs array when configuring the SDK.
Example:
if iap.hasAccess(to: "prod_pro_features") {
    // Show pro features
}

purchase(_:)

Initiates a purchase flow for a plan. Presents a checkout sheet, handles the payment, and returns when complete.
func purchase(_ planId: String) async throws -> PurchaseResult
Parameters:
ParameterTypeDescription
planIdStringThe plan ID to purchase (starts with plan_)
Returns: PurchaseResult containing the receipt ID and membership information Throws:
  • WhopIAPError.cancelled if the user dismisses the checkout
  • WhopIAPError.tokenUnavailable if the access token is unavailable
  • WhopIAPError.paymentFailed(String) if the payment fails
Example:
do {
    let result = try await iap.purchase("plan_xxxxxxxxxxxxxx")
    print("Success! Membership: \(result.membership.id)")
} catch WhopIAPError.cancelled {
    // User cancelled
} catch {
    // Handle error
}

logIn(appUserId:)

Logs in a user and claims any unclaimed memberships associated with the device.
func logIn(appUserId: String) async throws
Parameters:
ParameterTypeDescription
appUserIdStringYour app’s user ID (should not change for the same user)
Throws: WhopIAPError.tokenUnavailable if the access token is unavailable Example:
try await iap.logIn(appUserId: "user_123")

logOut()

Logs out the current user and clears their memberships from the local state.
func logOut()
Example:
iap.logOut()

Types

PurchaseResult

The result of a successful purchase.
struct PurchaseResult {
    let receiptId: String
    let membership: WhopIAPMembership
}
PropertyTypeDescription
receiptIdStringThe unique receipt ID for this purchase
membershipWhopIAPMembershipThe membership created by this purchase

WhopIAPPlan

A subscription plan available for purchase.
struct WhopIAPPlan: Identifiable {
    let id: String
    let productId: String?
    let title: String?
    let planType: PlanType
    let billingPeriodDays: Int?
    let baseCurrency: String
    let initialPrice: Double
    let renewalPrice: Double
    let trialPeriodDays: Int?
}

enum PlanType: String {
    case oneTime = "one_time"
    case renewal
    case unknown
}
PropertyTypeDescription
idStringThe plan ID
productIdString?The product this plan belongs to
titleString?Display name of the plan
planTypePlanTypeWhether this is a one-time or recurring plan
billingPeriodDaysInt?Number of days in billing cycle (30 = monthly, 365 = yearly)
baseCurrencyStringCurrency code (e.g., “usd”)
initialPriceDoubleInitial price of the plan
renewalPriceDoublePrice for renewals
trialPeriodDaysInt?Number of days in trial period

WhopIAPMembership

An active subscription membership.
struct WhopIAPMembership: Identifiable {
    let id: String
    let productId: String
    let planId: String
    let status: Status
    let isClaimed: Bool
    let createdAt: Date
    let expiresAt: Date?
    let renewalPeriodEnd: Date?
    let cancelAtPeriodEnd: Bool
    let receiptId: String?
}

enum Status: String {
    case active
    case canceled
    case canceling
    case completed
    case drafted
    case expired
    case pastDue = "past_due"
    case trialing
    case unresolved
    case unknown
}
PropertyTypeDescription
idStringThe membership ID
productIdStringThe product this membership belongs to
planIdStringThe plan this membership is for
statusStatusCurrent status of the membership
isClaimedBoolWhether the membership has been claimed by a user
createdAtDateWhen the membership was created
expiresAtDate?When the membership expires
renewalPeriodEndDate?End of the current renewal period
cancelAtPeriodEndBoolWhether the membership will cancel at period end
receiptIdString?The receipt ID for this membership

WhopIAPError

Errors thrown by the SDK.
enum WhopIAPError: Error {
    case cancelled
    case tokenUnavailable
    case paymentFailed(String)
}
CaseDescription
cancelledUser dismissed the checkout sheet without completing purchase
tokenUnavailableAPI key is invalid or missing
paymentFailed(String)Payment failed. The associated string contains the error message.

Requirements

  • iOS 17.0+
  • Xcode 16.0+
  • Swift 5.10+