This page documents all classes, methods, properties, and types available in WhopIAP.
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
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:
| Parameter | Type | Description |
|---|
companyID | String | Your Whop company ID (starts with biz_) |
productIDs | [String] | Array of product IDs to manage (starts with prod_) |
apiKey | String | Your 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:
| Parameter | Type | Description |
|---|
productId | String | The 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:
| Parameter | Type | Description |
|---|
planId | String | The 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:
| Parameter | Type | Description |
|---|
appUserId | String | Your 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.
Example:
Types
PurchaseResult
The result of a successful purchase.
struct PurchaseResult {
let receiptId: String
let membership: WhopIAPMembership
}
| Property | Type | Description |
|---|
receiptId | String | The unique receipt ID for this purchase |
membership | WhopIAPMembership | The 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
}
| Property | Type | Description |
|---|
id | String | The plan ID |
productId | String? | The product this plan belongs to |
title | String? | Display name of the plan |
planType | PlanType | Whether this is a one-time or recurring plan |
billingPeriodDays | Int? | Number of days in billing cycle (30 = monthly, 365 = yearly) |
baseCurrency | String | Currency code (e.g., “usd”) |
initialPrice | Double | Initial price of the plan |
renewalPrice | Double | Price for renewals |
trialPeriodDays | Int? | 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
}
| Property | Type | Description |
|---|
id | String | The membership ID |
productId | String | The product this membership belongs to |
planId | String | The plan this membership is for |
status | Status | Current status of the membership |
isClaimed | Bool | Whether the membership has been claimed by a user |
createdAt | Date | When the membership was created |
expiresAt | Date? | When the membership expires |
renewalPeriodEnd | Date? | End of the current renewal period |
cancelAtPeriodEnd | Bool | Whether the membership will cancel at period end |
receiptId | String? | The receipt ID for this membership |
WhopIAPError
Errors thrown by the SDK.
enum WhopIAPError: Error {
case cancelled
case tokenUnavailable
case paymentFailed(String)
}
| Case | Description |
|---|
cancelled | User dismissed the checkout sheet without completing purchase |
tokenUnavailable | API 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+