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
- This is expected behavior for non-success states — verify the trade_status and only treat TRADE_SUCCESS as payment confirmation.
- If orders should also be finalized for TRADE_FINISHED, add that status to the check or handle it separately.
- Query Alipay (alipay.trade.query via the query method) with out_trade_no to confirm the real transaction state.
- 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.
- 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
- Handle every documented Alipay trade_status value explicitly instead of a single equality check.
- Return 'success' for callbacks you intentionally ignore so Alipay stops retrying.
- Make paySuccessByOrderSn idempotent since Alipay retries notifications.
- Cross-check uncertain callbacks with alipay.trade.query before updating orders.
- Monitor this warning rate in production to spot abandoned-payment or sandbox-misconfiguration issues.
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)