news 2026/10/5 6:31:37

yansongda/pay 抖音通用交易系统订单查询实战:order / cps / refund 三合一 query 接口详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
yansongda/pay 抖音通用交易系统订单查询实战:order / cps / refund 三合一 query 接口详解
  • 金融科技
  • 后端

【免费下载链接】pay

可能是我用过的最优雅的 Alipay/WeChat/Douyin/Unipay/江苏银行 的支付 SDK 扩展包了

项目地址:https://gitcode.com/gh_mirrors/pa/pay
点击查看免费下载

本篇指南聚焦yansongda/pay抖音支付(通用交易系统 trade_basic)的订单查询能力:一次Pay::douyin()->query($order)调用,通过_action参数即可分发到订单查询、CPS 信息查询与退款单查询三类官方接口。读完本文,你将掌握三类查询的完整调用方式、必填参数规则、返回值形态,以及查询背后的插件管线与源码级实现原理,可直接用于对账、风控与售后等真实业务场景。

1. 方法总览:一个 query 方法,三类查询能力

抖音通用交易系统的查询统一由query方法完成,方法签名如下:

方法名参数返回值
queryarray $orderCollection

查询目标通过$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 → ParserPlugin

CPS 与退款查询仅将中间的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 扩展包了

项目地址:https://gitcode.com/gh_mirrors/pa/pay
点击查看免费下载

相关推荐

上一篇:Opium:OCaml开发者必备的轻量级Web框架入门指南
下一篇:掌握Ollama模型可复现性:确保AI实验一致性的完整指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/5 6:26:29

S7-1200与温控仪表的Modbus RTU通信:从接线到调试全流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/5 6:25:56

Java二维码标签生成与打印全解析:从ZXing到DPI匹配

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/5 6:25:53

君正X1000嵌入式开发实战:从环境搭建到驱动移植与调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华