{"record":{"id":"dcc7bf2318cbb674","repo":"macrozheng/mall-swarm","slug":"trade-status","errorCode":null,"errorMessage":"订单未支付成功，trade_status:{}","messagePattern":"订单未支付成功，trade_status:(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"mall-portal/src/main/java/com/macro/mall/portal/service/impl/AlipayServiceImpl.java","lineNumber":90,"sourceCode":"    public String notify(Map<String, String> params) {\n        String result = \"failure\";\n        boolean signVerified = false;\n        try {\n            //调用SDK验证签名\n            signVerified = AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipayPublicKey(), alipayConfig.getCharset(), alipayConfig.getSignType());\n        } catch (AlipayApiException e) {\n            log.error(\"支付回调签名校验异常！\",e);\n            e.printStackTrace();\n        }\n        if (signVerified) {\n            String tradeStatus = params.get(\"trade_status\");\n            if(\"TRADE_SUCCESS\".equals(tradeStatus)){\n                result = \"success\";\n                log.info(\"notify方法被调用了，tradeStatus:{}\",tradeStatus);\n                String outTradeNo = params.get(\"out_trade_no\");\n                portalOrderService.paySuccessByOrderSn(outTradeNo,1);\n            }else{\n                log.warn(\"订单未支付成功，trade_status:{}\",tradeStatus);\n            }\n        } else {\n            log.warn(\"支付回调签名校验失败！\");\n        }\n        return result;\n    }\n\n    @Override\n    public String query(String outTradeNo, String tradeNo) {\n        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();\n        //******必传参数******\n        JSONObject bizContent = new JSONObject();\n        //设置查询参数，out_trade_no和trade_no至少传一个\n        if(StrUtil.isNotEmpty(outTradeNo)){\n            bizContent.put(\"out_trade_no\",outTradeNo);\n        }\n        if(StrUtil.isNotEmpty(tradeNo)){\n            bizContent.put(\"trade_no\",tradeNo);","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/macrozheng/mall-swarm/blob/04c442fe318356bae4445a109dde7af297ce1e84/mall-portal/src/main/java/com/macro/mall/portal/service/impl/AlipayServiceImpl.java#L72-L108","documentation":"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.","triggerScenarios":"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'.","commonSituations":"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.","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."],"exampleFix":"// before\nif(\"TRADE_SUCCESS\".equals(tradeStatus)){ ... }else{ log.warn(\"订单未支付成功，trade_status:{}\",tradeStatus); }\n// after\nif(\"TRADE_SUCCESS\".equals(tradeStatus) || \"TRADE_FINISHED\".equals(tradeStatus)){\n    portalOrderService.paySuccessByOrderSn(params.get(\"out_trade_no\"),1);\n    result = \"success\";\n} else {\n    log.warn(\"订单未支付成功，trade_status:{}\", tradeStatus);\n    result = \"success\"; // stop Alipay retries for intentionally ignored statuses\n}","handlingStrategy":"validation","validationCode":"// Before processing the callback's business logic\nString tradeStatus = params.get(\"trade_status\");\nif (tradeStatus == null || !(\"TRADE_SUCCESS\".equals(tradeStatus) || \"TRADE_FINISHED\".equals(tradeStatus))) {\n    log.warn(\"忽略非成功状态的支付回调: {}\", tradeStatus);\n    return \"success\"; // acknowledge so Alipay stops retrying\n}","typeGuard":"boolean isPaidStatus(String tradeStatus) {\n    return \"TRADE_SUCCESS\".equals(tradeStatus) || \"TRADE_FINISHED\".equals(tradeStatus);\n}","tryCatchPattern":"try {\n    portalOrderService.paySuccessByOrderSn(outTradeNo, 1);\n    result = \"success\";\n} catch (Exception e) {\n    log.error(\"支付成功后更新订单失败, outTradeNo={}\", outTradeNo, e);\n    result = \"failure\"; // let Alipay retry the notification\n}","preventionTips":["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."],"tags":["alipay","payment-callback","trade-status","java"],"backgroundTag":"invalid-enum-value","analyzedSha":"04c442fe318356bae4445a109dde7af297ce1e84","analyzedAt":"2026-09-08T00:00:41.853Z","contentChangedAt":"2026-09-08T00:00:41.853Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}