Web entitlements enable apps that sell subscriptions via web checkout (e.g., Stripe) to unlock premium features in the native app in real-time. After calling identify(), the SDK listens for entitlement changes automatically — when a user purchases on the web, the app unlocks instantly without a restart.
How It Works
- User purchases a subscription on your website (via Stripe or another web payment provider).
- Your backend writes the entitlement to AppDNA.
- The SDK detects the change in real-time and updates the local cache.
- Your app reacts via the callback and unlocks premium features.
Web entitlements are separate from in-app purchase entitlements (StoreKit / Play Billing). They are designed for apps that also sell subscriptions through a web checkout flow.
Check Current Entitlement
After identify(), the current web entitlement is available synchronously from cache:
if let entitlement = AppDNA.webEntitlement, entitlement.isActive {
// User has an active web subscription
unlockPremium()
print("Plan: \(entitlement.planName ?? "unknown"), Status: \(entitlement.status)")
if let periodEnd = entitlement.currentPeriodEnd {
print("Renews: \(periodEnd)")
}
}
Listen for Changes
Register a callback to react in real-time when the entitlement status changes:
AppDNA.onWebEntitlementChanged { entitlement in
if entitlement?.isActive == true {
unlockPremium()
} else {
lockPremium()
}
}
This fires immediately when:
- A new web subscription is purchased
- A subscription renews
- A subscription expires or is canceled
- A subscription enters a grace period
WebEntitlement
| Property | Type | Description |
|---|
isActive | Bool | Whether the subscription is currently active |
planName | String? | Name of the subscription plan |
priceId | String? | Stripe price identifier |
status | EntitlementStatus | Current status enum (see below) |
currentPeriodEnd | Date? | End date of the current billing period |
interval | String? | Billing interval (e.g., "month", "year") |
trialEnd | Date? | Trial expiration date, if in a trial |
Entitlement Statuses
| Status | Description |
|---|
active | Subscription is active and paid |
trialing | User is in a free trial period |
past_due | Payment failed, in grace period |
canceled | Subscription is canceled (access may continue until period ends) |
Access
Web entitlements are accessed as a top-level static property on AppDNA:
let webEntitlement = AppDNA.webEntitlement
Auto-Tracked Events
| Event | Trigger |
|---|
web_entitlement_activated | Web subscription becomes active |
web_entitlement_expired | Web subscription expires or is canceled |
Full Example
import AppDNASDK
class PremiumManager {
func setup() {
// Listen for web entitlement changes
AppDNA.onWebEntitlementChanged { [weak self] entitlement in
DispatchQueue.main.async {
self?.updateAccessState(entitlement: entitlement)
}
}
}
func checkAccessOnLaunch() {
// Check in-app purchase entitlements
Task {
let hasIAP = await AppDNA.billing.hasActiveSubscription()
if hasIAP {
unlockPremium()
return
}
}
// Check web entitlement
if let web = AppDNA.webEntitlement, web.isActive {
unlockPremium()
return
}
// No active subscription from either source
lockPremium()
}
private func updateAccessState(entitlement: WebEntitlement?) {
if entitlement?.isActive == true {
unlockPremium()
} else {
// Re-check IAP entitlements before locking
Task {
let hasIAP = await AppDNA.billing.hasActiveSubscription()
if !hasIAP {
lockPremium()
}
}
}
}
private func unlockPremium() {
// Enable premium features
}
private func lockPremium() {
// Disable premium features
}
}
Web entitlements require Stripe (or compatible payment provider) integration configured in the Console under Settings > Billing > Web Payments. The real-time listener activates automatically after identify() is called.