macrozheng/mall-swarm · warning

订单未支付成功,trade_status

Error message

订单未支付成功,trade_status:{}

What it means

In AlipayServiceImpl.notify, after the async payment callback passes signature verification, the code checks the trade_status parameter. If it is not exactly 'TRADE_SUCCESS' (e.g., WAIT_BUYER_PAY, TRADE_CLOSED, TRADE_FINISHED), the order is NOT marked paid, 'failure' is eventually returned to Alipay, and this warning is logged. It is an informational warning that Alipay sent a notification for a state other than successful payment.

Solutions

  1. This is expected behavior for non-success states — verify the trade_status and only treat TRADE_SUCCESS as payment confirmation.
  2. If orders should also be finalized for TRADE_FINISHED, add that status to the check or handle it separately.
  3. Query Alipay (alipay.trade.query via the query method) with out_trade_no to confirm the real transaction state.
  4. Check that you are not repeatedly receiving failure notifies: returning 'failure' makes Alipay retry; fix the root state (e.g., expired order) or return 'success' for statuses you intentionally ignore.
  5. Verify the pay flow in the sandbox to ensure the callback is only triggered after a completed payment.

Example fix

// before
if("TRADE_SUCCESS".equals(tradeStatus)){ ... }else{ log.warn("订单未支付成功,trade_status:{}",tradeStatus); }
// after
if("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)){
    portalOrderService.paySuccessByOrderSn(params.get("out_trade_no"),1);
    result = "success";
} else {
    log.warn("订单未支付成功,trade_status:{}", tradeStatus);
    result = "success"; // stop Alipay retries for intentionally ignored statuses
}
Defensive patterns

Strategy: validation

Validate before calling

// Before processing the callback's business logic
String tradeStatus = params.get("trade_status");
if (tradeStatus == null || !("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus))) {
    log.warn("忽略非成功状态的支付回调: {}", tradeStatus);
    return "success"; // acknowledge so Alipay stops retrying
}

Type guard

boolean isPaidStatus(String tradeStatus) {
    return "TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus);
}

Try / catch

try {
    portalOrderService.paySuccessByOrderSn(outTradeNo, 1);
    result = "success";
} catch (Exception e) {
    log.error("支付成功后更新订单失败, outTradeNo={}", outTradeNo, e);
    result = "failure"; // let Alipay retry the notification
}

Prevention

When it happens

Trigger: Alipay's async notify arrives with trade_status values like WAIT_BUYER_PAY (buyer scanned but not paid), TRADE_CLOSED (payment canceled/expired/refunded), or TRADE_FINISHED (transaction finished after refund period) — anything other than the literal 'TRADE_SUCCESS'.

Common situations: Test sandbox notifications where the payment was never completed; users abandoning checkout mid-payment; Alipay closing an overdue order; notifications for already-refunded transactions; accidentally treating the synchronous return URL as if it must carry TRADE_SUCCESS.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of macrozheng/mall-swarm@04c442fe31 (2026-09-08). Data as JSON: /api/errors/dcc7bf2318cbb674. Report an issue: GitHub.

Appendix: source

Thrown at mall-portal/src/main/java/com/macro/mall/portal/service/impl/AlipayServiceImpl.java:90

    public String notify(Map<String, String> params) {
        String result = "failure";
        boolean signVerified = false;
        try {
            //调用SDK验证签名
            signVerified = AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipayPublicKey(), alipayConfig.getCharset(), alipayConfig.getSignType());
        } catch (AlipayApiException e) {
            log.error("支付回调签名校验异常!",e);
            e.printStackTrace();
        }
        if (signVerified) {
            String tradeStatus = params.get("trade_status");
            if("TRADE_SUCCESS".equals(tradeStatus)){
                result = "success";
                log.info("notify方法被调用了,tradeStatus:{}",tradeStatus);
                String outTradeNo = params.get("out_trade_no");
                portalOrderService.paySuccessByOrderSn(outTradeNo,1);
            }else{
                log.warn("订单未支付成功,trade_status:{}",tradeStatus);
            }
        } else {
            log.warn("支付回调签名校验失败!");
        }
        return result;
    }

    @Override
    public String query(String outTradeNo, String tradeNo) {
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        //******必传参数******
        JSONObject bizContent = new JSONObject();
        //设置查询参数,out_trade_no和trade_no至少传一个
        if(StrUtil.isNotEmpty(outTradeNo)){
            bizContent.put("out_trade_no",outTradeNo);
        }
        if(StrUtil.isNotEmpty(tradeNo)){
            bizContent.put("trade_no",tradeNo);

View on GitHub (pinned to 04c442fe31)