mirror of
https://github.com/BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot.git
synced 2026-05-02 10:46:25 +00:00
Merge pull request #41 from yazhog/main
Убрал копейки + QR код для рефералки
This commit is contained in:
@@ -179,8 +179,8 @@ class Settings(BaseSettings):
|
||||
return ["ru", "en"]
|
||||
|
||||
def format_price(self, price_kopeks: int) -> str:
|
||||
rubles = price_kopeks / 100
|
||||
return f"{rubles:.2f} ₽"
|
||||
rubles = price_kopeks // 100
|
||||
return f"{rubles} ₽"
|
||||
|
||||
def kopeks_to_rubles(self, kopeks: int) -> float:
|
||||
return kopeks / 100
|
||||
|
||||
6
app/external/telegram_stars.py
vendored
6
app/external/telegram_stars.py
vendored
@@ -45,8 +45,8 @@ class TelegramStarsService:
|
||||
)
|
||||
|
||||
logger.info(
|
||||
f"Создан Stars invoice на {stars_amount} звезд (~{amount_rubles:.2f}₽) "
|
||||
f"для {chat_id}, курс: {settings.get_stars_rate():.2f}₽/⭐"
|
||||
f"Создан Stars invoice на {stars_amount} звезд (~{int(amount_rubles)}₽) "
|
||||
f"для {chat_id}, курс: {int(settings.get_stars_rate())}₽/⭐"
|
||||
)
|
||||
return invoice_link
|
||||
|
||||
@@ -80,7 +80,7 @@ class TelegramStarsService:
|
||||
|
||||
logger.info(
|
||||
f"Отправлен Stars invoice {message.message_id} на {stars_amount} звезд "
|
||||
f"(~{amount_rubles:.2f}₽), курс: {settings.get_stars_rate():.2f}₽/⭐"
|
||||
f"(~{int(amount_rubles)}₽), курс: {int(settings.get_stars_rate())}₽/⭐"
|
||||
)
|
||||
return {
|
||||
"message_id": message.message_id,
|
||||
|
||||
@@ -37,7 +37,7 @@ async def show_servers_menu(
|
||||
• С подключениями: {stats['servers_with_connections']}
|
||||
|
||||
💰 <b>Выручка от серверов:</b>
|
||||
• Общая: {stats['total_revenue_rubles']:.2f} ₽
|
||||
• Общая: {int(stats['total_revenue_rubles'])} ₽
|
||||
|
||||
Выберите действие:
|
||||
"""
|
||||
@@ -83,7 +83,7 @@ async def show_servers_list(
|
||||
|
||||
for i, server in enumerate(servers, 1 + (page - 1) * 10):
|
||||
status_emoji = "✅" if server.is_available else "❌"
|
||||
price_text = f"{server.price_rubles:.2f} ₽" if server.price_kopeks > 0 else "Бесплатно"
|
||||
price_text = f"{int(server.price_rubles)} ₽" if server.price_kopeks > 0 else "Бесплатно"
|
||||
|
||||
text += f"{i}. {status_emoji} {server.display_name}\n"
|
||||
text += f" 💰 Цена: {price_text}"
|
||||
@@ -222,7 +222,7 @@ async def show_server_edit_menu(
|
||||
return
|
||||
|
||||
status_emoji = "✅ Доступен" if server.is_available else "❌ Недоступен"
|
||||
price_text = f"{server.price_rubles:.2f} ₽" if server.price_kopeks > 0 else "Бесплатно"
|
||||
price_text = f"{int(server.price_rubles)} ₽" if server.price_kopeks > 0 else "Бесплатно"
|
||||
|
||||
text = f"""
|
||||
🌐 <b>Редактирование сервера</b>
|
||||
@@ -304,7 +304,7 @@ async def toggle_server_availability(
|
||||
server = await get_server_squad_by_id(db, server_id)
|
||||
|
||||
status_emoji = "✅ Доступен" if server.is_available else "❌ Недоступен"
|
||||
price_text = f"{server.price_rubles:.2f} ₽" if server.price_kopeks > 0 else "Бесплатно"
|
||||
price_text = f"{int(server.price_rubles)} ₽" if server.price_kopeks > 0 else "Бесплатно"
|
||||
|
||||
text = f"""
|
||||
🌐 <b>Редактирование сервера</b>
|
||||
@@ -378,7 +378,7 @@ async def start_server_edit_price(
|
||||
await state.set_data({'server_id': server_id})
|
||||
await state.set_state(AdminStates.editing_server_price)
|
||||
|
||||
current_price = f"{server.price_rubles:.2f} ₽" if server.price_kopeks > 0 else "Бесплатно"
|
||||
current_price = f"{int(server.price_rubles)} ₽" if server.price_kopeks > 0 else "Бесплатно"
|
||||
|
||||
await callback.message.edit_text(
|
||||
f"💰 <b>Редактирование цены</b>\n\n"
|
||||
@@ -424,7 +424,7 @@ async def process_server_price_edit(
|
||||
|
||||
await cache.delete("available_countries")
|
||||
|
||||
price_text = f"{price_rubles:.2f} ₽" if price_kopeks > 0 else "Бесплатно"
|
||||
price_text = f"{int(price_rubles)} ₽" if price_kopeks > 0 else "Бесплатно"
|
||||
await message.answer(
|
||||
f"✅ Цена сервера изменена на: <b>{price_text}</b>",
|
||||
reply_markup=types.InlineKeyboardMarkup(inline_keyboard=[
|
||||
@@ -613,8 +613,8 @@ async def show_server_detailed_stats(
|
||||
• С активными подключениями: {stats['servers_with_connections']}
|
||||
|
||||
<b>💰 Финансовая статистика:</b>
|
||||
• Общая выручка: {stats['total_revenue_rubles']:.2f} ₽
|
||||
• Средняя цена за сервер: {(stats['total_revenue_rubles'] / max(stats['servers_with_connections'], 1)):.2f} ₽
|
||||
• Общая выручка: {int(stats['total_revenue_rubles'])} ₽
|
||||
• Средняя цена за сервер: {int(stats['total_revenue_rubles'] / max(stats['servers_with_connections'], 1))} ₽
|
||||
|
||||
<b>🔥 Топ серверов по цене:</b>
|
||||
"""
|
||||
@@ -622,7 +622,7 @@ async def show_server_detailed_stats(
|
||||
sorted_servers = sorted(available_servers, key=lambda x: x.price_kopeks, reverse=True)
|
||||
|
||||
for i, server in enumerate(sorted_servers[:5], 1):
|
||||
price_text = f"{server.price_rubles:.2f} ₽" if server.price_kopeks > 0 else "Бесплатно"
|
||||
price_text = f"{int(server.price_rubles)} ₽" if server.price_kopeks > 0 else "Бесплатно"
|
||||
text += f"{i}. {server.display_name} - {price_text}\n"
|
||||
|
||||
if not sorted_servers:
|
||||
|
||||
@@ -636,9 +636,9 @@ async def process_balance_edit(
|
||||
|
||||
description = f"Изменение баланса администратором {db_user.full_name}"
|
||||
if amount_kopeks > 0:
|
||||
description = f"Пополнение администратором: +{amount_rubles} ₽"
|
||||
description = f"Пополнение администратором: +{int(amount_rubles)} ₽"
|
||||
else:
|
||||
description = f"Списание администратором: {amount_rubles} ₽"
|
||||
description = f"Списание администратором: {int(amount_rubles)} ₽"
|
||||
|
||||
success = await user_service.update_user_balance(
|
||||
db, user_id, amount_kopeks, description, db_user.id
|
||||
|
||||
@@ -381,7 +381,7 @@ async def process_stars_payment_amount(
|
||||
f"⭐ <b>Оплата через Telegram Stars</b>\n\n"
|
||||
f"💰 Сумма: {texts.format_price(amount_kopeks)}\n"
|
||||
f"⭐ К оплате: {stars_amount} звезд\n"
|
||||
f"📊 Курс: {settings.get_stars_rate():.2f}₽ за звезду\n\n"
|
||||
f"📊 Курс: {int(settings.get_stars_rate())}₽ за звезду\n\n"
|
||||
f"Нажмите кнопку ниже для оплаты:",
|
||||
reply_markup=keyboard,
|
||||
parse_mode="HTML"
|
||||
@@ -465,7 +465,7 @@ async def process_yookassa_payment_amount(
|
||||
await state.clear()
|
||||
|
||||
logger.info(f"Создан платеж YooKassa для пользователя {db_user.telegram_id}: "
|
||||
f"{amount_kopeks/100}₽, ID: {payment_result['yookassa_payment_id']}")
|
||||
f"{amount_kopeks//100}₽, ID: {payment_result['yookassa_payment_id']}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка создания YooKassa платежа: {e}")
|
||||
|
||||
@@ -1,12 +1,21 @@
|
||||
import logging
|
||||
from aiogram import Dispatcher, types, F
|
||||
from pathlib import Path
|
||||
|
||||
import qrcode
|
||||
from aiogram import Dispatcher, F, types
|
||||
from aiogram.exceptions import TelegramBadRequest
|
||||
from aiogram.types import FSInputFile
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.config import settings
|
||||
from app.database.models import User
|
||||
from app.keyboards.inline import get_referral_keyboard, get_back_keyboard
|
||||
from app.keyboards.inline import get_referral_keyboard
|
||||
from app.localization.texts import get_texts
|
||||
from app.utils.user_utils import get_user_referral_summary, get_detailed_referral_list, get_referral_analytics
|
||||
from app.utils.user_utils import (
|
||||
get_detailed_referral_list,
|
||||
get_referral_analytics,
|
||||
get_user_referral_summary,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -82,11 +91,59 @@ async def show_referral_info(
|
||||
|
||||
referral_text += "📢 Приглашайте друзей и зарабатывайте!"
|
||||
|
||||
await callback.message.edit_text(
|
||||
referral_text,
|
||||
reply_markup=get_referral_keyboard(db_user.language),
|
||||
parse_mode="HTML"
|
||||
if callback.message.text:
|
||||
await callback.message.edit_text(
|
||||
referral_text,
|
||||
reply_markup=get_referral_keyboard(db_user.language),
|
||||
parse_mode="HTML"
|
||||
)
|
||||
else:
|
||||
await callback.message.delete()
|
||||
await callback.message.answer(
|
||||
referral_text,
|
||||
reply_markup=get_referral_keyboard(db_user.language),
|
||||
parse_mode="HTML"
|
||||
)
|
||||
await callback.answer()
|
||||
|
||||
|
||||
async def show_referral_qr(
|
||||
callback: types.CallbackQuery,
|
||||
db_user: User,
|
||||
):
|
||||
texts = get_texts(db_user.language)
|
||||
|
||||
bot_username = (await callback.bot.get_me()).username
|
||||
referral_link = f"https://t.me/{bot_username}?start={db_user.referral_code}"
|
||||
|
||||
qr_dir = Path("data") / "referral_qr"
|
||||
qr_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
file_path = qr_dir / f"{db_user.id}.png"
|
||||
if not file_path.exists():
|
||||
img = qrcode.make(referral_link)
|
||||
img.save(file_path)
|
||||
|
||||
photo = FSInputFile(file_path)
|
||||
keyboard = types.InlineKeyboardMarkup(
|
||||
inline_keyboard=[[types.InlineKeyboardButton(text=texts.BACK, callback_data="menu_referrals")]]
|
||||
)
|
||||
|
||||
try:
|
||||
await callback.message.edit_media(
|
||||
types.InputMediaPhoto(
|
||||
media=photo,
|
||||
caption=f"🔗 Ваша реферальная ссылка:\n{referral_link}",
|
||||
),
|
||||
reply_markup=keyboard,
|
||||
)
|
||||
except TelegramBadRequest:
|
||||
await callback.message.delete()
|
||||
await callback.message.answer_photo(
|
||||
photo,
|
||||
caption=f"🔗 Ваша реферальная ссылка:\n{referral_link}",
|
||||
reply_markup=keyboard,
|
||||
)
|
||||
await callback.answer()
|
||||
|
||||
|
||||
@@ -243,6 +300,11 @@ def register_handlers(dp: Dispatcher):
|
||||
create_invite_message,
|
||||
F.data == "referral_create_invite"
|
||||
)
|
||||
|
||||
dp.callback_query.register(
|
||||
show_referral_qr,
|
||||
F.data == "referral_show_qr"
|
||||
)
|
||||
|
||||
dp.callback_query.register(
|
||||
show_detailed_referral_list,
|
||||
|
||||
@@ -92,7 +92,7 @@ async def handle_successful_payment(
|
||||
await message.answer(
|
||||
f"🎉 <b>Платеж успешно обработан!</b>\n\n"
|
||||
f"⭐ Потрачено звезд: {payment.total_amount}\n"
|
||||
f"💰 Зачислено на баланс: {rubles_amount:.2f} ₽\n"
|
||||
f"💰 Зачислено на баланс: {int(rubles_amount)} ₽\n"
|
||||
f"🆔 ID транзакции: {payment.telegram_payment_charge_id[:8]}...\n\n"
|
||||
f"Спасибо за пополнение! 🚀",
|
||||
parse_mode="HTML"
|
||||
@@ -100,7 +100,7 @@ async def handle_successful_payment(
|
||||
|
||||
logger.info(
|
||||
f"✅ Stars платеж успешно обработан: "
|
||||
f"пользователь {user.id}, {payment.total_amount} звезд → {rubles_amount:.2f}₽"
|
||||
f"пользователь {user.id}, {payment.total_amount} звезд → {int(rubles_amount)}₽"
|
||||
)
|
||||
else:
|
||||
logger.error(f"Ошибка обработки Stars платежа для пользователя {user.id}")
|
||||
|
||||
@@ -521,10 +521,10 @@ async def complete_registration_from_callback(
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка при отправке главного меню: {e}")
|
||||
try:
|
||||
balance_rubles = user.balance_kopeks / 100
|
||||
balance_rubles = user.balance_kopeks // 100
|
||||
await callback.message.answer(
|
||||
f"Добро пожаловать, {user.full_name}!\n"
|
||||
f"Баланс: {balance_rubles:.2f} ₽\n"
|
||||
f"Баланс: {balance_rubles} ₽\n"
|
||||
f"Подписка: Нет активной подписки",
|
||||
reply_markup=get_main_menu_keyboard(
|
||||
language=user.language,
|
||||
@@ -684,10 +684,10 @@ async def complete_registration(
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка при отправке главного меню: {e}")
|
||||
try:
|
||||
balance_rubles = user.balance_kopeks / 100
|
||||
balance_rubles = user.balance_kopeks // 100
|
||||
await message.answer(
|
||||
f"Добро пожаловать, {user.full_name}!\n"
|
||||
f"Баланс: {balance_rubles:.2f} ₽\n"
|
||||
f"Баланс: {balance_rubles} ₽\n"
|
||||
f"Подписка: Нет активной подписки",
|
||||
reply_markup=get_main_menu_keyboard(
|
||||
language=user.language,
|
||||
|
||||
@@ -1415,13 +1415,13 @@ async def get_traffic_packages_info() -> str:
|
||||
info_lines.append("\n✅ Активные:")
|
||||
for pkg in enabled_packages:
|
||||
gb_text = "♾️ Безлимит" if pkg['gb'] == 0 else f"{pkg['gb']} ГБ"
|
||||
info_lines.append(f" • {gb_text}: {pkg['price']/100}₽")
|
||||
info_lines.append(f" • {gb_text}: {pkg['price']//100}₽")
|
||||
|
||||
if disabled_packages:
|
||||
info_lines.append("\n❌ Отключенные:")
|
||||
for pkg in disabled_packages:
|
||||
gb_text = "♾️ Безлимит" if pkg['gb'] == 0 else f"{pkg['gb']} ГБ"
|
||||
info_lines.append(f" • {gb_text}: {pkg['price']/100}₽")
|
||||
info_lines.append(f" • {gb_text}: {pkg['price']//100}₽")
|
||||
|
||||
info_lines.append(f"\n📊 Всего пакетов: {len(packages)}")
|
||||
info_lines.append(f"🟢 Активных: {len(enabled_packages)}")
|
||||
@@ -1918,9 +1918,9 @@ async def confirm_purchase(
|
||||
|
||||
if remnawave_user and hasattr(subscription, 'subscription_url') and subscription.subscription_url:
|
||||
success_text = f"{texts.SUBSCRIPTION_PURCHASED}\n\n"
|
||||
success_text += f"Ваша ссылка для импорта в VPN приложение:\n"
|
||||
success_text += f"🔗 <b>Ваша ссылка для импорта в VPN приложение:</b>\n"
|
||||
success_text += f"<code>{subscription.subscription_url}</code>\n\n"
|
||||
success_text += f"Нажмите кнопку ниже, чтобы получить инструкцию по настройке VPN на вашем устройстве"
|
||||
success_text += f"📱 Нажмите кнопку ниже, чтобы получить инструкцию по настройке VPN на вашем устройстве"
|
||||
|
||||
connect_mode = settings.CONNECT_BUTTON_MODE
|
||||
|
||||
@@ -1928,12 +1928,12 @@ async def confirm_purchase(
|
||||
connect_keyboard = InlineKeyboardMarkup(inline_keyboard=[
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text="Подключиться",
|
||||
text="🔗 Подключиться",
|
||||
web_app=types.WebAppInfo(url=subscription.subscription_url),
|
||||
)
|
||||
],
|
||||
[InlineKeyboardButton(text="Моя подписка", callback_data="menu_subscription")],
|
||||
[InlineKeyboardButton(text="В главное меню", callback_data="back_to_menu")],
|
||||
[InlineKeyboardButton(text="📱 Моя подписка", callback_data="menu_subscription")],
|
||||
[InlineKeyboardButton(text="⬅️ В главное меню", callback_data="back_to_menu")],
|
||||
])
|
||||
elif connect_mode == "miniapp_custom":
|
||||
if not settings.MINIAPP_CUSTOM_URL:
|
||||
@@ -1943,18 +1943,18 @@ async def confirm_purchase(
|
||||
connect_keyboard = InlineKeyboardMarkup(inline_keyboard=[
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text="Подключиться",
|
||||
text="🔗 Подключиться",
|
||||
web_app=types.WebAppInfo(url=settings.MINIAPP_CUSTOM_URL),
|
||||
)
|
||||
],
|
||||
[InlineKeyboardButton(text="Моя подписка", callback_data="menu_subscription")],
|
||||
[InlineKeyboardButton(text="В главное меню", callback_data="back_to_menu")],
|
||||
[InlineKeyboardButton(text="📱 Моя подписка", callback_data="menu_subscription")],
|
||||
[InlineKeyboardButton(text="⬅️ В главное меню", callback_data="back_to_menu")],
|
||||
])
|
||||
else:
|
||||
connect_keyboard = InlineKeyboardMarkup(inline_keyboard=[
|
||||
[InlineKeyboardButton(text="Подключиться", callback_data="subscription_connect")],
|
||||
[InlineKeyboardButton(text="Моя подписка", callback_data="menu_subscription")],
|
||||
[InlineKeyboardButton(text="В главное меню", callback_data="back_to_menu")],
|
||||
[InlineKeyboardButton(text="🔗 Подключиться", callback_data="subscription_connect")],
|
||||
[InlineKeyboardButton(text="📱 Моя подписка", callback_data="menu_subscription")],
|
||||
[InlineKeyboardButton(text="⬅️ В главное меню", callback_data="back_to_menu")],
|
||||
])
|
||||
|
||||
await callback.message.edit_text(
|
||||
|
||||
@@ -533,6 +533,12 @@ def get_referral_keyboard(language: str = "ru") -> InlineKeyboardMarkup:
|
||||
callback_data="referral_create_invite"
|
||||
)
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text="📱 Показать QR код",
|
||||
callback_data="referral_show_qr"
|
||||
)
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text="👥 Список рефералов",
|
||||
@@ -715,14 +721,14 @@ def get_add_traffic_keyboard(language: str = "ru", subscription_end_date: dateti
|
||||
|
||||
if gb == 0:
|
||||
if language == "ru":
|
||||
text = f"♾️ Безлимитный трафик - {total_price/100:.2f} ₽{period_text}"
|
||||
text = f"♾️ Безлимитный трафик - {total_price//100} ₽{period_text}"
|
||||
else:
|
||||
text = f"♾️ Unlimited traffic - {total_price/100:.2f} ₽{period_text}"
|
||||
text = f"♾️ Unlimited traffic - {total_price//100} ₽{period_text}"
|
||||
else:
|
||||
if language == "ru":
|
||||
text = f"📊 +{gb} ГБ трафика - {total_price/100:.2f} ₽{period_text}"
|
||||
text = f"📊 +{gb} ГБ трафика - {total_price//100} ₽{period_text}"
|
||||
else:
|
||||
text = f"📊 +{gb} GB traffic - {total_price/100:.2f} ₽{period_text}"
|
||||
text = f"📊 +{gb} GB traffic - {total_price//100} ₽{period_text}"
|
||||
|
||||
buttons.append([
|
||||
InlineKeyboardButton(text=text, callback_data=f"add_traffic_{gb}")
|
||||
@@ -761,9 +767,9 @@ def get_add_devices_keyboard(current_devices: int, language: str = "ru", subscri
|
||||
total_price = price_per_month * months_multiplier
|
||||
|
||||
if language == "ru":
|
||||
text = f"📱 +{count} устройство(а) (итого: {new_total}) - {total_price/100:.2f} ₽{period_text}"
|
||||
text = f"📱 +{count} устройство(а) (итого: {new_total}) - {total_price//100} ₽{period_text}"
|
||||
else:
|
||||
text = f"📱 +{count} device(s) (total: {new_total}) - {total_price/100:.2f} ₽{period_text}"
|
||||
text = f"📱 +{count} device(s) (total: {new_total}) - {total_price//100} ₽{period_text}"
|
||||
|
||||
buttons.append([
|
||||
InlineKeyboardButton(text=text, callback_data=f"add_devices_{count}")
|
||||
@@ -835,10 +841,10 @@ def get_manage_countries_keyboard(
|
||||
if uuid not in current_subscription_countries and uuid in selected:
|
||||
total_price = price_per_month * months_multiplier
|
||||
if months_multiplier > 1:
|
||||
price_text = f" ({price_per_month/100:.2f}₽/мес × {months_multiplier} = {total_price/100:.2f}₽)"
|
||||
price_text = f" ({price_per_month//100}₽/мес × {months_multiplier} = {total_price//100}₽)"
|
||||
logger.info(f"🔍 Сервер {name}: {price_per_month/100}₽/мес × {months_multiplier} мес = {total_price/100}₽")
|
||||
else:
|
||||
price_text = f" ({total_price/100:.2f}₽)"
|
||||
price_text = f" ({total_price//100}₽)"
|
||||
display_name = f"{icon} {name}{price_text}"
|
||||
else:
|
||||
display_name = f"{icon} {name}"
|
||||
@@ -851,7 +857,7 @@ def get_manage_countries_keyboard(
|
||||
])
|
||||
|
||||
if total_cost > 0:
|
||||
apply_text = f"✅ Применить изменения ({total_cost/100:.2f} ₽)"
|
||||
apply_text = f"✅ Применить изменения ({total_cost//100} ₽)"
|
||||
logger.info(f"🔍 Общая стоимость новых серверов: {total_cost/100}₽")
|
||||
else:
|
||||
apply_text = "✅ Применить изменения"
|
||||
|
||||
@@ -57,7 +57,7 @@ class Texts:
|
||||
|
||||
@staticmethod
|
||||
def format_price(kopeks: int) -> str:
|
||||
return f"{kopeks / 100:.2f} ₽"
|
||||
return f"{int(kopeks / 100)} ₽"
|
||||
|
||||
@staticmethod
|
||||
def format_traffic(gb: float) -> str:
|
||||
@@ -125,7 +125,7 @@ class RussianTexts(Texts):
|
||||
MENU_LANGUAGE = "🌐 Язык"
|
||||
MENU_ADMIN = "⚙️ Админ-панель"
|
||||
BALANCE_BUTTON = "💰 Баланс: {balance}"
|
||||
BALANCE_BUTTON_ZERO = "💰 Баланс: 0.00 ₽"
|
||||
BALANCE_BUTTON_ZERO = "💰 Баланс: 0 ₽"
|
||||
|
||||
SUBSCRIPTION_NONE = "❌ Нет активной подписки"
|
||||
SUBSCRIPTION_TRIAL = "🧪 Тестовая подписка"
|
||||
|
||||
@@ -48,7 +48,7 @@ class PaymentService:
|
||||
prices=[LabeledPrice(label="Пополнение", amount=stars_amount)]
|
||||
)
|
||||
|
||||
logger.info(f"Создан Stars invoice на {stars_amount} звезд (~{amount_rubles:.2f}₽)")
|
||||
logger.info(f"Создан Stars invoice на {stars_amount} звезд (~{int(amount_rubles)}₽)")
|
||||
return invoice_link
|
||||
|
||||
except Exception as e:
|
||||
@@ -90,7 +90,7 @@ class PaymentService:
|
||||
|
||||
logger.info(f"💰 Баланс пользователя {user.telegram_id} изменен: {old_balance} → {user.balance_kopeks} (изменение: +{amount_kopeks})")
|
||||
|
||||
description_for_referral = f"Пополнение Stars: {rubles_amount:.2f}₽ ({stars_amount} ⭐)"
|
||||
description_for_referral = f"Пополнение Stars: {int(rubles_amount)}₽ ({stars_amount} ⭐)"
|
||||
logger.info(f"🔍 Проверка реферальной логики для описания: '{description_for_referral}'")
|
||||
|
||||
if any(word in description_for_referral.lower() for word in ["пополнение", "stars", "yookassa", "topup"]) and not any(word in description_for_referral.lower() for word in ["комиссия", "бонус"]):
|
||||
@@ -125,13 +125,15 @@ class PaymentService:
|
||||
f"Баланс пополнен автоматически!",
|
||||
parse_mode="HTML"
|
||||
)
|
||||
logger.info(f"✅ Отправлено уведомление пользователю {user.telegram_id} о пополнении на {rubles_amount:.2f}₽")
|
||||
logger.info(
|
||||
f"✅ Отправлено уведомление пользователю {user.telegram_id} о пополнении на {int(rubles_amount)}₽"
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка отправки уведомления о пополнении Stars: {e}")
|
||||
|
||||
logger.info(
|
||||
f"✅ Обработан Stars платеж: пользователь {user_id}, "
|
||||
f"{stars_amount} звезд → {rubles_amount:.2f}₽"
|
||||
f"{stars_amount} звезд → {int(rubles_amount)}₽"
|
||||
)
|
||||
return True
|
||||
else:
|
||||
@@ -313,7 +315,7 @@ class PaymentService:
|
||||
f"Баланс пополнен автоматически!",
|
||||
parse_mode="HTML"
|
||||
)
|
||||
logger.info(f"✅ Отправлено уведомление пользователю {user.telegram_id} о пополнении на {updated_payment.amount_kopeks/100:.2f}₽")
|
||||
logger.info(f"✅ Отправлено уведомление пользователю {user.telegram_id} о пополнении на {updated_payment.amount_kopeks//100}₽")
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка отправки уведомления о пополнении: {e}")
|
||||
else:
|
||||
@@ -352,7 +354,7 @@ class PaymentService:
|
||||
|
||||
user = await get_user_by_id(db, payment.user_id)
|
||||
if user:
|
||||
await add_user_balance(db, user, payment.amount_kopeks, f"Пополнение YooKassa: {payment.amount_kopeks/100:.2f}₽")
|
||||
await add_user_balance(db, user, payment.amount_kopeks, f"Пополнение YooKassa: {payment.amount_kopeks//100}₽")
|
||||
|
||||
logger.info(f"Успешно обработан платеж YooKassa {payment.yookassa_payment_id}: "
|
||||
f"пользователь {payment.user_id} получил {payment.amount_kopeks/100}₽")
|
||||
|
||||
@@ -221,7 +221,7 @@ class TributeService:
|
||||
|
||||
text = (
|
||||
f"✅ **Платеж успешно получен!**\n\n"
|
||||
f"💰 Сумма: {amount_rubles:.2f} ₽\n"
|
||||
f"💰 Сумма: {int(amount_rubles)} ₽\n"
|
||||
f"💳 Способ оплаты: Tribute\n"
|
||||
f"🎉 Средства зачислены на баланс!\n\n"
|
||||
f"Спасибо за оплату! 🙏"
|
||||
@@ -277,7 +277,7 @@ class TributeService:
|
||||
|
||||
text = (
|
||||
f"🔄 **Возврат средств**\n\n"
|
||||
f"💰 Сумма возврата: {amount_rubles:.2f} ₽\n"
|
||||
f"💰 Сумма возврата: {int(amount_rubles)} ₽\n"
|
||||
f"💳 Способ: Tribute\n\n"
|
||||
f"Средства будут возвращены на вашу карту в течение 3-5 рабочих дней.\n\n"
|
||||
f"Если у вас есть вопросы, обратитесь в поддержку."
|
||||
|
||||
@@ -25,3 +25,4 @@ APScheduler==3.10.4
|
||||
python-dateutil==2.8.2
|
||||
pytz==2023.4
|
||||
cryptography>=41.0.0
|
||||
qrcode[pil]==7.4.2
|
||||
|
||||
Reference in New Issue
Block a user