- 金融科技
- 后端
【免费下载链接】pay
可能是我用过的最优雅的 Alipay/WeChat/Douyin/Unipay/江苏银行 的支付 SDK 扩展包了
本篇指南聚焦yansongda/pay抖音支付(通用交易系统 trade_basic)的订单查询能力:一次Pay::douyin()->query($order)调用,通过_action参数即可分发到订单查询、CPS 信息查询与退款单查询三类官方接口。读完本文,你将掌握三类查询的完整调用方式、必填参数规则、返回值形态,以及查询背后的插件管线与源码级实现原理,可直接用于对账、风控与售后等真实业务场景。
1. 方法总览:一个 query 方法,三类查询能力
抖音通用交易系统的查询统一由query方法完成,方法签名如下:
| 方法名 | 参数 | 返回值 |
|---|---|---|
| query | array $order | Collection |
查询目标通过$order参数中的_action键分发(不传时默认查询订单),对应关系如下:
_action | 说明 | 对应官方 API 端点 |
|---|---|---|
order(默认) | 查询订单 | /api/trade_basic/v1/developer/order_query/ |
cps | 查询 CPS | /api/trade_basic/v1/developer/query_cps/ |
refund | 查询退款单 | /api/trade_basic/v1/developer/refund_query/ |
从源码看,分发逻辑实现在 QueryShortcut.php 中:getPlugins()通过match表达式按_action值匹配,_action缺省时取DouyinAction::QUERY_DEFAULT(即default),与order等价;非法_action会抛出InvalidParamsException,错误码为PARAMS_SHORTCUT_ACTION_INVALID。全部合法取值定义在 DouyinAction.php:QUERY_DEFAULT = 'default'、QUERY_ORDER = 'order'、QUERY_CPS = 'cps'、QUERY_REFUND = 'refund'。
2. 查询支付订单(order,默认)
不传_action或显式传_action => 'order'均查询订单:
Pay::config($config); $order = [ 'out_order_no' => '202408040747147327', // '_action' => 'order', // 查询订单,默认 ]; $result = Pay::douyin()->query($order);2.1 订单配置参数
order_id(抖音侧订单号)与out_order_no(商户侧订单号)二选一必填,其余参数与官方接口无任何差别,兼容所有功能字段。全部参数请参考官方「查询订单」接口的「请求参数」一栏(对应端点order_query)。
需要强调的是,SDK 对业务字段采取全量透传策略:查询插件只负责设置请求方法与请求地址,不注入、不篡改任何业务字段。这一点在 QueryPlugin.php 中体现得十分明确——assembly()仅向 payload 合并_method与_url两个键;测试 QueryPluginTest.php 也断言了传入order_id后 payload 中仅新增_method/_url,不会出现app_id等多余字段,保证与官方请求参数一一对应。
3. 查询 CPS 信息(cps)
Pay::config($config); $order = [ 'out_order_no' => '202408040747147327', '_action' => 'cps', ]; $result = Pay::douyin()->query($order);3.1 订单配置参数
与订单查询一致,order_id与out_order_no二选一必填,其余参数参照官方「查询 CPS」接口的「请求参数」一栏(端点query_cps)。实现上由 QueryCpsPlugin.php 完成,行为与QueryPlugin完全相同:仅设置POST方法与/api/trade_basic/v1/developer/query_cps/地址,业务字段透传。
4. 查询退款订单(refund)
Pay::config($config); $order = [ 'out_refund_no' => '202408040747147327R', '_action' => 'refund', ]; $result = Pay::douyin()->query($order);4.1 订单配置参数
退款查询的必填参数为三选一:
refund_id(抖音侧退款单号);out_refund_no(商户侧退款单号);order_id(抖音侧订单号,按订单查询上限 50 条)。
其余参数参照官方「查询退款」接口的「请求参数」一栏(端点refund_query)。
与订单/CPS 查询不同的是,退款查询插件 Refund/QueryPlugin.php 增加了参数非空校验:若 payload 经filter_params过滤后为空,会直接抛出InvalidParamsException,错误码PARAMS_NECESSARY_PARAMS_MISSING(提示"缺少必要的业务参数"),避免向官方发送无意义的空请求。
5. 底层实现:查询管线与源码剖析
5.1 插件管线
query方法在 Provider/Douyin.php 中先派发MethodCalled事件,再经__call('query', ...)动态加载QueryShortcut并组装插件管线。三类查询对应的管线均由 QueryShortcut.php 返回,以订单查询为例:
StartPlugin → ObtainClientTokenPlugin → QueryPlugin → AddPayloadBodyPlugin → AddRadarPlugin → ResponsePlugin → ParserPluginCPS 与退款查询仅将中间的QueryPlugin替换为QueryCpsPlugin/Refund\QueryPlugin,其余环节完全一致。这一结构在 QueryShortcutTest.php 中被逐条断言,五个用例分别验证了默认、order、cps、refund 的插件链以及非法_action抛异常。
各环节职责如下:
StartPlugin:初始化 Rocket 与运行环境;ObtainClientTokenPlugin:注入client_token(优先使用params['_access_token']外部注入,否则自动获取并进程内缓存),对应 all.md 中的基础插件说明;- 业务插件(QueryPlugin / QueryCpsPlugin / Refund\QueryPlugin):设置端点与请求方法;
AddPayloadBodyPlugin:组装请求体;AddRadarPlugin:构建请求,注入access-token请求头并序列化 JSON body(_body优先);ResponsePlugin:校验响应,要求 HTTP 2xx 且顶层err_no === 0,异常消息取err_msg ?? err_tips;ParserPlugin:将响应解析为Collection返回。
5.2 client_token 的获取与缓存
查询类接口需要携带access-token请求头完成鉴权,token 的获取逻辑位于 DouyinTrait.php 的getDouyinClientToken():
- 端点
POST /oauth/client_token/,请求体包含grant_type=client_credential、client_key、client_secret; - 子调用管线为
[StartPlugin, GetClientTokenPlugin, AddRadarPlugin, ParserPlugin],仅传最小参数集(仅_config),避免业务字段混入 token 请求体; - 结果按
app_id缓存在静态数组$clientTokens中,expires_in(默认 7200 秒)提前 60 秒过期; - 若业务方自建了共享缓存,可通过
params['_access_token']外部注入 token,优先级高于自动获取。
5.3 请求地址与沙盒注意事项
业务端点统一为POST /api/trade_basic/v1/developer/<name>/形式(注意尾斜杠),域名由mode决定,定义在 Provider/Douyin.php 的URL常量中:normal与service指向https://open.douyin.com,sandbox指向https://open-sandbox.douyin.com。
重要限制:trade_basic业务接口没有沙盒环境。MODE_SANDBOX会把包括查询在内的全部请求指向open-sandbox.douyin.com,该域名并未部署trade_basic服务,仅适合验证client_token获取。真实查询请使用MODE_NORMAL,详见 快速入门。
6. 配置要求:纯查询用户的最小配置
抖音查询所需的配置项定义在 DouyinConfig.php,与通用交易系统保持一致:
"douyin": { "default": { "app_id": "ttxxxxxx", // 必填,client_key(即小程序 appid) "app_secret": "xxx", // 必填,获取 client_token "app_private_key": "-----BEGIN ...", // 应用私钥,下单加签用(纯查询无需配置) "douyin_public_key": "-----BEGIN ...", // 平台公钥,回调验签用(纯查询无需配置) "notify_url": "https://xx/notify", // 选填,支付/退款回调默认地址 "mode": 0 } }必填校验仅包含app_id+app_secret(缺失时抛CONFIG_DOUYIN_INVALID,错误码 9405);两把 RSA 密钥在使用点校验,因此只做查询、不做下单与回调的业务方无需配置私钥与平台公钥,这是查询链路相对下单/回调更轻量的关键设计。
7. 返回值与事件
查询成功返回Collection类型,即官方响应的解析结果(含err_no/err_msg/log_id及业务数据data),可直接链式取用,例如:
$result = Pay::douyin()->query($order); $outOrderNo = $result->get('data.out_order_no'); // 按实际响应结构取字段同时,Provider\Douyin::query()在每次调用时会派发MethodCalled事件(对应 MethodCalled.php),可用于链路日志与埋点观测;若需更深层的请求/响应追踪,还可借助 HttpStart.php 与 HttpEnd.php 事件。关于抖音回调、退款等周边能力,可进一步阅读 douyin-trade-system.md(通用交易系统完整设计说明)与 all.md(全部可用插件清单)。
8. 常见问题速查
- 三个接口请求参数记不住怎么办?记住口诀:订单/CPS 查询
order_id与out_order_no二选一;退款查询refund_id、out_refund_no、order_id三选一(按订单查上限 50 条)。 - 传了非法
_action会怎样?抛出InvalidParamsException(PARAMS_SHORTCUT_ACTION_INVALID),提示"不支持的 _action"。 - 查询报
PARAMS_NECESSARY_PARAMS_MISSING?常见于_action=refund且三选一参数全部缺失,补充任一退款/订单号即可。 - 沙盒模式查不到数据?属预期行为,
trade_basic无沙盒部署,请切回正式环境mode: 0。 - 高并发下 token 被频控?进程内缓存按
app_id提前 60 秒过期,官方频控约为 5 分钟 500 次;可通过_access_token外部注入接入 Redis 等共享缓存。
至此,抖音通用交易系统的三类查询已全部打通:一个入口方法、一个_action参数、一组清晰的必填规则,配合源码级的插件管线理解,足以应对订单对账、CPS 结算核对与退款状态轮询等绝大多数生产场景。
- 金融科技
- 后端
【免费下载链接】pay
可能是我用过的最优雅的 Alipay/WeChat/Douyin/Unipay/江苏银行 的支付 SDK 扩展包了
相关推荐
yansongda/pay 江苏银行 e融支付订单查询实战:query() 查询交易支付订单与退款订单
yansongda/pay 江苏银行 e融支付订单查询实战:query 查询交易支付订单与退款订单 本篇技术指南围绕 yansongda/pay 扩展包中江苏银
金融科技后端yansongda/pay 抖音小程序支付实战:通用交易系统(trade_basic)JSAPI 下单签名指南
yansongda/pay 抖音小程序支付实战:通用交易系统(trade_basic)JSAPI 下单签名指南 本篇技术指南聚焦 yansongda/pay 中
金融科技后端yansongda/pay 抖音快速入门:通用交易系统小程序支付集成实战
yansongda/pay 抖音快速入门:通用交易系统小程序支付集成实战 本篇技术指南围绕 yansongda/pay v3.8 起的抖音「通用交易系统」(tr
金融科技后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考