Skip to main content
Supported on: iOS SDK 1.0.61+ · Android SDK 1.0.33+ · React Native SDK 1.0.4+
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

  1. User purchases a subscription on your website (via Stripe or another web payment provider).
  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 subscription callback and unlocks premium features.
Web entitlements are separate from in-app purchase entitlements (StoreKit on iOS, Play Billing on Android). 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 via an async getter on AppDNA. The native SDK returns the cached value immediately when available:
import { AppDNA } from '@appdna/react-native-sdk';

const entitlement = await AppDNA.getWebEntitlement();
if (entitlement && entitlement.isActive) {
  // User has an active web subscription
  unlockPremium();
  console.log(`Plan: ${entitlement.planName ?? 'unknown'}, Status: ${entitlement.status}`);
  if (entitlement.currentPeriodEnd) {
    console.log(`Renews: ${entitlement.currentPeriodEnd}`);
  }
}

Listen for Changes

AppDNA.onWebEntitlementChanged is backed by a native event on NativeEventEmitter. Subscribe to react in real-time when the entitlement status changes:
const unsubscribe = AppDNA.onWebEntitlementChanged((entitlement) => {
  if (entitlement?.isActive === true) {
    unlockPremium();
  } else {
    lockPremium();
  }
});

// Remember to unsubscribe when no longer needed
// unsubscribe();
The callback 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

PropertyTypeDescription
isActivebooleanWhether the subscription is currently active
planName`stringnull`Name of the subscription plan
priceId`stringnull`Stripe price identifier
statusstringCurrent status (see below)
currentPeriodEnd`stringnull`End of the current billing period (ISO 8601)
interval`stringnull`Billing interval (e.g., "month", "year")
trialEnd`stringnull`Trial expiration date (ISO 8601), if in a trial

Entitlement Statuses

StatusDescription
activeSubscription is active and paid
trialingUser is in a free trial period
past_duePayment failed, in grace period
canceledSubscription is canceled (access may continue until period ends)

Access

Web entitlements are accessed as top-level members on AppDNA:
// Current value (one-shot Promise)
const webEntitlement = await AppDNA.getWebEntitlement();

// Live subscription of changes (returns an unsubscribe function)
const unsubscribe = AppDNA.onWebEntitlementChanged((entitlement) => { /* ... */ });

Auto-Tracked Events

EventTrigger
web_entitlement_activatedWeb subscription becomes active
web_entitlement_expiredWeb subscription expires or is canceled

Full Example

import { AppDNA, WebEntitlement } from '@appdna/react-native-sdk';

export class PremiumManager {
  private unsubscribe: (() => void) | null = null;

  setup(): void {
    // Listen for web entitlement changes
    this.unsubscribe = AppDNA.onWebEntitlementChanged((entitlement) => {
      this.updateAccessState(entitlement);
    });
  }

  dispose(): void {
    this.unsubscribe?.();
    this.unsubscribe = null;
  }

  async checkAccessOnLaunch(): Promise<void> {
    // Check in-app purchase entitlements
    const hasIAP = await AppDNA.billing.hasActiveSubscription();
    if (hasIAP) {
      this.unlockPremium();
      return;
    }

    // Check web entitlement
    const web = await AppDNA.getWebEntitlement();
    if (web && web.isActive) {
      this.unlockPremium();
      return;
    }

    // No active subscription from either source
    this.lockPremium();
  }

  private async updateAccessState(entitlement: WebEntitlement | null): Promise<void> {
    if (entitlement?.isActive === true) {
      this.unlockPremium();
    } else {
      // Re-check IAP entitlements before locking
      const hasIAP = await AppDNA.billing.hasActiveSubscription();
      if (!hasIAP) {
        this.lockPremium();
      }
    }
  }

  private unlockPremium(): void {
    // Enable premium features
  }

  private lockPremium(): void {
    // 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.