Files
malenia/texts.py
hexdev d98383285e feat: implement billing system with Pally integration
- Added billing models and repository for handling bills.
- Introduced BillingService to manage payment initiation and bill creation.
- Updated user service to remove ticket-related functionality.
- Refactored settings to include new billing-related fields.
- Removed ticket-related handlers and schemas.
- Added new billing handlers for processing payments.
- Updated database schema with new bills table and status enum.
- Enhanced utility functions to calculate prices considering discounts.
- Introduced prehandling for non-private messages.
- Updated main application to initialize new billing services and repositories.
2026-04-23 19:55:51 +07:00

248 lines
11 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ============================================================
# PREMIUM EMOJI
# ============================================================
class PremiumEmoji:
def __init__(self, emoji_id: int, emoji: str):
self.emoji_id = emoji_id
self.emoji = emoji
def __str__(self) -> str:
return f'<tg-emoji emoji-id="{self.emoji_id}">{self.emoji}</tg-emoji>'
# — Иконки бота
MALENIA_LOGO = PremiumEmoji(5265053829522562789, "☀️")
MALENIA_HEART = PremiumEmoji(5276516908257025723, "❤️")
MALENIA_LINK = PremiumEmoji(5276012730636082950, "🔗")
MALENIA_COINS = PremiumEmoji(5276298354551199712, "🪙")
MALENIA_LOCKED = PremiumEmoji(5276346642868508688, "🔒")
MALENIA_SUPPORT = PremiumEmoji(5275968088746006467, "🎧")
# ============================================================
# ШАБЛОНЫ — ОБЩИЕ БЛОКИ
# ============================================================
_SUPPORT_USER_DESCRIPTION = (
"👤 <b>Профиль:</b> {full_name}\n"
"🔗 <b>Alias:</b> {username_display}\n"
"🆔 <b>UID:</b> <code>{telegram_id}</code>\n\n"
"❤️ <b>Referal UID:</b> <code>{referal_id}</code>\n\n"
"💰 <b>Баланс:</b> <code>{balance}</code>"
)
_DIVIDER = "────────────────────────────\n\n"
# ============================================================
# МАППИНГИ
# ============================================================
# ============================================================
# СТАТУСЫ ПОДПИСКИ
# ============================================================
# — Иконки статусов
STATUS_ICON_ACTIVE = "🟢"
STATUS_ICON_DISABLED = ""
STATUS_ICON_EXPIRED = "🔴"
STATUS_ICON_LIMITED = "🟠"
STATUS_ICON_UNKNOWN = ""
# — Тексты статусов
STATUS_ACTIVE = "активна"
STATUS_DISABLED = "отключена"
STATUS_EXPIRED = "истёк"
STATUS_LIMITED = "трафик ограничен"
STATUS_UNKNOWN = "неизвестный статус"
# ============================================================
# ФОРМАТИРОВАНИЕ ДАННЫХ
# ============================================================
# — Дни до истечения подписки
DAYS_LEFT_POSITIVE = "{days} дн."
DAYS_LEFT_EXPIRED = "истекла {days} дн. назад"
DAYS_LEFT_TODAY = "подходит к концу сегодня"
# — Username
NO_USERNAME = "отсутствует"
USERNAME_DISPLAY = "@{username}"
# — Internal Squads
NO_SQUADS = "отсутствуют"
# — HWID лимит
UNLIMITED_HWID = "без лимитов"
# — Трафик
NO_TRAFFIC_LIMIT = "не ограничен"
TRAFFIC_WITH_LIMIT = "{used} / {limit}"
TRAFFIC_NO_LIMIT = "{used}"
# — Прочее
NOTHING_PLACEHOLDER = ""
# ============================================================
# ПОЛЬЗОВАТЕЛЬСКИЙ ИНТЕРФЕЙС
# ============================================================
MAIN_MENU = (
str(MALENIA_LOGO)
+ " <b>Malenia — <i>{quote}</i></b>\n\n"
+ f"<i>{MALENIA_COINS} Личный кабинет</i>\n"
+ f"<b>{MALENIA_LINK} Ссылка на подписку: <code>{{link}}</code></b>"
)
FAQ_TEXT = (
"<b>Ваши частые вопросы:</b>\n\n"
"<b>— Зачем мне это?</b>\n"
"Если вас устраивает, что ваш интернет ограничен парой сайтов и банков, то вам не к нам. Но если хочется свободы и анонимности — добро пожаловать.\n\n"
"<b>— Это безопасно?</b>\n"
"Мы не храним ваши данные, не используем их в коммерческих целях и не передаем третьим лицам,"
"но важно понимать, что полной анонимности не существует. Мы делаем всё, чтобы минимизировать риски, но не продаём иллюзий.\n\n"
"<b>— Почему что-то не работает?</b>\n"
"Фильтры постоянно обновляются и подстраиваются под новые методы обхода. А мы подстраиваемся под них.\n"
"Если что-то перестало работать, скорее всего, это временно, и мы уже работаем над решением. Но обращения в поддержку с описанием проблемы и скриншотами всегда приветствуются, это помогает нам быстрее находить и устранять проблемы.\n\n"
"<b>— Как работает реферальная система?</b>\n"
"Вы получаете уникальную ссылку, по которой могут прийти ваши друзья. За каждого приведённого друга, который оформит подписку,"
"<b>вам будет начисляться процент от их оплаченной подписки</b> на баланс."
)
GENERAL_PROCESSING = "<i>⏳ Подождите...</i>"
STANDARD_FALLBACK = (
"<b>❌ Ошибка.</b> Прожмите /start. Если не поможет — значит, мы где-то не доглядели."
)
CALLBACK_FALLBACK = "❌ Что-то пошло не так. Повторите попытку или обратитесь в поддержку."
CONTEXT_REINITIATED = "🌑 Сессия сброшена. Данные могли обновиться."
UNDEFINED_MESSAGE = "❌ Таких команд у нас нет.\n\n<i>Ищете техподдержку? Вам в /support</i>\n<i>Потерялись? Вам в /start.</i>"
SUBSCRIPTION_INFORMATION = (
"<b>📊 Данные о подписке</b>\n\n"
f"{MALENIA_LINK} Ссылка на подписку: <code>{{link}}</code>\n\n"
"{status_icon} <b>Статус:</b> {status}\n"
+ "📅 <b>Истекает:</b> {expire_date}\n"
+ "⏳ <b>Осталось дней:</b> {days_left}\n"
+ "📊 <b>Израсходовано трафика:</b> {used_traffic}\n"
+ "📱 <b>Количество устройств:</b> {hwid_limit}\n"
)
NO_SUBSCRIPTION = "⚠️ <b>Подписка не найдена.</b>"
# ============================================================
# РЕФЕРАЛЬНАЯ СИСТЕМА
# ============================================================
REFERALS_MENU = (
"<b>👥 Реферальная система</b>\n\n"
"Делитесь свободой с друзьями и получайте деньги на оплату своей подписки.\n"
f"<b>{MALENIA_COINS} На вашем счету:</b> "
"<code>{balance}₽</code>\n"
f"<b>{MALENIA_LINK} Ваша реферальная ссылка:</b> "
"<code>{link}</code>"
)
# ============================================================
# ОФОРМЛЕНИЕ ПОДПИСКИ
# ============================================================
SUBSCRIPTION_DEVICE_SELECTOR = "Сколько устройств вы хотите подключить?\n\nЦена: <b>{price}₽</b>"
SUBSCRIPTION_DURATION_SELECTOR = (
"На какой срок хотите оформить подписку?\n\nИтого: <b>{price}₽</b> <i>(скидка: {discount}%)</i>"
)
WHITELISTS_ALREADY_ON = "Белые списки уже активны."
CHECKOUT_PAYMENT_CHOICE = "Пока что без автоплатежа. Нажмите кнопку ниже и обратитесь в поддержку для оплаты и активации подписки."
# ============================================================
# BILLING
# ============================================================
_BILL_TEMPLATE = (
"<b>💸 Счёт на {amount}₽</b>\n\n"
"<i>‼️ Вам придёт уведомление в течение нескольких минут после завершения платежа.</i>\n"
"<b>🔒 Способ оплаты:</b> <i>{provider}</i>\n\n"
)
_BILL_LINK = f"<b>{MALENIA_LINK} Ссылка на оплату:</b>"
BILL_CREATION = _BILL_TEMPLATE + _DIVIDER + GENERAL_PROCESSING
BILL_CREATED = _BILL_TEMPLATE + _DIVIDER + _BILL_LINK
# ============================================================
# ПОДДЕРЖКА
# ============================================================
SUPPORT_INIT = "<b>🎧 Тех. Поддержка Malenia</b> — не здесь. Кнопка ниже."
SUPPORT_MSG_SENT = "⏳ Приняли ваше сообщение. Мы постараемся ответить на него в ближайшее время.\n<i>Вернуться в меню: /cancel</i>"
SUPPORT_SIGNATURE = "<b>📡 Ответ от Malenia:</b>"
# ============================================================
# ШАБЛОНЫ — ЗАЯВКИ И ТИКЕТЫ
# ============================================================
SUPPORT_SUBSCRIPTION = (
"<b>🎫 ВХОДЯЩИЙ ЗАПРОС:</b>\n\n"
+ _SUPPORT_USER_DESCRIPTION
+ "\n"
+ _DIVIDER
+ "🗓️ Срок: <b>{duration} мес.</b>\n"
+ "📱 Устройства: <b>{devices}</b>\n"
+ "🏳️ Whitelists: <b>{whitelist_description}</b>\n\n"
+ "💰 К оплате: <b>{price}₽</b>"
)
ADMIN_TICKET_WITH_RW = (
"🎫 <b>ТИКЕТ T-{ticket_number:04d}</b>\n\n"
+ _SUPPORT_USER_DESCRIPTION
+ "\n"
+ _DIVIDER
+ "📊 <b>ТЕХ. ДАННЫЕ (Remnawave)</b>\n\n"
+ "{status_icon} <b>Статус:</b> {status}\n"
+ "📅 <b>Deadline:</b> {expire_date}\n"
+ "⏳ <b>Остаток:</b> {days_left}\n"
+ "📊 <b>Трафик:</b> {used_traffic}\n"
+ "📱 <b>HWID:</b> {hwid_limit}\n"
+ "🎯 <b>Squads:</b> {squads}\n\n"
+ _DIVIDER
+ "🔑 <b>UUID:</b> <code>{remnawave_uuid}</code>"
)
ADMIN_TICKET_WITHOUT_RW = (
"🎫 <b>ТИКЕТ T-{ticket_number:04d}</b>\n\n"
+ _SUPPORT_USER_DESCRIPTION
+ "\n"
+ _DIVIDER
+ NO_SUBSCRIPTION
)
ADMIN_STANDARD_FALLBACK = "<b>❌ Ошибка выполнения.</b> Проверь логи, что-то пошло не по чертежу."
# ============================================================
# АДМИНСКАЯ ХУЙНЯ
# ============================================================
ADMIN_PROMOTION_INIT = "👥 Введите текст рассылки"
ADMIN_PROMOTION_CONFIRMATION = "❓ Отправить сообщение всем пользователям бота?"
SUCCESSFULLY_SENT_PROMOTION = "Успешно разосланно {user_count} пользователям."
SPECIFY_REFERAL_PAYMENT_AMOUNT = "Укажите количество средств для перевода рефералу пользователя."
USER_NO_REFERAL = "У пользователя нет реферала."
INVALID_ARGUMENT_REFPAY = "❌ Укажите в аргументах количество средств, которые необходимо перевести рефералу пользователя."
SUCCESSFUL_REFPAY = "<b>💸 Баланс реферала ({referal_id}) пополнен на {amount}₽</b>"