PAYATHON 2026

支付宝交易查询能否获取订单已退款金额

支付小周

明确结论

可以。

调用支付宝统一收单交易查询接口 alipay.trade.query 后,可以通过响应字段 refund_amount 获取该笔交易的累计退款金额。订单未发生退款时,该字段可能返回 0.00,也可能不返回,应以实际响应为准。

refund_amount 记录的是整笔交易的累计退款金额,并非某一次退款请求的金额。如果要查询单笔退款结果,应使用 alipay.trade.fastpay.refund.query。

查询方法

调用 alipay.trade.query 时,传入以下任一订单标识:

  • out_trade_no:商户订单号
  • trade_no:支付宝交易号

请求示例:

{
  "method": "alipay.trade.query",
  "biz_content": {
    "out_trade_no": "ORDER_202609080001"
  }
}

响应中主要查看 refund_amount:

{
  "code": "10000",
  "msg": "Success",
  "trade_no": "2026090822000000000000000000",
  "out_trade_no": "ORDER_202609080001",
  "trade_status": "TRADE_SUCCESS",
  "total_amount": "100.00",
  "refund_amount": "30.00"
}

这个响应表示订单总金额为 100.00 元,当前累计退款金额为 30.00 元。

Java 示例

下面是核心调用代码。SDK 初始化、密钥和网关地址应沿用项目现有配置:

AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();

JSONObject bizContent = new JSONObject();
bizContent.put("out_trade_no", "ORDER_202609080001");
request.setBizContent(bizContent.toString());

AlipayTradeQueryResponse response = alipayClient.execute(request);

if (response.isSuccess()) {
    String tradeStatus = response.getTradeStatus();
    String totalAmount = response.getTotalAmount();
    String refundAmount = response.getRefundAmount();

    // 未退款时 refund_amount 可能为空,业务侧可按 0 处理
    BigDecimal refunded = refundAmount == null
            ? BigDecimal.ZERO
            : new BigDecimal(refundAmount);

    System.out.println("交易状态:" + tradeStatus);
    System.out.println("订单金额:" + totalAmount);
    System.out.println("累计退款金额:" + refunded.toPlainString());
} else {
    System.out.println("查询失败,code=" + response.getCode()
            + ", subCode=" + response.getSubCode()
            + ", subMsg=" + response.getSubMsg());
}

计算金额时应使用 BigDecimal,不要使用 double 或 float:

BigDecimal total = new BigDecimal(response.getTotalAmount());
BigDecimal refunded = response.getRefundAmount() == null
        ? BigDecimal.ZERO
        : new BigDecimal(response.getRefundAmount());

BigDecimal remaining = total.subtract(refunded);

这里的 remaining 只是用订单金额减去累计退款金额得到的业务计算结果,不能直接视为实际结算金额。

查询单笔退款

如果一笔订单发生过多次退款,仅凭 refund_amount 无法判断每次退款的情况。业务侧应保存退款请求号 out_request_no,再调用:

alipay.trade.fastpay.refund.query

请求示例:

{
  "out_trade_no": "ORDER_202609080001",
  "out_request_no": "REFUND_202609080001"
}

其中:

  • out_trade_no 用于定位原交易。
  • out_request_no 用于定位某一次退款请求。
  • 同一订单多次退款时,每次都应使用不同的 out_request_no。

注意事项

  1. refund_amount 是累计金额
    如果订单先退款 10.00 元,之后又退款 20.00 元,交易查询通常会返回累计退款金额 30.00 元。

  2. 不要仅根据字段是否存在判断退款状态
    订单未退款时,refund_amount 可能为空。可以在业务侧将空值按 0 处理,同时检查接口返回码和交易状态。

  3. 退款结果可能有短暂的同步延迟
    提交退款后立即查询,交易查询结果可能还没有更新。需要确认某次退款是否成功时,应优先调用退款查询接口,并结合支付宝异步通知处理。

  4. 先确认接口调用成功
    只有 code 表示业务调用成功后,才能继续读取 refund_amount。调用失败时,应记录 code、sub_code 和 sub_msg,不能因为缺少退款金额就判断订单未退款。

  5. 保留本地退款记录
    如果业务需要展示退款明细,应在本地保存每次退款的 out_request_no、申请金额、退款状态和完成时间。alipay.trade.query 适合核对订单级的累计退款金额,不能代替退款明细管理。

备注:内容仅供参考。