Какой аргумент нужно поставить первым? (aiosend + aiogram + crypto handler)

Делаю бота для покупки звезд через aiogram + aiosend. В handle_payment() принимаю 3 аргумента: invoice, state (FSM) и message. Жалуется, что пропускаю аргумент state. Ставлю такой порядок: state, invoice, message. Теперь жалуется, что пропускаю аргумент invoice. Ставлю порядок invoice, state, message - выскакивает первая ошибка.

В чем может быть проблема? Может ли быть это из-за того, что тип state - FSMContext?

Код:

import asyncio, os, requests, aiosend
from aiogram import (
    Dispatcher,
    Bot,
    Router,
    F
)
from aiogram.filters import CommandStart
from aiogram.fsm.state import (
    StatesGroup,
    State
)
from aiogram.types import (
    Message,
    InlineKeyboardButton,
    InlineKeyboardMarkup, CallbackQuery
)
from dotenv import load_dotenv
from aiogram.fsm.context import FSMContext
from aiogram.utils.chat_action import ChatActionSender
from aiosend import CryptoPay
from aiosend.types import Invoice


load_dotenv()
TOKEN = os.getenv("TOKEN")
CRYPTO_TOKEN = os.getenv("CRYPTO_TOKEN")
CRYPTOTEST_TOKEN = os.getenv("CRYPTOTEST_TOKEN")

bot = Bot(TOKEN)
dp = Dispatcher()
cp = CryptoPay(CRYPTOTEST_TOKEN, network=aiosend.TESTNET)
"""For test network"""

#cp = CryptoPay(CRYPTO_TOKEN)
"""For main network"""
router = Router()


class Form(StatesGroup):
    quantity = State()
    username = State()

@router.message(CommandStart())
async def start(message: Message):
    msg = """
Приветствуем вас в магазине ...!

На данный момент, у нас одни из самых низких цен на наши товары, так что мы с уверенностью 
можем вам сказать, что вы остановились в правильном месте. 

Пожалуйста, выберите категорию ?
        """

    keyboard = [
        [InlineKeyboardButton(text="Звёзды", callback_data="stars"),
         InlineKeyboardButton(text="Premium", callback_data="premium")],
        [InlineKeyboardButton(text="Поддержка", url="https://t.me/MYTELEGRAM")]
    ]

    reply_markup = InlineKeyboardMarkup(inline_keyboard=keyboard)

    await message.answer(msg, reply_markup=reply_markup)

@router.callback_query(F.data == "stars")
async def stars(message: CallbackQuery, state: FSMContext):
    async with ChatActionSender.typing(bot=bot, chat_id=message.message.chat.id):
        msg = """
*Введите количество звезд, которое хотите купить\.*
        """
        await message.message.answer(msg, parse_mode="markdownv2")
    await state.set_state(Form.quantity)

@router.message(F.text, Form.quantity)
async def recepient(message: Message, state: FSMContext):
    await state.update_data(quantity=int(message.text))
    async with ChatActionSender.typing(bot=bot, chat_id=message.chat.id):
        msg = """
Теперь давайте определимся, *кому* вы хотите купить звезды\?

>Вы можете купить звезды как *себе*, так и своим *друзьям* или *близким\!*"""
        reply_markup=InlineKeyboardMarkup(inline_keyboard=
            [[InlineKeyboardButton(text="Себе", callback_data="buyMe"),
            InlineKeyboardButton(text="Другу", callback_data="buyFriend")]]
        )
        await message.answer(msg, parse_mode="markdownv2", reply_markup=reply_markup)

@router.message(F.text, Form.username)
@router.callback_query(F.data == "buyMe")
async def pay(message: Message, state: FSMContext):
    #req = requests.get("https://api.coinbase.com/v2/exchange-rates?currency=TON")
    #data = req.json()
    invoice: Invoice = await cp.create_invoice(5, "TRX")
    reply_markup = InlineKeyboardMarkup(inline_keyboard=[[InlineKeyboardButton(text="Оплатить ✅", url=f"{invoice.bot_invoice_url}")]])
    data = await state.get_data()

    msg = f"""
*Новый заказ \#{invoice.invoice_id}*

? *Получатель\:* \@{message.message.chat.username if F.data == "buyMe" else data.get("username")}
? *Количество звёзд\:* {data.get("quantity")}
? *Сумма в ₽\:* {str(int(float(data["quantity"])) * 1.35).replace(".", "\.")}₽

Кнопка на оплату находится ниже ?
        """

    await message.message.answer(msg, reply_markup=reply_markup, parse_mode="markdownv2")
    invoice.poll(message=message)
    await state.clear()
    # todo: меню звезд

@router.callback_query(F.data == "buyFriend")
async def buyFriend(message: Message, state: FSMContext):
    async with ChatActionSender.typing(bot=bot, chat_id=message.chat.id):
        msg = """
*Пожалуйста, введите \@username аккаунта, которому будут отправлены звёзды\.*

> _Внимание\! Магазин не несёт ответственности за неправильно указанные данные\._
        """
        await message.answer(msg, parse_mode="markdownv2")
    await state.set_state(Form.username)

@router.message(F.text, Form.username)
async def starsF(message: Message, state: FSMContext):
    await state.update_data(username=message.text)
    async with ChatActionSender.typing(bot=bot, chat_id=message.chat.id):
        msg = """
*Введите количество звезд, которое хотите купить\.*
        """
        await message.message.answer(msg, parse_mode="markdownv2")
    await state.set_state(Form.quantity)

@cp.invoice_polling()
async def handle_payment(state: FSMContext, invoice: Invoice,  message: Message):
    global status
    if invoice.status == "paid":
        status = "Успешно ✅"
    elif invoice.status == "expired":
        status = "Просрочено ⏰"
    elif invoice.status == "active":
        status = "Ждет оплаты ?"
    data = await state.get_data()

    msg = f"""
? *Оплата заказа \#{invoice.invoice_id}*

? *Получатель\:* \@{data.get("username")}
? *Количество звёзд\:* {data.get("quantity")}
? *Сумма в ₽\:* {str(int(float(data.get("quantity"))) * 1.35).replace(".", "\.")}₽
? *Сумма в криптовалюте\:* {invoice.amount} {invoice.asset}
? *Комиссия\:* {invoice.fee_amount} {invoice.fee_asset}
? *Итого\:* {invoice.amount - invoice.fee_amount} {invoice.asset}
? *Статус\:* {status}

Звезды в скором времени будут начислены!
    """

    print(msg)
    print(f"invoice #{invoice.invoice_id} has been paid")
    await message.message.reply(msg, parse_mode="markdownv2")
    await state.clear()
    #todo: выдача звезд

async def main():
    dp.include_router(router)

    await bot.delete_webhook(True)
    await asyncio.gather(
        dp.start_polling(bot),
        cp.start_polling()
    )

if __name__ == '__main__':
    asyncio.run(main())

Ответы (1 шт):

Автор решения: VoVcHiC

На связи автор aiosend.

Чтобы в handle_payment передался state, нужно передать его в метод poll следующим образом:

invoice.poll(message=message, state=state)

Порядок аргументов при этом - invoice, state, message.

→ Ссылка