Tyxo Pay API

Принимайте оплату в криптовалюте прямо в Telegram. Создайте счёт, отправьте покупателю ссылку, а когда он оплатит в боте @tyxobot, мы пришлём вебхук на ваш сервер. Деньги сразу падают на баланс владельца приложения.

Base URLhttps://api.tyxo.app/v1/

Быстрый старт

  1. Откройте @tyxobot, затем мини-апп: Сервисы → Для бизнеса → Новое приложение.
  2. Сохраните токен. Он показывается один раз, у нас хранится только его хеш. Потеряли или засветили токен? Выпустите новый в настройках приложения, старый сразу перестанет работать.
  3. Укажите адрес вебхука, если хотите получать уведомления об оплате.
  4. Сделайте первый запрос:
curl https://api.tyxo.app/v1/getMe \
  -H "Tyxo-Api-Token: ВАШ_ТОКЕН"

Запросы и ответы

Каждый метод вызывается по адресу https://api.tyxo.app/v1/<метод>. Токен передаётся в заголовке Tyxo-Api-Token. Параметры можно передать в строке запроса (GET) или телом JSON (POST, Content-Type: application/json), можно и смешать. Тело не больше 64 КБ.

Все суммы это строки с десятичной дробью, например "12.5". Так не теряется точность: у GRAM 9 знаков после запятой, у USDT 6. Больше знаков, чем у актива, передать нельзя.

Успешный ответ всегда HTTP 200:

200 OK
{ "ok": true, "result": { ... } }

Ошибка приходит с HTTP-кодом из error.code и машинным именем в error.name:

400 Bad Request
{ "ok": false, "error": { "code": 400, "name": "AMOUNT_INVALID" } }

Активы

В параметре asset передаётся код актива, регистр не важен. Монета сети TON в приложении называется GRAM (ex. TON), а в API у неё код TON.

КодНазваниеЗнаков после запятой
TONGRAM (ex. TON), нативная монета сети9
USDTTether USD6
XAUTTether Gold6
NOTNotcoin9
DOGSDOGS9
HMSTRHamster Kombat9
CATICatizen9
MAJORMajor9
STONSTON.fi9
TSTONTonstakers TON9

Комиссии и лимиты

  • С оплаченного счёта удерживается 0.5%. Точная сумма комиссии видна в поле fee счёта сразу при создании.
  • Выплаты через transfer внутри Tyxo бесплатные.
  • До 10 приложений на один аккаунт.
  • Описание счёта до 200 символов, payload до 4096 символов, spend_id до 64 символов.

getMe

GETPOST

Проверяет токен и возвращает данные приложения. Параметров нет.

result
{
  "app_id": "6c1f6c1e-6c4e-4c79-9d63-1f2a0b7d9c11",
  "name": "Мой магазин",
  "webhook_url": "https://shop.example/tyxo",
  "transfers_enabled": false
}

getBalance

GETPOST

Баланс владельца приложения по всем активам. Параметров нет.

result
[
  { "asset": "TON", "available": "128.4512" },
  { "asset": "USDT", "available": "214.5" }
]

createInvoice

POSTGET

Создаёт счёт и возвращает Invoice. Отправьте покупателю pay_url: он откроет бота и оплатит с баланса Tyxo.

ПараметрОписание
assetобязателенКод актива из таблицы.
amountобязателенСумма строкой, больше нуля.
descriptionнеобязателенЧто оплачивают. Покупатель видит это в боте. До 200 символов.
payloadнеобязателенЛюбые ваши данные, например номер заказа или JSON. Покупатель их не видит, они вернутся в счёте и вебхуке. До 4096 символов.
curl https://api.tyxo.app/v1/createInvoice \
  -H "Tyxo-Api-Token: ВАШ_ТОКЕН" \
  -H "Content-Type: application/json" \
  -d '{"asset":"USDT","amount":"25","description":"Заказ №42","payload":"order-42"}'

getInvoices

GETPOST

Счета приложения, сначала новые. Возвращает { "items": [Invoice] }.

ПараметрОписание
statusнеобязателенactive, paid или cancelled.
invoice_idsнеобязателенИдентификаторы счетов через запятую.
offsetнеобязателенСколько счетов пропустить. По умолчанию 0.
countнеобязателенСколько вернуть, от 1 до 1000. По умолчанию 100.

deleteInvoice

POSTGET

Отменяет активный счёт, после этого его нельзя оплатить. Оплаченный счёт отменить нельзя, придёт INVOICE_NOT_ACTIVE. Возвращает true.

ПараметрОписание
invoice_idобязателенИдентификатор счёта.

transfer

POSTGET

Переводит деньги с баланса владельца пользователю Tyxo по его Telegram ID. Подходит для выплат, кэшбэка и выигрышей. Пользователь получит уведомление в боте.

Метод выключен по умолчанию. Включите Выплаты через API в настройках приложения, иначе придёт TRANSFERS_DISABLED.
ПараметрОписание
user_idобязателенTelegram ID получателя. Он должен хотя бы раз запустить @tyxobot.
assetобязателенКод актива.
amountобязателенСумма строкой.
spend_id обязателен Ваш уникальный ключ выплаты, до 64 символов. Повторный запрос с тем же spend_id вернёт ту же выплату и не спишет деньги второй раз, так что запрос безопасно повторять при сетевых ошибках. Тот же ключ с другими параметрами вернёт SPEND_ID_REUSED.
result
{
  "transfer_id": "f3b0c2a4-1d2e-4c5b-9a8f-6e7d5c4b3a21",
  "user_id": "123456789",
  "asset": "USDT",
  "amount": "5",
  "spend_id": "cashback-2026-10-15-77"
}

