🔑

Бот продажи VPN-подписок по СБП в Telegram

для закрытого VPN-сервиса: инвайт-код, пробный период, чек подтверждает админ

Telegram-бот продажи VPN-подписок на Marzban: регистрация по инвайт-коду, пробный период 2 часа, тарифы на 1, 6 и 12 месяцев, оплата по СБП с подтверждением чека администратором. Python, aiogram 3, MariaDB.

Тестирование у заказчикаNDA
2 часа
пробный доступ выдаётся автоматически после регистрации по инвайт-коду
3 тарифа
1, 6 и 12 месяцев; за 6 месяцев +10 дней, за 12 месяцев +30 дней
3 суток и 1 сутки
за столько до окончания подписки бот напоминает о продлении

Задача

Для закрытого круга клиентов нужно было выдавать и продлевать доступ к VPN без ручной работы в панели Marzban. Каждый шаг такого доступа требует внимания администратора: понять, кто пришёл, завести пользователя, отправить ключ, принять оплату, продлить срок, вовремя напомнить о продлении и объяснить, как настроить приложение на конкретном устройстве.

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

Решение

Telegram-бот продажи VPN-подписок на базе Marzban для закрытого VPN-сервиса. Реализовано в версии 2.0.0:

Для пользователя

  • Регистрация по инвайт-коду. Без кода бот доступа не даёт; с верным кодом автоматически выдаёт пробный доступ на 2 часа.
  • Профиль подключения. Статус подписки, остаток времени и VLESS-ключ из Marzban.
  • Покупка. Тарифы 1, 6 и 12 месяцев (по умолчанию 500, 2800 и 5500 рублей, меняются настройкой). Бот показывает реквизиты СБП и ссылку на банк, пользователь присылает скриншот чека.
  • Бонусы за длинные тарифы. За 6 месяцев +10 дней, за 12 месяцев +30 дней.
  • Инструкции. Для iOS, Android, Windows, macOS, Linux, роутеров и Smart TV; открываются как WebApp, для роутеров есть кнопка связи с мастером настройки.
  • Напоминания. За 3 суток и за 1 сутки до окончания подписки, ежедневно в 10:00.
  • Порядок в чате. Служебные сообщения бота удаляются через час; есть FAQ, поддержка и команда /myid.

Для администратора

  • Подтверждение платежей. Кнопки под чеком, защита от двойной обработки несколькими администраторами; при подтверждении подписка продлевается в Marzban.
  • Панель «Root Access». Статистика, поиск по ID, списки пользователей (все, активные, истёкшие), удаление с подтверждением, подарок часов или дней, рассылка с отчётом о доставке, логи, ручной бэкап.
  • Уведомления. О регистрации новых пользователей, старте и остановке бота, результатах бэкапов.
  • Скрытая команда /version. Показывает версию запущенного экземпляра, не-админы её игнорируют.

Как это устроено

Регистрация по инвайт-коду и пробный доступ на 2 часа

Инвайт-код — это общий пароль для входа в закрытый сервис: без него бот чужого человека не зарегистрирует. Верный код запускает автоматическую выдачу пробного доступа на 2 часа: бот сам создаёт пользователя в Marzban, а клиент получает ключ и может проверить сервис до оплаты. Администратор регистрируется без кода, его доступ в Marzban действует 24 часа.

Marzban API: создание пользователя с потоком xtls-rprx-vision

Marzban — панель управления VPN-сервером: она хранит пользователей и выдаёт ключи. Бот обращается к её API (набору адресов для команд от программ), получает токен и создаёт пользователя вида user_ и Telegram-ID. Для него задаются поток xtls-rprx-vision, лимит в одно устройство онлайн и отсутствие лимита трафика. Подписки строятся на VLESS и Reality: это протокол и способ маскировки, которыми клиентское приложение подключается к серверу. При продлении новый срок считается от текущей даты окончания, а не от дня оплаты.

Оплата по СБП: подтверждение чека администратором

Клиент выбирает тариф, бот показывает реквизиты и ссылку на банк, клиент платит и присылает скриншот чека. Чек получают все администраторы: у каждого под сообщением кнопки «Подтвердить» и «Отклонить». После подтверждения подписка продлевается в Marzban (для 6 и 12 месяцев с бонусными днями), а пользователю приходит уведомление. Это ручная проверка: автоматической интеграции платёжной системы в проекте нет.

Защита от двойного подтверждения платежа несколькими администраторами

Чек приходит сразу нескольким администраторам, и есть риск, что двое нажмут «Подтвердить» и подписка продлится дважды. В истории версий это исправлено отдельной записью: обработка платежа защищена от повторного подтверждения. Как именно устроена блокировка, в README не описано.

Напоминания и обслуживание по расписанию

