资讯详情

资讯详情

aiogram 基于类的 PreCheckoutQueryHandler 处理器:从注册到应答的完整实践指南

后端即时通讯API设计【免费下载链接】aiogramaiogram is a modern and fully asynchronous framework for Telegram Bot API written in Python using asyncio项目地址https://gitcode.com/gh_mirrors/ai/aiogram点击查看免费下载导读预结算查询Pre-Checkout Query是 Telegram Bot API 支付流程中用户在确认支付与配送信息之后、真正扣款之前发送给机器人的最后一个校验节点。本文基于 aiogram 官方文档 pre_checkout_query.rst 的核心内容围绕PreCheckoutQueryHandler这一基于类的处理器展开先说明其注册方式与继承自BaseHandler的扩展能力再结合仓库源码与测试用例深入讲解事件对象PreCheckoutQuery的字段结构、应答方法answer()以及与之配套的函数式写法帮助你在机器人支付链路中可靠地完成库存校验与订单确认。一、什么是 PreCheckoutQueryHandlerPreCheckoutQueryHandler是 aiogram 为预结算查询事件提供的基于类的处理器基类定义于 aiogram/handlers/pre_checkout_query.pyfrom abc import ABC from aiogram.handlers import BaseHandler from aiogram.types import PreCheckoutQuery, User class PreCheckoutQueryHandler(BaseHandler[PreCheckoutQuery], ABC): Base class for pre-checkout handlers property def from_user(self) - User: return self.event.from_user从源码结构可以看到三个关键信息它是一个泛型子类泛型参数为PreCheckoutQuery因此self.event被类型标注为PreCheckoutQuery对象它被声明为ABC抽象基类继承者必须实现async def handle()方法才能实例化使用它通过from_user属性对self.event.from_user做了别名这是文档中提到的“扩展”Extension之一。该处理器与 ShippingQueryHandler 的实现模式完全一致ShippingQueryHandler同样只增加了from_user别名可见这是一组为支付类事件统一设计的快捷属性。二、简单用法三步注册一个预结算处理器官方文档给出了最精简的用法from aiogram.handlers import PreCheckoutQueryHandler ... router.pre_checkout_query() class MyHandler(PreCheckoutQueryHandler): async def handle(self) - Any: ...这里router.pre_checkout_query()是类装饰器用法。结合源码 aiogram/dispatcher/router.py 可以看到Router在初始化时便创建了名为pre_checkout_query的TelegramEventObserverself.pre_checkout_query TelegramEventObserver( routerself, event_namepre_checkout_query, )因此router.pre_checkout_query直接对应 Bot API 更新中的pre_checkout_query事件字段。当被装饰的类实例通过__await__协议把执行委托给handle()方法见 base.py事件分发引擎便可以在过滤器全部通过后直接await这个类实例。实际运行时TelegramEventObserver.trigger()会对每个已注册 handler 依次执行过滤器检查、包裹中间件并调用处理逻辑见 telegram.py命中后立即返回、停止继续传播。三、Extension继承 BaseHandler 后自带的能力官方文档明确指出PreCheckoutQueryHandler是BaseHandler的子类并带有扩展属性self.from_user。这一节把这两点拆开讲透。3.1 BaseHandler 提供的通用基础设施BaseHandler定义在 aiogram/handlers/base.py它是所有基于类处理器的共同基类详见 class_based_handlers/base.rst默认构造器会自动接收事件与全部上下文数据无需覆写def __init__(self, event: T, **kwargs: Any) - None: self.event: T event self.data: dict[str, Any] kwargs由此每个子类实例都会获得以下成员self.event当前分发进来的PreCheckoutQuery事件对象self.data携带的上下文字典包含bot、update等键self.bot从上下文中解析出的Bot实例若不存在则抛出RuntimeErrorself.update当前完整Update对象async def handle()必须由子类实现的抽象方法返回值即处理器结果。测试用例 tests/test_handler/test_base.py 对上述行为逐一做了验证例如handler.event event、handler.data[key] 42、await handler 42以及 bot 缺失时抛出RuntimeError等。3.2 from_user 属性别名PreCheckoutQueryHandler扩展的from_user是self.event.from_user的类型化快捷方式其正确性由仓库测试 tests/test_handler/test_pre_checkout_query.py 直接印证class MyHandler(PreCheckoutQueryHandler): async def handle(self) - Any: assert self.event event assert self.from_user self.event.from_user return True assert await MyHandler(event)因此在处理逻辑中你可以直接用self.from_user拿到发起支付的用户而不必每次写self.event.from_user。四、深入事件对象PreCheckoutQuery 的关键字段要正确实现支付确认逻辑需要清楚self.event即PreCheckoutQuery携带了哪些数据。其完整字段定义在 aiogram/types/pre_checkout_query.py核心字段如下字段类型说明idstr预结算查询的唯一标识符from_userUser发起支付的用户序列化别名fromcurrencystr三位 ISO 4217 货币代码Telegram Stars 支付时为XTRtotal_amountint以货币最小单位表示的订单总价整数非浮点。例如US$ 1.45应传145invoice_payloadstr机器人下发票时自定义的负载字符串用于关联订单shipping_option_idstr \| None可选用户选择的配送选项标识符有配送时才有order_infoOrderInfo \| None可选用户提交的订单信息from_user通过 pydantic 的Field(..., aliasfrom)映射 Bot API 中的from字段因此在构造或测试时以from_user为参数名序列化时会自动转换为 Telegram 要求的from。五、应答预结算查询answer() 方法收到预结算查询后机器人必须在10 秒内调用AnswerPreCheckoutQuery方法给出应答否则支付流程会失败。PreCheckoutQuery对象内置了便捷方法answer()源码见 pre_checkout_query.py它会自动填充pre_checkout_query_iddef answer( self, ok: bool, error_message: str | None None, **kwargs: Any, ) - AnswerPreCheckoutQuery: return AnswerPreCheckoutQuery( pre_checkout_query_idself.id, okok, error_messageerror_message, **kwargs, ).as_(self._bot)okTrue一切正常商品有货等机器人准备继续处理订单okFalse存在任何问题此时必须提供error_messageTelegram 会将该人类可读的错误原因展示给用户例如“商品已售罄请更换颜色或款式”。该方法返回的是AnswerPreCheckoutQuery方法对象定义于 aiogram/methods/answer_pre_checkout_query.py通过.as_(self._bot)绑定到当前 bot 后即可await执行。仓库测试 tests/test_api/test_types/test_pre_checkout_query.py 验证了answer()生成的AnswerPreCheckoutQuery实例确实携带了pre_checkout_query_id及透传的ok、error_message而 tests/test_api/test_methods/test_answer_pre_checkout_query.py 则验证了bot.answer_pre_checkout_query(...)底层调用的正确性。六、完整实践基于类的支付确认处理器结合上面所有要点一个完整的基于类实现的预结算处理器如下from typing import Any from aiogram import Router from aiogram.handlers import PreCheckoutQueryHandler router Router() # 模拟库存实际项目中应查询数据库 GOODS {demo: 1, another: 0} router.pre_checkout_query() class PreCheckoutHandler(PreCheckoutQueryHandler): async def handle(self) - Any: stock GOODS.get(self.event.invoice_payload, 0) if stock 0: await self.event.answer(okTrue) # 确认可以扣款 return True # 拒绝支付并给出对用户友好的原因 await self.event.answer(okFalse, error_message商品已售罄请稍后再试) return False要点回顾用router.pre_checkout_query()装饰类即可完成注册类在分发时会被当作可等待对象执行handle()通过self.event.invoice_payload关联到下单时的业务负载做库存/订单校验通过self.event.answer(ok...)在 10 秒窗口内给出最终确认或拒绝校验失败必须附带error_message便于用户理解失败原因。七、补充函数式写法的对照基于类的处理器与 aiogram 的函数式注册是可以并存的两种风格。仓库自带的支付示例 examples/stars_invoice.py 给出了函数式写法作为对照invoices_router.pre_checkout_query(F.invoice_payload demo) async def pre_checkout_query(query: PreCheckoutQuery) - None: # if your product is available for sale, # confirm that you are ready to accept payment if GOODS.get(query.invoice_payload) 0: await query.answer(okTrue) else: await query.answer(okFalse, error_messageThe product is out of stock)该示例还展示了完整支付链路的其他环节用message.answer_invoice(...)发起发票货币为XTR时即 Telegram Stars 支付、用F.invoice_payload过滤器只处理特定订单、以及支付成功后通过bot.refund_star_payment(...)退款。无论函数式还是基于类query.answer()/self.event.answer()的应答语义完全一致。八、小结PreCheckoutQueryHandler是 aiogram 为支付类事件提供的基于类处理器基类使用流程可以概括为注册router.pre_checkout_query()装饰自定义类继承与扩展继承BaseHandler获得event、data、bot、update等基础设施并额外获得from_user别名见 pre_checkout_query.py业务校验读取PreCheckoutQuery的invoice_payload、total_amount、currency等字段确认订单应答在 10 秒内调用self.event.answer(ok...)确认或拒绝支付。对于需要复用支付逻辑、组合继承与 mixin 的复杂项目基于类的写法能显著提升代码的组织性与可测试性仓库中 tests/test_handler/test_pre_checkout_query.py 的测试模式也可以直接借鉴到自己的测试套件中。赞分享后端即时通讯API设计【免费下载链接】aiogramaiogram is a modern and fully asynchronous framework for Telegram Bot API written in Python using asyncio项目地址https://gitcode.com/gh_mirrors/ai/aiogram点击查看免费下载相关推荐aiogram 类处理器之 PollHandler基于类的轮询Poll事件处理完整指南aiogram 类处理器之 PollHandler基于类的轮询Poll事件处理完整指南 在 aiogram 中除了函数式处理器 async def 回后端即时通讯API设计aiogram 基于类的处理器Class-based Handlers全面指南从 BaseHandler 到可复用的事件处理架构aiogram 基于类的处理器Class based Handlers全面指南从 BaseHandler 到可复用的事件处理架构 在 aiogram 中后端即时通讯API设计aiogram 类式错误处理器 ErrorHandler从装饰器到 handle() 的完整异常处理方案aiogram 类式错误处理器 ErrorHandler从装饰器到 handle 的完整异常处理方案 导读 本文围绕 docs/dispatcher/clas后端即时通讯API设计上一篇Golem服务依赖管理组件间通信的版本兼容性保障下一篇GitHub_Trending/rea/react-conf-appReact 项目中的数据迁移策略创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →