Оплата Click и Payme прямо в Telegram-боте: опыт Splash Water
В 2024 году мы сделали два бота, которые принимают деньги совершенно по-разному. Splash Water продаёт воду с оплатой через Click и Payme прямо в чате. Foydali Nuqtalar просит прислать скриншот чека, а админ подтверждает его вручную. Оба способа работают, и у обоих есть свои грабли.
Mirodil OrtiqovБэкенд-разработчик
Первый вопрос, который задаёт почти каждый клиент с ботом для заказов: «А оплату можно прямо в Telegram?» Можно. Но прежде чем отвечать «да», я теперь спрашиваю, сколько заказов в день вы ждёте и кто у вас будет сверять деньги с заказами.
От ответа зависит, нужна ли вам интеграция с платёжными системами или хватит фото чека и одного внимательного администратора.
Два бота, два способа принять деньги
Splash Water — доставка бутилированной воды. Клиент собирает корзину, выбирает дату и время, отправляет геолокацию и платит. Способов оплаты три: Click, Payme и наличные курьеру. Заказ сразу падает в закрытый канал операторов.
Foydali Nuqtalar — платная электронная книга по точечному массажу в мобильном приложении для iOS и Android. Первые главы бесплатные, остальные открываются после оплаты. Оплата идёт через отдельный Telegram-бот: человек переводит деньги и присылает скриншот чека, а сотрудник в админке ставит статус «оплачено».
Первый вариант — полноценная интеграция. Второй — по сути, человек в цепочке. Разберу оба.
Как устроена оплата в Splash Water
Мы не подключали API Click и Payme напрямую. Вместо этого использовали Telegram Payments: Click и Payme есть среди платёжных провайдеров Telegram, и подключаются они через @BotFather. Бот выставляет счёт, Telegram показывает свою платёжную форму, провайдер списывает деньги, а бот получает уведомление об успешной оплате.
Почему не прямой API? Через Telegram Payments не нужно делать свою платёжную страницу и хранить что-то о картах: форму показывает сам Telegram, а данные карты видит только провайдер. Но договор с Click или Payme всё равно нужен. Токен в @BotFather выдаётся под конкретного мерчанта, так что бизнесу сначала надо подключиться к платёжной системе как юрлицо или ИП. Это нередко занимает больше времени, чем сама разработка оплаты, поэтому я теперь прошу клиентов начинать этот процесс в первую же неделю проекта.
Вот как выглядит путь клиента:
А вот что происходит внутри:
- Корзина и данные заказа. Дата доставки (начиная с завтрашнего дня), временное окно, комментарий, геолокация. Всё хранится в состоянии FSM aiogram, пока заказ не оформлен.
- Счёт.
send_invoiceс валютойUZSи позициями корзины. Суммы передаются в минимальных единицах, то есть в тийинах: цену в сумах умножаем на 100. - pre_checkout_query. Перед списанием Telegram спрашивает бота: «Подтверждаешь этот платёж?» На ответ есть 10 секунд.
- successful_payment. Приходит сообщение с идентификаторами платежа. Мы сохраняем транзакцию в базе: пользователь, способ оплаты, сумма,
telegram_payment_charge_id. - Заказ в канал операторов. Текст заказа с товарами и суммой, отдельным ответом на него — геолокация, и кнопка «Перейти к заказу», которая открывает этот заказ в Django-админке.
- Статусы. Оператор двигает заказ: «В модерации» → «Подтверждено» → «Доставлено».
Для наличных шаги 2–4 пропускаются: бот показывает сводку заказа и спрашивает «Подтверждаете?». Наличными, кстати, до сих пор платят многие: курьер приносит 19-литровую бутыль к двери, и человеку проще отдать деньги ему.
Канал операторов оказался самой удачной частью проекта. Операторам не нужно держать админку открытой: заказ прилетает уведомлением в Telegram, адрес открывается с карты одним нажатием, а если надо что-то поправить, кнопка ведёт прямо на нужную запись.
Что мы сделали неправильно
Теперь о том, что я бы переделал. Вот наш обработчик pre_checkout в первой версии:
async def pre_checkout(query: types.PreCheckoutQuery):
await OrderForm.success_state.set()
await query.bot.answer_pre_checkout_query(query.id, ok=True)
Он подтверждает любой платёж, ничего не проверяя. Пока цены меняются редко, это работает. Но между выставлением счёта и нажатием «Заплатить» может пройти полчаса: за это время админ может поменять цену или убрать товар из каталога, а клиент заплатит по старому счёту.
Вторая ошибка — payload. Мы передавали в него одну и ту же строку для всех счетов. Payload возвращается в successful_payment, и это самый простой способ связать платёж с конкретным заказом. Правильно класть туда ID заказа, созданного до выставления счёта, а не собирать заказ из состояния FSM уже после оплаты.
Третья — состояние в памяти. Если бот перезапускается между счётом и оплатой, данные заказа в FSM пропадают, а деньги приходят. Для платёжных сценариев хранилище состояний должно быть в Redis или базе, а не в MemoryStorage.
Ни одна из этих ошибок не стоила клиенту денег, насколько мы знаем. Но все три я бы исправил в первый же день, если бы делал бот заново.
Ручная проверка чеков: Foydali Nuqtalar
Во втором проекте логика другая. Пользователь в приложении нажимает «Купить», приложение открывает Telegram-бот по ссылке вида t.me/<бот>?start=<id пользователя>. Так бот сразу знает, кто платит, без регистрации.
Дальше человек переводит деньги и присылает в бот скриншот чека. Бот сохраняет картинку, создаёт транзакцию со статусом «pending» и отправляет фото в закрытый канал с именем, временем и ссылкой на запись в админке. Сотрудник открывает, сверяет с поступлением, ставит транзакции «completed» или «rejected» и включает пользователю премиум-доступ. Приложение получает push «Теперь вы можете читать всю книгу», и главы открываются.
Звучит архаично, но для этого проекта подошло. Продукт один, цена одна, покупок не тысячи в день, и у клиента был человек, который всё равно каждый день проверял поступления.
- +Запуск за пару дней, без договора с платёжной системой
- +Подходит для любого способа перевода, включая перевод с карты на карту
- +Сотрудник видит каждый платёж своими глазами
- −Покупатель ждёт подтверждения, иногда часами, особенно ночью
- −Скриншот можно подделать, и проверка держится на внимательности человека
- −Не масштабируется: при сотне заказов в день это отдельная ставка
- −Пользователь может прислать не тот файл, и это ещё одна переписка
Как выбрать между ними
Моё мнение после обоих проектов: если товар физический, заказов много и они повторяются, сразу делайте Click и Payme через Telegram Payments. Это не дорого в разработке, а клиент платит в том же окне, где заказывает, и не уходит «потом переведу».
Если продукт один, продажи штучные и вы только проверяете, будут ли вообще покупать, ручная проверка чеков — нормальный старт. Главное — заранее договориться, кто и как быстро отвечает, и поставить статусы, чтобы ни один чек не потерялся в чате.
И в обоих случаях заказы и платежи должны приходить туда, где их видят люди, а не только в базу. Канал операторов с кнопкой в админку — самое дешёвое и самое полезное, что мы делали в таких ботах. Как мы потом считаем, откуда пришли эти заказы, я писал в статье про аналитику заявок из Telegram.
Посмотреть проекты подробнее можно в кейсах Splash Water и Foydali Nuqtalar.



