"""Часто задаваемые вопросы (FAQ).""" from __future__ import annotations from dataclasses import dataclass @dataclass(frozen=True, slots=True) class FaqItem: id: str question: str answer: str FAQ_ITEMS: tuple[FaqItem, ...] = ( FaqItem( id="what_is", question="Что это за VPN?", answer=( "Это сервис на базе Remnawave: после оплаты ты получаешь " "ссылку подписки. Её вставляешь в клиент (Hiddify, Streisand, " "v2rayNG и др.) — и подключаешься к серверам." ), ), FaqItem( id="how_start", question="Как начать пользоваться?", answer=( "1) Пополни баланс: Stars / криптой в боте или кодом (карта/СБП — через покупку кода)\n" "2) Купи тариф в «Тарифы» или Mini App\n" "3) Открой «Моя подписка» → скопируй ссылку\n" "4) Скачай клиент → вставь ссылку подписки\n" "5) Выбери сервер и подключись" ), ), FaqItem( id="clients", question="Какой клиент скачать?", answer=( "В боте есть раздел «Скачать клиент» — топ приложений с docs.rw.\n" "Популярные варианты:\n" "• iOS / macOS — Streisand, Happ, Shadowrocket\n" "• Android — v2rayNG, Hiddify, Happ\n" "• Windows — Hiddify, FlClash\n\n" "Главное — клиент с поддержкой subscription URL." ), ), FaqItem( id="sub_link", question="Где взять ссылку подписки?", answer=( "«Моя подписка» в боте или главная в Mini App.\n" "Ссылка выглядит как HTTPS URL — её целиком копируешь в клиент " "(Add subscription / Import from URL)." ), ), FaqItem( id="devices", question="Сколько устройств можно?", answer=( "База — 10 устройств на подписку (в тарифе).\n" "Доп. слот: 50 ₽/мес за каждое (первый месяц при покупке).\n" "Списание с баланса каждые 30 дней за все доп. устройства.\n" "Если средств нет — доп. слоты отключаются до пополнения.\n" "Если устройств больше оплаченной квоты — " "подписка отключается, пока не оплатишь превышение " "или не отвяжешь лишние устройства в клиенте." ), ), FaqItem( id="extras_monthly", question="Почему списывают за доп. трафик и устройства каждый месяц?", answer=( "Дополнительные 500 ГБ и устройства сверх 10 — " "это отдельная подписка к основному тарифу.\n\n" "• При покупке списывается первый месяц\n" "• Далее — автоматически с баланса раз в 30 дней\n" "• Сумма = (число пакетов × 50 ₽) + (число доп. устройств × 50 ₽)\n" "• Не хватает баланса — доп. лимиты приостанавливаются, " "основная подписка остаётся на базовых 1000 ГБ и 10 устройств" ), ), FaqItem( id="traffic", question="Сколько трафика даётся?", answer=( "В каждом тарифе база — 1000 ГБ (включено в тариф).\n" "Докупка: +500 ГБ = 50 ₽/мес (можно несколько пакетов).\n" "Первый месяц списывается при покупке, далее — каждые 30 дней " "с баланса за все подключённые пакеты.\n" "Если на балансе не хватает — доп. ГБ отключаются до оплаты.\n" "Расход смотри в «Моя подписка» или Mini App." ), ), FaqItem( id="traffic_over", question="Что если трафик закончится?", answer=( "Подключение может ограничиться, пока не докупишь пакет " "или не начнётся новый период после продления тарифа.\n" "Докупка трафика не продлевает срок подписки — только лимит ГБ." ), ), FaqItem( id="pay", question="Как оплатить?", answer=( "• Тарифы и услуги — с баланса\n\n" "Без кода (напрямую в боте):\n" "• Telegram Stars — оплата ⭐ прямо в Telegram\n" "• Crypto Bot — крипта\n" "• Heleket — резервная крипта\n\n" "Карта, СБП и другие фиатные способы — через " "код пополнения:\n" "• На странице покупки кода — более 40 способов оплаты\n" "• После оплаты введи код в «Баланс» → «Код пополнения» " "или в Mini App\n\n" "Пополнение — раздел «Баланс» в боте." ), ), FaqItem( id="stars", question="Как пополнить через Telegram Stars?", answer=( "1) «Баланс» → «Telegram Stars» в боте\n" " или в Mini App / Telegram Web — блок «Telegram Stars»\n" "2) Выбери сумму в рублях (курс задаёт сервис)\n" "3) Оплати инвойс Stars в Telegram\n" "4) Баланс зачислится сразу после оплаты\n\n" "В веб-версии Telegram удобнее кнопка оплаты по ссылке " "или оплата прямо из Mini App." ), ), FaqItem( id="topup_code", question="Как пополнить по коду?", answer=( "Нужен, если хочешь оплатить картой, СБП или другим фиатом " "(напрямую в боте без кода — только крипта).\n\n" "1) «Баланс» → «Код пополнения» → «Купить код» " "или кнопка в Mini App\n" "2) На странице оплаты — более 40 способов\n" "3) Введи код в боте или на главной Mini App\n" "4) Сумма зачислится на баланс сразу\n\n" "Один код — одно использование." ), ), FaqItem( id="cards_sbp", question="Картой или СБП — как пополнить?", answer=( "Купи код пополнения по ссылке из бота или кабинета.\n" "На странице оплаты доступно более 40 способов " "(банковские карты, СБП, электронные кошельки и др.).\n\n" "После успешной оплаты придёт код — активируй его в боте " "или на сайте. Дальше тарифы оплачиваешь с баланса.\n\n" "Без кода напрямую в боте пополнить можно " "только криптовалютой." ), ), FaqItem( id="lava", question="Как пополнить через Lava?", answer=( "Если в меню «Баланс» есть Lava — можно попробовать этот способ.\n" "Для карты и СБП основной вариант — код пополнения " "(40+ способов на странице покупки кода).\n\n" "Напрямую без кода в боте доступна только крипта." ), ), FaqItem( id="digiseller", question="Как пополнить через Digiseller?", answer=( "1) «Баланс» → Digiseller → «Оплатить на Digiseller»\n" "2) Оплати товар на сайте\n" "3) Digiseller сам откроет страницу проверки — баланс " "зачислится автоматически, в бот придёт уведомление\n\n" "Код вводить не нужно. Если автозачисление не сработало — " "в боте есть «Не зачислилось? Ввести код»." ), ), FaqItem( id="renew", question="Как продлить подписку?", answer=( "«Моя подписка» → «Продлить с баланса» или купи тариф снова.\n" "Дни добавляются к текущей дате окончания, " "если подписка ещё активна.\n\n" "За 7 дней до конца бот пришлёт напоминание раз в сутки.\n" "Если автопродление включено и на балансе хватает на последний тариф — " "за сутки до окончания подписка продлится автоматически " "(вкл/выкл в кабинете)." ), ), FaqItem( id="auto_renew", question="Автопродление подписки", answer=( "Если автопродление включено, система смотрит на " "последний купленный тариф и баланс.\n\n" "• За 7 дней до окончания — ежедневное напоминание в Telegram\n" "• В последние 24 часа (или сразу после истечения до 3 дней) " "при достаточном балансе — автоматическое продление с баланса\n" "• Включить или выключить можно при регистрации и в любой момент " "в кабинете на вкладке «Главная»\n" "• Если средств мало или автопродление выключено — " "пополни баланс или продли вручную в боте / Mini App" ), ), FaqItem( id="not_working", question="Не подключается / не работает", answer=( "Проверь по шагам:\n" "1) Подписка не истекла и трафик не на нуле\n" "2) Ссылка в клиенте актуальная (обнови subscription)\n" "3) Сервер онлайн — «Статус серверов»\n" "4) Попробуй другой сервер / другой клиент\n" "5) Выключи лишний VPN/антивирус на телефоне\n\n" "Если не помогло — напиши админу и приложи скрин ошибки." ), ), FaqItem( id="slow", question="Медленно / высокий пинг", answer=( "Смени сервер в клиенте (ближе к тебе или менее загруженный).\n" "Проверь «Статус серверов» — оффлайн ноды не выбирай.\n" "На мобильном интернете скорость зависит от оператора и Wi‑Fi." ), ), FaqItem( id="miniapp", question="Зачем Mini App?", answer=( "Это кабинет в Telegram: баланс, подписка, трафик, тарифы, " "клиенты и серверы в одном окне.\n" "Сайт тоже открывается в браузере — там можно войти по логину " "или через Telegram Login." ), ), FaqItem( id="refund", question="Можно вернуть деньги?", answer=( "Автоматического возврата нет: доступ выдаётся сразу после оплаты.\n" "Если была техническая ошибка (списали, а ключ не выдали) — " "создай тикет в боте или Mini App, разберём и вернём на баланс " "или перевыпустим." ), ), FaqItem( id="tickets", question="Как связаться с поддержкой?", answer=( "В боте: кнопка «🎫 Тикеты» → «Новый тикет».\n" "В Mini App: вкладка «Тикеты».\n" "Ответ придёт в Telegram и будет виден в переписке тикета." ), ), ) def get_faq(item_id: str) -> FaqItem | None: for item in FAQ_ITEMS: if item.id == item_id: return item return None def faq_intro() -> str: return ( "❓ FAQ — частые вопросы\n\n" "Выбери вопрос ниже. Если не нашёл ответ — создай тикет." ) def faq_answer_text(item: FaqItem) -> str: return f"❓ {item.question}\n\n{item.answer}"