Aiogram 3.3.0调用send_invoice无响应无报错,支付界面不弹出求助
问题描述
为机器人添加订阅支付功能,参考示例和文档后未发现明显错误。发送/payment命令时,仅收到文本消息Your order payment,调用send_invoice()后完全无反应:既不弹出支付界面,也无任何报错信息。
项目结构
/ |- handlers | |- bot_message.py |- main.py
代码片段
bot_messages.py
from aiogram import Router,F,Bot from aiogram.types import ( Message, ContentType, LabeledPrice, PreCheckoutQuery ) from aiogram.filters import ( Command ) @router.message(Command(commands="payment")) async def pay(message:Message,bot=Bot): print("pay send") await bot.send_message(message.chat.id,f"Your order payment") # 仅收到此消息 await bot.send_invoice( chat_id= message.chat.id, title="title", description="desc_test", payload=f'test-invoice-payload', provider_token='TEST_TOKEN', currency='USD', prices=[ LabeledPrice( label='Sub month', amount=299*100 ) ], max_tip_amount=100*100, suggested_tip_amounts=[100*100,300*100], start_parameter=f'testpaymentbot', provider_data=None, need_email=True, need_phone_number=True, need_name=True, need_shipping_address=False, send_phone_number_to_provider=False, send_email_to_provider=False, is_flexible=False, disable_notification=False, protect_content=True, reply_to_message_id=None, allow_sending_without_reply=True, reply_markup=None, request_timeout=30 ) @router.pre_checkout_query() async def process_pre_checkout_query(pre_checkout_query: PreCheckoutQuery, bot: Bot): if pre_checkout_query.invoice_payload != "test_payload": await bot.answer_pre_checkout_query(pre_checkout_query.id, ok=False, error_message="errors gere...") else: await bot.answer_pre_checkout_query(pre_checkout_query.id, ok=True) @router.message(F.content_type == ContentType.SUCCESSFUL_PAYMENT) async def succesfull_payment(message: Message): print("succesfull_payment activate") msg = f"Thank you for sub {message.successful_payment.total_amount // 100} {message.successful_payment.currency}!" await message.answer(msg)
main.py
from handlers import bot_messages async def main() -> None: try: bot = Bot(token=f"{conf.bot_token}",parse_mode="HTML") dp = Dispatcher() dp.include_routers( bot_messages.router ) logger_bot.info("Bot initialization succesful!") except (Exception,AiogramError) as _ex: logger_bot.critical(f"Can't initilize bot! Error: {_ex}") try: await bot.delete_webhook(drop_pending_updates=True) logger_bot.info(f"Bot start succesful! {bot.id}|{bot.get_my_name}") await dp.start_polling(bot) except (Exception,AiogramError) as _ex: logger_bot.critical(f"Can't start bot! Error: {_ex}") return None if __name__ == "__main__": asyncio.run(main())
已尝试的操作
- 更换不同支付提供商(如PayMaster),仍无响应且无报错
- 尝试使用
create_invoice_link()替代send_invoice() - 确认金额已乘以100转换为最小货币单位
排查步骤及解决方案
捕获
send_invoice的异常信息
当前代码未对send_invoice()做异常处理,可能错误被静默吞掉。修改pay函数,添加try-except块打印错误:async def pay(message:Message,bot: Bot): print("pay send") await bot.send_message(message.chat.id,f"Your order payment") try: await bot.send_invoice(...) # 保留原参数不变 except Exception as e: print(f"send_invoice error: {e}") await message.answer(f"支付发起失败: {str(e)}")修正Payload匹配问题
send_invoice中设置的payload是test-invoice-payload,但pre_checkout_query处理函数中判断的是test_payload,两者不匹配。后续即使支付弹窗出现,也会被拒绝。需统一两者的payload值:# send_invoice里的payload改为"test_payload" payload=f'test_payload',检查Provider Token有效性
- 若使用测试环境,确保
TEST_TOKEN是支付提供商提供的有效测试token,且机器人已在提供商后台完成绑定。 - 若为正式环境,必须使用真实的生产token,且完成所有资质审核步骤。
- 若使用测试环境,确保
调整
protect_content参数
当前protect_content=True会隐藏消息内容,导致支付弹窗无法显示。先改为False测试:protect_content=False,修正Bot参数注入
pay函数中bot=Bot的写法错误,应使用类型注解bot: Bot,确保Aiogram正确注入Bot实例:async def pay(message:Message,bot: Bot):验证机器人支付权限
前往BotFather,确认已为机器人配置支付提供商:发送/mybots选择对应机器人,进入Bot Settings->Payments,检查是否已绑定正确的支付服务。测试环境限制
部分支付提供商的测试token仅支持私有聊天(机器人与用户一对一对话),若在群组中测试可能无法正常弹出支付界面,切换到私有聊天重试。
内容的提问来源于stack exchange,提问作者максим огуенко

