Pay 支付宝订单查询实战指南:find/query 查询支付、退款与转账订单
Pay 支付宝订单查询实战指南:find/query 查询支付、退款与转账订单
本文以 Pay 开源支付 SDK 的 v2 文档《支付宝查询》为核心,系统讲解如何使用 find 方法查询支付宝普通支付订单、退款订单与转账订单,并结合当前仓库源码剖析查询接口的底层实现(_action 分发、插件链与网关 method 映射),帮助读者在 v2 与 v3 两套 API 风格之间平滑迁移。
方法签名一览
v2 文档给出的查询方法签名如下:
| 方法名 | 参数 | 返回值 |
|---|---|---|
| find | string/array $order, string/null $type | Collection |
$order:订单信息,既可以传关联数组,也可以直接传字符串订单号(此时等价于['out_trade_no' => '1514027114']);$type:查询类型,可传'refund'(查询退款单)或'transfer'(查询转账单),默认null表示查询普通支付订单;- 返回值:
Yansongda\Supports\Collection实例,可通过$result->xxx直接访问服务器返回的字段。
说明:后续示例中的
$alipay均代表Pay::alipay($config),完整初始化配置可参考 v2 支付宝概述(含app_id、ali_public_key、private_key、日志与 http 配置,以及沙箱模式'mode' => 'dev')。
查询普通支付订单
$order = [
'out_trade_no' => '1514027114',
];
// $order = '1514027114'; // 也可以直接传订单号字符串
$result = $alipay->find($order);
该调用等价于查询「电脑网站支付(Web)」场景下的普通支付订单,对应官方接口 alipay.trade.query。订单数组中 out_trade_no 为商户订单号,二者必传其一,trade_no(支付宝交易号)与 out_trade_no 二选一即可定位订单。在 QueryPlugin 中可以看到,SDK 会将整个参数数组原样写入 biz_content,并固定 method 为 alipay.trade.query:
$rocket->mergePayload([
'method' => 'alipay.trade.query',
'biz_content' => $rocket->getParams(),
]);
查询退款订单
$order = [
'out_trade_no' => '1514027114',
'out_request_no' => '1514027114'
];
$result = $alipay->find($order, 'refund');
查询退款单时,$type 必须传 'refund',对应官方接口 alipay.trade.fastpay.refund.query。相比支付查询,退款查询必须额外携带 out_request_no(退款请求号,即退款时使用的商户退款单号),否则无法唯一定位某次退款。
这一约定在底层插件中同样得到印证:QueryRefundPlugin 将 method 固定为 alipay.trade.fastpay.refund.query,并将 out_request_no 等参数原样透传进 biz_content:
$rocket->mergePayload([
'method' => 'alipay.trade.fastpay.refund.query',
'biz_content' => $rocket->getParams(),
]);
查询转账订单
$order = [
'out_trade_no' => '1514027114',
];
// $order = '1514027114';
$result = $alipay->find($order, 'transfer');
查询转账订单时,$type 传 'transfer',对应官方接口 alipay.fund.trans.common.query,用于查询单笔转账到支付宝账户(alipay.fund.trans.toaccount.transfer)的交易结果,常用于对账与状态轮询。SDK 内部在 Transfer/Fund/QueryPlugin 中固定 method 为 alipay.fund.trans.common.query。
需要留意:按该官方接口的「请求参数」约定,转账单通常以 out_biz_no(商户转账订单号)与 order_id(支付宝转账单据号)二选一进行查询;仓库 v3 文档的转账查询示例即采用 out_biz_no 字段(见 v3 支付宝查询订单)。由于 SDK 对 biz_content 是原样透传,实际业务中按官方文档填写对应字段即可,v2 文档示例中的 out_trade_no 写法在部分历史场景下同样被接受。
配置参数说明
v2 文档明确:所有订单配置参数和官方无任何差别,兼容所有功能。也就是说,你在调用 find 时传入的数组键名与支付宝官方文档「请求参数」一栏完全一致,SDK 不会做任何二次加工,而是整体放入 biz_content 后随请求体发送。
这一「原样透传」的设计从插件链可见一斑:查询请求依次经过 StartPlugin → 具体查询插件 → FormatPayloadBizContentPlugin → AddPayloadSignaturePlugin → AddRadarPlugin → VerifySignaturePlugin → ResponsePlugin → ParserPlugin 完成「拼装参数 → 格式化 biz_content → RSA2 签名 → 组装请求 → 验签 → 解析响应」的完整闭环(见 QueryShortcut 等插件列表)。签名环节使用支付宝官方推荐的 RSA2(SHA256withRSA) 加密方式,验签逻辑见 AlipayTrait::verifyAlipaySign。
返回值
所有查询接口统一返回 Yansongda\Supports\Collection 类型,直接通过属性访问即可取得服务器返回的数据:
$result = $alipay->find($order);
// 例如获取交易状态(TRADE_SUCCESS / TRADE_FINISHED / WAIT_BUYER_PAY 等)
$status = $result->trade_status;
// 例如获取支付宝交易号
$tradeNo = $result->trade_no;
Collection 是 Pay 底层 Yansongda\Supports 组件提供的集合类,支持 $collection->xxx 属性式访问、$collection->toArray() 转数组等便捷操作,与 v2 支付宝概述 中其他支付/退款/取消/关闭接口的返回值风格完全一致。
从 find 到 query:查询 API 的演进与 _action 分发
当前仓库主干已进入 v3 架构,CHANGELOG 明确记录了这次变化:「查询 API 方法由 find 改为 query,同时参数只支持 array」(见 CHANGELOG)。因此 v2 文档中的 find($order, $type) 在 v3 中演化为:
| v2 写法 | v3 等价写法 |
|---|---|
$alipay->find($order) |
Pay::alipay()->query($order)(_action 缺省即 default/web) |
$alipay->find($order, 'refund') |
Pay::alipay()->query(array_merge($order, ['_action' => 'refund'])) |
$alipay->find($order, 'transfer') |
Pay::alipay()->query(array_merge($order, ['_action' => 'transfer'])) |
v3 将原来 find 的第二个参数 $type 抽象为参数数组中的 _action 键,由 QueryShortcut 统一分发。从 AlipayAction 的常量定义可以看到完整支持的动作矩阵:default、agreement、app、authorization、face、mini、pos、scan、h5、web、transfer 以及一系列 refund_* 退款查询动作(refund_app、refund_mini、refund_pos、refund_scan、refund_h5、refund_web)。
在 Alipay::query() 入口,SDK 会先派发 MethodCalled 事件,再通过 __call('query', <a href="https://link.gitcode.com/i/d4ec3bbd6d5b9aebaaf3ce12e1605a00" target="_blank">$order]) 动态解析到 Shortcut\Alipay\QueryShortcut(见 [Alipay::__call),随后按 _action 选择对应的业务插件组装请求。各动作与网关 method 的映射(以已确认源码为准):
| _action | 对应插件 | 网关 method |
|---|---|---|
| default / web | Pay/Web/QueryPlugin | alipay.trade.query |
| refund / refund_web | Pay/Web/QueryRefundPlugin | alipay.trade.fastpay.refund.query |
| transfer | Fund/Transfer/Fund/QueryPlugin | alipay.fund.trans.common.query |
| app / mini / pos / scan / h5 / agreement / authorization / face 等 | 分别对应 Shortcut/Alipay/QueryShortcut.php 中各分支插件 | 均可推断为对应官方查询接口 |
值得一提的是,QueryShortcut 还有一个隐式智能判断:当参数数组中存在 out_request_no 时,即使未显式指定 _action,也会自动路由到退款查询插件(见 QueryShortcut::getPlugins),与 v2 中 find($order, 'refund') 的语义天然对齐。上述插件链行为均有对应的单元测试覆盖,见 tests/Shortcut/Alipay/QueryShortcutTest.php(含 _action 非法值抛 InvalidParamsException 的用例)。
网关与沙箱环境
查询请求最终发往支付宝网关,网关地址由 Alipay::URL 常量按运行模式决定:正式环境为 https://openapi.alipay.com,沙箱环境为 https://openapi-sandbox.dl.alipaydev.com。若需在沙箱中联调查询接口,只需在初始化配置中设置 'mode' => 'dev' 即可,find/query 的调用方式无需任何改动(相关配置见 v2 支付宝概述)。
小结
- 查询三类订单:普通支付订单(
$alipay->find($order))、退款订单(find($order, 'refund'),需带out_request_no)、转账订单(find($order, 'transfer')); - 参数与官方文档完全一致、原样透传进
biz_content,SDK 负责签名、请求、验签与解析; - 返回值统一为
Collection,属性式访问即可取得trade_status、trade_no等字段; - v3 架构下
find已演进为query+_action分发,查询能力(app/mini/pos/scan/h5/agreement/authorization/face 等场景)更加完备,详见 v3 支付宝查询订单。