Перейти к содержанию
Innovialabs

Как принимать оплату в Telegram-боте через Payme и Click

Практика4 мин

Коротко

Есть два пути: подключить Payme или Click как провайдера в BotFather и выставлять инвойс прямо в чате, либо отправлять ссылку на оплату и подтверждать заказ по callback от платежной системы; в обоих случаях заказ считается оплаченным только после серверного подтверждения.

Короткий ответ

Принять оплату в боте через узбекские платежные системы можно двумя способами:

  • Встроенный инвойс Telegram. Вы подключаете Payme или Click как платежного провайдера в BotFather, бот отправляет счет, пользователь платит, не выходя из чата.
  • Ссылка на оплату (redirect). Бот создает заказ у себя, формирует ссылку на страницу оплаты Payme или Click и ждет callback от платежной системы на ваш сервер.

Важное ограничение: цифровые товары и услуги внутри Telegram (подписки, доступ к контенту, внутриигровые бонусы) по правилам Telegram продаются за Telegram Stars. Payme и Click подходят для физических товаров, доставки, записи на услуги и других офлайн-сценариев.

Сравнение двух подходов

КритерийИнвойс TelegramСсылка на оплату
Где платит клиентВ окне TelegramНа странице платежной системы
Что нужно подключитьПровайдер в BotFatherМерчант-аккаунт и API платежной системы
Кто подтверждает оплатуTelegram присылает successful_paymentПлатежная система вызывает ваш сервер
ГибкостьОграничена форматом инвойсаПолный контроль над логикой и чеками
СложностьНижеВыше: нужен отдельный endpoint для callback

Инвойс удобнее для клиента и быстрее в запуске. Redirect выбирают, когда оплата уже интегрирована на сайте, нужна общая логика заказов для сайта и бота или формат инвойса не подходит.

Вариант 1: инвойс через провайдера

  1. В BotFather откройте бота, раздел Payments, выберите Payme или Click и пройдите подключение. Сначала берите тестовый режим.
  2. Получите provider token и храните его в переменных окружения, а не в коде.
  3. Отправьте счет методом sendInvoice. Сумма передается в минимальных единицах валюты: для UZS это тийины, то есть сумму в сумах умножаем на 100.
  4. Ответьте на pre_checkout_query. Это последний шанс отказать: товар закончился, цена изменилась, заказ отменен. Ответить нужно быстро, иначе Telegram отменит платеж.
  5. Дождитесь сообщения с successful_payment и только после этого отметьте заказ оплаченным.

Минимальный пример на aiogram 3:

from aiogram import Bot, F, Router
from aiogram.types import LabeledPrice, Message, PreCheckoutQuery

router = Router()

@router.message(F.text == "/buy")
async def buy(message: Message, bot: Bot):
    await bot.send_invoice(
        chat_id=message.chat.id,
        title="Заказ #1024",
        description="Доставка по Ташкенту",
        payload="order:1024",
        provider_token=PROVIDER_TOKEN,
        currency="UZS",
        prices=[LabeledPrice(label="Товар", amount=15000000)],  # 150 000 сум
    )

@router.pre_checkout_query()
async def pre_checkout(query: PreCheckoutQuery):
    ok = await order_is_valid(query.invoice_payload, query.total_amount)
    await query.answer(ok=ok, error_message=None if ok else "Заказ больше недоступен")

@router.message(F.successful_payment)
async def paid(message: Message):
    sp = message.successful_payment
    await mark_paid(sp.invoice_payload, sp.provider_payment_charge_id)

В payload кладите идентификатор заказа из вашей базы, а не данные о товаре: по нему вы найдете заказ на всех следующих шагах.

Вариант 2: ссылка на оплату

  1. Бот создает заказ в вашей базе со статусом «ожидает оплаты».
  2. Сервер формирует ссылку на страницу оплаты с ID заказа и суммой по правилам платежной системы и отправляет ее кнопкой.
  3. Клиент платит на стороне Payme или Click.
  4. Платежная система обращается к вашему серверу: у Payme это Merchant API с методами вроде CheckPerformTransaction, CreateTransaction, PerformTransaction, у Click — запросы Prepare и Complete.
  5. Сервер проверяет подпись или авторизацию запроса, сумму и статус заказа, после чего бот пишет клиенту, что оплата прошла.

Обратите внимание на единицы суммы: у разных систем они отличаются (тийины или сумы), это проверяется по их документации.

Подтверждение заказа: что проверять

  • Сумма и валюта в подтверждении совпадают с заказом в базе.
  • Идемпотентность: повторный callback или повторное сообщение не создают второй оплаты. Храните ID транзакции и проверяйте его.
  • Статус заказа меняется только на сервере. Кнопка «Я оплатил» от клиента не доказательство оплаты.
  • Отмены и возвраты обрабатываются: у Payme для этого есть отдельный метод отмены транзакции.
  • Уведомление менеджеру уходит после подтверждения, а не после нажатия кнопки «Оплатить».

Частые ошибки

  • Сумма в сумах вместо тийинов в sendInvoice, и клиент видит счет в сто раз меньше.
  • Долгая логика в обработчике pre_checkout_query: платеж отменяется по таймауту.
  • Продажа цифрового доступа через Payme или Click внутри Telegram, что противоречит правилам платформы.
  • Тестовый токен на продакшене или боевой токен в репозитории.

Подробности о платежах в ботах — в документации Telegram.

Частые вопросы

Да. Подключение провайдера в BotFather привязывает бота к вашему мерчант-аккаунту, поэтому юридическое оформление и проверка бизнеса проходят у самой платежной системы.

Поможем с этим

Если хотите не разбираться самим, а получить результат — этим мы занимаемся каждый день.

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.