Telegram-боты

Приём платежей в Telegram-боте

Бот создаёт платёж одним запросом, покупатель платит по СБП или картой, а бот получает уведомление и сразу выдаёт товар.

Как это работает

Оплата в боте за четыре шага

  1. 01

    Бот создаёт платёж

    POST /v1/payments с суммой и Telegram ID покупателя в metadata.

  2. 02

    Покупатель платит

    Кнопка со ссылкой payment_url: СБП из приложения банка или карта.

  3. 03

    Приходит callback

    Событие payment.succeeded на ваш сервер с подписью HMAC.

  4. 04

    Бот выдаёт товар

    Начисляет баланс, открывает доступ или отправляет заказ.

Что ещё есть для ботов

Отмена из бота

Кнопка «Отменить» в боте вызывает POST /v1/payments/{id}/cancel — счёт закрывается сразу.

Без двойных счетов

Повторное нажатие кнопки с тем же Idempotency-Key вернёт уже созданный платёж.

Комиссия на покупателе

Комиссию может платить магазин, покупатель или стороны пополам — настраивается в проекте.

Тестовая среда

Ключ Sandbox и тестовые сценарии оплаты, отказа и истечения срока — без реальных денег.

Пример

Пополнение баланса в боте

Создаём платёж и отправляем кнопку оплаты. Зачисление — по callback payment.succeeded.

python · aiogram 3
import os, uuid, aiohttp
from aiogram import F, Router
from aiogram.types import CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup

router = Router()
API = "https://larpcassa.cc/v1/payments"
LC_KEY = os.environ["LC_KEY"]

async def create_payment(user_id: int, rub: int) -> dict:
    order_id = f"tg-{user_id}-{uuid.uuid4().hex[:8]}"
    async with aiohttp.ClientSession() as s:
        r = await s.post(API, headers={"X-Api-Key": LC_KEY, "Idempotency-Key": order_id}, json={
            "amount": rub * 100,          # в копейках
            "method": "SBP_C2B",
            "order_id": order_id,
            "description": "Пополнение баланса",
            "metadata": {"telegram_user": str(user_id)},
        })
        return await r.json()

@router.callback_query(F.data == "topup_500")
async def topup(cb: CallbackQuery):
    p = await create_payment(cb.from_user.id, 500)
    kb = InlineKeyboardMarkup(inline_keyboard=[[
        InlineKeyboardButton(text="Оплатить 500 ₽", url=p["payment_url"]),
    ]])
    await cb.message.answer("Счёт на 500 ₽", reply_markup=kb)
FAQ

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

Нужен ли ИП, чтобы принимать оплату в боте?+

Нет. Подключаем и физлиц без ИП и самозанятости — для ботов и каналов это частый случай. Методы оплаты согласуем при подключении.

Как бот узнаёт, что платёж прошёл?+

На ваш сервер приходит callback payment.succeeded с подписью. Статус также можно запросить в любой момент через GET /v1/payments/{id}.

Можно ли отменить счёт из бота?+

Да. POST /v1/payments/{id}/cancel отменяет неоплаченный платёж. Если покупатель уже успел оплатить, API вернёт already_paid.

На каком языке писать бота?+

На любом: API — обычный HTTPS с JSON. В документации есть примеры на curl, Node.js и Python.

Можно ли проверить всё без реальных денег?+

Да. В Sandbox отдельный ключ и баланс, а исход оплаты выбирается копейками суммы.