Как принимать криптоплатежи в боте Telegram
Как связать заказ физического товара в собственном Telegram-боте с инвойсом Cryptanio, отправить платёжную ссылку и проверить оплату. С ограничениями Telegram Stars и Mini Apps.
Обновлено:
Криптоплатёж можно связать с заказом в собственном Telegram-боте: сервер создаёт инвойс Cryptanio, бот отправляет покупателю ссылку, а после проверки оплаты сообщает о принятом заказе. Ниже разберём магазин физических товаров — например, печатных постеров. Бот и обработка заказов остаются вашей разработкой.
Сначала проверьте правила Telegram
Для цифровых товаров и услуг, продаваемых внутри Telegram, обязательны Telegram Stars с обозначением XTR. Это касается, например, платного доступа к содержимому бота. Ссылка на внешний сайт не даёт исключения: нельзя предлагать криптовалюту вместо Stars для такой покупки. Эти ограничения прямо описаны в документации Telegram Stars.
Наш сценарий — обычный бот без Mini App и заказ физического товара. У Mini Apps и связанных с ними ботов действуют дополнительные ограничения на блокчейн-интеграции, включая использование TON. Обычные боты без Mini App отдельно исключены из этих правил в Blockchain Guidelines Telegram. Поэтому переносить эту инструкцию в Mini App без дополнительной проверки нельзя. Правила Telegram сверены 13 ноября 2026 года.
Что понадобится
Подготовьте собственного бота, сервер для его работы, аккаунт Cryptanio и проект с активной услугой Payments. Нужны адреса получения платежей, подключённые к Payments этого проекта, и рабочий API-ключ с правами на инвойсы и нужную услугу.
Токен Telegram-бота, API-ключ Cryptanio и секрет проверки webhook храните на сервере. Покупателю передаётся только его платёжная ссылка. Готового подключения, которое само создаст ваш магазин и обработает заказы, этот сценарий не предполагает.
1. Подготовьте платёжный проект
Подключите Payments и добавьте адреса получения в пул услуги через кабинет. Запись адреса только в адресной книге недостаточна. Убедитесь, что нужные сеть и актив доступны в вашем проекте; не обещайте покупателю варианты, которых нет на странице оплаты.
Если различие между USDT и сетью пока неочевидно, сначала прочитайте «Сеть и токен». Сам инвойс связывает конкретный запрос оплаты с его состоянием.
2. Свяжите заказ с покупателем
Когда пользователь выбрал постер и подтвердил заказ, сервер создаёт внутренний номер заказа. Сохраните связь между заказом, Telegram-покупателем и будущим ID инвойса. Контактные данные и адрес доставки храните в своей системе: включать их в техническую ссылку или общедоступное сообщение не нужно.
Один заказ должен однозначно находиться по сохранённому ID инвойса. Это позволит обработать оплату и после перезапуска бота.
3. Создайте отдельный инвойс
Вызовите создание инвойса через API v1 на сервере. Для сценария с выбором сети и актива задайте котировку заказа через invoice_currency и invoice_amount. Например, USD 12.50 — единица котировки, а оплата производится поддерживаемой криптовалютой. Это не приём долларов и не автоматическая конвертация средств.
Ниже — ссылка на поддерживаемый пример создания заказа из каталога документации:
#!/usr/bin/env bash
set -euo pipefail
: "${CRYPTANIO_API_KEY:?Set CRYPTANIO_API_KEY}"
: "${CRYPTANIO_OPERATION_ID:?Set CRYPTANIO_OPERATION_ID}"
: "${CRYPTANIO_PROJECT_ID:?Set CRYPTANIO_PROJECT_ID}"
json_string() {
local text="$1" char code index output='"'
for ((index=0; index<${#text}; index++)); do
char="${text:index:1}"
case "$char" in
'"'|'\') output+="\\$char" ;;
*) printf -v code '%d' "'$char"
if ((code < 32)); then printf -v char '\\u%04x' "$code"; fi
output+="$char" ;;
esac
done
printf '%s"' "$output"
}
response_file="$(mktemp)"
trap 'rm -f "$response_file"' EXIT
transfer_status=0
http_status="$(curl \
--silent --show-error --max-time 30 --request POST \
--header "Authorization: Bearer $CRYPTANIO_API_KEY" \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header "Idempotency-Key: $CRYPTANIO_OPERATION_ID" \
--data-binary '{"project":'"$(json_string "$CRYPTANIO_PROJECT_ID")"',"invoice_currency":"USD","invoice_amount":"12.50","reference":"order-42"}' \
"https://api.cryptanio.com/v1/invoices" \
--output "$response_file" --write-out '%{http_code}')" || transfer_status=$?
if [[ "$http_status" == 2?? ]]; then
cat "$response_file"
exit "$transfer_status"
fi
printf 'HTTP %s\n' "$http_status" >&2
cat "$response_file" >&2
exit 1
Передайте собственные параметры заказа. Для новой операции нужен уникальный Idempotency-Key; при повторе того же запроса после сбоя сохраните прежний ключ. Так повторное нажатие не должно создавать ещё один счёт. Подробности разобраны в руководстве по подтверждению заказа.
4. Отправьте покупателю ссылку
Сохраните checkout_url из ответа создания и отправьте его кнопкой со ссылкой в личном чате. Bot API поддерживает URL-кнопки: это описано в InlineKeyboardButton. Покупатель откроет страницу Cryptanio и выберет доступный способ оплаты.
Передавайте точный полученный URL. Не собирайте ссылку из ID: ссылка, возвращаемая при чтении инвойса, предназначена для просмотра. Сохранённый ответ создания нужен именно для продолжения интерактивной оплаты.
5. Подтвердите оплату на сервере
Настройте webhook проекта на свой обработчик и проверяйте подпись по исходному телу запроса. Сопоставляйте событие с сохранённым инвойсом, затем проверяйте его текущее состояние через API.
Передавайте заказ в обработку только при успешном состоянии paid. Обнаружение транзакции, возврат покупателя в чат и его сообщение «я оплатил» таким подтверждением не являются. Частичная, недостаточная, избыточная или поздняя оплата может требовать отдельного решения; не подтверждайте такой заказ автоматически. Повторный webhook не должен повторно запускать исполнение заказа.
Как проверить и где искать ошибки
Проверьте полный путь на собственном заказе: создание, переход по ссылке, оплату, изменение состояния и сообщение бота. Учитывайте комиссии сети; такое создание инвойса работает с реальными данными. Отдельно проверьте повторное нажатие кнопки и повторную доставку события.
Если деньги отправлены, а заказ не подтверждён, сверяйте сеть, актив, реквизиты и подтверждения транзакции. Если статус уже paid, ищите ошибку в связи заказа с инвойсом и в обработчике бота. Уведомления владельцу в Telegram можно настроить по отдельной инструкции; они сами по себе не заменяют проверку заказа сервером.