Access your plans through the checkout.plans array. Each plan includes pricing and display information:
Report incorrect code
Copy
Ask AI
struct PlansView: View { @Environment(Checkout.self) var checkout var body: some View { Group { if checkout.plans.isEmpty { ProgressView("Loading plans...") } else { List(checkout.plans) { plan in HStack { VStack(alignment: .leading) { Text(plan.title ?? "Subscription") .font(.headline) Text(plan.description ?? "") .font(.subheadline) .foregroundStyle(.secondary) } Spacer() Text(plan.initialPrice, format: .currency(code: plan.baseCurrency)) .bold() } } } } }}
Plans are fetched during configure(). The plans array will be empty until configuration completes successfully. You can refresh plans later using refreshPlans().
The CheckoutPurchaseResult gives you confirmation details:
Report incorrect code
Copy
Ask AI
let result = try await checkout.purchase("plan_xxxxxxxxxxxxxx")// Access the new membership (for Whop purchases)if let membership = result.membership { print("Membership ID: \(membership.id)") print("Product: \(membership.productId)") print("Status: \(membership.status)")}// Store receipt for your recordssaveReceipt(result.receiptId)
Property Reference: CheckoutPurchaseResult
Property
Type
Description
receiptId
String
Unique receipt identifier
membership
CheckoutMembership?
The created/updated membership (nil for StoreKit-only purchases)
do { let result = try await checkout.purchase("plan_xxxxxxxxxxxxxx") showSuccessMessage()} catch WhopCheckoutError.cancelled { // User tapped outside the sheet or hit cancel // This is normal - don't show an error} catch WhopCheckoutError.notConfigured { // SDK not configured - shouldn't happen in production showError("Please restart the app.")} catch WhopCheckoutError.paymentFailed(let message) { // Card declined, insufficient funds, etc. showError("Payment failed: \(message)")} catch { // Unexpected error showError("Something went wrong. Please try again.")}
Don’t treat WhopCheckoutError.cancelled as an error. Users commonly dismiss checkout sheets to think about their purchase or check something else first.
You can refresh plans after initialization to get updated pricing or availability:
Report incorrect code
Copy
Ask AI
// Refresh and use the return valuelet plans = try await Checkout.shared.refreshPlans()// Or just refresh (plans property updates automatically)try await Checkout.shared.refreshPlans()