---
title: Plans & prices
description: Plan is the primary purchase object; entitlements fill it; price is the paywall offer.
---

# Plans & prices

**Plan is the center of the model.** Users buy a plan (via a paywall price).  
**Entitlements** attach to the plan and are granted on successful payment / key.  
**Plan price** is the concrete offer (month / year / lifetime / free) on the storefront.

```text
Paywall
  └── plan_price  ← selected + passed to createPayment
        └── plan
              └── entitlements[]
```

## Plan

| Field | Notes |
| --- | --- |
| `code` | Stable id (`arken_pro_year`, `free`) |
| `name` | Paywall label |
| `billing_type` | `one_time` \| `recurring` \| `lifetime` \| `free` |
| `duration_days` | Timed plans |
| `is_lifetime` | No expiry |
| `status` | Public paywall needs `active` |
| entitlements | Rights this plan grants |

## Price (`plan_prices`)

| Field | Notes |
| --- | --- |
| `amount` | Charged amount. `0` = free |
| `currency` | e.g. `RUB` |
| `discount_percent` | UI only |
| `payment_provider` | `yookassa` or `free` |
| `is_active` | Must be true |

API also returns `compare_at_amount`, `has_discount`, `display`, `is_free`, `requires_purchase`, `works_offline`.

## Free

- Catalog / comparison on paywall
- Not purchasable → `free_plan_offline`
- Baseline features stay local in the app

## Paid

- Success → subscription period + **plan entitlements**
- Additive to free-local features

## SDK flow

1. `getPaywall` — show offers.
2. UI bullets from plan entitlements.
3. `createPayment({ plan_price_id })` — paid only.
4. After pay — `hasEntitlement(code)` for gates.