Объект Invoice

ПолеТипОписание
invoice_idstringИдентификатор счёта (UUID).
hashstringКороткий код счёта, из него собрана ссылка.
statusstringactive, paid или cancelled.
assetstringКод актива.
amountstringСумма, которую платит покупатель.
feestringКомиссия Tyxo. На баланс приходит amount минус fee.
descriptionstring | nullОписание для покупателя.
payloadstring | nullВаши данные из createInvoice.
pay_urlstringСсылка на оплату в боте.
created_atstringВремя создания, ISO 8601 в UTC.
paid_atstring | nullВремя оплаты, если оплачен.
Invoice
{
  "invoice_id": "0b6f3e2a-8c1d-4f5e-9a7b-2c3d4e5f6a7b",
  "hash": "Vj3kQ9xZp2LmN7aB4cD8eF",
  "status": "active",
  "asset": "USDT",
  "amount": "25",
  "fee": "0.125",
  "description": "Заказ №42",
  "payload": "order-42",
  "pay_url": "https://t.me/tyxobot?start=i_Vj3kQ9xZp2LmN7aB4cD8eF",
  "created_at": "2026-10-15T12:00:00.000Z",
  "paid_at": null
}

Вебхуки

Когда счёт оплачен, мы отправляем POST с JSON на адрес вебхука приложения. Адрес задаётся в настройках приложения в мини-аппе и должен быть публичным https с доменом, IP-адреса не принимаются.

POST на ваш адрес
{
  "update_id": 1042,
  "update_type": "invoice_paid",
  "request_date": "2026-10-15T12:03:41.512Z",
  "payload": { Invoice со статусом "paid" }
}
  • Ответьте любым кодом 2xx в течение 10 секунд, иначе доставка считается неудачной. Редиректы не выполняются.
  • Неудачную доставку повторяем: первая попытка через 30 секунд, дальше пауза удваивается до часа. Попытки идут 3 дня.
  • Одно и то же событие может прийти повторно, если ваш ответ потерялся в сети. Обрабатывайте update_id один раз.
  • Перед тем как выдавать товар, проверьте подпись запроса.

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

Каждый вебхук подписан. В заголовке Tyxo-Api-Signature лежит HMAC-SHA256 от сырого тела запроса в hex. Ключ HMAC это SHA-256 от токена приложения (32 байта, не hex-строка). Считайте подпись по байтам тела как они пришли, до разбора JSON.

import { createHash, createHmac, timingSafeEqual } from 'node:crypto';

export function isSignedByTyxo(rawBody, signature, token) {
  const key = createHash('sha256').update(token).digest();
  const expected = createHmac('sha256', key).update(rawBody).digest('hex');
  return typeof signature === 'string'
    && signature.length === expected.length
    && timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

app.post('/tyxo', express.raw({ type: 'application/json' }), (request, response) => {
  if (!isSignedByTyxo(request.body, request.get('tyxo-api-signature'), process.env.TYXO_TOKEN)) {
    return response.sendStatus(401);
  }
  const update = JSON.parse(request.body);
  response.sendStatus(200);
});
Не доверяйте вебхуку без проверки подписи и сверяйте amount и asset с заказом. При сомнениях запросите счёт через getInvoices по invoice_ids.

Ошибки

nameHTTPЧто случилось
UNAUTHORIZED401Нет токена или он неверный, отозван.
METHOD_NOT_FOUND404Такого метода нет.
BODY_INVALID400Тело не JSON-объект.
BODY_TOO_LARGE413Тело больше 64 КБ.
ASSET_REQUIRED400Не передан asset.
ASSET_INVALID400Такого актива нет.
AMOUNT_REQUIRED400Не передан amount.
AMOUNT_INVALID400Сумма не число, не больше нуля или с лишними знаками после запятой.
DESCRIPTION_TOO_LONG400Описание длиннее 200 символов.
PAYLOAD_TOO_LONG400payload длиннее 4096 символов.
STATUS_INVALID400Неизвестный status в фильтре.
PAGINATION_INVALID400offset или count вне допустимых значений.
INVOICE_IDS_INVALID400В invoice_ids есть не UUID.
INVOICE_ID_INVALID400invoice_id не передан или не UUID.
INVOICE_NOT_FOUND404Счёта нет или он принадлежит другому приложению.
INVOICE_NOT_ACTIVE409Счёт уже оплачен или отменён.
TRANSFERS_DISABLED403Выплаты через API выключены в настройках приложения.
USER_ID_REQUIRED400Не передан user_id.
USER_NOT_FOUND400Пользователь ни разу не запускал бота.
USER_IS_APP_OWNER400Нельзя перевести самому себе.
SPEND_ID_REQUIRED400Не передан spend_id.
SPEND_ID_TOO_LONG400spend_id длиннее 64 символов.
SPEND_ID_REUSED409Этот spend_id уже использован для другой выплаты.
INSUFFICIENT_FUNDS400На балансе владельца не хватает средств.
INTERNAL_ERROR500Сбой на нашей стороне. Запрос можно повторить.