@saultarvitz

Как реализовать оплату в боте через ЮKassa?

Есть код, пробовал реализовать оплату через Юкассу. Не доходит до функции pay(), да и в принципе уже устал что-то пробовать. Что я делаю не так?
import json
from loader import PAYMENTS_TOKEN, bot
from Tools.i18n.msgfmt import MESSAGES
from aiogram import types
from yookassa import Configuration, Payment
from data import config
Configuration.account_id = config.SHOP_ID
Configuration.secret_key = config.SHOP_API_TOKEN
from Tools.i18n.msgfmt import MESSAGES
from aiogram import types, Dispatcher
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters import Regexp
from aiogram.dispatcher.filters.state import StatesGroup, State
from aiogram.types import ContentType
from loader import PAYMENTS_TOKEN
from utils.db_api import sqlite
from keyboards.inline.choice_button import get_payment_keyboard, get_keyboard_for_finish
from data.payments import create_payment_form
from .register_purchase import register_purchase
from loader import dp, bot
from src.const import const_ru
from data.strings import create_comment, get_pay_message


class PurchaseCreator(StatesGroup):
    item_count = State()
    select_pay = State()
    pay = State()
    check_purchase = State()


async def select_count(message: types.Message, item_id):
    """
    Клавиатура для выбора количества товаров

    :param message:
    :param item_id: id выброанного товара
    :return:
    """
    await PurchaseCreator.item_count.set()

    item_count = sqlite.get_item_count(item_id)

    state = Dispatcher.get_current().current_state()
    await state.update_data(item_id=item_id)

    keyboard = types.InlineKeyboardMarkup(row_width=5)

    i = 1
    btn_list = []
    btn_list.append(types.InlineKeyboardButton(text=f"{str(i)} шт.", callback_data=f"select_count={str(i)}"))
    await state.update_data(max_count=item_count)
    keyboard.add(*btn_list)
    keyboard.add(types.InlineKeyboardButton(text=const_ru['cancel_buy'], callback_data="cancel_buy"))

    await message.answer(" Введите необходимое количество товара", reply_markup=keyboard)


@dp.callback_query_handler(Regexp("select_count"), state=PurchaseCreator.item_count)
async def get_count_keyboard(call: types.CallbackQuery, state: FSMContext):
    """
    Количество товара из клавиатуры

    :param call:
    :param state:
    :return:
    """
    await call.message.delete()

    await state.update_data(count=int(call.data.split("=")[1]))
    await select_pay(call.message, state)




@dp.message_handler(state=PurchaseCreator.item_count)
async def check_count(message: types.Message, state: FSMContext):
    """
    Проверка количества товара

    :param message:
    :param state:
    :return:
    """
    data = await state.get_data()

    max_count = data['max_count']
    count = message.text

    if count.isdigit() and int(count) <= max_count:
        count = int(count)
    else:
        await message.answer("❗️ Некорректное значение")
        return

    await state.update_data(count=count)
    await select_pay(message, state)


@dp.message_handler(state=PurchaseCreator.check_purchase)
async def select_pay(message: types.Message, state: FSMContext):
    """
    Выбор оплаты

    :param message:
    :param state:
    :return:
    """
    keyboard = get_payment_keyboard()
    length = len(json.loads(keyboard.as_json())["inline_keyboard"])
    if length > 0:
        keyboard.row(types.InlineKeyboardButton(text=const_ru['cancel_buy'], callback_data="cancel_buy"))
        await message.answer(" Выберите способ покупки", reply_markup=keyboard)
        await PurchaseCreator.next()
    else:
        await message.answer(" К сожалению, оплата в данный момент не работает",
                             reply_markup=get_keyboard_for_finish(message.chat.id))
        await state.finish()


@dp.callback_query_handler(Regexp("payment"), state=PurchaseCreator.select_pay)
async def payment(call: types.CallbackQuery, state: FSMContext):
    await call.message.delete()
    call_data = call.data.split("=")

    await state.update_data(payment=call_data[1])
    await create_purchase(call.message, state)


async def create_purchase(message: types.Message, state: FSMContext):
    """
    Обработка покупки

    :param message:
    :param state:
    :return:
    """
    data = await state.get_data()
    comment = create_comment()
    payment_type = data['payment']
    item_data = sqlite.get_item(data['item_id'])
    amount = item_data[4] * int(data['count'])
    print(amount, "\n", comment)

    keyboard = types.InlineKeyboardMarkup()
    keyboard.row(types.InlineKeyboardButton(text=const_ru['buy_item']),
                 types.InlineKeyboardButton(text=const_ru['check_buy'], callback_data="check_buy"))

    keyboard.row(types.InlineKeyboardButton(text=const_ru['cancel_buy'], callback_data="cancel_buy"))
    await state.update_data(amount=amount)
    await state.update_data(comment=comment)
    await PurchaseCreator.next()

@dp.message_handler(state=PurchaseCreator.pay)
async def pay(message: types.CallbackQuery, state: FSMContext):
    print(123123123)
    value = await state.get_data()
    payment = Payment.create({
        "amount": {
            "value": value['amount'],
        "currency": "RUB"
    },
        "payment_method_data": {
        "type": "bank_card"
    },
    "confirmation": {
        "type": "redirect",
        "return_url": ""
    },
    "capture": True,
    "description": value['item_id']
    })
    payment_data = json.loads(payment.json())
    await message.answer(f"Вот ваша ссылка для оплаты: \n{(payment_data['confirmation'])['confirmation_url']}")
@dp.message_handler(content_types=ContentType.SUCCESSFUL_PAYMENT)
async def process_successful_payment(message: types.Message, state: FSMContext):
    print('successful_payment:')
    pmnt = message.successful_payment.to_python()
    for key, val in pmnt.items():
        print(f'{key} = {val}')

    await bot.send_message(
        message.chat.id,
        MESSAGES['successful_payment'].format(
            total_amount=message.successful_payment.total_amount // 100,
            currency=message.successful_payment.currency
        )
    )
    data = await state.get_data()
    await register_purchase(message, data, True)
@dp.callback_query_handler(Regexp("check_buy"), state=PurchaseCreator.check_purchase)
async def check_purchase(call: types.CallbackQuery, state: FSMContext):
    """
    Проверка покупки

    :param call:
    :param state:
    :return:
    """
    data = await state.get_data()

    await register_purchase(call.message, data)


@dp.callback_query_handler(Regexp("cancel_buy"), state=PurchaseCreator)
async def cancel_buy(call: types.CallbackQuery):
    """
    Отмена покупки

    :param call:
    :return:
    """
    await call.message.delete()
    await call.message.answer("❗️ Покупка отменена")

    state = Dispatcher.get_current().current_state()
    await state.finish()
  • Вопрос задан
  • 398 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы