Skip to main content
Требуется подписка Silver или выше — как для подачи заявки, так и для каждого авторизованного вызова. Если подписка владельца ключа истекает, проект замораживается до её возобновления.
REST API, позволяющий вашему приложению работать с балансом Vito пользователя прямо из Discord: читать его, списывать, начислять или переводить между пользователями. Все эндпоинты возвращают JSON и версионированы под /v1.
Vito никогда не переходит в реальные деньги и не берётся из них. Он перемещается только между балансами Vetox.
Все эндпоинты находятся под https://api.vetox.io/public/vito.Пути, указанные на этой странице — /v1/deduct, /v1/balance/:discordId и остальные — заданы относительно этого префикса, который SDK подставляет за вас. Если вызываете сами, используйте полный URL:
https://api.vetox.io/v1/deduct не является маршрутом и вернёт 404.
Пишете на Node.js? Не собирайте REST-вызовы вручную — возьмите официальный пакет @vetox-bot/vito. Он покрывает все девять эндпоинтов и проверку вебхуков, а идемпотентность и повторные попытки берёт на себя. См. Официальный SDK для Node.js ниже.

Получение доступа

Доступ выдаётся на каждый проект отдельно. Нужны все четыре условия:
1

Активная подписка, Silver или выше

Проверяется при каждом вызове, а не только при одобрении.
2

Одобренная заявка разработчика

Отправляется со страницы Vito API в панели управления. Рассматривается командой Vetox вручную.
3

Принятые условия для разработчиков API

Подтверждаются при отправке заявки.
4

Scopes, необходимые вашему проекту

Выдаются командой Vetox исходя из вашего описания.
Пишите конкретно, что вы создаёте и как будете хранить ключ. Отклоняют именно расплывчатые заявки.

Scopes

Аутентификация

Передавайте секретный ключ как Bearer-токен:
Два необязательных уровня дополнительно защищают проект:
  • Список разрешённых IP — ограничивает вызовы конкретными IP-адресами серверов
  • Лимиты частоты — потолки на проект, растущие вместе с уровнем подписки владельца

Ключи, ротация и хранение

Ключ и секрет подписи показываются ровно один раз. После одобрения у вас есть окно в 7 дней, чтобы раскрыть их на вкладке API-ключей. Vetox хранит только хеш и не может показать их снова — если пропустите окно, придётся выполнить ротацию.
  • Держите ключ только на сервере — кто им владеет, может списывать средства ваших пользователей
  • Выполняйте ротацию на вкладке API-ключей. Прежний ключ продолжает работать 24 часа — льготный период, чтобы выкатить обновление без простоя
  • Секрет подписи вебхуков ротируется отдельно, со своим 24-часовым перекрытием
  • При утечке немедленно выполните ротацию

Официальный SDK для Node.js

Официальный пакет @vetox-bot/vito оборачивает все девять эндпоинтов и проверку вебхуков. Он берёт на себя заголовок Idempotency-Key, повторные попытки с нарастающей задержкой, тайм-ауты и классификацию ошибок.

Установка

Требуется Node.js 20 или новее. У пакета нет ни одной зависимости времени выполнения — он использует встроенный fetch и node:crypto — и поставляется сразу в ESM и CommonJS с полными определениями TypeScript.

Инициализация

Если не передать apiKey, SDK прочитает VITO_API_KEY из окружения. Формат ключа проверяется при создании клиента, поэтому некорректный ключ упадёт сразу, а не после сетевого обхода и ответа 401.
Ключ перемещает деньги — держите его только на сервере, никогда в клиентской сборке или в браузере. console.log(vito) печатает [redacted] вместо ключа, а SDK отклоняет любой baseUrl с http:// для нелокального хоста, чтобы ключ не шёл открытым текстом.

Параметры клиента

Доступные методы

Каждый метод сразу возвращает распакованное поле data — вам никогда не приходится самостоятельно разбирать success или data. Все методы принимают и параметры на конкретный вызов: { timeoutMs, maxRetries, signal, headers }, а методы записи дополнительно — { idempotencyKey }.

