from aiogram import Router, types
from aiogram.filters import Command
from aiogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton
from decimal import Decimal
from tg_bot.config.settings import settings
from tg_bot.payment.yookassa.client import yookassa_client
from tg_bot.domain.services.user_service import UserService
from datetime import datetime
router = Router()
user_service = UserService()
@router.message(Command("buy"))
async def cmd_buy(message: Message):
user_id = message.from_user.id
username = message.from_user.username or f"user_{user_id}"
try:
user = await user_service.get_user_by_telegram_id(user_id)
if user and user.is_premium and user.premium_until and user.premium_until > datetime.now():
days_left = (user.premium_until - datetime.now()).days
await message.answer(
f"У вас уже есть активная подписка!\n\n"
f"• Статус: Premium активен\n"
f"• Действует до: {user.premium_until.strftime('%d.%m.%Y')}\n"
f"• Осталось дней: {days_left}\n\n"
f"Новая подписка будет добавлена к текущей.",
parse_mode="HTML"
)
except Exception:
pass
await message.answer(
"*Создаю ссылку для оплаты...*\n\n"
"Пожалуйста, подождите несколько секунд.",
parse_mode="Markdown"
)
try:
payment_data = await yookassa_client.create_payment(
amount=Decimal(str(settings.PAYMENT_AMOUNT)),
description=f"Подписка VibeLawyerBot для @{username}",
user_id=user_id
)
print(f"Платёж создан в ЮKассе: {payment_data['id']}")
keyboard = InlineKeyboardMarkup(
inline_keyboard=[
[
InlineKeyboardButton(
text="Оплатить онлайн",
url=payment_data["confirmation_url"]
)
],
[
InlineKeyboardButton(
text="Проверить статус оплаты",
callback_data=f"check_payment:{payment_data['id']}"
)
]
]
)
response_text = (
f"Оплата подписки VibeLawyerBot\n\n"
f"Детали платежа:\n"
f"• Сумма: {settings.PAYMENT_AMOUNT} руб.\n"
f"• Описание: Подписка на 30 дней\n"
f"• ID платежа: {payment_data['id'][:20]}...\n\n"
f"Что даёт подписка:\n"
f"• Неограниченное число вопросов\n"
f"• Приоритетная обработка\n"
f"• Доступ ко всем функциям\n\n"
f"После оплаты доступ активируется автоматически в течение 1-2 минут."
)
await message.answer(
response_text,
parse_mode="HTML",
reply_markup=keyboard,
disable_web_page_preview=True
)
await message.answer(
"Инструкция по оплате:\n\n"
"1. Нажмите кнопку 'Оплатить онлайн'\n"
"2. Введите данные банковской карты\n"
"3. Подтвердите оплату\n"
"4. После успешной оплаты нажмите 'Проверить статус оплаты'\n\n"
"Тестовые карты для проверки:\n"
"• 5555 5555 5555 4477 - успешная оплата\n"
" Срок: любой будущий (напр. 12/30)\n"
" CVV: любые 3 цифры (напр. 123)\n\n"
"Это тестовые карты, реальные деньги не списываются!",
parse_mode="HTML"
)
except Exception as e:
print(f"Ошибка создания платежа: {e}")
await message.answer(
"Произошла ошибка при создании платежа\n\n"
"Пожалуйста, попробуйте позже или обратитесь к администратору.\n\n"
f"Ошибка: {str(e)[:100]}",
parse_mode="HTML"
)
@router.callback_query(lambda c: c.data.startswith("check_payment:"))
async def check_payment_status(callback_query: types.CallbackQuery):
yookassa_id = callback_query.data.split(":")[1]
user_id = callback_query.from_user.id
await callback_query.answer("Проверяю статус оплаты...")
try:
from yookassa import Payment as YooPayment
payment = YooPayment.find_one(yookassa_id)
if payment.status == "succeeded":
try:
success = await user_service.activate_premium(user_id)
if success:
user = await user_service.get_user_by_telegram_id(user_id)
if user:
await callback_query.message.answer(
"Оплата подтверждена!\n\n"
f"Ваш premium-доступ активирован до: "
f"{user.premium_until.strftime('%d.%m.%Y') if user.premium_until else 'Не указано'}\n\n"
"Теперь вы можете:\n"
"• Задавать неограниченное количество вопросов\n"
"• Получать приоритетные ответы\n"
"• Использовать все функции бота\n\n"
"Спасибо за покупку!",
parse_mode="HTML"
)
else:
await callback_query.message.answer(
"Оплата подтверждена, но не удалось активировать premium\n\n"
"Пожалуйста, обратитесь к администратору.",
parse_mode="HTML"
)
else:
await callback_query.message.answer(
"Оплата подтверждена, но не удалось активировать premium\n\n"
"Пожалуйста, обратитесь к администратору.",
parse_mode="HTML"
)
except Exception as e:
print(f"Ошибка обработки платежа: {e}")
await callback_query.message.answer(
"Ошибка активации premium\n\n"
"Пожалуйста, обратитесь к администратору.",
parse_mode="HTML"
)
elif payment.status == "pending":
await callback_query.message.answer(
"Платёж ещё не завершён\n\n"
"Если вы уже оплатили, пожалуйста, подождите 1-2 минуты "
"и проверьте статус снова.\n\n"
"Проверьте правильность данных карты:\n"
"• Срок действия должен быть будущим\n"
"• CVV - 3 цифры на обратной стороне карты",
parse_mode="HTML"
)
else:
await callback_query.message.answer(
f"Статус платежа: {payment.status}\n\n"
"Попробуйте оплатить ещё раз или обратитесь в поддержку.\n\n"
"Для теста используйте карту:\n"
"5555 5555 5555 4477\n"
"Срок: 12/30, CVV: 123",
parse_mode="HTML"
)
except Exception as e:
print(f"Ошибка проверки статуса: {e}")
await callback_query.message.answer(
"Не удалось проверить статус платежа\n\n"
"Попробуйте позже или обратитесь к администратору.",
parse_mode="HTML"
)
@router.message(Command("mypayments"))
async def cmd_my_payments(message: Message):
await message.answer(
"История платежей\n\n"
"История платежей хранится в системе оплаты ЮKassa.\n"
"Для проверки статуса подписки используйте команду /stats.\n\n"
"Для оформления новой подписки используйте команду /buy",
parse_mode="HTML"
)
@router.message(Command("testcards"))
async def cmd_testcards(message: Message):
testcards_text = (
f"Тестовые банковские карты для оплаты\n\n"
f"Для тестирования оплаты используйте:\n\n"
f"Карта для успешной оплаты:\n"
f"• Номер: 5555 5555 5555 4477\n"
f"• Срок действия: ЛЮБОЙ будущий (например: 12/30)\n"
f"• CVV код: ЛЮБЫЕ 3 цифры (например: 123)\n"
f"• Результат: Оплата пройдёт успешно\n\n"
f"Карта для отказа в оплате:\n"
f"• Номер: 5555 5555 5555 4445\n"
f"• Срок действия: ЛЮБОЙ будущий\n"
f"• CVV код: ЛЮБЫЕ 3 цифры\n"
f"• Результат: Оплата будет отклонена\n\n"
f"Важно:\n"
f"• Это тестовые карты, реальные деньги не списываются\n"
f"• Используются только для проверки работы оплаты\n"
f"• После успешной тестовой оплаты premium активируется\n\n"
f"Для оплаты подписки используйте команду /buy"
)
await message.answer(testcards_text, parse_mode="HTML")