Purchases
Process in-app purchases with StoreKit 2 and sync to Nuxie
Purchases
Integrate StoreKit 2 purchases with Nuxie. The SDK syncs verified transactions to the server, which updates entitlements and feature access automatically. Purchases can be initiated from your native code or from within flows via the runtime bridge.
Setting up a purchase delegate
The SDK uses a delegate pattern for purchases. Implement NuxiePurchaseDelegate and assign it during configuration:
class MyPurchaseDelegate: NuxiePurchaseDelegate {
func purchase(_ product: StoreProductProtocol) async -> PurchaseResult {
// Initiate the StoreKit purchase
do {
let result = try await product.purchase()
return .success
} catch {
return .failed(error)
}
}
func purchaseOutcome(_ product: StoreProductProtocol) async -> PurchaseOutcome {
// Optional: return verified transaction data for faster sync
// Falls back to purchase() if not implemented
return .notHandled
}
func restore() async -> RestoreResult {
// Restore previous purchases
do {
try await AppStore.sync()
return .success
} catch {
return .failed(error)
}
}
}
let config = NuxieConfiguration(apiKey: "your_api_key")
config.purchaseDelegate = MyPurchaseDelegate()
try NuxieSDK.shared.setup(with: config)Warning: If your flows contain purchase or restore actions and no
purchaseDelegateis configured, those actions will fail at runtime.
How purchase sync works
When a user completes a purchase, the SDK syncs the transaction with Nuxie:
- StoreKit 2 verifies the transaction and provides a signed JWT.
- The SDK sends the JWT to the server.
- The server validates the transaction and updates the user's entitlements.
- The response includes updated feature access, which the SDK applies immediately to
FeatureInfo. - A
$purchase_syncedevent is tracked.
This means your UI can reflect the new entitlements as soon as the sync completes -- no need to wait for a profile refresh.
Transaction observer
On setup, the SDK starts a StoreKit 2 transaction observer that listens for:
- Unfinished transactions from prior sessions (e.g., purchases made while the app was offline).
- Transaction updates (new purchases, subscription renewals, revocations).
For each verified transaction, the observer:
- Extracts the signed JWT.
- Syncs it to the server.
- Updates
FeatureInfowith the new feature access. - Tracks a
$purchase_syncedevent. - Finishes the StoreKit transaction.
The observer deduplicates transactions by their original transaction ID, so the same transaction is not synced twice.
Purchases from flows
When a flow contains a purchase button, the runtime bridge handles the interaction:
- The user taps a purchase button in the flow.
- The bridge sends a purchase request to the native SDK with the StoreKit product ID.
- The SDK resolves the product details from StoreKit.
- Your
purchaseDelegateinitiates the purchase. - The SDK sends status messages back to the flow (success, cancelled, error).
- On success, the transaction is synced and features are updated.
The flow UI updates automatically based on these status messages, showing loading states and confirmation.
Restore from flows
Restore actions work the same way:
- The user taps a restore button in the flow.
- The bridge sends a restore request to the native SDK.
- Your
purchaseDelegate.restore()is called. - The result is sent back to the flow (success, error, no purchases found).
Purchase events
The SDK tracks these events during the purchase lifecycle:
Provider bridges
If you use RevenueCat or Superwall for purchase management, the SDK includes optional bridge libraries that implement NuxiePurchaseDelegate for you.
RevenueCat
import NuxieRevenueCat
let config = NuxieConfiguration(apiKey: "your_api_key")
config.purchaseDelegate = NuxieRevenueCatPurchaseDelegate()
try NuxieSDK.shared.setup(with: config)The RevenueCat bridge routes purchases through Purchases.purchase(product:) and restores through Purchases.restorePurchases().
Superwall
import NuxieSuperwall
let config = NuxieConfiguration(apiKey: "your_api_key")
config.purchaseDelegate = NuxieSuperwallPurchaseDelegate()
try NuxieSDK.shared.setup(with: config)The Superwall bridge routes purchases through Superwall.purchase(...) and restores through Superwall.restorePurchases().
Manual entitlement sync
To sync all current entitlements (for example, after a server-side grant), refresh the profile:
try await NuxieSDK.shared.refreshProfile()This fetches the latest profile from the server, which includes updated feature access from any source.
Next steps
- Features & Entitlements -- check and gate features based on purchases
- Presenting Flows -- learn how purchase actions work within flows
- Monetization -- configure products, pricing, and entitlements in the dashboard