Telegram Shop — Admin API Reference
Актуальная документация по REST API админ-панели (admin-next/, Next.js 16 + Prisma).
- Базовый URL:
http://<host>:3000
- Формат: JSON (
Content-Type: application/json)
- Аутентификация: cookie
admin_token (httpOnly, 24ч), устанавливается через POST /api/auth/login
Аутентификация
| Метод |
Путь |
Описание |
| POST |
/api/auth/login |
Вход по токену. Body: { "token": "..." }. Rate-limit: 5 попыток / 15 мин на IP (429). Устанавливает cookie admin_token |
| GET |
/api/auth/session |
Проверка сессии. Ответ: { "role": "admin" | "super_admin" } (401 если нет/просрочен) |
| POST |
/api/auth/logout |
Выход, удаляет cookie |
Роли
admin — обычный администратор
super_admin — доступ к seed-фразам, экспорту, импорту, очистке БД
Роль определяется при входе: если SUPER_ADMIN_SECRET не задан или равен ADMIN_SECRET — все админы получают super_admin. Иначе роль super_admin даёт только вход по SUPER_ADMIN_SECRET.
Все эндпоинты ниже требуют cookie admin_token (иначе 401). Эндпоинты с пометкой 🔒 требуют роль super_admin (иначе 403).
Дашборд и статистика
GET /api/stats/dashboard
Сводная статистика для дашборда:
- counts:
totalUsers, totalProducts, totalPurchases, totalSubcategories, bannedUsers, activeWallets
- статусы покупок:
completedPurchases, pendingPurchases, cancelledPurchases
- метрики:
totalRevenue (сумма completed), aov, conversionRate
- временные ряды:
revenueByDay, purchasesByDay, newUsersByDay (последние 30 дней)
topProducts, recentPurchases, recentUsers
Каталог
GET /api/catalog/tree
Полное дерево каталога: локации, категории, подкатегории с _count (вложенные сущности).
Локации
| Метод |
Путь |
Описание |
| GET |
/api/locations/bulk |
Список локаций (с _count категорий/товаров) |
| POST |
/api/locations/bulk |
Создать. Body: { country, city, district } |
| PUT |
/api/locations/[id] |
Обновить. Body: { country?, city?, district? } |
| PATCH |
/api/locations/[id] |
Переключить is_active (0/1) |
| DELETE |
/api/locations/[id] |
Удалить (409 если есть связанные сущности) |
Категории
| Метод |
Путь |
Описание |
| GET |
/api/categories/bulk |
Список категорий (с локацией и _count) |
| POST |
/api/categories/bulk |
Создать. Body: { name, locationId } |
| PUT |
/api/categories/[id] |
Обновить. Body: { name?, locationId? } (409 при дубликате в локации) |
| PATCH |
/api/categories/[id] |
Переключить is_active |
| DELETE |
/api/categories/[id] |
Удалить (409 если есть связанные сущности) |
Подкатегории
| Метод |
Путь |
Описание |
| GET |
/api/subcategories/bulk |
Список подкатегорий |
| POST |
/api/subcategories/bulk |
Создать. Body: { name, categoryId } |
| PUT |
/api/subcategories/[id] |
Обновить. Body: { name?, categoryId? } |
| PATCH |
/api/subcategories/[id] |
Переключить is_active |
| DELETE |
/api/subcategories/[id] |
Удалить |
Товары
| Метод |
Путь |
Описание |
| GET |
/api/products/bulk |
Список. Query: loc, cat, sub, search, page, limit (≤100). Ответ: { data, total, page, limit } |
| POST |
/api/products/add |
Создать. Body: { locationId, categoryId, subcategoryId?, name, description?, privateData?, price, quantityInStock?, photoUrl?, hiddenPhotoUrl?, hiddenCoordinates?, hiddenDescription?, isMono? }. Обязательны: locationId, categoryId, name, price. isMono=1 → quantityInStock=999999 |
| GET |
/api/products/[id] |
Детали товара (с category, subcategory, location) |
| PUT |
/api/products/[id] |
Обновить (частично) |
| DELETE |
/api/products/[id] |
Удалить |
| POST |
/api/products/[id]/clone |
Клонировать (имя получает суффикс (Copy)) |
Пользователи
| Метод |
Путь |
Описание |
| GET |
/api/users/bulk |
Список. Query: search (username/telegramId), status (0/2), page, limit (≤100). Ответ: { data, total, page, limit } |
| GET |
/api/users/[id] |
Детали: пользователь + кошельки + последние 20 покупок + связанный лид |
| POST |
/api/users/[id] |
Обновить (username, country, city, district, notes и т.д.) |
| PATCH |
/api/users/[id] |
Переключить status (0=active, 2=blocked) |
| POST |
/api/users/[id]/adjust-balance |
Изменить баланс. Body: { amount: number, currency: "total_balance" | "bonus_balance" }. Пишет audit-запись |
| POST |
/api/users/batch-status |
Массово сменить статус. Body: { userIds: number[], newStatus: 0 | 2 } |
Кошельки
| Метод |
Путь |
Описание |
| GET |
/api/wallets/bulk |
Пользователи, у которых есть кошельки. Query: search. Ответ: { users, totalWallets, totalBalance } |
| GET |
/api/wallets/[userId] |
Кошельки конкретного пользователя |
| GET |
/api/wallets/overview |
Сводка: суммы и количество по типам (BTC/LTC/ETH/USDT/USDC), последние 20 комиссионных выплат |
| GET |
/api/wallets/seeds |
🔒 Seed-фразы всех кошельков (пишет audit seed_phrase_viewed) |
| GET |
/api/wallets/export-seeds |
🔒 Экспорт seed-фраз в CSV (Content-Disposition: attachment) |
| POST |
/api/wallets/record-payment |
Записать комиссионную выплату. Body: { paidAmount: number, note? } |
Покупки
| Метод |
Путь |
Описание |
| GET |
/api/purchases/bulk |
Список. Query: status (pending/completed/cancelled), from, to (YYYY-MM-DD), page, limit (≤100). Ответ: { data, total, page, limit } |
| PATCH |
/api/purchases/[id] |
Сменить статус. Body: { status: "completed" | "cancelled" }. Только для pending |
| POST |
/api/purchases/batch-status |
Массово. Body: { purchaseIds: number[], status: "completed" | "cancelled" } (обновляет только pending) |
Транзакции
| Метод |
Путь |
Описание |
| GET |
/api/transactions/bulk |
Список. Query: userId, page, limit (≤100, по умолчанию 20). Ответ: { data, total, page, limit } |
Лиды и чат
Лиды
| Метод |
Путь |
Описание |
| GET |
/api/leads/bulk |
Список. Query: search (name/phone/email/telegram/telegramId), status, page, limit (≤100). Ответ: { data, total, page, limit } |
| GET |
/api/leads/[id] |
Детали лида + связанный пользователь (баланс, покупки, кошельки) |
| PUT |
/api/leads/[id] |
Обновить (name, phone, email, telegram, status, notes, customFields и т.д.) |
| GET |
/api/leads/[id]/activity |
Активность: { hourly: number[24], yearly: { "YYYY-MM-DD": count }, total } (по audit_log) |
| GET |
/api/leads/[id]/sessions |
Чат-сессии лида с распарсенными сообщениями |
Чат (публичный виджет)
| Метод |
Путь |
Описание |
| POST |
/api/chat |
Отправить сообщение в чат-виджет. Body: { sessionId?, message, language?, device?, ip?, country? }. Создаёт/обновляет ChatSession, извлекает данные лида (имя/телефон/email/telegram), вызывает ИИ-провайдера, при chatbot_sleep_mode отвечает sleep-сообщением |
Оператор
| Метод |
Путь |
Описание |
| POST |
/api/operator |
Подключение/отключение оператора. Body: { sessionId, action: "connect" | "disconnect", operatorName }. Пишет audit operator_connect |
Чатбот (настройки)
| Метод |
Путь |
Описание |
| GET |
/api/admin/chatbot |
Настройки чатбота из site_settings (ключи chatbot_*), API-ключ маскируется |
| PUT |
/api/admin/chatbot |
Обновить настройки. Валидация: chatbot_temperature 0–2, chatbot_max_tokens 50–4000, chatbot_max_history 1–50 |
| GET |
/api/chatbot/models?endpoint=&apiKey= |
Список моделей провайдера через OpenAI-совместимый /models. Без query — берёт сохранённые настройки. Поддерживает OpenAI (data[]) и Ollama (models[]) |
Ключи настроек чатбота (defaults):
chatbot_enabled, chatbot_sleep_mode, chatbot_sleep_message, chatbot_system_prompt, chatbot_temperature (0.7), chatbot_max_tokens (1024), chatbot_max_history (20), chatbot_knowledge_base, chatbot_provider (ollama), chatbot_api_endpoint, chatbot_api_key, chatbot_model.
Аудит
| Метод |
Путь |
Описание |
| GET |
/api/audit/bulk |
Журнал аудита. Query: page, limit (≤200, по умолчанию 100), userId, from, to, search, action. Ответ: { data, total, page, limit } |
Локализация (i18n)
| Метод |
Путь |
Описание |
| GET |
/api/locales |
Все переводы: { en: {...}, es: {...}, de: {...} } |
| PUT |
/api/locales |
Обновить ключ. Body: { lang, key, value } |
Настройки
| Метод |
Путь |
Описание |
| GET |
/api/settings |
Список настроек (секреты маскированы, список в _masked) |
| PUT |
/api/settings |
Обновить. Body: { key, value }. Ответ: «Settings saved. Restart required.» |
| GET |
/api/settings/export |
Полный экспорт БД в JSON (users, wallets, purchases, categories, subcategories, locations, products, auditLogs, commissionPayments, userStates) |
| POST |
/api/settings/import |
🔒 Импорт (заглушка: «Import not yet implemented») |
Seed / Demo
| Метод |
Путь |
Описание |
| GET |
/api/seed/data |
Проверка: { seeded: boolean } (есть ли пользователи) |
| POST |
/api/seed/demo |
Заполнить демо-данными. Body: { reauthToken } (повторный ввод секрета) |
| POST |
/api/seed/clear |
🔒 Очистить все данные. Body: { reauthToken }. Пишет audit clear_all |
Корневой
| Метод |
Путь |
Описание |
| GET |
/api |
Служебный ответ (health API) |
Коды ошибок
| Код |
Значение |
| 400 |
Невалидный запрос / отсутствуют обязательные поля |
| 401 |
Нет cookie admin_token или токен невалиден/просрочен |
| 403 |
Недостаточно прав (нужен super_admin) |
| 404 |
Сущность не найдена |
| 409 |
Конфликт (дубликат, есть связанные записи) |
| 429 |
Слишком много попыток входа |
| 500 |
Внутренняя ошибка |
Соглашения
- Пагинация:
page (с 1), limit (кап зависит от эндпоинта: 50/100/200)
- Даты:
from/to в формате YYYY-MM-DD (to инклюзивно до конца дня)
is_active/status пользователей: 0 = активно, 2 = заблокировано
- Статусы покупок:
pending / completed / cancelled
- Статусы лидов:
new / contacted / qualified / lost / spam