Обзор
Система “сквозной корзины” решает проблему: пользователь хочет купить подписку, но баланса не хватает. Вместо того чтобы заставлять пользователя начинать покупку заново после пополнения, бот сохраняет параметры покупки и может автоматически оформить подписку после зачисления средств.
Как работает
1. Пользователь выбирает подписку → не хватает баланса
2. Параметры покупки сохраняются в Redis (корзина)
3. Пользователь пополняет баланс любым способом
4. После зачисления бот проверяет наличие корзины
5a. AUTO_PURCHASE=true и баланса хватает → покупка автоматически
5b. Иначе → кнопка "Вернуться к корзине"
Сохранение корзины
При недостатке средств бот сообщает:
- Сколько не хватает для покупки
- Что корзина сохранена
- Предлагает кнопку Пополнить баланс
Что сохраняется
Корзина хранится в Redis с ключом user_cart:{user_id} и содержит все параметры покупки:
| Режим корзины | Что сохраняется |
|---|
extend | ID подписки, тариф, период, цена, скидки, серверы |
tariff_purchase | ID тарифа, период, трафик, устройства, серверы, скидки |
daily_tariff_purchase | ID тарифа, суточная цена, трафик, устройства, серверы |
add_devices | Количество устройств, цена |
add_traffic | ID подписки, объем трафика, цена, скидка |
TTL корзины
По умолчанию корзина живет 1 час (3600 секунд). Настраивается через CART_TTL_SECONDS.
После истечения TTL корзина автоматически удаляется из Redis.
Автоматическая покупка
При AUTO_PURCHASE_AFTER_TOPUP_ENABLED=true покупка происходит полностью автоматически — без подтверждения от пользователя.
Когда срабатывает
После каждого успешного платежа через любую платежную систему:
- YooKassa, CryptoBot, Telegram Stars, CloudPayments
- Freekassa, Platega, PayPalych, Heleket
- MulenPay, Tribute, WATA, Kassa AI
Логика после пополнения
- Проверяется
AUTO_PURCHASE_AFTER_TOPUP_ENABLED
- Загружается корзина из Redis
- Проверяется защита от дублирования (не было ли покупки за последние 60 секунд)
- Проверяется достаточность баланса
- Выполняется покупка, баланс списывается
- Подписка создается/продлевается, синхронизируется с RemnaWave
- Корзина удаляется
- Пользователю отправляется уведомление об автопокупке
Если баланса все еще не хватает
- Автопокупка не выполняется
- Корзина не удаляется (остается до истечения TTL)
- Пользователю отправляется сообщение с кнопкой Вернуться к корзине
Пересчет цены
Для тарифных корзин цена пересчитывается из БД в момент покупки, а не берется из сохраненных данных. Это защищает от ситуации, когда тариф подорожал между сохранением корзины и покупкой.
Уведомления пользователю
При сохранении корзины
Недостаточно средств для оформления подписки.
Не хватает: 150₽
Корзина сохранена! После пополнения баланса
подписка будет оформлена автоматически.
[Пополнить баланс] [Назад]
При автоматической покупке
В зависимости от типа:
- Продление: “Подписка автоматически продлена на 30 дней”
- Новый тариф: “Подписка на 90 дней автоматически оформлена после пополнения баланса”
- Суточный: “Суточный тариф ‘Базовый’ активирован!”
- Устройства: “Устройства добавлены автоматически! +2 устройства”
- Трафик: “Трафик добавлен автоматически! +10 ГБ”
Все уведомления содержат кнопки: Моя подписка и Главное меню.
При недостатке средств (корзина осталась)
[Вернуться к сохраненной корзине]
Ручное управление корзиной
Пользователь может:
- Вернуться к корзине — кнопка в сообщении после пополнения (если автопокупка не сработала)
- Очистить корзину — кнопка
clear_saved_cart удаляет корзину из Redis
Источники корзины
Корзина сохраняется из трех интерфейсов:
| Интерфейс | Описание |
|---|
| Telegram бот | Все хендлеры покупки/продления/докупки |
| Cabinet WebApp | API возвращает HTTP 402 с cart_saved: true |
| MiniApp | После успешной покупки сохраняет корзину для будущего автопродления |
Настройка
| Переменная | По умолчанию | Описание |
|---|
AUTO_PURCHASE_AFTER_TOPUP_ENABLED | false | Включить автоматическую покупку |
CART_TTL_SECONDS | 3600 | Время жизни корзины в Redis (секунды) |
Настройку AUTO_PURCHASE_AFTER_TOPUP_ENABLED можно менять без перезапуска бота через админ-панель (категория настроек: Payment).
Для работы корзины необходим Redis. Без Redis параметры покупки не сохраняются.
Защита от дублирования
- Перед автопокупкой проверяется, не было ли транзакции типа
SUBSCRIPTION_PAYMENT за последние 60 секунд
- Если была — корзина очищается без покупки (предотвращает двойное списание при быстрых платежах)