Планировщик APScheduler работает в часовом поясе Europe/Moscow. Проверка истекающих подписок запускается в 10:00 и напоминает за 3 суток и за 1 сутки. Старые резервные копии чистятся в 00:30, а еженедельное обслуживание базы (удаление старых записей журнала) идёт по понедельникам в 03:00.

Резервные копии: локально и на Google Drive из бота

Бот сам делает JSON-дамп пользователей, администраторов и последних 100 записей журнала и составляет текстовый отчёт. Копия сохраняется в локальной папке и загружается на Google Drive через сервисный аккаунт (это служебная учётная запись для программ). Час копирования настраивается, по умолчанию 14:00 и 14:05. Финальная копия создаётся при остановке бота, а запуск копии вручную доступен кнопкой в админ-панели.

Polling или webhook в aiogram

Бот по умолчанию запрашивает обновления у Telegram сам (polling). Для сервера с публичным адресом есть режим webhook: Telegram присылает обновления на встроенный веб-сервер. Режим переключается настройкой.

Результат

  • Клиент проходит путь от регистрации до ключа без участия администратора: инвайт-код, пробные 2 часа, покупка, ключ.
  • Администратору не нужно заходить в Marzban: подтверждение платежа, подарок времени, поиск и удаление пользователей делаются в Telegram.
  • Подписка продлевается в Marzban сразу после подтверждения платежа, а бонусные дни за длинные тарифы начисляются автоматически.
  • Клиент получает напоминание об окончании подписки, администратор получает уведомления о регистрациях, старте, остановке и бэкапах.
  • Состояние бота сохраняется в MariaDB, а резервные копии уходят на Google Drive.

Технологии: что и зачем

  • Python 3.10+ и aiogram 3 — бот: диалоги на конечных автоматах состояний, кнопки под сообщениями, WebApp с инструкциями.
  • MariaDB (aiomysql) — пользователи, администраторы, журнал, платежи; таблицы создаются при старте, соединения берутся из пула.
  • Marzban API (aiohttp) — создание пользователей, продление подписок, получение ключей.
  • APScheduler — напоминания о подписках, бэкапы, очистка и обслуживание базы по расписанию.
  • Google Drive API (PyDrive2) — выгрузка резервных копий через сервисный аккаунт.
  • aiohttp — встроенный веб-сервер для режима webhook.

Статус

Тестовая версия. Текущая версия 2.0.0 от 2 февраля 2026 года: оплата по СБП с подтверждением чека администратором, обновлённые тарифы и WebApp-инструкции. Затем в код добавлены константа версии, скрытая команда /version и вывод версии в лог при старте.

Пока не сделано: вынести все настройки из кода в .env и добавить .env.example, Docker, автоматические тесты и защиту от частых запросов; настройки ограничения частоты и длительности пробного периода объявлены в конфигурации, но пока не применяются. Оплата остаётся ручной, автоматической интеграции платёжной системы нет.

Вопросы по проекту

Как продавать VPN-подписки через Telegram-бот, если нет подключённого эквайринга?
Бот показывает реквизиты для оплаты по СБП и ссылку на банк, а пользователь присылает скриншот чека. Чек уходит всем администраторам с кнопками «Подтвердить» и «Отклонить». После подтверждения подписка в Marzban продлевается сама. Автоматической интеграции платёжной системы в проекте нет: платёж проверяет человек.
Как устроены инвайт-код и пробный период?
Новый пользователь вводит инвайт-код и получает пробный доступ на 2 часа: бот сам создаёт для него пользователя в Marzban и присылает VLESS-ключ. Неверный код бот отклоняет. Администратор регистрируется без кода и получает доступ на 24 часа.
Как бот создаёт пользователя в панели Marzban?
Через API Marzban создаётся пользователь вида user_ и Telegram-ID с потоком xtls-rprx-vision, лимитом в одно устройство онлайн и без лимита трафика. Продление считается от текущей даты окончания. Ключ для профиля бот получает из Marzban.
Что администратор может делать прямо из Telegram?
В панели «Root Access»: статистика (всего, активные, истёкшие, истекают сегодня), поиск по ID, списки пользователей, удаление с подтверждением, подарок часов или дней с комментарием, рассылка всем с отчётом о доставке, просмотр последних логов и запуск резервной копии.
Куда сохраняются резервные копии бота?
Бот делает JSON-дамп пользователей, администраторов и последних 100 записей журнала с текстовым отчётом. Копия хранится в локальной папке и выгружается на Google Drive через сервисный аккаунт. Финальная копия создаётся при остановке бота, старые копии по расписанию удаляются.
Как запускается бот и на чём он работает?
Бот запускается как обычная программа на Python 3.10 и новее, рядом нужны MariaDB или MySQL и панель Marzban. Таблицы в базе он создаёт сам при старте. Режим по умолчанию — polling, есть и webhook. Docker и docker-compose в репозитории пока нет.

Нужно похожее?

Расскажите о задаче — покажем, как решали такое, и прикинем объём работ.