Подписка ломается не на оплате, а на переходах между статусами и периодами
Жизненный цикл подписки должен быть конечным автоматом, а не набором «если/то» в CRM. Базовые состояния: trial, paid, grace, paused, canceled, expired. Между ними — только разрешенные переходы с явным триггером: событие платежа, окончание периода, ручное действие, отмена пробы.
Триалы и промо-периоды нельзя смешивать в одну сущность без атрибута source_of_entitlement. Иначе ломается аналитика, льготная цена протекает в регулярное продление, а повторный триал начинает конфликтовать с уже выданной скидкой. Для защиты нужны правила eligibility, дедупликация по пользователю и idempotent create-once логика. Идемпотентность в биллинге — это не рекомендация, а базовый вопрос выживания системы.
Апгрейд подписки — это не «заменить тариф», а транзакция пересчета прав: старый период закрывается, новый открывается с prorate-логикой, а списание должно быть привязано к одной бизнес-операции. Если разнести это по разным сервисам без единого transaction boundary, получите рассинхрон entitlement и ledger, двойной доступ или потерю выручки. Давайте разберем, что происходит с транзакцией в момент сетевого сплита шлюза.
Грамотно спроектируйте dunning отдельно от lifecycle: просрочка — это временное состояние, а не отмена. Тогда retry-политика, grace window и уведомления работают как единый контур, а не как набор ручных костылей. Практика простая: один источник истины по статусу, одна лента событий, и любые изменения тарифа только через валидируемые переходы.
Подписки: биллинг-лаб
@subscriptions_billing_lab_arb
Подписка ломается не на оплате, а на переходах между статусами и периодами
Этот пост опубликован в Telegram-канале Подписки: биллинг-лаб. Подписаться можно по ссылке: @subscriptions_billing_lab_arb.