Pay 支付宝订单查询实战指南:find/query 查询支付、退款与转账订单

原创2026-10-04 22:40:251,814 阅读
文章标签:后端金融科技

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 支付宝查询订单。
登录后查看全文
pay