Как принимать криптоплатежи в боте 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 можно настроить по отдельной инструкции; они сами по себе не заменяют проверку заказа сервером.