ПодпискиEPIC #451
Поверхность 1 · web/root

Админка — суперадмин и орг-администратор страны

Тот же root-app, скоуп по countryId. Глобальный суперадмин (isAdmin) видит всё; член орг-администратора страны — только свою страну по platform.* permissions. Новая группа сайдбара — «Биллинг».

Планы — список CRUD

Таблица в паттерне остальных страниц root (Countries, Permissions). Правка — в Drawer справа.

root.batele.app/billing/plans
root · superadmin

Тарифные планы

Потолок прав + фичи + лимиты. Бандлы задают цену за период.
ПланТарификацияВидимостьPermsФичиБандлыСтатус
Бесплатный по умолчаниюБесплатныйpublic126active
Trial 14 днТриалhidden186active
СтартПлатныйpublic2483active
БизнесПлатныйpublic41124active
EnterpriseПлатныйhidden6215customdraft
Бесплатный тариф по умолчанию. Ровно один isDefault план — назначается новой орг автоматически при создании, без бандлов и инвойсов, статус подписки всегда active. Базовый уровень freemium; апгрейд на платный — по желанию.

Редактор плана — Drawer

Permissions — мультиселект из каталога apps/auth (потолок орг). Фичи — из каталога с per-plan лимитом и политикой овеража. Эффективное право = role-perms ∩ plan.allowedPermissions.

Название
Бизнес
Видимость
publichidden
Тарификация
ПлатныйБесплатный
План по умолчанию для новых орг
только для бесплатного · ровно один в системе
Разрешённые permissions · потолок орг
catalogue.writeorders.managestock.managefinance.readcouriers.manageanalytics.export +
Фичи и лимиты
Безлимит · limit = null NЛимит без превышения · block на пределе N+Лимит + превышение · доп оплата за сверх
Филиалы state
шт
Курьеры state
шт
Заказы/мес flow
/мес
+c/шт
SMS/мес flow
Онлайн-оплата bool
Флаг · без лимита
включена
Экспорт аналитики bool
Флаг · без лимита
выключена

Выбери режим в списке → появится поле лимита. «Лимит + доплата» добавляет поле цены за превышение (c/шт). «Безлимит» скрывает лимит. bool-фичи — только флаг вкл/выкл. Модель: limit (null → ∞) + overagePolicy + overageUnitPrice.

Каталог фич + бандлы плана

Фичи — key, тип (bool / state / flow), единица.

keyТипЕд.
branchesquota_stateшт
couriersquota_stateшт
orders_pmquota_flow/мес
online_payboolean

Бандлы — цена за период: month / quarter / half_year / year / custom.

Бизнес · бандлы
Месяц
1 200 c
Квартал
3 200 c
−11%
Год
11 500 c
−20%
Прекондишн. Продать бандл в стране нельзя, пока у ответственной орг нет платёжной интеграции.

Подписка организации — карточка

Просмотр / активация / продление / отмена, история инвойсов, ручная отметка оплаты (v1 без автосписания).

root.batele.app/billing/subscriptions/org_7f3
org-scope · KG
Подписки / ОсОО «Тандыр»

ОсОО «Тандыр»

grace
План «Бизнес» · период до 05.07.2026 · autoRenew off
Филиалы3 / 5
Курьеры8 / 10
Заказы/мес512 / 500
+12 овераж · к счёту 36 c
ИнвойсПериодСуммаСтатусpaymentRef
INV-104июн — сен 20263 200 cpendingodengi:q_88…
INV-097мар — июн 20263 200 cpaidodengi:q_71…✓ 03.03
Ручная отметка — фолбэк, если вебхук не дошёл. Обычный путь: вебхук провайдера → инвойс paid → период продлён автоматически.

Страна ↔ орг-администратор 1 : 1

Суперадмин назначает одну орг на страну (country_admin: countryId unique, orgId unique). Её платёжная интеграция собирает оплату подписок страны.

СтранаОрг-администраторПлатёжная интеграцияПродажи планов
🇰🇬 КыргызстанОсОО «Batele KG»O!DengiоткрытыЗаменить
🇰🇿 КазахстанТОО «Batele KZ»нет интеграциизаблокированыЗаменить
🇺🇿 Узбекистан— не назначенплатформенная орготкрыты

Нет орг-администратора → оплата на глобальную платформенную орг. Нет интеграции у ответственной орг → продажи в стране заблокированы.

Поверхность 2 · web/batele-vendor

Vendor — подписка организации

Новый пункт «Подписка» в меню орг. Владелец видит план, usage vs лимиты и покупает бандлы ручной оплатой.

vendor.batele.app/o/tandyr/subscription
vendor · владелец

Подписка

Тариф, использование и оплата
Период истёк — grace до 05.07. Оплатите, чтобы не потерять доступ к платным фичам.
Текущий план
Бизнес
grace
Квартал · до 05.07.2026 · autoRenew off
Использование
Филиалы3 / 5
Заказы · июль340 / 500
Экспорт аналитикине в плане
Доступно в тарифе выше

Сменить план

Только visibility: public планы. Скрытые (Trial / Enterprise) не показываются.

Бесплатный тариф доступен всегда. Можно вернуться на него без оплаты — даунгрейд не блокируется. Платные фичи отключатся, данные останутся read-only по превышенным лимитам.

Старт

600 c/мес
  • 2 филиала
  • 200 заказов/мес
  • Онлайн-оплата
  • Экспорт

Бизнес

1 200 c/мес
  • 5 филиалов
  • 500 заказов/мес
  • Онлайн-оплата
  • Экспорт
Мес
1200
Квартал
3200
−11%
Год
11500
−20%

Бизнес+

2 400 c/мес
  • Безлимит филиалов
  • 2000 заказов/мес
  • Онлайн-оплата
  • Экспорт

