Skip to main content
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.

How It Works

  1. User purchases a subscription on your website.
  2. Your backend writes the entitlement to AppDNA.
  3. The SDK detects the change in real-time and updates the local cache.
  4. Your app reacts via the callback and unlocks premium features.
Web entitlements are separate from in-app purchase entitlements (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:
val entitlement = AppDNA.billing.webEntitlement
if (entitlement != null && entitlement.isActive) {
    unlockPremium()
    println("Plan: ${entitlement.planName}, Status: ${entitlement.status}")
}

Listen for Changes

Register a callback to react in real-time when the entitlement status changes:
AppDNA.billing.onWebEntitlementChanged { entitlement ->
    if (entitlement?.isActive == true) {
        unlockPremium()
    } else {
        lockPremium()
    }
}

WebEntitlement

PropertyTypeDescription
isActiveBooleanWhether the subscription is currently active
planNameStringName of the subscription plan
productIdStringProduct identifier
statusStringCurrent status
expiresAtDate?Expiration date

Entitlement Statuses

StatusDescription
activeSubscription is active and paid
trialingUser is in a free trial period
past_duePayment failed, in grace period
canceledSubscription is canceled

Auto-Tracked Events

EventTrigger
web_entitlement_activatedWeb subscription becomes active
web_entitlement_expiredWeb subscription expires or is canceled

Full Example

import ai.appdna.sdk.AppDNA

class PremiumManager {
    fun setup() {
        AppDNA.billing.onWebEntitlementChanged { entitlement ->
            updateAccessState(entitlement)
        }
    }

    fun checkAccessOnLaunch() {
        // Check in-app purchase entitlements
        val hasIAP = AppDNA.billing.hasActiveSubscription()
        if (hasIAP) {
            unlockPremium()
            return
        }

        // Check web entitlement
        val web = AppDNA.billing.webEntitlement
        if (web != null && web.isActive) {
            unlockPremium()
            return
        }

        lockPremium()
    }

    private fun updateAccessState(entitlement: WebEntitlement?) {
        if (entitlement?.isActive == true) {
            unlockPremium()
        } else {
            val hasIAP = AppDNA.billing.hasActiveSubscription()
            if (!hasIAP) lockPremium()
        }
    }
}
Web entitlements require Stripe integration configured in the Console under Settings > Billing > Web Payments. The real-time listener activates after identify() is called.