PAYATHON 2026

调用alipay.trade.close后Web支付二维码还能扫码吗?

支付阿杰

结论

alipay.trade.close 成功关闭交易后,这笔支付宝交易将无法继续支付,原二维码也不能再用于付款。

需要注意,“能扫码”和“能支付”是两回事:

  • 二维码图片仍可能被正常识别,用户也可能进入支付宝收银台。
  • 由于对应交易已经关闭,继续支付时通常会提示订单已关闭、交易不存在或无法支付。
  • 如果用户仍需付款,必须创建一笔新交易并生成新二维码。原交易无法重新开启。

以上结论的前提是关闭接口确实返回成功,并且交易在关闭前尚未支付成功。

为什么二维码不能继续支付

Web 支付二维码关联的是支付宝侧的一笔具体交易。调用 alipay.trade.close 并成功关闭后,交易状态会变为 TRADE_CLOSED。

二维码只是一段支付链接或收银台入口。即使页面上仍保留着二维码图片,它指向的交易也已经失效。重新展示或刷新原二维码并不能恢复支付。

推荐处理流程

业务系统不能只根据关闭接口是否已经发起来判断订单状态,可以按以下流程处理:

  1. 业务订单超时后,先将订单标记为“关闭处理中”,并停止展示原二维码。
  2. 调用 alipay.trade.close,传入原交易的 out_trade_no 或 trade_no。
  3. 检查支付宝返回的业务结果,确认关闭请求是否成功。
  4. 调用 alipay.trade.query 查询交易的最终状态。
  5. 确认状态为 TRADE_CLOSED 后,再将本地订单更新为“已关闭”。
  6. 如果查询结果是 TRADE_SUCCESS 或 TRADE_FINISHED,说明交易已经支付,不能再按超时订单处理。
  7. 用户需要重新付款时,生成新的商户订单号并重新发起支付。

Java 示例

以下示例使用支付宝 Java SDK。客户端初始化参数应从业务配置中读取。

AlipayClient alipayClient = new DefaultAlipayClient(
    gatewayUrl,
    appId,
    merchantPrivateKey,
    "json",
    "UTF-8",
    alipayPublicKey,
    signType
);

AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
request.setBizContent("""
{
  "out_trade_no": "ORDER_202609090001"
}
""");

AlipayTradeCloseResponse response = alipayClient.execute(request);

if (response.isSuccess()) {
    // 接口受理成功,建议继续查询交易最终状态
    System.out.println("交易关闭请求成功");
} else {
    System.out.println("交易关闭失败");
    System.out.println("code: " + response.getCode());
    System.out.println("subCode: " + response.getSubCode());
    System.out.println("subMsg: " + response.getSubMsg());
}

随后调用查询接口确认状态:

AlipayTradeQueryRequest queryRequest = new AlipayTradeQueryRequest();
queryRequest.setBizContent("""
{
  "out_trade_no": "ORDER_202609090001"
}
""");

AlipayTradeQueryResponse queryResponse =
    alipayClient.execute(queryRequest);

if (queryResponse.isSuccess()) {
    String tradeStatus = queryResponse.getTradeStatus();

    switch (tradeStatus) {
        case "TRADE_CLOSED":
            // 更新本地订单为已关闭,禁止继续支付
            break;

        case "TRADE_SUCCESS":
        case "TRADE_FINISHED":
            // 交易已经支付,进入支付成功处理流程
            break;

        case "WAIT_BUYER_PAY":
            // 仍处于待支付状态,需要结合关闭接口返回结果继续处理
            break;

        default:
            // 记录状态,按业务策略重试查询或人工核对
            break;
    }
}

注意事项

关闭请求与支付可能同时发生

用户扫码支付和业务系统关闭订单可能同时进行。比如关闭请求发出时,用户已经完成付款,但支付结果通知还没有到达业务系统。

因此,调用过关闭接口并不代表订单一定已经关闭。最终状态需要结合以下信息判断:

  • alipay.trade.close 的返回结果
  • alipay.trade.query 查询到的交易状态
  • 支付异步通知及其验签结果

不要复用原商户订单号重新支付

已经关闭的交易无法恢复。重新发起支付时,应创建新的 out_trade_no,并记录它与原业务订单之间的关联,避免订单号冲突和状态混乱。

前端应及时移除二维码

订单超时或确认关闭后,前端应停止轮询并隐藏原二维码,明确提示用户“订单已失效,请重新下单”。即使二维码还能被扫描,也不应继续展示给用户。

不能仅依赖前端倒计时

前端倒计时只用于交互提示,实际的超时控制应由服务端完成。服务端需要记录订单失效时间,并在处理支付结果时再次检查支付宝交易状态,避免页面刷新、本地时间被修改或网络延迟造成状态不一致。

备注:内容仅供参考。