A complete StoreKit 2 purchase: plans load, the purchase runs, success lands, the app unlocks.
A complete StoreKit 2 paywall: loading skeleton, intro offers, purchase, restore, a transaction listener, a designed error state and a success moment before unlock.
$199 once, every piece included. See how installing works · Sign in
SwiftUI source you own, built on Apple frameworks only.
Paywall. Installed together, automatically.
In-App Purchase capability
Subscription Utility (brief), Onboarding to Paywall (recipe). Your agent builds around this screen in the same design.
Subscription App (template), Meditation App (template), Travel App (template), Sleep App (template), Smart Home App (template), Weather App (template), Meal Planner (template)
How it behaves, what it handles, and the decisions behind it.
Loads products with Product.products(for:), maps them to PaywallPlan including eligible free-trial intro offers, purchases with verification, restores with AppStore.sync() and Transaction.currentEntitlements, and keeps a Transaction.updates listener running so Ask to Buy, renewals and purchases on other devices are finished and unlock the app. While loading, the Paywall screen shows skeleton cards; a load failure shows a designed retry card; purchase failures surface inline through PaywallStatus. A verified unlock plays a brief ring-and-check moment before onUnlocked fires.
PaywallModel is an @Observable @MainActor class you can drive from tests without the view.onDismiss when the screen is embedded (for example inside OnboardingFlowScreen) rather than presented.GlassPaywallScreenExample at the end of GlassPaywallScreen.swift is the screen shown in the preview; copy it as a starting point.SPTheme from @Environment(\.spTheme) and requires the design-system item. The theme flows into GlassPaywallBlock through the environment, so one assignment styles both.accent at 45% to bg. The hero tile, close button and load-error card use spGlass, which turns opaque surfaceElevated under Reduce Transparency.accent; "Try again" uses accent with accentOn text.productIDs.Pieces that work well next to this one.