Примеры использования

Проверка ключа при запуске

Чтение баланса

Списание с пользователя (продажа товара)

Здесь фиксируйте заказ только как ожидающий. Списание ещё не произошло — выдавайте товар по вебхуку confirmation.completed, а не по этому ответу.

Начисление пользователю

Перебор транзакций

Идемпотентность и повторные попытки

SDK отправляет заголовок Idempotency-Key при каждой записи (deduct, credit, transfer). Если вы его не передали, SDK формирует ключ один раз на вызов и повторяет ровно тот же ключ при каждой повторной попытке, поэтому повтор не может провести операцию дважды. Передавайте свой ключ, когда одна и та же логическая операция может быть повторена из нового процесса — обработчика задач, повторной доставки из очереди или планового прогона:
auth.rotateKey() исключён намеренно — повтор там выпустит второй ключ и обесценит тот, что вернула первая попытка.
Если Retry-After больше maxRetryDelayMs (то есть ваша часовая квота действительно исчерпана), SDK сразу бросает VitoRateLimitError, а не спит весь бюджет вашего запроса.

Проверка вебхуков через SDK

constructEvent проверяет пятиминутное окно повторов, сравнивает за постоянное время с каждой подписью h1 в заголовке — поэтому автоматически работает во время 24-часового перекрытия при ротации — затем разбирает полезную нагрузку и возвращает типизированное событие. В обработчике маршрута Next.js (App Router) используйте вариант, который сам читает сырое тело:
Подпись покрывает сырые байты. В Express подключите express.raw({ type: 'application/json' }) к маршруту вебхука — express.json() поглощает тело, и после этого любая проверка проваливается. В Next.js не вызывайте request.json() до constructEventFromRequest.
Доставка происходит как минимум один раз. Исключайте дубли по event.eventId, прежде чем выполнять любой побочный эффект.

Обработка ошибок

Всё, что бросает SDK, наследуется от VitoError и несёт code, status, type, requestId и retryable.
Всегда логируйте requestId — именно он нужен поддержке, чтобы отследить конкретный вызов.

Отмена вызова

Отмена также останавливает ожидающую повторную попытку и бросает VitoConnectionError с кодом VITO_SDK_ABORTED.

Списание с пользователя

Один только ключ не может переместить Vito пользователя. Каждое списание требует подтверждения пользователем PIN-кодом его кошелька, на vetox.io — никогда внутри вашего приложения и никогда внутри Discord.
1

Ваше приложение вызывает POST /v1/deduct

С пользователем, суммой, исходным guildId и данными товара.
2

Vito возвращает confirmUrl

Ожидающее подтверждение, действительное 10 минут. Пользователю также приходит ЛС.
3

Пользователь подтверждает PIN-кодом

На vetox.io.
4

Vito проводит расчёт и уведомляет

Баланс списывается, транзакция записывается, и отправляется подписанный вебхук, если он у вас настроен.
5

Ваше приложение проверяет и завершает

Проверьте подпись, затем откройте доступ к контенту или выдайте товар.
Завершайте своё действие только по confirmation.completed — никогда по ответу /deduct. На этом этапе списание ещё не окончательное.

Параметры запроса — /v1/deduct

Начисление пользователю

POST /v1/add начисляет Vito пользователю из вашего собственного баланса — для наград или возвратов. Те же поля, что и у /deduct, кроме guildId и product.
В отличие от списания, начисление не имеет шага подтверждения — расчёт происходит сразу. Требуется scope credit:create и достаточный баланс, иначе вызов вернёт 402 VITO_INSUFFICIENT_OWNER_FUNDS.

Комиссии

Каждое списание поступает вам за вычетом комиссии платформы — по той же шкале, что и переводы Vito внутри приложения, в зависимости от вашего уровня подписки:
Суммы 5 Vito и меньше не облагаются комиссией, а начисления через /v1/add не облагаются ею никогда.

