3

WebTech

Личный кабинет

Проекты, коммерческие предложения, документы и отчёты — в одном месте.

Войти Зарегистрироваться Забыли пароль?
Подписки и удержание SaaS

Подписки, которые меняют тариф сами без ручных пересчётов

Проектируем ядро управления подписками: статусы trial, active, past_due, paused и cancelled, апгрейды и даунгрейды с пропорциональным пересчётом, места в командных тарифах, промокоды, self-service кабинет и метрики удержания.

Или сразу: +7 (962) 368-39-51 Telegram

5
статусов жизненного цикла с явными переходами
pro-rata
пересчёт при апгрейде и даунгрейде
0
двойных списаний при повторных вебхуках
Churn
удержание и отток по когортам подписок
Задачи

Где ломается управление подписками

Проблемы, с которыми приходят SaaS-команды, когда подписок становится больше, чем помещается в голове у поддержки.

Статус подписки меняют прямым UPDATE

trial, past_due и paused выставляются из контроллеров и скриптов, поэтому никто не может сказать, почему клиент активен, а денег нет.

Апгрейд в середине периода считают «на глаз»

Клиент переходит на старший тариф 12-го числа: без пропорционального пересчёта он платит дважды или получает месяц бесплатно.

Отложенные изменения теряются

Даунгрейд «с конца периода» записан в CRM или в комментарии к тикету, и в нужную дату его просто никто не применяет.

Места в командном тарифе не сходятся со счётом

Приглашённые, но не принявшие приглашение пользователи, удалённые участники и места, добавленные в середине периода, ломают сумму в счёте.

Промокоды и скидки конфликтуют между собой

Накопительные акции, скидки на первые месяцы и партнёрские условия складываются в отрицательный счёт, который нечем закрыть.

Новый прайс-лист рвёт старые подписки

После смены цен существующие клиенты внезапно получают новые суммы, а отток и удержание невозможно разложить по причинам.

Решения

Модули управления подписками

Собираем подписки как отдельный домен с явной моделью состояний, чтобы продукт, поддержка и финансы смотрели на одни и те же данные.

Ядро жизненного цикла и переходы статусов

Конечный автомат подписки с проверяемыми переходами вместо россыпи UPDATE по таблице.

  • Статусы trial, active, past_due, paused, cancelled и матрица допустимых переходов
  • Каждый переход — доменное событие с причиной, инициатором и меткой времени
  • Восстановление состояния подписки на любую дату из журнала событий
  • Идемпотентная обработка вебхуков эквайринга и повторных задач очереди

Апгрейды, даунгрейды и пропорциональный пересчёт

Правила смены тарифа в середине периода с предсказуемой суммой доплаты или остатка.

  • Pro-rata по оставшимся дням с настраиваемой базой периода: календарный или anniversary
  • Апгрейд применяется сразу с доплатой, даунгрейд — отложенно на конец оплаченного периода
  • Остаток уходит в credit balance, а не в отрицательный счёт; при необходимости — корректировочный документ
  • Пересчёт мест и дополнений внутри периода при изменении их количества

Места, пауза и отложенные изменения

Управление количеством пользователей и временной остановкой подписки без потери истории.

  • Синхронизация количества мест с приглашениями, SSO и SCIM-провижинингом
  • Очередь отложенных изменений, которая применяется при закрытии периода или по расписанию
  • Пауза с остановкой начислений и сохранением данных; заморозка вместо отмены
  • Явные правила доступа к функциям и лимитам для каждого статуса

Self-service, промокоды и миграция прайс-листа

Кабинет клиента, скидки и смена цен без ручных писем в поддержку.

  • Self-service: смена тарифа, мест, способа оплаты и отмена с отложенным вступлением в силу
  • Уведомления о конце trial, о продлении и о неудачном платеже по email и вебхуками
  • Промокоды с лимитами, сроком действия и запретом на суммирование скидок
  • Версионирование тарифов и grandfathering: старые подписки продолжают жить на своих условиях
Процесс

Как мы строим управление подписками