Оплата бандла — QR / ссылка + история

Оплата · Бизнес · квартал
Инвойс INV-104 · 3 200 c
Отсканируйте в приложении банка
или откройте ссылку оплаты →
Ждём подтверждение оплаты… Период продлится автоматически после вебхука.
ПериодСуммаСтатус
июн—сен 20263 200 cожидает
мар—июн 20263 200 cоплачен
дек—мар 20263 200 cоплачен
Триал-баннер (при trialing): «Пробный период Бизнес · осталось 9 дней» + «Выбрать план». Показывается один раз — триал не возвращается.
Поверхность 3 · web/batele-go

Go — доставка, узкий экран

Орг доставки (курьеры). Тот же биллинг, акцент на state-квоте «курьеры» и flow-квоте «доставки/мес». Экраны — ключевые состояния энфорса.

Тандыр Доставка
Бизнес · активна
Бизнес · до 05.10.2026
Курьеры8 / 10
Доставки · июль340 / 500
active — норма
Тандыр Доставка
Лимит курьеров
Курьеры10 / 10
Лимит достигнут
Нельзя добавить курьера. План «Бизнес» — до 10.
state-квота — hard block
Тандыр Доставка
Оплата просрочена
Подписка не оплачена. Приём новых доставок остановлен. Активные — доводятся до конца.
Новая доставказаблок.
Доступ вернётся сразу после оплаты
past_due — read-only фолбэк
Go = та же подписка орг, что и в vendor (одна орг может быть продавцом и доставкой). Экран переиспользует entitlements, меняется лишь набор ключевых фич и узкая раскладка.
Основа

Модель и логика энфорсмента

Экраны говорят на этом языке. Статус подписки и тип квоты кодируются цветом и формой бейджа.

Жизненный цикл подписки

free (default) trialing active grace past_due expired· canceled

Новая орг стартует на бесплатном тарифе по умолчанию (isDefault) — постоянный базовый уровень, без бандлов и инвойсов. Триал — разовый апгрейд-превью платного плана. После истечения платного/триала без оплаты орг откатывается на бесплатный тариф (не в «нет доступа»).

Режимы лимита фичи plan_feature

Безлимит

limit = null. Проверка не считает, всегда allowed. Метр без числа, значок ∞.

NЛимит без превышения

overagePolicy = block. На пределе — hard-block действия. Метр краснеет, кнопка «добавить» задизейблена.

N+Лимит + превышение

allow_overage + overageUnitPrice. Сверх лимита пропускаем, аккумулируем, инвойс в конце периода.

Два типа квот важно для UI

quota_state — «сколько сейчас»count(*)

Филиалы, продукты, члены, курьеры. Считает сервис-владелец, subscription отдаёт только лимит. В UI — метр «текущее / лимит», блок «добавить» на пределе.

Курьеры8 / 10
2 слота осталось
quota_flow — «за период»usage_counter

Заказы/мес, SMS. Централизованный счётчик в apps/subscription, идемпотентный ReportUsage(eventId). В UI — метр за период + политика овеража.

Заказы · июль340 / 500
Овераж: allow_overage · 3 c/заказ сверх, счёт в конце периода

Что видит пользователь в каждом состоянии

Источник правды — снапшот entitlements + live CheckFeature для денежных/квотных операций. Гейтвей: у члена есть permission И план орг разрешает И в пределах лимита.

СтатусПлатные фичиБаннерОсновное действиеДанные
freeпо фичам бесплатного плана— (опц. «апгрейд»)Выбрать платный планчтение+запись
trialingполный доступ (план триала)info · «осталось N дней»Выбрать планчтение+запись
activeпо фича-флагам + лимитамПродлить (в конце периода)чтение+запись
graceещё работаютwarn · «grace до DD.MM»Оплатить сейчасчтение+запись
past_duehard-blockcrit · «не оплачено»Оплатитьread-only фолбэк
expiredоткат на бесплатный тарифcrit · «платный истёк»Выбрать планчтение+запись (по free)
canceledдо конца периодаwarn · «доступ до DD.MM»Возобновитьдо конца периода
Овераж. block — жёсткий стоп на лимите. allow_overage — пропускаем, аккумулируем usage, инвойс в конце периода по overageUnitPrice. Метр краснеет + «+N сверх лимита, к счёту X».
State vs flow в энфорсе. state (курьеры/филиалы) — count(*) vs лимит из снапшота, блок «добавить». flow (заказы/SMS) — live CheckFeature gRPC, источник шлёт ReportUsage.

Покупка бандла — ручной флоу v1

vendor / go · владелец
Выбор плана и бандла

Видны только public-планы. Если у ответственной орг страны нет платёжной интеграции — кнопка оплаты задизейблена (прекондишн).

apps/subscription
Создание инвойса

subscription_invoice = pending, paymentRef = ссылка в payment-system на интеграцию администрирующей орг (страна→орг-админ, иначе глобальная).

O!Dengi / провайдер
Оплата QR / ссылкой

Пользователь платит. Модалка показывает QR + статус «ждём подтверждение».

webhook → apps/subscription
Вебхук → инвойс paid

Идемпотентно по paymentRef. Инвойс paid → период продлён → entitlementsVersion++ → снапшот в токене инвалидируется.

все поверхности
Доступ обновлён

Баннер снят, статус active, лимиты нового плана. Фолбэк: суперадмин отмечает оплату вручную в root, если вебхук не пришёл.

Порядок MVP (из EPIC): Track A домен → B страна↔орг-админ → E root CRUD+ручная активация → C энфорс (vendor→go→order) → D оплата → F vendor UI. Card-on-file авто-продление (autoRenew) — база заложена, no-op до карточной интеграции.