☰
Pay 微信支付 v2:close 关闭订单接口完整实战指南
2026/10/15 20:48:33 网站建设 项目流程
  • 后端
  • 金融科技

【免费下载链接】pay

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

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

微信支付官方规定:订单生成后未支付,超过 7 天将自动关闭;而通过关闭订单接口,商户可以在超时前主动对处于「未支付」状态的订单执行关单。本文以 Pay 开源支付 SDK(yansongda/pay)v2 文档中 web/docs/v2/wechat/close.md 为骨架,结合仓库源码(Provider、Shortcut、Plugin 三层实现)与测试用例,完整讲解close关闭订单的调用方式、场景参数、返回值处理与底层插件执行链,帮你快速掌握并排查线上关单问题。

方法签名与返回值

微信关闭订单在 Pay 中对应close方法,其签名与返回值如下:

方法名参数返回值
closestring/array$orderCollection
  • 参数:既可以直接传入商户订单号字符串,也可以传入包含out_trade_no等订单配置的数组;
  • 返回值:Yansongda\Supports\Collection实例,可通过$collection->xxx访问服务器返回的数据。

最小调用示例

在 Pay 中先完成微信支付配置(完整配置可参考 微信概述与快速上手,需包含app_id/appid/miniapp_id、mch_id、key等基础信息),随后即可关闭订单:

$order = [ 'out_trade_no' => '1514027114', ]; // 也可以直接传入订单号字符串 // $order = '1514027114'; $result = $wechat->close($order);

其中$wechat为Pay::wechat($config)返回的实例。两种传参方式等价:当传入字符串时,SDK 内部会将其作为out_trade_no处理,简化只关单个订单的场景。

订单配置参数

close的订单配置参数与微信支付官方接口无任何差别,兼容所有官方功能。所有可用参数请以官方《JSAPI 支付-关闭订单》文档(原 v2 文档中指向官方 wiki 的「请求参数」一栏)为准。

其中最关键、也是唯一必填的参数是:

参数类型必填说明
out_trade_nostring✅商户系统内部订单号,必须是 32 个字符内、且与下单时一致的订单号

这一约束在源码中有明确校验:以 JSAPI 场景的 Jsapi 关闭订单插件 为例,插件从请求载荷中读取out_trade_no,若为空则直接抛出InvalidParamsException(错误码PARAMS_NECESSARY_PARAMS_MISSING),提示“Jsapi 关闭订单,参数缺少out_trade_no”。因此调用前务必确认订单号不为空且与支付下单时保持一致。

APP / 小程序订单关闭

默认情况下,close关闭的是JSAPI(公众号)订单;如果你需要关闭APP或小程序场景的订单,请传入场景标识参数:

// 关闭 APP 支付订单 $result = $wechat->close([ 'out_trade_no' => '1514027114', 'type' => 'app', ]); // 关闭小程序支付订单 $result = $wechat->close([ 'out_trade_no' => '1514027114', 'type' => 'miniapp', ]);

即通过['type' => 'app']与['type' => 'miniapp']分别指定 APP 与小程序关单场景。

从当前仓库源码结构看,v3 版本已将场景分发机制统一收敛为_action参数(jsapi/app/mini/h5/native/combine),详见下文「场景分发」小节与 微信关闭订单 v3 文档;v2 文档中的type写法保留了旧版本的调用习惯,两者表达的是同一组场景语义。

返回值与异常处理

close返回Yansongda\Supports\Collection类型的实例,你可以通过属性方式访问服务器返回的数据:

$result = $wechat->close(['out_trade_no' => '1514027114']); // 例如判断关单是否成功、读取微信返回的相关字段 // $result->xxx

需要特别留意的是关闭订单接口的返回语义:微信关单接口在成功时返回 HTTP 204 状态码、响应体为空。从 微信 Provider 的 close 实现 可以看出,close在内部派发MethodCalled事件并执行关单链路后,返回的是new Collection()(空集合),而不是携带业务字段的完整响应。因此实践中判断关单是否成功,应依赖是否抛出异常而非响应内容:

  • 若请求链路无异常,说明关单请求已被微信受理(HTTP 2xx);
  • 若参数缺失(如无out_trade_no),会抛出InvalidParamsException;
  • 若微信返回状态码异常,则由 微信响应插件 统一拦截,抛出InvalidResponseException(错误码RESPONSE_CODE_WRONG),提示“微信返回状态码异常,请检查参数是否错误”。

调用时建议用 try/catch 包裹并记录异常,避免关单失败被静默吞掉。

源码级原理:close 的插件执行链

在 Pay v3 架构中,close最终由Yansongda\Pay\Shortcut\Wechat\CloseShortcut编排一组插件完成。以默认(JSAPI)场景为例,CloseShortcut 的 jsapiPlugins() 返回的插件链依次为:

StartPlugin → JsapiClosePlugin(组装请求:URL、方法、mchid) → AddPayloadBodyPlugin(组装请求体) → AddPayloadSignaturePlugin(对载荷签名) → AddRadarPlugin(生成 Guzzle 请求) → VerifySignaturePlugin(校验微信响应签名) → ResponsePlugin(校验 HTTP 状态码) → ParserPlugin(解析响应为 Collection)

这一插件链在 CloseShortcut 测试用例 中有完整断言,可作为理解请求链路的直接证据。

场景分发

CloseShortcut::getPlugins() 是整个关单逻辑的分发中枢,它支持两类触发方式:

  1. 自动识别合单:只要参数中包含combine_out_trade_no或sub_orders,就自动走合单关单插件链(对应测试 testCombineParams);
  2. _action显式指定场景:取值与 WechatAction 中 CLOSE_ 系列常量 一一对应,包括default(默认,等价于 jsapi)、app、h5、jsapi、mini、native、combine;传入未知场景(如virtual、foo)则抛出InvalidParamsException(错误码PARAMS_SHORTCUT_ACTION_INVALID),测试见 testVirtual 与 testFoo。

各场景请求地址(来自源码)

场景插件类请求接口(普通商户/服务商)
JSAPI(默认)Jsapi/ClosePluginPOST /v3/pay/transactions/out-trade-no/{out_trade_no}/close(服务商为partner路径)
APPApp/ClosePlugin同上
H5H5/ClosePlugin同上
小程序Mini/ClosePlugin同上
NativeNative/ClosePlugin同上
合单Combine/ClosePluginPOST /v3/combine-transactions/out-trade-no/{combine_out_trade_no}/close

普通商户模式下请求体仅包含mchid;而合单关单插件还会自动补上combine_appid(优先取参数中的值,否则回退到配置的公众号appid),并剔除combine_out_trade_no避免污染请求体,详见 合单关闭插件。

服务商模式说明

若你处于服务商(mode => 'service')模式下,各关单插件会在装配请求时自动切换到_service_url(/v3/pay/partner/transactions/...),且请求体由normal()变为service()组装:以 Jsapi 关闭插件的 service() 为例,会携带sp_mchid(服务商商户号)与sub_mchid(子商户商户号,优先取参数中的sub_mchid,否则回退到配置项),开发者无需手写两套请求逻辑。

相关阅读

  • 微信概述与快速上手(配置、服务商模式)
  • 微信支付下单 pay
  • 微信订单查询 find
  • 微信退款 refund
  • 微信回调 callback
  • v3 版本关闭订单(_action场景分发与合单关单)
  • 后端
  • 金融科技

【免费下载链接】pay

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

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

相关推荐

上一篇:GitHub中文界面终极指南:5分钟告别英文困扰,专注代码开发
下一篇:GitHub中文界面终极指南:告别英文障碍的完整解决方案

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询