-
Notifications
You must be signed in to change notification settings - Fork 2
Subscription
Enjoy Player uses three membership tiers. Entitlements are local-first in the UI but reconciled against the Enjoy API whenever the app starts or resumes.
| Tier | Active daily credits | Feature access |
|---|---|---|
| Free | 1,000 | Free baseline |
| Lite | 12,000 | Paid-tier features |
| Pro | 60,000 | Paid-tier features |
SubscriptionStatus derives isLite, isPro, and the shared isPaidTier gate from both the tier and active status. Lite and Pro therefore share paid feature gates; their principal difference is the daily credit allocation. The membership card displays tier-aware labels, renewal or expiry details, and credits.
The subscription screen presents Free, Lite, and Pro cards with a monthly/yearly selector. Pricing and savings come from GET /api/v1/subscriptions/plans; missing plan data produces a loading skeleton rather than a hardcoded fallback.
flowchart LR
Catalog["Free, Lite, Pro catalog"] --> Plans["GET /api/v1/subscriptions/plans"]
Catalog --> Purchase["Unified purchase sheet"]
Purchase --> Checkout["External checkout"]
Checkout --> Reconcile["Resume reconciliation"]
Reconcile --> Status["Live tier and credits"]
On Windows, macOS, and Linux, choosing Lite or Pro opens an adaptive purchase sheet. Auto-renew is the primary path; prepaid months are the secondary path. The selected tier is carried through PurchaseRequest. Mobile currently shows a purchase-unavailable dialog instead of launching an external checkout.
| Method | Path | Purpose |
|---|---|---|
GET |
/api/v1/subscriptions |
Current tier, activity, expiry, and auto-renew state |
GET |
/api/v1/subscriptions/plans |
Tier and billing-interval catalog |
POST |
/api/v1/subscriptions |
Prepaid checkout with months, processor, and tier
|
POST |
/api/v1/subscriptions/auto_renew |
Start auto-renew with plan_id
|
POST |
/api/v1/subscriptions/cancel |
Cancel renewal at the period end |
See the REST client and tier catalog.
TierReconcileHost refreshes live subscription status, the cached profile, and credits on cold start and app resume. After an app-initiated checkout, it polls every three seconds for up to 30 seconds and accepts either Lite or Pro as a successful paid upgrade. A genuine Free-to-paid transition produces a tier-specific success notice.
See reconciliation orchestration and ADR-0041.