Сначала описываем состояния и правила денег, потом автоматизируем — иначе код закрепит текущую путаницу.

  1. 01 1–2 недели

    Аудит текущего цикла подписки

    Разбираем, какие статусы существуют фактически, кто их меняет и где состояние подписки расходится с платежами.

  2. 02 2–3 недели

    Проектирование модели переходов

    Описываем автомат состояний, правила пропорционального пересчёта, отложенные изменения, места и политику скидок.

  3. 03 6–12 недель

    Разработка и интеграции

    Реализуем ядро подписок, связываем его с эквайрингом и очередями, собираем self-service кабинет и уведомления.

  4. 04 2–3 недели

    Миграция и запуск

    Переносим существующие подписки на новую модель прайс-листа, прогоняем пересчёты на исторических периодах, включаем дашборды удержания и оттока.

Жизненный цикл подписки как конечный автомат

Подписка — это не поле status в таблице, а конечный автомат с ограниченным набором состояний: trial, active, past_due, paused, cancelled. Пока переходы делаются прямым UPDATE из контроллера или консольного скрипта, через полгода невозможно объяснить, почему клиент видит активный тариф, а денег за него не поступало. Мы выносим переходы в доменный сервис: каждое изменение — событие с причиной, инициатором и меткой времени, а состояние подписки на любую дату восстанавливается из журнала.

Для каждого статуса явно определяется, что он значит для продукта: доступ к функциям и лимитам, поведение мест, начислений, счетов и уведомлений. past_due — это не блокировка, а льготный период с расписанием повторных списаний; paused останавливает начисления, но сохраняет данные и настройки; cancelled переводит подписку в отключение по концу оплаченного периода, а не мгновенно.

Пересчёт при смене тарифа, места и отложенные изменения

Главный источник споров — апгрейд или даунгрейд в середине расчётного периода. Считаем пропорционально оставшимся дням и фиксируем базу периода в самом тарифе: календарный месяц или anniversary-дата подписки дают разные суммы, и выбирать это должен продукт, а не разработчик при списании. Апгрейд применяется сразу с доплатой разницы, даунгрейд встаёт в очередь отложенных изменений и вступает в силу при закрытии периода.

  • остаток от пересчёта хранится как credit balance и зачитывается в следующем счёте;
  • количество мест синхронизируется с приглашениями и SSO, их изменение внутри периода считается pro-rata;
  • отложенное изменение можно отменить до применения, клиент видит его в кабинете;
  • промокоды имеют лимит применений, срок и правило совместимости со скидками.

При изменении прайс-листа версионируем тарифы: старые подписки остаются на своих условиях, а миграция идёт отдельным сценарием с прогоном пересчётов на исторических периодах.

Частые вопросы

Разница в цене умножается на долю оставшихся дней расчётного периода, база которого задана в тарифе: календарный месяц или anniversary-дата подписки. При апгрейде подписка меняется сразу, а доплата либо списывается отдельным платежом, либо относится в credit balance и учитывается в следующем счёте. Даунгрейд по умолчанию не возвращает деньги, а вступает в силу с начала следующего периода.

Подписка переходит в past_due, и запускается сценарий dunning: повторные попытки списания по расписанию, уведомления клиенту и льготный период, в течение которого доступ сохраняется. Если оплата так и не поступила, доступ ограничивается по заранее описанным правилам, а подписка переводится в cancelled с сохранением данных для последующей реактивации.

При паузе начисления останавливаются, но данные, настройки и история подписки сохраняются, поэтому возврат клиента не требует нового онбординга. Количество мест фиксируется на момент паузы и не списывается, а при возобновлении пересчитывается пропорционально оставшимся дням текущего периода. Вместо отмены мы чаще используем заморозку на срок — это заметно снижает отток по клиентам с сезонной нагрузкой.

Мы версионируем тарифы и оставляем действующие подписки на прежних условиях, помечая их как grandfathered. Миграция выполняется отдельным сценарием с предварительным прогоном пересчётов на исторических периодах, чтобы заранее увидеть, у кого изменится сумма. Клиенты получают уведомление с датой перехода и точной новой суммой, а метрики удержания по когортам показывают эффект миграции отдельно от обычного оттока.

Технические основы: другие темы

Смежные технические темы, с которыми эта задача обычно решается в одном проекте.

Сделаем подписки управляемыми

Покажем, как описать жизненный цикл, апгрейды и отложенные изменения так, чтобы смена тарифа считалась автоматически.