From bc138e00d0dc8e2c0815485c8d0a0e6aa943350d Mon Sep 17 00:00:00 2001 From: Redsandyg Date: Fri, 13 Jun 2025 14:12:56 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D1=81=D0=BE=D1=81=D1=82=D0=BE=D1=8F=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=B4=D0=BB=D1=8F=20=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4?= =?UTF-8?q?=D0=B0=20=D1=81=D1=80=D0=B5=D0=B4=D1=81=D1=82=D0=B2=20=D0=B8=20?= =?UTF-8?q?=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B0=20=D0=BE=D0=B1?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B8=20=D0=B7=D0=B0=D0=BF?= =?UTF-8?q?=D1=80=D0=BE=D1=81=D0=B0=20=D0=BD=D0=B0=20=D0=B2=D1=8B=D0=B2?= =?UTF-8?q?=D0=BE=D0=B4.=20=D0=9F=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=20=D1=82=D0=B5=D0=BF=D0=B5=D1=80?= =?UTF-8?q?=D1=8C=20=D0=BC=D0=BE=D0=B6=D0=B5=D1=82=20=D0=B2=D0=B2=D0=BE?= =?UTF-8?q?=D0=B4=D0=B8=D1=82=D1=8C=20=D1=81=D1=83=D0=BC=D0=BC=D1=83=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4=D0=B0,=20?= =?UTF-8?q?=D0=B0=20=D1=82=D0=B0=D0=BA=D0=B6=D0=B5=20=D0=BE=D0=B1=D1=80?= =?UTF-8?q?=D0=B0=D0=B1=D0=B0=D1=82=D1=8B=D0=B2=D0=B0=D1=8E=D1=82=D1=81?= =?UTF-8?q?=D1=8F=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B8=20=D0=B2=D0=B2?= =?UTF-8?q?=D0=BE=D0=B4=D0=B0=20=D0=B8=20=D0=BF=D0=BE=D0=B4=D0=BA=D0=BB?= =?UTF-8?q?=D1=8E=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BA=20API.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 244a4c2..108c1a6 100644 --- a/main.py +++ b/main.py @@ -175,6 +175,9 @@ class LinkStates(StatesGroup): waiting_for_description = State() link_created = State() +class WithdrawStates(StatesGroup): + waiting_for_amount = State() + @dp.callback_query(F.data == 'create_link') async def create_link(callback: types.CallbackQuery, state: FSMContext): sent = await callback.message.edit_text( @@ -242,8 +245,86 @@ async def back_to_links_from_success(callback: types.CallbackQuery, state: FSMCo await callback.answer() @dp.callback_query(F.data == 'withdraw') -async def not_implemented_withdraw(callback: types.CallbackQuery): - await callback.answer('Функция вывода средств пока не реализована.', show_alert=True) +async def withdraw_funds(callback: types.CallbackQuery, state: FSMContext): + """ + Запрашивает сумму для вывода средств. + """ + sent = await callback.message.edit_text( + 'Введите сумму для вывода:', + reply_markup=InlineKeyboardMarkup( + inline_keyboard=[[InlineKeyboardButton(text='Назад', callback_data='back_to_main_from_withdraw')]] + ) + ) + await state.set_state(WithdrawStates.waiting_for_amount) + await state.update_data(withdraw_msg_id=sent.message_id) + await callback.answer() + +@dp.callback_query(F.data == 'back_to_main_from_withdraw', WithdrawStates.waiting_for_amount) +async def back_to_main_from_withdraw(callback: types.CallbackQuery, state: FSMContext): + await callback.message.edit_text(WELCOME_TEXT, reply_markup=main_keyboard) + await state.clear() + await callback.answer() + +@dp.message(WithdrawStates.waiting_for_amount) +async def process_withdraw_amount(message: types.Message, state: FSMContext): + try: + amount = float(message.text.strip()) + if amount <= 0: + await message.answer('Сумма для вывода должна быть положительной.') + return + except ValueError: + await message.answer('Пожалуйста, введите корректное число для суммы.') + return + + tg_id = message.from_user.id + token = user_tokens.get(tg_id) + + if not token: + await message.answer('Ошибка авторизации. Пожалуйста, перезапустите бота командой /start.') + await state.clear() + return + + headers = {"Authorization": f"Bearer {token}"} + data = await state.get_data() + withdraw_msg_id = data.get('withdraw_msg_id') + + if withdraw_msg_id: + try: + await message.bot.edit_message_reply_markup( + chat_id=message.chat.id, + message_id=withdraw_msg_id, + reply_markup=None + ) + except Exception: + pass + + async with aiohttp.ClientSession() as session: + try: + async with session.post(f'{API_URL}/withdraw', json={'tg_id': tg_id, 'amount': amount}, headers=headers) as resp: + if resp.status == 200: + response_data = await resp.json() + transaction_id = response_data.get('transaction_id') + await message.answer( + f'Запрос на вывод средств успешно создан!\nСумма: {amount:.2f}\nID транзакции: {transaction_id}', + reply_markup=InlineKeyboardMarkup( + inline_keyboard=[[InlineKeyboardButton(text='Назад', callback_data='back_to_main')]] + ) + ) + else: + error_detail = 'Неизвестная ошибка' + try: + error_json = await resp.json() + if 'detail' in error_json: + error_detail = error_json['detail'] + except Exception: + pass + await message.answer(f'Ошибка при создании заявки на вывод средств: {error_detail}') + except aiohttp.ClientConnectorError: + await message.answer('Не удалось подключиться к серверу API. Пожалуйста, попробуйте позже.') + except Exception as e: + await message.answer(f'Произошла непредвиденная ошибка: {e}') + + await state.clear() @dp.callback_query(F.data == 'question') async def not_implemented_question(callback: types.CallbackQuery):