Бюро Цифровых Технологий

База знаний

Документация «Вираж»

База знаний по продуктам и API экосистемы «Вираж»: модули, методы, вебхуки — с примерами.

Обновлено: 22.08.2026

Программа лояльности

Начисление и списание баллов, статусы и персональные условия. Уровни и правила перехода настраиваются в админ-панели клуба — через API можно только читать конфигурацию и менять баланс.

Обзор методов

МетодПутьОписание
GET/loyalty/{user_id}Статус и баланс
GET/loyalty/tiersУровни программы
POST/loyalty/{user_id}/accrueНачислить баллы
POST/loyalty/{user_id}/redeemСписать баллы
GET/loyalty/{user_id}/historyИстория начислений и списаний
POST/loyalty/{user_id}/adjustРучная корректировка баланса

Статус и баланс

Эндпоинт
GET /loyalty/{user_id}

Текущий уровень программы лояльности и количество баллов пользователя.

Параметры

ПараметрГдеТипОбязателенОписание
user_idпутьstringдаИдентификатор пользователя.
Запрос
curl https://api.virazh.io/v1/loyalty/usr_8f21c \
  -H "Authorization: Bearer sk_test_51H..."
Ответ
{
  "user_id": "usr_8f21c",
  "status": "silver",
  "points": 1240,
  "next_status": "gold",
  "points_to_next": 760
}

Поля ответа

ПолеТипОписание
statusstringТекущий уровень: silver, gold, platinum.
pointsintegerТекущий баланс баллов.
next_statusstring | nullСледующий уровень, если есть.
points_to_nextinteger | nullСколько баллов не хватает до next_status.

Уровни программы

Эндпоинт
GET /loyalty/tiers

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

Запрос
curl https://api.virazh.io/v1/loyalty/tiers \
  -H "Authorization: Bearer sk_test_51H..."
Ответ
{
  "tiers": [
    { "name": "silver", "min_points": 0, "accrual_rate": 0.05 },
    { "name": "gold", "min_points": 2000, "accrual_rate": 0.08 },
    { "name": "platinum", "min_points": 6000, "accrual_rate": 0.12 }
  ]
}

Поля ответа

ПолеТипОписание
tiersarray<Tier>Уровни по возрастанию min_points, с полями name, min_points, accrual_rate.

Начислить баллы

Эндпоинт
POST /loyalty/{user_id}/accrue

Начисляет баллы за событие — покупку, посещение, активность. Источник начисления передаётся в поле reason для последующей аналитики.

Параметры

ПараметрГдеТипОбязателенОписание
user_idпутьstringдаИдентификатор пользователя.
amountтелоintegerдаКоличество баллов к начислению, целое положительное число.
reasonтелоstringдаКод источника: ticket_purchase, shop_order, training_attended и т.д.
Запрос
curl https://api.virazh.io/v1/loyalty/usr_8f21c/accrue \
  -X POST \
  -H "Authorization: Bearer sk_test_51H..." \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 150,
    "reason": "ticket_purchase"
  }'
Ответ
{
  "user_id": "usr_8f21c",
  "accrued": 150,
  "balance": 1390
}

Поля ответа

ПолеТипОписание
accruedintegerСколько баллов начислено этим запросом.
balanceintegerБаланс после начисления.

Списать баллы

Эндпоинт
POST /loyalty/{user_id}/redeem

Списывает баллы в счёт оплаты или бонуса. Возвращает ошибку insufficient_points, если баланса не хватает.

Параметры

ПараметрГдеТипОбязателенОписание
user_idпутьstringдаИдентификатор пользователя.
amountтелоintegerдаКоличество баллов к списанию.
reasonтелоstringдаКод назначения списания: shop_order, ticket_discount и т.д.
Запрос
curl https://api.virazh.io/v1/loyalty/usr_8f21c/redeem \
  -X POST \
  -H "Authorization: Bearer sk_test_51H..." \
  -H "Content-Type: application/json" \
  -d '{ "amount": 500, "reason": "shop_order" }'
Ответ
{
  "user_id": "usr_8f21c",
  "redeemed": 500,
  "balance": 890
}

Поля ответа

ПолеТипОписание
redeemedintegerСколько баллов списано.
balanceintegerБаланс после списания.

История начислений и списаний

Эндпоинт
GET /loyalty/{user_id}/history

Постраничный журнал операций по баллам с указанием причины и итогового баланса на момент операции — источник для раздела «История баллов» в личном кабинете.

Параметры

ПараметрГдеТипОбязателенОписание
user_idпутьstringдаИдентификатор пользователя.
limitqueryintegerнетРазмер страницы, до 100. По умолчанию — 20.
Запрос
curl "https://api.virazh.io/v1/loyalty/usr_8f21c/history?limit=20" \
  -H "Authorization: Bearer sk_test_51H..."
Ответ
{
  "user_id": "usr_8f21c",
  "data": [
    { "type": "accrual", "amount": 150, "reason": "ticket_purchase", "at": "2026-08-20T18:03:00Z", "balance_after": 1390 },
    { "type": "redemption", "amount": -500, "reason": "shop_order", "at": "2026-08-18T09:12:00Z", "balance_after": 890 }
  ],
  "has_more": false
}

Поля ответа

ПолеТипОписание
dataarray<LedgerEntry>Операции с полями type (accrual | redemption), amount, reason, at, balance_after.
has_morebooleanЕсть ли следующая страница.

Ручная корректировка баланса

Эндпоинт
POST /loyalty/{user_id}/adjust

Начисляет или списывает баллы вручную, в обход стандартных правил — для компенсаций и разбора спорных ситуаций. Требует scope loyalty:admin, действие фиксируется в аудит-логе.

Параметры

ПараметрГдеТипОбязателенОписание
user_idпутьstringдаИдентификатор пользователя.
amountтелоintegerдаВеличина корректировки — положительная (начисление) или отрицательная (списание).
reasonтелоstringдаКод причины, например support_compensation.
commentтелоstringнетСвободный комментарий для аудит-лога.
Запрос
curl https://api.virazh.io/v1/loyalty/usr_8f21c/adjust \
  -X POST \
  -H "Authorization: Bearer sk_test_51H..." \
  -H "Content-Type: application/json" \
  -d '{ "amount": 200, "reason": "support_compensation", "comment": "Задержка рейса на выезд" }'
Ответ
{
  "user_id": "usr_8f21c",
  "adjusted": 200,
  "balance": 1090,
  "audit_log_id": "adj_3391"
}

Поля ответа

ПолеТипОписание
adjustedintegerВеличина применённой корректировки.
balanceintegerБаланс после корректировки.
audit_log_idstringИдентификатор записи в аудит-логе.

Полезно знать

  • Начисление и списание — отдельные операции: система не позволяет уйти в отрицательный баланс, redeem вернёт insufficient_points, если баллов не хватает.
  • Уровни (/loyalty/tiers) настраиваются в админ-панели клуба и могут отличаться у разных клубов — не хардкодьте названия уровней в своём приложении.
  • Начисление идемпотентно по паре user_id + reason в пределах 24 часов — повторный вызов с тем же reason для того же заказа не задвоит баллы.
  • Ручная корректировка (/loyalty/{user_id}/adjust) требует scope loyalty:admin и всегда пишется в аудит-лог с указанной причиной — используйте её только для компенсаций, не как замену обычному начислению.