Как принимать оплату в Telegram-боте на aiogram: пример кода и подключение за час

Пошаговая инструкция: как подключить приём оплаты по СБП, картам и USDT в Telegram-боте на aiogram, создать счёт через API и обработать вебхук.

· 5 мин чтения

Как принимать оплату в Telegram-боте на aiogram: пример кода и подключение за час

Telegram-бот давно стал полноценным каналом продаж: через него продают доступы, подписки, цифровые товары и услуги. Но как только дело доходит до денег, многие разработчики упираются в вопрос: как принять оплату, не строя собственную платёжную инфраструктуру. Ниже разберём рабочую схему для бота на aiogram: от создания счёта до выдачи товара после подтверждения платежа.

Как устроена оплата в боте

Схема одинакова для любого бота. Пользователь выбирает товар, бот создаёт счёт на стороне платёжного шлюза и отправляет ссылку на оплату. Покупатель платит на защищённой странице, а шлюз уведомляет ваш сервер вебхуком. Только после этого бот выдаёт товар. Главное правило: источник истины о платеже — подписанный вебхук, а не нажатая кнопка «Я оплатил».

Payra закрывает эту схему целиком: счёт создаётся одним POST-запросом, а покупателю доступны СБП, карты РФ (Visa, Mastercard, «Мир» с 3-D Secure) и USDT в сетях TRC20 и BEP20. Вам не нужно разрабатывать страницу оплаты и хранить платёжные данные.

Что подготовить заранее

  1. Зарегистрируйтесь в кабинете мерчанта и добавьте проект: бота или сайт, с которого он продаёт.
  2. Пройдите модерацию проекта и подтвердите домен, на котором будет принимать вебхуки ваш сервер.
  3. Получите API-ключ и сохраните его в переменных окружения, а не в коде.
  4. Подготовьте публичный HTTPS-адрес для вебхуков. На время разработки подойдёт любой туннель до локальной машины.
  5. Включите тестовый режим и проверьте весь цикл без реальных денег (подробнее в разделе о тестировании).

Подключите приём оплаты по СБП, картам и USDT для вашего бота без абонентской платы.

Подключиться

Создаём счёт из aiogram

Ниже условный пример на aiogram 3 и aiohttp. Адрес, схема авторизации и названия полей приведены для наглядности: точные параметры запроса сверяйте с разделом про счета и быстрым стартом.

import aiohttp
from aiogram import Router, F
from aiogram.filters import Command
from aiogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton

router = Router()

async def create_invoice(amount: int, order_id: str) -> dict:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            'https://payrapay.net/api/v1/invoices',
            # схему авторизации и обязательные поля сверьте с документацией
            headers={'Authorization': 'Bearer YOUR_API_KEY'},
            json={'amount': amount, 'order_id': order_id},
        ) as resp:
            resp.raise_for_status()
            return await resp.json()

@router.message(Command('buy'))
async def buy(message: Message):
    order_id = f'{message.from_user.id}-{message.message_id}'
    invoice = await create_invoice(500, order_id)
    pay_url = invoice['url']  # имя поля уточните в документации
    kb = InlineKeyboardMarkup(inline_keyboard=[
        [InlineKeyboardButton(text='Оплатить', url=pay_url)]
    ])
    await message.answer('Заказ создан. Нажмите кнопку для оплаты.', reply_markup=kb)

Обратите внимание на идентификатор заказа: он должен связывать платёж с конкретным пользователем и покупкой. Заведите у себя таблицу заказов со статусами «создан», «оплачен», «выдан» и сохраняйте заказ до того, как отправите ссылку покупателю.

Принимаем вебхук и выдаём товар

Бот и приём вебхуков удобно держать в одном процессе: aiogram работает на asyncio, и aiohttp-сервер легко запускается рядом. Главное — проверять подпись каждого уведомления. Алгоритм подписи описан в разделе о вебхуках, функцию verify_signature ниже реализуйте по нему.

from aiohttp import web

async def payra_webhook(request: web.Request) -> web.Response:
    raw_body = await request.read()

    # проверка подписи по правилам из документации
    if not verify_signature(raw_body, request.headers):
        return web.Response(status=400)

    event = await request.json()

    # 1. найдите заказ в своей базе по order_id
    # 2. убедитесь, что платёж успешен, а заказ ещё не обработан
    # 3. отметьте заказ оплаченным и отправьте пользователю товар:
    #    await bot.send_message(user_id, 'Оплата получена, вот ваш доступ')

    return web.Response(text='ok')

app = web.Application()
app.add_routes([web.post('/payra/webhook', payra_webhook)])

Шлюз повторяет доставку вебхука, если ваш сервер не ответил успешно. Это защищает от потери уведомлений, но означает, что одно и то же событие может прийти дважды. Поэтому обработчик должен быть идемпотентным: повторное уведомление по уже выданному заказу не должно выдавать товар второй раз.

Частые ошибки при оплате в ботах

  • Выдача товара без проверки подписи. Без неё любой, кто знает адрес вебхука, сможет отправить поддельное уведомление.
  • Обработка в самом обработчике сообщений. Не ждите оплату внутри хендлера бота: платёж подтверждается асинхронно, через вебхук.
  • Отсутствие идемпотентности. Повторная доставка уведомления не должна приводить к двойной выдаче.
  • Ключ в репозитории. Храните API-ключ в переменных окружения и не публикуйте его в коде.
  • Тест сразу на боевых платежах. Сначала пройдите весь путь в тестовом режиме: создание счёта, оплата, вебхук, выдача.

Альтернатива без кода: платёжные ссылки

Если у вас фиксированный набор товаров, API можно не использовать вовсе. В Payra есть платёжные ссылки, которые создаются в кабинете без кода. Вы вставляете такую ссылку в кнопку бота и принимаете оплату. Минус подхода в том, что для автоматической выдачи товара всё равно понадобится вебхук, а для динамических сумм и привязки платежа к пользователю удобнее счёт через API.

Сколько это стоит и как выводить деньги

Абонентской платы нет: Payra берёт процент с успешного платежа, ставка начинается от 1% и определяется индивидуально, в зависимости от ниши и оборота. При желании комиссию можно переложить на покупателя. Актуальные условия смотрите на странице тарифов. Выплаты мерчанту производятся в USDT: заявку на вывод вы оформляете из кабинета.

Если ваш бот продаёт цифровые товары или услуги, заранее проясните вопросы налогообложения и учёта выручки с юристом или бухгалтером: от формата бизнеса зависит и порядок отчётности.

Вывод

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

Создайте проект в Payra и примите первую оплату в Telegram-боте уже сегодня.

Начать приём оплаты

Начните принимать платежи сегодня

Регистрация бесплатная, абонентской платы нет. Тестовый режим доступен сразу — подключите API, проверьте вебхуки и выходите в бой, когда будете готовы.