linlinjava/litemall · critical · WxPayException

微信通知支付失败!

Error message

微信通知支付失败!

What it means

In the WeChat pay-notify handler (WxOrderService.wxNotify), after parsing the notify XML with wxPayService.parseOrderNotifyResult, the service checks result.getResultCode() (business result) against WxPayConstants.ResultCode.SUCCESS. If WeChat reports a non-SUCCESS result_code — e.g. PAY_ERROR, TRADE_FAIL, or a refund/bank-side failure — the handler throws WxPayException('微信通知支付失败!'). The local catch converts it to WxPayNotifyResponse.fail(e.getMessage()), telling WeChat the notify was rejected so it will retry.

Solutions

  1. Inspect the logged xmlResult for the failing notify to see the real result_code and err_code_des — that tells you whether it is a genuine payment failure or a config problem.
  2. Verify merchant config (app-id, mch-id, mch-key, sign type) in the wxPayService bean; mismatched keys produce failure results on notify.
  3. Do not change the code path itself: responding fail is correct so WeChat retries; only act if failures are systematic across orders.

Example fix

// before
if(!WxPayConstants.ResultCode.SUCCESS.equals(result.getResultCode())){
    logger.error(xmlResult);
    throw new WxPayException("微信通知支付失败!");
}

// after - keep the failure response but capture the reason code
if(!WxPayConstants.ResultCode.SUCCESS.equals(result.getResultCode())){
    logger.error("微信支付通知失败: result_code={}, err_code={}, err_code_des={}",
            result.getResultCode(), result.getErrCode(), result.getErrCodeDes());
    throw new WxPayException("微信通知支付失败!");
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
    result = wxPayService.parseOrderNotifyResult(xmlResult);
    if (!WxPayConstants.ResultCode.SUCCESS.equals(result.getResultCode())
            || !WxPayConstants.ResultCode.SUCCESS.equals(result.getReturnCode())) {
        logger.error("微信通知失败 result_code={} return_code={} xml={}",
                result.getResultCode(), result.getReturnCode(), xmlResult);
        return WxPayNotifyResponse.fail("支付结果非SUCCESS"); // WeChat will retry
    }
} catch (WxPayException e) {
    logger.error("微信通知解析失败", e);
    return WxPayNotifyResponse.fail(e.getMessage());
}

Prevention

When it happens

Trigger: WeChat sends a notify whose XML has result_code != SUCCESS (actual payment failure or intermediate failure state); occasionally caused by the two-check order being wrong for cases where result_code is SUCCESS but return_code is not (that variant is error [8]). The raw XML is logged via logger.error(xmlResult) right before the throw, so the exact payload is identifiable in logs.

Common situations: Genuine payment failure at the bank/wallet level; sandbox/test environment sending synthetic failure notifications; WeChat platform incidents producing fail result_codes; misconfigured merchant parameters (mch_id, key) causing WeChat to return failure payloads.

Related errors


AI-assisted analysis of linlinjava/litemall@a1ef964a71 (2026-08-14). Data as JSON: /api/errors/8eeb6533ede0cfb5. Report an issue: GitHub.

Appendix: source

Thrown at litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/service/WxOrderService.java:743

     * @return 操作结果
     */
    @Transactional
    public Object payNotify(HttpServletRequest request, HttpServletResponse response) {
        String xmlResult = null;
        try {
            xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
        } catch (IOException e) {
            e.printStackTrace();
            return WxPayNotifyResponse.fail(e.getMessage());
        }

        WxPayOrderNotifyResult result = null;
        try {
            result = wxPayService.parseOrderNotifyResult(xmlResult);

            if(!WxPayConstants.ResultCode.SUCCESS.equals(result.getResultCode())){
                logger.error(xmlResult);
                throw new WxPayException("微信通知支付失败!");
            }
            if(!WxPayConstants.ResultCode.SUCCESS.equals(result.getReturnCode())){
                logger.error(xmlResult);
                throw new WxPayException("微信通知支付失败!");
            }
        } catch (WxPayException e) {
            e.printStackTrace();
            return WxPayNotifyResponse.fail(e.getMessage());
        }

        logger.info("处理腾讯支付平台的订单支付");
        logger.info(result);

        String orderSn = result.getOutTradeNo();
        String payId = result.getTransactionId();

        // 分转化成元
        String totalFee = BaseWxPayResult.fenToYuan(result.getTotalFee());

View on GitHub (pinned to a1ef964a71)