Вебхуки

Добавьте один или несколько https-адресов обратного вызова на вкладке настроек. Vito отправляет подписанный POST, как только подтверждение достигает конечного состояния.
Вебхуки отправляются, только если у проекта есть и адрес обратного вызова, и секрет подписи. Раскройте секрет (whsec_…) один раз на вкладке API-ключей.

Проверка подписи

Каждая доставка содержит заголовок X-Vito-Signature:
Каждую доставку сопровождают ещё два заголовка — используйте X-Vito-Event-Id как ключ дедупликации, поскольку повторная попытка отправляет тот же идентификатор:
Во время ротации секрета подписи заголовок содержит несколько подписей, самая новая первой:
Принимайте доставку, если совпадает любая из h1. Проверяющий код, читающий только первую, будет отвергать все вебхуки, пока не выкатит новый секрет, — а это сводит на нет весь смысл 24-часового перекрытия.
На Node.js: Webhooks.constructEvent из пакета @vetox-bot/vito делает всё это за вас — окно повторов, сверку с каждой подписью h1 и сравнение за постоянное время — и возвращает типизированное событие. Код ниже нужен для собственной реализации или другого языка.
Пересчитайте HMAC по <ts>:<rawBody> вашим секретом подписи и сравните за постоянное время.
Проверяйте по сырому телу запроса, до любого разбора JSON или middleware, которое его перепишет.

События

Пять типов событий с одинаковой структурой полезной нагрузки. Поле data.status содержит исход.
Вебхуки повторяются 5 раз с нарастающей задержкой. Быстро отвечайте 2xx, а выдачу выполняйте асинхронно.

Коды ошибок

Каждый ответ обёрнут в конверт. Успех несёт data, ошибка — error, и никогда оба сразу:
Каждый код имеет префикс VITO_. Сравнивайте строку целиком — голый RATE_LIMITED или FORBIDDEN никогда не приходит в ответе.

Лимиты частоты

Также действует лимит на один IP, равный половине вашей минутной квоты, но не менее 30.
Под нагрузкой эндпоинты записи отказывают «закрыто» — списание отклоняется, чтобы не рисковать двойным расходом. Эндпоинты чтения отказывают «открыто». Считайте отклонённую запись как «не произошло» и повторите её.
Отправляйте заголовок Idempotency-Key, чтобы безопасно исключать дубли при повторных попытках.

Эндпоинты

Ограничения

  • Подтверждения истекают через 10 минут — считайте неподтверждённые запросы брошенными
  • amount должен быть положительным целым числом
  • metadata ограничена 10 ключами
  • Лимиты на транзакцию и на день задаёт команда Vetox; они отображаются только для чтения на вкладке настроек

Чек-лист безопасности

API-ключу и секрету подписи не место в клиентском коде. При утечке любого из них немедленно выполните ротацию.
Сверяйте подпись с сырым телом запроса и отклоняйте доставки старше ~5 минут.
Никогда не выдавайте товар по ответу /deduct — списание окончательно только при confirmation.completed.
Запрашивайте только те scopes, которые действительно используете, и включите список разрешённых IP.

Устранение неполадок

Подписка владельца истекла. Она перепроверяется при каждом вызове.
Восстановить его нельзя — хранится только хеш. Выполните ротацию, чтобы получить новый.
Принимайте оба секрета в течение 24-часового перекрытия.
Пользователь его не подтвердил. Подтверждения истекают через 10 минут.
Проекту нужны и адрес обратного вызова, и секрет подписи. С одним из двух ничего не доставляется.
Это расчётная комиссия. Используйте суммы 5 Vito и меньше, чтобы её избежать, либо закладывайте её в цену.
/v1/add финансируется из вашего собственного баланса, а не создаётся из ничего. Пополните его.

Vito

Балансы, PIN-код и комиссии.

Запросы на оплату

Что видит пользователь, когда вы списываете с него.

@vetox-bot/vito на npm

Официальный пакет Node.js — одна установка, полная интеграция.