Токены (limit metered) и докупка пакетов
Внешний продукт может полностью полагаться на BillBill: не вести собственные счётчики, а использовать limit metered метрики, userMetric для остатков и metricNewEvent для списания.
Layered limits (час / день / месяц)
Для сценария «не больше N токенов в час, M в день, K в месяц» создайте limit group из нескольких метрик в админке:
| code | reset period | role | limit на плане |
|---|---|---|---|
tokens | subscription_period | primary | 100 000 |
tokens_hour | hour | member | 1 000 |
tokens_day | day | member | 10 000 |
Продукт шлёт один POST /merchant/metric/event/new с metricCode=tokens. BillBill атомарно проверяет все лимиты группы.
- Границы часа/дня/недели/месяца — календарные (timezone: user → merchant → UTC).
- Grants работают только на метрике со сбросом
subscription_period(обычно primary). - Member-метрики не принимают события напрямую.
В userMetric для каждой метрики: limitResetPeriod, windowStart, windowEnd, windowResetsAt.
Список групп для админки: GET /merchant/metric/limit_group/list.
Схема
- Основной план (в т.ч. бесплатный) задаёт period limit — месячная квота, сбрасывается в начале биллинг-периода.
- Разовый аддон (plan type = one-time) с metric limit пополняет grants при оплате.
- При списании сначала расходуется period limit, затем grants (FIFO по времени создания).
- Поддержка и промо: ручное начисление через Merchant API
limitGrantNewили вкладку Metric grants в админке.
Grant scope на разовом аддоне
grantScope | Поведение |
|---|---|
lifetime | Неиспользованный остаток не сгорает при смене периода |
period | Остаток сгорает в конце текущего биллинг-периода подписки |
Начисление при оплате: amount = metricLimit × quantity.
API для продукта
Остатки
GET /merchant/metric/user/sub/metric?subscriptionId=… — в limitStats для каждой метрики:
periodLimit,periodUsed,periodRemaininggrantRemaining,totalRemaininglimitResetPeriod,windowStart,windowEnd,windowResetsAtgrants[]— разбивка активных грантов (опционально для UI)
Списание
POST /merchant/metric/event/new — как раньше; при превышении totalRemaining событие отклоняется.
Ручной грант (support / миграция)
POST /merchant/metric/limit_grant_new
{
"userId": 123,
"metricId": 42,
"amount": 5000,
"grantScope": "lifetime",
"note": "Promo Q1",
"externalGrantId": "promo-abc-123"
}externalGrantId обеспечивает идемпотентность.
Настройка при отмене подписки
В Subscription Config (админка → Settings):
- Keep grants — гранты остаются у пользователя
- Forfeit grants — немедленное обнуление
- Grace period — льготные дни, после которых гранты истекают (cron)
Гранты с scope=period всегда сгорают при смене периода, независимо от этой настройки.
Требования
- У пользователя должна быть активная подписка на продукт (для привязки period grants и period limit).
- На разовом аддоне допускаются только метрики типа limit metered.
Пример потока
См. также Metered и лимитные метрики.