Free works without network; paid entitlements should be cached for offline.

Free tier & offline

Free tier

Free is the default local mode of the product app:

  • Works without internet
  • Does not call createPayment
  • Usually has no server entitlements
  • May still appear on the paywall for comparison (is_free: true)

Paid + free together

Purchasing a plan adds entitlements. It does not remove free local capabilities.

effective access = free-local features ∪ active paid entitlements

Offline with a previous purchase

ActorBehavior
AppOn last online sync, persist entitlement snapshot (codes, expires_at, is_lifetime). Offline: allow free-local always; allow paid features from cache until expiry.
Admin / APIOnline only. Revokes and extensions apply on next successful sync.

Recommended client algorithm

canUse(feature):
  if feature in FREE_LOCAL_SET:
    return true
  if network available:
    snapshot = getMyEntitlements()
    saveCache(snapshot)
    return snapshot.codes.contains(feature)
  cached = loadCache()
  if cached missing:
    return false
  if entitlement expired (and not lifetime):
    return false
  return cached.codes.contains(feature)

SDKs currently provide network APIs; caching is the app’s responsibility (secure storage / preferences).