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

Почему моделям ценообразования нужен план по данным
Ценообразование — это не просто страница на сайте. Оно определяет, что вы должны записывать, как вы это отчётите и сможете ли объяснить списание спустя месяцы. Когда вы выбираете подписки или оплату по использованию, вы также выбираете форму ваших биллинговых данных.
Простую подписку часто можно посчитать по нескольким фактам: план, период выставления счёта, дата начала и скидки. Ценообразование по использованию требует большего: что было использовано, когда это произошло, какому клиенту это принадлежит и как это использование превращается в деньги. Без этих записей вы всё ещё можете выставлять счета, но не сможете их защитить.
Добавление учёта использования позже без планирования обычно ломается в трёх местах:
- Нет надёжной истории использования, поэтому клиенты оспаривают списания.
- Аналитика превращается в предположения, потому что разные команды по‑разному определяют «использование».
- Финансы не могут проверить счета, потому что отсутствуют или были перезаписаны исходные данные.
Цель — скучная, но важная: вычислять один и тот же счёт одинаково каждый раз. Это значит, что вы можете воспроизвести расчёт по сохранённым фактам (условия плана, правила счётчиков, события использования и точная версия цен, которая применялась).
«Вид с точки зрения моделирования» просто означает описать биллинг как блоки, которые складываются вместе, даже если вы не инженер. Представьте продукт для командного чата:
- Подписка: $99 за рабочую область в месяц
- Использование: $0.01 за сообщение после 50 000 сообщений
Чтобы поддержать это позже, ваши данные должны отвечать на вопросы: какая рабочая область, за какой месяц, сколько сообщений, что входило в пакет и какие правила ценообразования были активны.
Подписки и оплата по использованию: чем они отличаются на практике
Подписки взимают плату за доступ. Оплата по использованию — за потребление. При апгрейдах, даунгрейдах, прорации и реальных пограничных случаях они ведут себя очень по‑разному.
В случае подписки ключевой вопрос: «Был ли клиент вправе пользоваться продуктом в этот период?» В основном вы отслеживаете план, количество мест, период выставления счёта и оплачен ли счёт. Использование всё ещё важно, но чаще выступает в виде лимитов (мягких или жёстких), а не отдельных строк в счёте.
При оплате по использованию ключевой вопрос: «Что произошло, точно, и когда?» Нужен надёжный учёт, понятные правила, когда считаете использование, и способ объяснить каждое списание. Даже если в интерфейсе видно одно число (например, «1 243 API‑запроса»), за ним стоит набор событий, которые должны быть последовательны и проверяемы.
Многие команды B2B SaaS выбирают гибридную модель: базовый взнос, покрывающий пакет, плюс плата за сверхнорму.
Распространённые гибридные шаблоны
Большинство гибридных моделей сводятся к знакомым формам:
- Базовый платформенный взнос плюс плата за место
- Базовый взнос плюс включённые единицы (сообщения, задачи, API‑запросы) и ставка за превышение
- Тиринговый план плюс дополнительный модуль по использованию (оплачивается только при включении)
- Минимальное обязательство с вычитанием кредитов за использование
Предсказуемость важна, когда клиенту нужно утвердить бюджет и сохранить стабильные ежемесячные расходы. Pay‑as‑you‑go лучше подходит, когда ценность масштабируется с активностью (например, «за обработанный счёт») или когда клиенты пробуют продукт и хотят снизить риск.
Планы меняются неизбежно. Цены, пакеты и упаковка будут меняться. Проектируйте биллинг так, чтобы можно было добавить новый счётчик, ввести новый уровень или изменить, что значит «включено», не переписывая историю. Практическое правило: сохраняйте план клиента и условия ценообразования такими, какими они были на момент списания, а не только то, что они означают сегодня.
Определяйте счётчики, которые можно измерить надёжно
Счётчик — это точная вещь, за которую вы берёте плату, описанная настолько ясно, чтобы двое людей, считающих её, получили одинаковый результат. У него три части: событие (что произошло), единица (что вы считаете) и время (когда это учитывается).
Большинство споров начинается здесь. Одна сторона считает, что платят за результат, другая — что берут плату за измеримую активность.
Сделайте счётчик однозначным
Выбирайте счётчики, которые соответствуют реальным продуктовым действиям и могут фиксироваться автоматически. Распространённые примеры:
- Места (активные пользователи, которые могут войти)
- API‑запросы (успешные запросы или все запросы)
- Хранение (ГБ в момент времени или среднее за период)
- Сообщения (отправленные, доставленные или открытые)
- Минуты вычислений (время выполнения задачи)
Затем определите, что считается и что нет. Если вы берёте плату за API‑запросы, решите, учитываются ли повторы, 4xx и 5xx ответы, и учитываются ли внутренние вызовы от ваших интеграций.
Время важно так же, как и единица. Места часто удобнее считать как снимок в точке времени за период выставления счёта. API‑запросы обычно суммируются в окне. Хранение сложнее: клиенты ожидают платить за «сколько вы храните», что обычно означает среднее за время, а не пик.
Также решите область применения: по аккаунту или по рабочей области/проекту. Простое правило: если команды могут выставляться отдельно, счётчики должны быть по рабочей области.
Лимиты, уровни и права доступа (entitlements)
Права доступа — это правила того, что клиент может делать из‑за купленного пакета. Они отвечают на вопросы: сколько пользователей можно добавить? Какие функции включены? Какой объём разрешён в месяц? Права размещаются между доступом и биллингом: они формируют, что продукт разрешает, а учёт фиксирует, что произошло.
Держите права отдельно от логики учёта. Права должны быть читаемыми и стабильными (план, дополнения, условия контракта). Учёт будет меняться по мере развития продукта (новые события, новые счётчики), и вы не хотите, чтобы каждое изменение счётчика ломало доступ.
Жёсткие лимиты, мягкие лимиты и оплата за превышение могут выглядеть похоже в UI, но вести себя по‑разному:
- Жёсткий лимит блокирует действие после достижения потолка.
- Мягкий лимит позволяет действие, но предупреждает и помечает для последующих действий.
- Плата за превышение позволяет действие и взимает плату за дополнительное использование.
- Период льготы временно превращает жёсткий лимит в мягкий.
- Триалы и бесплатные уровни применяют права, но цена обычно нулевая до даты или порога.
Решите заранее, что происходит при превышении лимита. Пример: команда на тарифе «Starter» включает 5 мест и 10 000 API‑запросов в месяц. Если они приглашают 6‑го пользователя, блокируете ли вы его, начинаете ли взимать плату за лишнее место или разрешаете его на 7 дней как льготу? Каждый выбор требует правила, которое вы можете показать в счёте и логах поддержки.
Храните права как временные записи: клиент, план или дополнение, метки начала и окончания, значения лимитов и режим принудительного исполнения (жёсткий, мягкий, оплата за превышение). Это делает решения по доступу и биллингу согласованными.
Счета и биллинговые периоды, которые можно аудитить
Счёт — это не просто PDF. Это аудиторский след, который отвечает: кого выставили, за что, за какие даты, по каким правилам. Если вы меняете цены, вы всё равно должны уметь восстановить старые счета точно так же.
Начните с нескольких основных записей: Customer, Subscription (или Contract), Billing Period и Invoice с позициями. Каждая позиция должна ссылаться на источник: плата за план, сводка использования или разовый платёж. Эта ссылка и делает биллинг объяснимым при споре о списании.
Биллинг‑периоды нуждаются в якоре и часовом поясе. «Ежемесячно» недостаточно. Храните дату привязки цикла (например, 15‑е в 00:00) и часовой пояс, используемый для разреза периодов. Держите это согласованно, иначе появятся ошибки на границах дней при переходе на летнее время.
Для аудируемых счетов обычно требуются:
- period_start и period_end на каждом счёте и каждой позиции
- версия ценообразования (идентификаторы плана/цены), использованная для этого счёта
- Неизменяемые итоги: subtotal, tax, discounts, amount_due, currency
- Точное окно использования для любой позиции по использованию
- Внешние ссылки на платёж (id транзакции процессора), когда применимо
Учет доходов связан, но не тождественен выставлению счётов. Предоплаченная подписка обычно признаётся в течение периода обслуживания, в то время как использование часто признаётся по факту поставки. Даже если вы держите это на высоком уровне, сохраняйте достаточно дат, чтобы поддержать признание позже.
Обрабатывайте кредит‑ноты, возвраты и корректировки как полноценные записи, а не как правки старых счетов. Если клиент повышает тариф в середине цикла, создайте корректировочную позицию или кредит‑ноту, которая ссылается на исходный счёт и указывает использованное правило прорации.
Ключи идемпотентности важны для генерации счётов и попыток оплаты. Если задача запустится дважды, вы хотите получить один счёт, одну транзакцию и ясный лог.
Прорация и изменения в середине цикла
Изменения в середине цикла — это место, где начинаются споры по биллингу. Если кто‑то повышает тариф 20‑го числа, ставит на паузу на неделю, а затем отменяет, вам нужны правила, которые превращают эти действия в числа, понятные на счёте.
Решите, какие изменения вы допускаете и когда они вступают в силу. Многие команды применяют апгрейды немедленно, чтобы клиент сразу получил ценность, а даунгрейды откладывают до обновления, чтобы избежать сложных возвратов.
Выберите политику прорации, которую можно объяснить
Прорация может быть посуточной, почасовой или отсутствовать вовсе. Чем точнее вы хотите быть, тем больше меток времени, правил округления и пограничных случаев нужно хранить и тестировать.
Закрепите выборы политики рано:
- Прорация апгрейдов немедленно, даунгрейдов — при продлении
- Использовать суточную прорацию (проще, чем почасовая, обычно достаточно справедлива)
- Определить правила округления (например, округлять до ближайшего цента вверх)
- Решить, как работают паузы (возврат средств за время или продление периода)
- Установить понятную политику возвратов при отмене (полный, частичный или отсутствует)
Моделируйте прорацию как позиции в счёте
Избегайте скрытой математики. Представляйте прорацию как явные корректировки в счёте: дебет за оставшееся время на новом плане и кредит за неиспользованное время на старом плане. Каждая позиция должна ссылаться на точное событие изменения (change_id) и включать окно прорации (start_at, end_at), количество/временную базу и налоговую категорию.
Счётчики использования добавляют ещё одно решение: при изменении плана счётчики сбрасываются, продолжают накапливаться или разбиваются на сегменты? Простой, проверяемый подход — сегментировать использование по версии плана. Пример: клиент повышает с 10 до 25 мест в середине месяца. Вы сохраняете события использования как есть, но рейтинг группирует их по периоду действия права, активного в момент события.
Решите, что обратимо. Полезно считать события использования окончательными после их принятия, в то время как изменения подписки могут быть обратимы только до финализации счёта. Сохраняйте события изменений и корректировки счетов, чтобы при изменении правил можно было аккуратно регенерировать счета.
Данные, которые нужно хранить с первого дня
Если вы будете проектировать данные для биллинга после того, как клиенты пожаловались, вы начнёте угадывать. Независимо от того, выбрали вы подписку, оплату по использованию или гибридную модель B2B SaaS, безопасная отправная точка — небольшой набор записей, которые всегда позволят провести аудит.
Начните с ясной иерархии клиентов. В B2B SaaS плательщиком обычно является аккаунт компании, но использование часто происходит внутри рабочих областей или проектов, а действия совершают отдельные пользователи. Храните все три уровня (account, workspace, user) и записывайте, кто что сделал. Споры по биллингу часто сводятся к вопросу: «какая команда это сделала?»
Минимальный дизайн базы биллинга, поддерживающий реальные счета и понятные расследования:
- Аккаунты и оргструктура: account, workspace (или project), пользователи, роли, контакт для биллинга и налоговые поля при необходимости
- Подписки: план, статус, даты начала/окончания, настройки продления, причина отмены и версия ценообразования, применённая при старте
- Каталог цен: продукты, компоненты плана (базовая плата, места, счётчики), уровни, валюта и даты вступления в силу
- Данные учёта использования: неизменяемый журнал событий (append‑only) с временной меткой, рабочей областью, пользователем (если есть), именем счётчика, количеством и уникальным idempotency‑ключом
- Артефакты счетов: границы биллинговых периодов, позиции, итоги, налоговые/скидочные корректировки и снимок входных данных, использованных при расчёте
Не полагайтесь только на агрегированные счётчики. Держите агрегаты для скорости, но рассматривайте журнал событий как источник истины. Простое правило: события неизменяемы, исправления — это новые события (например, отрицательное количество), и каждое событие привязано к конкретному определению счётчика.
Пример: клиент говорит, что их «API‑запросы» удвоились в прошлом месяце. Если вы можете извлечь сырые события по рабочей области и дню, вы покажете, откуда пошёл всплеск или найдёте цикл интеграции.
Шаг за шагом: от событий использования до счёта
Сложность не в математике. Сложность в том, чтобы результат можно было объяснить через месяцы, даже после того как планы, цены и клиенты изменились.
1) Начните с каталога цен, который умеет путешествовать во времени
Настройте продукты, планы, счётчики и цены с датами вступления в силу. Никогда не перезаписывайте старую цену. Если клиент выставлялся в марте, вы должны уметь снова прогнать март с мартовским каталогом.
Пример: «API Calls» стоят $0.002 с 1 апреля. Счета за март должны использовать старую ставку.
2) Снимайте снапшот прав клиента на период
В начале каждого биллингового периода (или при изменении) сохраняйте снапшот прав: план, включённые единицы, лимиты, правила уровней, скидки и налоговые настройки. Думайте об этом как о «том, что мы обещали» на этот период.
3) Принимайте события использования и валидируйте их рано
Использование должно приходить как неизменяемые события: временная метка, клиент, счётчик, количество и уникальный идентификатор для дедупликации. Валидируйте базовые вещи на входе (отсутствие счётчика, отрицательное количество, невозможные метки времени) и фиксируйте сырое событие, даже если вы храните очищенную версию.
Затем выполняйте расчёт в два прохода:
- Аггрегируйте события в итоги по клиенту, счётчику и биллинговому периоду (и храните версию агрегации)
- Оцените итоги в стоимость, используя каталог и снапшот прав (включённые единицы, цена превышения, уровни)
Генерируйте позиции счёта, которые ссылаются на точные входные данные (версия каталога, id снапшота, id агрегации).
Наконец, заблокируйте счёт. Сохраните входные данные расчёта и результат, отметьте его как финальный и запретите изменения при поступлении поздних событий. Поздние события должны идти в следующий счёт (или отдельную корректировку) с явной заметкой аудита.
Потребности клиентов и внутренней отчётности
Клиентам всё равно, выбрали вы подписку или оплату по использованию. Им важно, чтобы ваши числа совпадали с их, и чтобы они могли предсказать следующую плату заранее.
Интерфейс для клиента лучше делать простым: домашняя страница биллинга, которая отвечает на ряд вопросов без тикетов в поддержку:
- На каком я плане и что в него входит?
- Сколько я использовал в этом периоде и как считается использование?
- Какие у меня лимиты и что происходит при их превышении?
- Когда заканчивается биллинговый период и какая ожидаемая следующая сумма?
- Где посмотреть прошлые счета и платежи?
Внутри компании поддержка и финансы должны уметь объяснить число, а не просто отобразить его. Это значит находить всплески, трассировать изменения и отделять превью расчёта от финализированного биллинга.
Держите превью счетов отдельно от реальных счетов. Превью можно пересчитывать при поступлении позднего использования или при уточнении определения счётчика. Счета не должны пересчитываться.
Ваша внутренняя отчётность должна позволять помечать аномалии (резкие скачки использования, отрицательное использование, дубликаты событий), воспроизводить позицию счёта из сырых данных и правил, и видеть изменения планов и правила прорации за период.
Аудиторские следы важнее, чем многие команды ожидают. Если клиент говорит: «Мы повысили тариф 12‑го», — вам нужны метки времени, субъект действия (пользователь, админ, автоматизация) и точные значения до/после для плана, мест, лимитов и ставок счётчиков.
Для хранения: сохраняйте сырые события использования и финализированные артефакты счетов длительно. Практическое правило: если запись может изменить сумму списания или помочь защитить списание в споре, храните её неизменяемо.
Распространённые ловушки, приводящие к спорам по биллингу
Большинство споров по биллингу не про цену. Они возникают, когда вы не можете объяснить число в счёте или когда одни и те же входные данные позднее дают другой итог.
Обычная ошибка — хранить только месячные итоги. Без сырых событий вы не ответите на простой вопрос: «В какой день мы перешли порог?» Храните событие, затем агрегируйте его.
Ещё частая проблема — менять смысл счётчика без версионирования. «Активный пользователь» мог означать «входился хотя бы раз», а потом стать «создал запись». Если вы не версионируете определения счётчиков, клиенты сравнивают старые и новые счета, и вы не сможете доказать, какое правило применялось.
Споры часто происходят из одних и тех же паттернов:
- Права применяются только в UI (бэкенд по‑прежнему позволяет лишнее использование или блокирует валидное)
- Одна метка времени используется для всего (время события, время приёма, время биллинга)
- Игнорирование часовых поясов (событие в 00:30 по локальному времени попало не в тот день/месяц)
- Забытые якоря биллинга (у некоторых клиентов биллинг 1‑го числа, у других — с даты регистрации)
- Отсутствие аудита изменений плана, цены и лимитов
Пример: клиент в Токио повышает тариф в середине цикла 31‑го по местному времени. Если вы храните только UTC‑метку и не храните якорь биллинга, апгрейд может выглядеть как произошедший 30‑го в вашей системе, сместив прорацию и использование не в тот период.
Самый быстрый способ потерять доверие — отсутствие возможности воспроизвести старый расчёт счета. Храните входные данные (события, версии, якори и применённые цены), чтобы повторно выполнить ту же логику и получить тот же результат, даже после изменений в продукте.
Бырые проверки перед запуском биллинга
Перед запуском выполните одну проверку: возьмите случайного клиента и воссоздайте его последний счёт, используя только сохранённые данные. Если вам нужно «то, что код делал тогда», у вас нет аудиторского следа.
Убедитесь, что каждый счётчик однозначен. Счётчик должен иметь чёткую единицу (запросы, места, ГБ, минуты), надёжный источник (какой сервис его эмитирует) и временное окно (в день, в биллинговый период, по календарному месяцу). Если вы не можете объяснить счётчик в одном предложении, клиенты ему не поверят.
Быстрые проверки, которые ловят большинство проблем:
- Вы можете воспроизвести счёт из входных данных: версия плана, цены, итоги использования, налоги, скидки и параметры прорации
- События использования — append‑only, неизменяемы и дедуплицируются (idempotency‑ключ или id события)
- Изменения планов и цен версионируются с датами вступления в силу (не перезаписывайте старые цены)
- Правила прорации задокументированы простым языком и покрыты тестами
- Поддержка может быстро ответить «почему мне выставили плату», используя те же сохранённые факты
Пример: клиент повышает с 10 до 25 мест 18‑го и пересекает порог использования 23‑го. Ваша система должна показать (1) какая версия плана была активна в каждую дату, (2) событие изменения мест с отметкой времени, (3) формулу прорации и (4) события использования, которые суммировались в итог.
Следующие шаги: реализуйте, не загоняя себя в тупик
Начните с малого, но не расплывчато. Самый безопасный путь — минимальная модель данных, которая всё ещё позволяет ответить на один вопрос через месяцы: «Почему нам выставили эту сумму?»
Прототипируйте схему биллинга и админ‑экраны рано, до первого изменения цен. Если ждать, пока коммерция попросит новый уровень или изменение в середине цикла, вы начнёте латать логику во многих местах.
Практическое разделение: пусть Stripe обрабатывает списания, квитанции и повторные попытки оплаты, но храните рейтинг (как использование превращается в позиции счёта) в своей системе. Это значит, что вы сохраняете сырые события использования, версии цен и результаты расчёта, которые использовались для генерации превью счета.
Простой план запуска, который остаётся гибким:
- Выберите 1–2 счётчика, которые можно надёжно измерять (например, активные места в день и API‑запросы)
- Версионируйте правила ценообразования с первого дня, чтобы старые счета совпадали со старыми правилами
- Постройте внутреннюю админ‑панель биллинга для просмотра использования, переопределений, кредитов и споров
- Добавьте простой портал для клиента: текущий план, использование за период, ожидаемый счёт
- Относитесь к каждому счёту как к аудируемому снимку, а не к пересчитываемой догадке
Если вы хотите двигаться быстро, не писав много кастомного кода, вы можете смоделировать эти сущности в AppMaster и построить админ‑и портальные экраны с помощью его визуальных инструментов, сохраняя PostgreSQL как систему записи для событий и счетов.
Конкретный пример: вы запускаетесь с одним счётчиком мест. Через три месяца добавляете хранение в ГБ. Если счётчики, права и правила ценообразования версионированы, вы можете ввести новый счётчик, не ломая старые счета, и поддержка сможет объяснить любую позицию счёта за несколько минут.
Вопросы и ответы
Начните с ответа на вопрос, который вам придётся доказать позже: почему клиенту выставили именно эту сумму. Подписки требуют истории планов, периодов и прав доступа; оплата по использованию — неизменяемой записи о том, что произошло, когда и по каким правилам ценообразования.
Если вы не можете воспроизвести счёт из сохранённых входных данных, вы не сможете надёжно отвечать на споры или проводить аудит. Безопасная конфигурация включает хранение временно ограниченных условий плана, версионированных цен, сырых событий использования и точных результатов расчёта, применённых при финализации счёта.
Хороший счётчик — это то, что двое людей посчитают одинаково. Определите событие, единицу измерения и временное окно, а также чётко пропишите, что считается и что нет (например, повторные запросы, неудачные ответы или внутренние вызовы), чтобы вы не меняли смысл посчитанного в середине периода.
Жёсткие лимиты блокируют действие, мягкие — предупреждают, но позволяют продолжать, а плата за превышение разрешает и выставляет счёт. Выберите поведение для каждого права доступа и сохраните его как правило с отметками начала и конца, чтобы поддержка, продукт и биллинг принимали одинаковые решения.
Они решают разные задачи: права (entitlements) контролируют, что клиенту разрешено делать, а метрика фиксирует, что действительно произошло. Разделение предотвращает ситуацию, когда изменение метрики случайно ломает доступ, и упрощает объяснение счётов.
Храните журнал событий использования в режиме append-only как источник истины, а агрегаты — опционально для скорости. События должны включать метку времени, область клиента (например, workspace), имя счётчика, количество и уникальный idempotency‑ключ, чтобы дубликаты не привели к двойному списанию.
Никогда не перезаписывайте старые цены или правила плана — добавляйте новые версии с датами вступления в силу. Затем сохраняйте, какая версия ценообразования применялась к каждому счёту (и часто к каждому периоду права), чтобы старые счета можно было воссоздать точно даже после изменений в упаковке.
Ежемесячная биллинг‑логика требует якоря цикла и часового пояса, а не просто «ежемесячно». Храните period_start и period_end последовательно и чётко разграничивайте время события и время приёма, чтобы избежать ошибок на границах дней и в переходах на летнее/зимнее время.
Выберите политику, которую можно объяснить в одном предложении, и моделируйте математику как явные позиции в счёте (кредиты и дебеты), связанные с событием изменения и окном прорации. Суточная прорация — распространённый выбор: проще тестировать и защищать, чем почасовая.
Финализируйте счета как неизменяемые снимки и обрабатывайте поздние события использования как новое корректировочное событие или в следующем периоде с явной заметкой. Превью можно пересчитывать, финальные счета менять нельзя.


