← К библиотеке
Бизнес Практика

Заморозка подписки и режим отпуска

Клиент уезжает в отпуск, VPN пока не нужен, а оплаченные дни тают — и он либо просит возврат, либо отменяет автоплатёж и часто не возвращается. Заморозка кладёт дни в банк вместо оттока. Показываю, как собрать её в боте — с реальной механикой из прода. Практика.

Что это и зачем

Клиент нажимает «❄️ Заморозить» — подписка встаёт на паузу, оплаченные дни не сгорают, а складываются в «банк». Вернулся из отпуска → «▶️ Разморозить» → дни продолжают отсчёт ровно с того места, где встали.

Вместо «верните деньги, я не пользуюсь» ты получаешь «ок, заморожу и вернусь». Это дешевле возврата, убирает повод для спора и заметно снижает отток на сезонных просадках — лето, новогодние каникулы. Приём собирается в боте — в самой панели Remnawave заморозки нет.

Поля в подписке

Хранение — четыре поля в строке подписки/ключа:

поля
frozen          # 0/1 — заморожена ли подписка
frozen_at       # когда заморозили
banked_days     # сколько дней "положили в банк" (остаток на момент заморозки)
last_freeze_at  # метка для лимита "раз в 30 дней"

Две операции

Заморозить (по кнопке клиента):

freeze
если frozen                          → "уже заморожена"
если (now - last_freeze_at) < 30 дн  → "заморозка раз в месяц, подождите N дн."
days_left = expireAt - now
если days_left < 2                   → "осталось меньше 2 дней — нельзя"
Remnawave PATCH /api/users { status: DISABLED }
frozen = 1, frozen_at = now, banked_days = days_left, last_freeze_at = now

Разморозить (по кнопке клиента или авто через 30 дней):

unfreeze
Remnawave PATCH /api/users { status: ACTIVE, expireAt: now + banked_days }
frozen = 0, frozen_at = NULL, expireAt = now + banked_days

Ключевой момент: пока подписка заморожена, expireAt не уменьшается — часы стоят. При разморозке срок пересчитывается как now + banked_days, поэтому ни один оплаченный день не теряется. Статус DISABLED просто отключает доступ, сохраняя скводы, лимит трафика, HWID и привязку Telegram — после разморозки клиент подключается тем же ключом, ничего не переоформляя.

Обязательные ограничения

Без них заморозка превращается в бесплатную парковку, на которой клиент живёт вечно.

  • Раз в 30 дней. Без лимита клиент будет морозить/размораживать по дню и жить вечно. Проверяем last_freeze_at.
  • Остаток ≥ 2 дней. Морозить «хвостик» бессмысленно и плодит баги на границе срока.
  • Авто-разморозка через 30 дней. Замороженный аккаунт не должен висеть вечно — шедулер сам размораживает по истечении 30 дней (expireAt = now + banked_days) и шлёт уведомление: «❄️➡️☀️ Подписка автоматически разморожена — прошло 30 дней, срок продолжил отсчёт». Так ты не держишь слот под мёртвыми паузами.
  • Не дёргать замороженных. Напоминания «подписка кончается» и автопродление в шедулере должны пропускать frozen-ключи — иначе клиент в отпуске получает спам «продлите» по замороженной подписке.

Что настроить в боте

По сути это скромный набор:

  • 4 поля в базе (выше).
  • Две ручки (/freeze, /unfreeze), каждая — одна проверка лимитов + один PATCH в Remnawave.
  • Пара кнопок «❄️ Заморозить / ▶️ Разморозить» в боте или miniapp.
  • Правка шедулера: пропускать frozen-ключи в напоминаниях/автопродлении + добавить авто-разморозку через 30 дней.

Собрать проще, чем кажется. Прежде чем включать на всех, прогони на себе: заморозил → дни встали → разморозил → срок продолжился ровно с остатка; и проверь, что напоминалки замороженного не трогают.

Бонус к отпуску: доступ к РФ-сервисам

Отпуск рождает второй запрос от того же клиента: за границей он хочет зайти в российский банк или Госуслуги, а приложение ругается «отключите VPN» — и не помогает, потому что дело не в VPN, а в том, что его IP не российский. Это лечится отдельной РФ-нодой (стелс-вход, белый IP), которую отдаёшь клиенту как сервер «🇷🇺 Россия» или через авто-роутинг РФ-сервисов. Но это уже про инфраструктуру и маршрутизацию — отдельная большая тема; здесь важно, что оба «отпускных» запроса закрываются и оба работают на удержание.

Чек-лист

  • [ ] В боте/miniapp кнопки ❄️ Заморозить / ▶️ Разморозить.
  • [ ] 4 поля: frozen, frozen_at, banked_days, last_freeze_at.
  • [ ] Лимиты: раз в 30 дней, остаток ≥ 2 дней, авто-разморозка через 30 дней.
  • [ ] Шедулер напоминаний/автопродления пропускает frozen-ключи.
  • [ ] Прогнано на себе: заморозил → разморозил → дни не потерялись.

Заморозка — один из трёх приёмов против оттока рядом со спасательным кругом (grace) и автопродлением; общую логику удержания смотри в теории удержания.

Следующий гайд Зачем CDN-фронтинг: работать под белыми списками → Не понравилась статья или что-то непонятно? Напишите мне — помогу или поправлю. @notrealvpn →
Материал носит образовательный характер и посвящён инженерии сетевой инфраструктуры. Вы отвечаете за соблюдение законов своей юрисдикции.