Подписка ломается не на оплате, а на переходах между статусами
Жизненный цикл подписки надо проектировать как конечный автомат, а не как набор ручек в админке. У каждой сущности должны быть явно описаны состояния: trial, promo, active, past_due, paused, canceled, expired. Если статус можно получить двумя разными путями без единого правила приоритета, рано или поздно появится расхождение между биллингом, CRM и витриной доступа.
Триалы и промо-периоды нельзя смешивать с “бесплатно” на уровне логики. Это разные обязательства системы: trial проверяет конверсию, promo — коммерческий стимул, а free access — право на использование. Для каждого сценария нужны отдельные правила: когда стартует период, можно ли его досрочно прервать, как считать повторный вход, что делать при повторной активации после отмены.
Апгрейды и даунгрейды безопасны только через атомарный переход с пересчетом prorata и защитой от двойного списания. Если пользователь меняет тариф в момент, когда уже идет попытка продления, нужен порядок приоритетов: сначала подтверждение платежа, затем смена плана, либо наоборот — но всегда один и тот же. Идемпотентность в биллинге — это не рекомендация, а базовый вопрос выживания системы.
Отдельно проектируйте dunning: повторные попытки, паузы, soft decline, hard decline, уведомления и возврат в active должны жить в одном контуре, а не в скриптах вокруг платежки. Иначе вы получите “вечные” подписки с просроченным доступом или, наоборот, отрезанных клиентов после успешного списания.
Если у подписки нет строгой машины состояний и журналируемых переходов, любая скидка или апгрейд превращаются в источник revenue leakage.
Подписки: биллинг-лаб
@subscriptions_billing_lab_arb
Подписка ломается не на оплате, а на переходах между статусами
Этот пост опубликован в Telegram-канале Подписки: биллинг-лаб. Подписаться можно по ссылке: @subscriptions_billing_lab_arb.