Биллинг и тарифы
Управление тарифами и биллингом школ. Суперадмин платформы ведёт каталог тарифов и управляет периодами оплаты школ (активация, продление, приостановка, история платежей) через `/api/v1/admin/*` (без заголовка X-Tenant-Subdomain). Админ школы читает собственный биллинг-досье через `/api/v1/t/billing/me` — этот эндпоинт доступен даже при приостановленном биллинге. Суммы хранятся в тиынах (KZT*100).
- POST
/api/v1/admin/tariffsСоздать тариф - GET
/api/v1/admin/tariffsСписок тарифов - PATCH
/api/v1/admin/tariffs/:idОбновить тариф - DELETE
/api/v1/admin/tariffs/:idУдалить тариф - GET
/api/v1/admin/tenantsСписок школ (биллинг) - GET
/api/v1/admin/tenants/:idБиллинг-досье школы - GET
/api/v1/admin/tenants/:id/paymentsИстория платежей школы - POST
/api/v1/admin/tenants/:id/activateАктивировать школу - POST
/api/v1/admin/tenants/:id/extendПродлить школу - POST
/api/v1/admin/tenants/:id/suspendПриостановить школу - POST
/api/v1/admin/tenants/:id/unsuspendСнять приостановку школы - GET
/api/v1/t/billing/meСобственный биллинг школы
/api/v1/admin/tariffsСоздать тариф
Создаёт новый тариф в платформенном каталоге. Доступно только суперадмину. Цена указывается в тиынах (1 тенге = 100 тиын).
Тело запроса
| Параметр | Тип | Описание |
|---|---|---|
titleобяз. | string | Название тарифа (1–255 символов). |
descriptionопц. | string | Описание тарифа (до 10000 символов). |
price_centsопц. | integer | Цена в тиынах (KZT*100), минимум 0.Пример: 1500000 |
duration_daysобяз. | integer | Длительность периода в днях (больше 0).Пример: 30 |
is_activeопц. | boolean | Активен ли тариф (по умолчанию true). |
sort_orderопц. | integer | Порядок сортировки в каталоге.Пример: 10 |
Пример запроса
curl -X POST https://api.edumentor.kz/api/v1/admin/tariffs \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"title": "Стандарт",
"price_cents": 1500000,
"duration_days": 30,
"sort_order": 10
}'Пример ответа
{
"success": true,
"data": {
"id": "8f3b1c2a-1d2e-4a5b-9c6d-7e8f9a0b1c2d",
"title": "Стандарт",
"description": null,
"price_cents": 1500000,
"duration_days": 30,
"is_active": true,
"sort_order": 10,
"created_at": "2026-05-28T10:00:00Z",
"updated_at": "2026-05-28T10:00:00Z"
}
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | validation error | Тело запроса не прошло валидацию (текст ошибки от валидатора). |
| 401 | unauthorized | Токен отсутствует, истёк или недействителен. |
| 403 | forbidden | Доступно только суперадмину платформы. |
/api/v1/admin/tariffsСписок тарифов
Возвращает каталог тарифов. С параметром active=true отдаются только активные тарифы (для выпадающего списка активации); без него — весь каталог. Доступно только суперадмину.
Query-параметры
| Параметр | Тип | Описание |
|---|---|---|
activeопц. | boolean | При true возвращаются только активные тарифы.Пример: true |
Пример запроса
curl "https://api.edumentor.kz/api/v1/admin/tariffs?active=true" \
-H "Authorization: Bearer <token>"Пример ответа
{
"success": true,
"data": [
{
"id": "8f3b1c2a-...",
"title": "Стандарт",
"description": null,
"price_cents": 1500000,
"duration_days": 30,
"is_active": true,
"sort_order": 10,
"created_at": "2026-05-28T10:00:00Z",
"updated_at": "2026-05-28T10:00:00Z"
}
]
}Ошибки
| Код | error | Когда |
|---|---|---|
| 401 | unauthorized | Токен отсутствует, истёк или недействителен. |
| 403 | forbidden | Доступно только суперадмину платформы. |
/api/v1/admin/tariffs/:idОбновить тариф
Частично обновляет тариф. Отсутствующее поле означает «не менять». Доступно только суперадмину.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
idобяз. | uuid | Идентификатор тарифа. |
Тело запроса
| Параметр | Тип | Описание |
|---|---|---|
titleопц. | string | Название тарифа (1–255 символов). |
descriptionопц. | string | Описание тарифа (до 10000 символов). |
price_centsопц. | integer | Цена в тиынах (минимум 0). |
duration_daysопц. | integer | Длительность периода в днях (больше 0). |
is_activeопц. | boolean | Активен ли тариф. |
sort_orderопц. | integer | Порядок сортировки. |
Пример запроса
curl -X PATCH https://api.edumentor.kz/api/v1/admin/tariffs/8f3b1c2a-1d2e-4a5b-9c6d-7e8f9a0b1c2d \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "price_cents": 1800000, "is_active": false }'Пример ответа
{
"success": true,
"data": {
"id": "8f3b1c2a-...",
"title": "Стандарт",
"price_cents": 1800000,
"duration_days": 30,
"is_active": false,
"sort_order": 10,
"created_at": "2026-05-28T10:00:00Z",
"updated_at": "2026-05-28T11:00:00Z"
}
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | invalid id format | Идентификатор тарифа не является валидным UUID. |
| 401 | unauthorized | Токен отсутствует, истёк или недействителен. |
| 403 | forbidden | Доступно только суперадмину платформы. |
| 404 | tariff not found | Тариф не найден. |
/api/v1/admin/tariffs/:idУдалить тариф
Мягко удаляет тариф из каталога. История платежей не затрагивается (название и цена хранятся в снимке платежа). Доступно только суперадмину.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
idобяз. | uuid | Идентификатор тарифа. |
Пример запроса
curl -X DELETE https://api.edumentor.kz/api/v1/admin/tariffs/8f3b1c2a-1d2e-4a5b-9c6d-7e8f9a0b1c2d \
-H "Authorization: Bearer <token>"Пример ответа
{
"success": true,
"data": { "deleted": true }
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | invalid id format | Идентификатор тарифа не является валидным UUID. |
| 401 | unauthorized | Токен отсутствует, истёк или недействителен. |
| 403 | forbidden | Доступно только суперадмину платформы. |
| 404 | tariff not found | Тариф не найден. |
/api/v1/admin/tenantsСписок школ (биллинг)
Возвращает список школ с биллинг-состоянием, с фильтрами, сортировкой и пагинацией. Доступно только суперадмину.
Query-параметры
| Параметр | Тип | Описание |
|---|---|---|
plan_stateопц. | string | Фильтр по состоянию плана: trial, paid, suspended. Пусто — все.Пример: paid |
searchопц. | string | Поиск по субдомену или названию школы. |
sort_byопц. | string | Поле сортировки: expires_at (по умолчанию), created_at, title. |
sort_dirопц. | string | Направление сортировки: asc или desc. |
limitопц. | integer | Размер страницы.Пример: 50 |
offsetопц. | integer | Смещение для пагинации.Пример: 0 |
Пример запроса
curl "https://api.edumentor.kz/api/v1/admin/tenants?plan_state=paid&limit=50" \
-H "Authorization: Bearer <token>"Пример ответа
{
"success": true,
"data": {
"items": [
{
"tenant_id": "0a1b2c3d-...",
"tenant_status": "active",
"plan_state": "paid",
"expires_at": "2026-06-28T00:00:00Z",
"days_remaining": 31
}
],
"total": 137,
"limit": 50,
"offset": 0
}
}Ошибки
| Код | error | Когда |
|---|---|---|
| 401 | unauthorized | Токен отсутствует, истёк или недействителен. |
| 403 | forbidden | Доступно только суперадмину платформы. |
/api/v1/admin/tenants/:idБиллинг-досье школы
Возвращает полное биллинг-досье школы: состояние плана, дату истечения, остаток дней, текущий тариф и историю платежей. Та же форма, что и /t/billing/me, но доступна суперадмину для любой школы.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
idобяз. | uuid | Идентификатор школы (тенанта). |
Пример запроса
curl https://api.edumentor.kz/api/v1/admin/tenants/0a1b2c3d-1d2e-4a5b-9c6d-7e8f9a0b1c2d \
-H "Authorization: Bearer <token>"Пример ответа
{
"success": true,
"data": {
"tenant_id": "0a1b2c3d-...",
"tenant_status": "active",
"plan_state": "paid",
"expires_at": "2026-06-28T00:00:00Z",
"days_remaining": 31,
"current_tariff": {
"id": "8f3b1c2a-...",
"title": "Стандарт",
"price_cents": 1500000,
"duration_days": 30,
"is_active": true,
"sort_order": 10
},
"payment_history": [
{
"id": "5e6f7a8b-...",
"tenant_id": "0a1b2c3d-...",
"tariff_id": "8f3b1c2a-...",
"tariff_title_snapshot": "Стандарт",
"amount_cents": 1500000,
"currency": "KZT",
"days": 30,
"method": "cash",
"applied_expires_at": "2026-06-28T00:00:00Z",
"created_by_user_id": "1a2b3c4d-...",
"created_at": "2026-05-28T10:00:00Z"
}
]
}
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | invalid id format | Идентификатор школы не является валидным UUID. |
| 401 | unauthorized | Токен отсутствует, истёк или недействителен. |
| 403 | forbidden | Доступно только суперадмину платформы. |
| 404 | tenant not found | Школа не найдена. |
/api/v1/admin/tenants/:id/paymentsИстория платежей школы
Возвращает платежи школы с пагинацией (по умолчанию 50, максимум 200 — ограничение на стороне сервиса). Доступно только суперадмину.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
idобяз. | uuid | Идентификатор школы (тенанта). |
Query-параметры
| Параметр | Тип | Описание |
|---|---|---|
limitопц. | integer | Размер страницы (по умолчанию 50, максимум 200).Пример: 50 |
offsetопц. | integer | Смещение для пагинации (по умолчанию 0).Пример: 0 |
Пример запроса
curl "https://api.edumentor.kz/api/v1/admin/tenants/0a1b2c3d-1d2e-4a5b-9c6d-7e8f9a0b1c2d/payments?limit=50" \
-H "Authorization: Bearer <token>"Пример ответа
{
"success": true,
"data": {
"items": [
{
"id": "5e6f7a8b-...",
"tenant_id": "0a1b2c3d-...",
"tariff_id": "8f3b1c2a-...",
"tariff_title_snapshot": "Стандарт",
"amount_cents": 1500000,
"currency": "KZT",
"days": 30,
"method": "cash",
"applied_expires_at": "2026-06-28T00:00:00Z",
"created_by_user_id": "1a2b3c4d-...",
"created_at": "2026-05-28T10:00:00Z"
}
],
"limit": 50,
"offset": 0
}
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | invalid id format | Идентификатор школы не является валидным UUID. |
| 401 | unauthorized | Токен отсутствует, истёк или недействителен. |
| 403 | forbidden | Доступно только суперадмину платформы. |
/api/v1/admin/tenants/:id/activateАктивировать школу
Активирует платный период школы (переходы trial→paid и suspended→paid). Полезная нагрузка задаётся либо по тарифу (tariff_id + periods), либо в свободной форме (days + amount_cents + title). Смешивать или опускать оба варианта нельзя. Идентификатор оператора берётся из JWT, не из тела. Доступно только суперадмину.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
idобяз. | uuid | Идентификатор школы (тенанта). |
Тело запроса
| Параметр | Тип | Описание |
|---|---|---|
tariff_idопц. | uuid | Идентификатор тарифа (вариант «по тарифу»). |
periodsопц. | integer | Количество периодов тарифа (1–24), для варианта «по тарифу». |
daysопц. | integer | Число дней (1–3650), для варианта «свободная форма». |
amount_centsопц. | integer | Сумма в тиынах (минимум 0), для свободной формы. |
titleопц. | string | Название периода (1–255 символов), для свободной формы. |
referenceопц. | string | Внешний референс платежа (до 64 символов). |
notesопц. | string | Примечания (до 10000 символов). |
Пример запроса
curl -X POST https://api.edumentor.kz/api/v1/admin/tenants/0a1b2c3d-1d2e-4a5b-9c6d-7e8f9a0b1c2d/activate \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "tariff_id": "8f3b1c2a-1d2e-4a5b-9c6d-7e8f9a0b1c2d", "periods": 1 }'Пример ответа
{
"success": true,
"data": {
"id": "5e6f7a8b-...",
"tenant_id": "0a1b2c3d-...",
"tariff_id": "8f3b1c2a-...",
"tariff_title_snapshot": "Стандарт",
"amount_cents": 1500000,
"currency": "KZT",
"days": 30,
"method": "cash",
"applied_expires_at": "2026-06-28T00:00:00Z",
"created_by_user_id": "1a2b3c4d-...",
"created_at": "2026-05-28T10:00:00Z"
}
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | invalid id format | Идентификатор школы не является валидным UUID. |
| 400 | invalid activation payload | Полезная нагрузка некорректна (смешаны или пропущены варианты «по тарифу»/«свободная форма»). |
| 400 | tariff is inactive | Выбранный тариф неактивен. |
| 401 | unauthorized | Токен отсутствует, истёк или недействителен. |
| 403 | forbidden | Доступно только суперадмину платформы. |
| 404 | tariff not found | Тариф не найден. |
| 404 | tenant not found | Школа не найдена. |
/api/v1/admin/tenants/:id/extendПродлить школу
Продлевает уже оплаченный период (paid→paid). Всегда свободная форма: дни + сумма + опциональные референс/примечания. Снимок тарифа сохраняется от последней активации. Идентификатор оператора берётся из JWT. Доступно только суперадмину.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
idобяз. | uuid | Идентификатор школы (тенанта). |
Тело запроса
| Параметр | Тип | Описание |
|---|---|---|
daysобяз. | integer | Число дней продления (1–3650).Пример: 30 |
amount_centsопц. | integer | Сумма в тиынах (минимум 0).Пример: 1500000 |
referenceопц. | string | Внешний референс платежа (до 64 символов). |
notesопц. | string | Примечания (до 10000 символов). |
Пример запроса
curl -X POST https://api.edumentor.kz/api/v1/admin/tenants/0a1b2c3d-1d2e-4a5b-9c6d-7e8f9a0b1c2d/extend \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "days": 30, "amount_cents": 1500000 }'Пример ответа
{
"success": true,
"data": {
"id": "6f7a8b9c-...",
"tenant_id": "0a1b2c3d-...",
"tariff_title_snapshot": "Стандарт",
"amount_cents": 1500000,
"currency": "KZT",
"days": 30,
"method": "cash",
"applied_expires_at": "2026-07-28T00:00:00Z",
"created_by_user_id": "1a2b3c4d-...",
"created_at": "2026-05-28T10:00:00Z"
}
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | invalid id format | Идентификатор школы не является валидным UUID. |
| 401 | unauthorized | Токен отсутствует, истёк или недействителен. |
| 403 | forbidden | Доступно только суперадмину платформы. |
| 404 | tenant not found | Школа не найдена. |
/api/v1/admin/tenants/:id/suspendПриостановить школу
Вручную приостанавливает школу. Тело опционально — можно передать reason. После приостановки администратора школы блокируют все маршруты /t/*, кроме whitelisted (брендинг и /t/billing/me). Доступно только суперадмину.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
idобяз. | uuid | Идентификатор школы (тенанта). |
Тело запроса
| Параметр | Тип | Описание |
|---|---|---|
reasonопц. | string | Причина приостановки (до 10000 символов). |
Пример запроса
curl -X POST https://api.edumentor.kz/api/v1/admin/tenants/0a1b2c3d-1d2e-4a5b-9c6d-7e8f9a0b1c2d/suspend \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "reason": "Просрочка оплаты" }'Пример ответа
{
"success": true,
"data": { "suspended": true }
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | invalid id format | Идентификатор школы не является валидным UUID. |
| 401 | unauthorized | Токен отсутствует, истёк или недействителен. |
| 403 | forbidden | Доступно только суперадмину платформы. |
| 404 | tenant not found | Школа не найдена. |
/api/v1/admin/tenants/:id/unsuspendСнять приостановку школы
Снимает ручную приостановку школы и восстанавливает доступ. Доступно только суперадмину.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
idобяз. | uuid | Идентификатор школы (тенанта). |
Пример запроса
curl -X POST https://api.edumentor.kz/api/v1/admin/tenants/0a1b2c3d-1d2e-4a5b-9c6d-7e8f9a0b1c2d/unsuspend \
-H "Authorization: Bearer <token>"Пример ответа
{
"success": true,
"data": { "unsuspended": true }
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | invalid id format | Идентификатор школы не является валидным UUID. |
| 401 | unauthorized | Токен отсутствует, истёк или недействителен. |
| 403 | forbidden | Доступно только суперадмину платформы. |
| 404 | tenant not found | Школа не найдена. |
/api/v1/t/billing/meСобственный биллинг школы
Возвращает биллинг-досье текущей школы для админа: состояние плана, дату истечения, остаток дней, текущий тариф и историю платежей. Эндпоинт находится в whitelist-подгруппе, поэтому доступен админу даже при приостановленном или истёкшем биллинге (чтобы показать баннер продления и совершить оплату). Ручная приостановка суперадмином блокирует всех.
Пример запроса
curl https://api.edumentor.kz/api/v1/t/billing/me \
-H "Authorization: Bearer <token>" \
-H "X-Tenant-Subdomain: acme"Пример ответа
{
"success": true,
"data": {
"tenant_id": "0a1b2c3d-...",
"tenant_status": "active",
"plan_state": "trial",
"expires_at": "2026-06-12T00:00:00Z",
"days_remaining": 14,
"current_tariff": null,
"payment_history": []
}
}Ошибки
| Код | error | Когда |
|---|---|---|
| 401 | unauthorized | Токен отсутствует, истёк или недействителен. |
| 403 | PAYMENT_REQUIRED | Школа приостановлена суперадмином вручную (whitelist не действует при админ-приостановке). |