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

Checkout

The main class for managing in-app purchases. An @Observable class that can be used with SwiftUI’s environment system.
@MainActor @Observable
public class Checkout

shared

The shared Checkout instance. Use this singleton to configure the SDK and manage purchases.
static let shared: Checkout
Example:
import WhopCheckout

// Configure at app startup
try await Checkout.shared.configure(...)

// Pass through SwiftUI environment
ContentView()
    .environment(Checkout.shared)

// Access in views
@Environment(Checkout.self) var checkout

configure(companyId:apiKey:plans:)

Configures and initializes the SDK. Call this once at app startup.
func configure(
    companyId: String,
    apiKey: String,
    plans: [Plan] = []
) async throws
Parameters:
ParameterTypeDescription
companyIdStringYour Whop company ID (starts with biz_)
apiKeyStringYour API key with iap:read permission
plans[Plan]Mapping of Whop plan IDs to Apple StoreKit product IDs (required for StoreKit purchases outside the US)
Example:
try await Checkout.shared.configure(
    companyId: "biz_xxxxxxxxxxxxxx",
    apiKey: "your_api_key_here",
    plans: [
        .init(whopId: "plan_xxxxx", appleId: "monthly_sub"),
        .init(whopId: "plan_yyyyy", appleId: "yearly_sub")
    ]
)

isInitialized

Indicates whether the SDK has finished initializing.
var isInitialized: Bool { get }
Example:
if checkout.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: [CheckoutPlan] { get }
Example:
ForEach(checkout.plans) { plan in
    Text(plan.title ?? "Plan")
}

memberships

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

isSubscribed

Whether the user has any active membership.
var isSubscribed: Bool { get }
Example:
if checkout.isSubscribed {
    // Show premium content
}

supportsExternalPurchases

Whether the current App Store region supports external (non-StoreKit) purchases. Currently true for US users, false elsewhere.
var supportsExternalPurchases: Bool { get }
When true, the SDK defaults to Whop web checkout (lower fees). When false, it defaults to StoreKit.

refreshPlans()

Refreshes the available plans from the server.
@discardableResult
func refreshPlans() async throws -> [CheckoutPlan]
Returns: The refreshed plans with current pricing. Throws: WhopCheckoutError if the refresh fails. Call this to update pricing or plan availability after initialization. The plans property will also be updated with the latest data. Example:
// Refresh and use the return value
let plans = try await Checkout.shared.refreshPlans()

// Or just refresh (plans property updates automatically)
try await Checkout.shared.refreshPlans()

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 Example:
// Replace with your product ID from the Whop dashboard
if checkout.hasAccess(to: "prod_xxxxxxxxxxxxxx") {
    // Show pro features
}

purchase(_:method:)

Initiates a purchase flow for a plan. By default, uses Whop web checkout in the US (lower fees) and StoreKit elsewhere.
func purchase(_ whopPlanId: String, method: PaymentMethod? = nil) async throws -> CheckoutPurchaseResult
Parameters:
ParameterTypeDescription
whopPlanIdStringThe Whop plan ID to purchase (starts with plan_)
methodPaymentMethod?Override the payment method. Defaults based on region.
Returns: CheckoutPurchaseResult containing the receipt ID and membership information Throws:
  • WhopCheckoutError.cancelled if the user dismisses the checkout
  • WhopCheckoutError.notConfigured if the SDK is not configured
  • WhopCheckoutError.paymentFailed(String) if the payment fails
Example:
do {
    // Use default payment method (Whop in US, StoreKit elsewhere)
    let result = try await checkout.purchase("plan_xxxxxxxxxxxxxx")
    print("Success! Receipt: \(result.receiptId)")
} catch WhopCheckoutError.cancelled {
    // User cancelled
} catch {
    // Handle error
}

// Or explicitly choose a payment method
let result = try await checkout.purchase("plan_xxx", method: .apple)

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)
Example:
try await checkout.logIn(appUserId: "user_123")

logOut()

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

restorePurchases()

Restores purchases from both StoreKit and Whop.
func restorePurchases() async throws -> Bool
Returns: true if any active subscription was found Example:
Button("Restore Purchases") {
    Task {
        let restored = try await checkout.restorePurchases()
        if restored {
            print("Purchases restored!")
        }
    }
}

Types

CheckoutPurchaseResult

The result of a successful purchase.
struct CheckoutPurchaseResult {
    let receiptId: String
    let membership: CheckoutMembership?
}
PropertyTypeDescription
receiptIdStringThe unique receipt ID for this purchase
membershipCheckoutMembership?The membership created by this purchase (nil for StoreKit-only purchases)

Plan

Mapping between a Whop plan and an Apple StoreKit product. Required for StoreKit purchases outside the US.
struct Plan: Sendable {
    let whopId: String
    let appleId: String

    init(whopId: String, appleId: String)
}
PropertyTypeDescription
whopIdStringThe Whop plan ID (e.g., plan_xxx)
appleIdStringThe Apple product ID from App Store Connect (e.g., com.yourapp.monthly)
Your Whop plans and Apple products should have matching pricing and billing periods. See Setup → Plan Mappings for details on configuring App Store Connect.

PaymentMethod

The payment method to use for a purchase.
enum PaymentMethod: Sendable {
    case whop   // Web checkout via Whop (lower fees)
    case apple  // StoreKit purchase via Apple
}
CaseDescription
whopWeb checkout via Whop. 2.7% + $0.30 fees (vs Apple’s 15-30%). Available in the US.
appleStoreKit purchase via Apple (15-30% fees). Required outside the US.

CheckoutPlan

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

    var renewalPeriod: RenewalPeriod? { get }
    var whopDisplayPrice: String { get }
    var appleDisplayPrice: String? { get }
}

enum PlanType: String {
    case oneTime = "one_time"
    case renewal
    case unknown
}

enum RenewalPeriod: Equatable {
    case weekly      // 7 days
    case monthly     // 30 days
    case quarterly   // 90 days
    case semiAnnual  // 180 days
    case yearly      // 365 days
    case custom(Int) // Custom period in days
}
PropertyTypeDescription
idStringThe plan ID
productIdString?The product this plan belongs to
titleString?Display name of the plan
descriptionString?Description text for 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
renewalPeriodRenewalPeriod?Computed renewal period (.monthly, .yearly, etc.)
whopDisplayPriceStringFormatted Whop price (e.g., “$9.99”)
appleDisplayPriceString?Localized StoreKit price, if a plan mapping exists

CheckoutMembership

An active subscription membership.
struct CheckoutMembership: 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?

    var isActive: Bool { get }
}

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
isActiveBoolWhether the membership grants access (true for active, trialing, canceling, pastDue, completed)
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

WhopCheckoutError

Errors thrown by the SDK.
enum WhopCheckoutError: Error {
    case cancelled
    case notConfigured
    case paymentFailed(String)
}
CaseDescription
cancelledUser dismissed the checkout sheet without completing purchase
notConfiguredSDK is not configured. Call Checkout.shared.configure() first.
paymentFailed(String)Payment failed. The associated string contains the error message.

Requirements

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