Crypto Pay API: приём криптоплатежей в Telegram-боте за час
Практический гайд по Crypto Pay API от Crypto Bot: получение токена, createInvoice, проверка подписи webhook, поддерживаемые активы
- Автор
- TON Adoption Team · исследовательская группа проекта
- Опубликовано
Содержание20разделов
- Когда Crypto Pay — правильный выбор
- Шаг 1. Создаём приложение и получаем токен
- Шаг 2. Первый запрос — getMe
- Шаг 3. Создаём invoice
- Multi-asset invoice
- Шаг 4. Webhook на оплату
- Проверка подписи — обязательна
- Идемпотентность
- Шаг 5. Polling как fallback
- Поддерживаемые активы (2026)
- Типовые ошибки и как их ловить
- INVOICE_NOT_FOUND
- EXPIRES_IN_INVALID
- Курс расходится с моментом оплаты
- Webhook прилетает без подписи
- Безопасность приложения
- Альтернативы и комбинация
- Production-чеклист
- Что в итоге
- Источники
Crypto Pay — HTTP API от Crypto Bot, через который Telegram-бот, сайт или мини-апп может принимать криптоплатежи в TON, USDT и ещё ~15 активах без своего бэкенд-кошелька, без интеграции с биржей и без on-chain инфраструктуры. На нём построены десятки тысяч мерчантов: магазины стикеров, подписки на боты, инфо-курсы, VPN-сервисы. В этом материале — практический сценарий «от нуля до production» для разработчика: получение токена, createInvoice, валидация webhook’ов, обработка ошибок и продакшен-чеклист.
Когда Crypto Pay — правильный выбор
- Telegram-нативная аудитория. Пользователи уже держат баланс в
@CryptoBot(десятки миллионов аккаунтов) — оплата в 1 клик, без копирования адресов. - Микро-платежи 1–50 USD. Подписки, виртуальные товары, чаевые, разовые услуги — там, где сетевые комиссии on-chain убивают экономику.
- Не хочется держать собственный hot-wallet. Crypto Pay — кастодиальный, и для приёма платежей у тебя нет своего seed: ключи держит CG.
- Нужна мульти-актив корзина. Один invoice можно сделать «принимаем TON или USDT или BTC» — выбор делает покупатель.
Шаг 1. Создаём приложение и получаем токен
- Открой
@CryptoBotв Telegram (или короткую ссылкуt.me/send). - Меню → Crypto Pay → My Apps → Create App.
- Дай приложению название (видно тебе и в логах операций).
- Бот выдаёт API-токен вида
12345:AAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. Сохрани его в секрет-стор (.env, Vault, AWS Secrets) — он эквивалент пароля к балансу приложения.
База URL’ов:
- Production:
https://pay.crypt.bot/api/ - Testnet:
https://testnet-pay.crypt.bot/api/— отдельный токен, выпускается через@CryptoTestnetBot. Полезно для CI/staging.
Авторизация — заголовок Crypto-Pay-API-Token: <твой токен> в каждом запросе.
Шаг 2. Первый запрос — getMe
Проверь, что токен живой:
GET https://pay.crypt.bot/api/getMe
Crypto-Pay-API-Token: 12345:AAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Ответ:
{
"ok": true,
"result": {
"app_id": 12345,
"name": "My Test Shop",
"payment_processing_bot_username": "CryptoBot"
}
}
Если "ok": false — смотри error.code. Самые частые:
401 UNAUTHORIZED— токен не совпадает (опечатка, скопировал с пробелом).400 USER_ID_INVALID— ошибка не из этого метода, но появляется приtransferс неправильнымuser_id.429 TOO_MANY_REQUESTS— лимит 100 запросов/секунду, добавь backoff.
Шаг 3. Создаём invoice
Базовый сценарий — пользователь хочет купить подписку «PRO» за $9.99 в USDT:
POST https://pay.crypt.bot/api/createInvoice
Content-Type: application/json
Crypto-Pay-API-Token: 12345:AAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
{
"currency_type": "crypto",
"asset": "USDT",
"amount": "9.99",
"description": "Подписка PRO, 30 дней",
"hidden_message": "Спасибо! Бот активирует доступ в течение минуты.",
"paid_btn_name": "openBot",
"paid_btn_url": "https://t.me/your_bot?start=invoice_paid",
"payload": "{\"user_id\":42,\"plan\":\"pro_30d\"}",
"expires_in": 1800
}
Ответ:
{
"ok": true,
"result": {
"invoice_id": 528347,
"status": "active",
"hash": "IVtN5sR1xVfH",
"asset": "USDT",
"amount": "9.99",
"pay_url": "https://t.me/CryptoBot?start=IVtN5sR1xVfH",
"bot_invoice_url": "https://t.me/CryptoBot?start=IVtN5sR1xVfH",
"mini_app_invoice_url": "https://t.me/CryptoBot/app?startapp=IVtN5sR1xVfH",
"web_app_invoice_url": "https://crypto-pay.io/invoice/...",
"description": "Подписка PRO, 30 дней",
"created_at": "2026-05-15T10:21:00Z",
"expiration_date": "2026-05-15T10:51:00Z",
"payload": "{\"user_id\":42,\"plan\":\"pro_30d\"}"
}
}
Ключевые поля для интеграции:
pay_url— даёшь пользователю как кнопку «Оплатить». Открывает@CryptoBotс подгруженным invoice.mini_app_invoice_url— для встраивания в Telegram Mini App (открывается прямо в боте без выхода).payload— строка до 4096 символов, твоя «memo». Сюда положиuser_id,order_id, любое что нужно вернуть в webhook’е. JSON-стрингифай — Crypto Pay не парсит.expires_in— секунды до экспирации. По умолчанию invoice бессрочный; для микро-платежей советую 600–3600.
Multi-asset invoice
Хочешь дать выбор «TON или USDT»? Передай массив:
{
"currency_type": "fiat",
"fiat": "USD",
"amount": "9.99",
"accepted_assets": "TON,USDT,USDC",
"description": "Подписка PRO, 30 дней",
"payload": "..."
}
Crypto Pay сам конвертирует $9.99 в TON и USDT по текущему курсу на момент оплаты — покупатель выбирает кнопкой.
Шаг 4. Webhook на оплату
Crypto Pay не присылает webhook’и автоматически — их нужно включить отдельно. В @CryptoBot → My Apps → твоё приложение → Webhooks → задай URL вида https://api.example.com/cryptopay/webhook.
Формат входящего запроса:
POST /cryptopay/webhook
Content-Type: application/json
crypto-pay-api-signature: <hex-signature>
{
"update_id": 7723,
"update_type": "invoice_paid",
"request_date": "2026-05-15T10:25:11Z",
"payload": {
"invoice_id": 528347,
"status": "paid",
"hash": "IVtN5sR1xVfH",
"asset": "USDT",
"amount": "9.99",
"paid_amount": "9.99",
"paid_asset": "USDT",
"paid_fiat_rate": "1",
"fee": "0",
"paid_anonymously": false,
"paid_btn_name": "openBot",
"paid_btn_url": "https://t.me/your_bot?start=invoice_paid",
"comment": null,
"payload": "{\"user_id\":42,\"plan\":\"pro_30d\"}",
"paid_at": "2026-05-15T10:25:05Z"
}
}
Проверка подписи — обязательна
Подпись — HMAC-SHA-256 от сырого тела запроса с ключом, который сам тоже SHA-256 от твоего API-токена. На Node.js:
import crypto from 'node:crypto';
function verifyWebhook(rawBody, signature, apiToken) {
const secret = crypto.createHash('sha256').update(apiToken).digest();
const expected = crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(expected, 'hex'),
);
}
На Python:
import hashlib
import hmac
def verify_webhook(raw_body: bytes, signature: str, api_token: str) -> bool:
secret = hashlib.sha256(api_token.encode()).digest()
expected = hmac.new(secret, raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(signature, expected)
Без этой проверки злоумышленник может прислать фальшивый POST с "status": "paid" и активировать заказ без оплаты. На этом «попадались» десятки магазинов в 2022–2024.
Идемпотентность
Crypto Pay при сбое доставки повторяет webhook несколько раз (с растущим backoff’ом). Это значит, что один и тот же update_id или invoice_id может прилететь дважды. Веди таблицу обработанных событий или просто проверяй статус заказа перед активацией:
if (await orderAlreadyFulfilled(invoiceId)) {
return res.status(200).end(); // ack, но ничего не делаем
}
await fulfillOrder(invoiceId, payloadJson);
await markAsFulfilled(invoiceId);
Шаг 5. Polling как fallback
Если webhook не дошёл (твой сервер был в дауне), не теряй платёж — раз в N минут опрашивай getInvoices:
GET https://pay.crypt.bot/api/getInvoices?status=paid&offset=0&count=100
Crypto-Pay-API-Token: ...
Возвращает массив со всеми оплаченными invoice’ами. Сравни с локальной БД, добей пропущенные. Хорошая частота для cron — раз в 5 минут для активных заказов.
Поддерживаемые активы (2026)
На момент написания Crypto Pay принимает:
| Сеть | Активы |
|---|---|
| TON | TON, USDT-TON, NOT, jUSDC, jUSDT, MAJOR, DOGS, HMSTR |
| Bitcoin | BTC |
| Ethereum | ETH, USDT-ERC20, USDC-ERC20 |
| Tron | USDT-TRC20 |
| BNB Chain | BNB, USDT-BEP20 |
| Solana | SOL, USDT-SPL |
| Litecoin | LTC |
Точный список меняется — запрашивай getCurrencies перед onboarding’ом мерчанта, чтобы UI не показывал отсутствующие активы.
Типовые ошибки и как их ловить
INVOICE_NOT_FOUND
Происходит при попытке вернуть getInvoices по invoice_id, который создан другим приложением (с другим токеном). Один токен видит только свои invoice’ы.
EXPIRES_IN_INVALID
expires_in должен быть от 1 до 2 678 400 (31 день). Если ставишь больше — invoice создаётся без экспирации, но при этом возвращается ошибка. Проверяй диапазон на стороне клиента.
Курс расходится с моментом оплаты
Если invoice в fiat ($9.99) с accepted_assets: TON,USDT, курс фиксируется на момент оплаты, не создания. При высокой волатильности это создаёт mini-arbitrage: пользователь может ждать выгодный момент. Для критичных позиций используй короткий expires_in (60–300 секунд).
Webhook прилетает без подписи
Признак фальшивки или старой версии Crypto Pay. Не доверяй запросам без crypto-pay-api-signature. С 2024 года все production webhook’и подписаны.
Безопасность приложения
- Никогда не клади токен в фронтенд / клиентскую часть бота. Crypto Pay-токен = доступ к балансу. Только серверная сторона.
- Используй HTTPS на webhook-endpoint’е. Без него подпись не спасает от MITM на роутере.
- Логируй
update_idкаждого webhook’а — поможет при разборе споров и для cron-fallback. - Раздели приложения по средам. Production-токен — отдельно, staging — отдельный токен в testnet. Случайный refund с production-кошелька портит много нервов.
- Включи 2FA в Telegram — компрометация аккаунта владельца приложения = компрометация баланса.
Альтернативы и комбинация
- xRocket Pay — прямой конкурент, очень похожий API (
createInvoice/webhook), отдельная база пользователей. Многие магазины интегрируют оба: пользователь выбирает «Crypto Bot или xRocket». - Telegram Stars — внутренняя валюта Telegram, не крипта. Подходит для цифрового контента в Telegram, но монетизация и payout — через Telegram, не через крипто-сеть.
- Прямой on-chain через TON Connect — некастодиально, без зависимости от стороннего бота, но требует своего бэкенда и UX-работы. Имеет смысл для крупных мерчантов, у которых уже есть TON-инфраструктура.
Гибридная стратегия для production: Crypto Pay + xRocket Pay покрывает 90% Telegram-аудитории, прямой on-chain через TON Connect — для тех, кто не доверяет кастодиальным сервисам или платит крупные суммы.
Production-чеклист
Перед запуском в прод пройдись по этим пунктам:
- Токен в
.env/ Vault, не закоммичен. - Webhook на HTTPS, подпись проверяется HMAC-SHA-256.
- Идемпотентность по
update_idилиinvoice_id. - Cron-fallback через
getInvoicesдля пропущенных webhook’ов (раз в 5 минут). - Логи всех webhook’ов с raw body — для разбора споров.
-
expires_inвыставлен (для fiat invoice’ов — короткий, 60–300с). - Retry’и на сетевые ошибки
createInvoiceс экспоненциальным backoff’ом. - Алёрт на падение баланса приложения ниже порога — чтобы не пропустить, что закончились средства для refund’ов.
- Документация по работе с поддержкой
@CryptoBot_Supportдля эскалаций. - Тест-сценарий через testnet с реальным
@CryptoTestnetBotпройден.
Что в итоге
Crypto Pay API — минимально болезненный способ начать принимать криптоплатежи в Telegram-боте. От нуля до первого подтверждённого invoice’а реально дойти за пару часов: получить токен, написать createInvoice, поднять webhook-endpoint с проверкой подписи. Кастодиальная природа — главный trade-off: ты экономишь на инфраструктуре, но отдаёшь надёжность и регуляторные риски на сторону Crypto Bot.
Для пилотов и микро-магазинов это правильный выбор почти всегда. Для серьёзного оборота — комбинируй с прямым on-chain приёмом через TON Connect, чтобы не зависеть от одного шлюза.
Источники
- help.crypt.bot/crypto-pay-api — официальная документация API, включая список методов и поля webhook’ов.
- Crypto Pay testnet — отдельная среда для интеграционных тестов.
- @CryptoBot — основной бот для управления приложениями.
Частые вопросы
Нужен ли KYC, чтобы выпустить токен Crypto Pay?
Чем Crypto Pay отличается от xRocket Pay и Telegram Stars?
Как обрабатывать частичные платежи или переплаты?
Что делать с возвратами?
Нужно ли проверять подпись webhook'а?
Какие комиссии берёт Crypto Pay с продавца?
Похожие материалы
- Кошельки9 мая 2026 г.
Crypto Bot 2026: гайд по платежам в Telegram
Как работает @CryptoBot в Telegram в 2026 году: чеки, P2P-маркет, инвойсы, Crypto Pay API, чаевые. Поддержка TON и USDT, комиссии, лимиты
- Кошельки17 дек. 2025 г.
Wallet в Telegram 2026: возможности и риски сервиса
Что умеет встроенный Wallet в Telegram, какие у него лимиты, чем кастодиальная природа отличается от Tonkeeper и когда сервис безопасен, а когда нет.
- Гейминг и мини-аппы2 мар. 2026 г.
Telegram Stars vs TON-платежи: в чём разница (2026)
Сравнение Telegram Stars и TON-платежей в 2026 — комиссии, ограничения, удобство для пользователя и разработчика. Когда выбирать каждую модель.