"""Часто задаваемые вопросы (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}"