Purchases, entitlements, and optional SwiftUI paywalls
Receive verified purchase and entitlement updates without the SDK
In-app purchases
Keep purchase code simple.
Expand operations when you need to.
Purpl brings in-app purchase products, entitlements, catalogs, and paywalls into one coherent structure. Start locally for free, then connect Purpl when remote operations become useful.
- The store remains the source of truth
- Complete without the Purpl server
- SwiftUI paywall included
standardDisplayed products: 3defaultClear responsibilities
We do not hide purchases. We organize the complexity.
Each store keeps the final say while Purpl gives products, entitlements, restoration, and paywalls one consistent API.
The store is the source of truth
Prices, currencies, availability, and verified transactions always come from the connected store.
The server is optional
Use purchases, restoration, entitlement checks, and paywalls with local configuration and no Purpl account or API key.
One paywall API
Configuration written in your app and configuration fetched from Purpl use the same paywall UI and purchase flow.
Start locally
A complete purchase flow without a server.
Configure the products and entitlements for your app once. Purpl maps verified store transactions to app access and keeps watching for changes.
import Purpl
import PurplUI
let plus = PurchaseEntitlement(
identifier: "plus"
)
let monthly = PurchaseProduct(
productIdentifier: "app.plus.monthly",
entitlementIdentifier: plus.identifier
)
let configuration = PurchaseConfiguration(
entitlements: [plus],
products: [monthly]
)
let standard = PurchaseCatalog(
identifier: "standard",
products: [monthly]
)
let localPaywall = PaywallConfiguration(
catalog: standard,
defaultProductIdentifier: monthly.productIdentifier
)
Purchases.configure(configuration)Use only what you need
Local and remote, built on the same structure.
Keep sales configuration in app code first. Move catalogs and product order to Purpl when you need to operate them without a release.
Configure directly in the app
Pass an app-owned catalog to the paywall with no network dependency or external account.
PaywallView(
configuration: localPaywall
) {
PremiumMarketingContent()
}Manage sales configuration on the web
Manage catalogs and default products without a release, then show the same paywall by remote identifier.
PaywallView(
paywallIdentifier: "standard"
) {
PremiumMarketingContent()
}Domain model
Every type has one responsibility.
Separate store products, app access, sales catalogs, and presentation so legacy purchases remain valid while current paywalls stay focused.
Product
Connect an App Store Connect product identifier to the app entitlements granted after purchase.
Entitlement
Represent app access independently from monthly, yearly, or lifetime products.
Catalog
Define the products currently sold together and their display order. Legacy products stay in the full configuration.
Paywall
Connect a catalog and default product, then present them with your app's marketing content.
Purpl when you need it
Operate sales configuration without another app release.
The SDK leaves actual purchases to each store while Purpl manages only the operational information that needs to change on the web.
Displayed products and order
Choose the products sold on each paywall and change the order customers see.
Product and entitlement mapping
Connect multiple products to one or more entitlements with an explicit model.
Access for legacy purchasers
Remove retired products from catalogs while keeping them in restoration and entitlement calculations.