wlzboy
2 天以前 08f95b2f159b56fa3bd4f4b348855989de8aa456
dryad-payment/src/main/java/com/ruoyi/payment/application/service/PaymentNotifyService.java
@@ -62,7 +62,7 @@
            // 通信成功且业务成功
            if ("SUCCESS".equals(returnCode) && "SUCCESS".equals(resultCode)) {
                // 查询订单和交易(使用业务订单号查询)
                PaymentOrder order = paymentOrderMapper.selectByBizOrderIdAndChannel(outTradeNo, "WECHAT");
                PaymentOrder order = paymentOrderMapper.selectById(Long.parseLong(outTradeNo));
                if (order == null) {
                    log.error("订单不存在: {}", outTradeNo);
                    updateNotifyLog(notifyLog.getId(), false, "订单不存在");
@@ -134,7 +134,7 @@
            // 交易成功
            if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
                // 查询订单和交易(使用业务订单号查询)
                PaymentOrder order = paymentOrderMapper.selectByBizOrderIdAndChannel(outTradeNo, "ALIPAY");
                PaymentOrder order = paymentOrderMapper.selectById(Long.parseLong(outTradeNo));
                if (order == null) {
                    log.error("订单不存在: {}", outTradeNo);
                    updateNotifyLog(notifyLog.getId(), false, "订单不存在");
@@ -183,6 +183,276 @@
    }
    /**
     * 处理第三方支付宝回调
     * 第三方支付宝通过GET方式回调,参数通过URL传递
     *
     * 参数格式:
     * method: 方法名
     * APPID: 应用ID
     * PaidMoneyType: 支付类型
     * PaidMoney: 支付金额(分)
     * PaidRemarks: 支付备注(包含transaction_id)
     * UnixTime: 时间戳
     * Sign: 签名
     */
    @Transactional(rollbackFor = Exception.class)
    public void processAlipayThirdPartyNotify(Map<String, String> params) {
        String method = params.get("method"); // 方法名
        String appId = params.get("APPID"); // 应用ID
        String paidMoneyType = params.get("PaidMoneyType"); // 支付类型
        String paidMoney = params.get("PaidMoney"); // 支付金额(分)
        String paidRemarks = params.get("PaidRemarks"); // 支付备注(可能包含订单号和交易号)
        String unixTime = params.get("UnixTime"); // 时间戳
        String sign = params.get("Sign"); // 签名
        log.info("处理第三方支付宝回调,method: {}, APPID: {}, PaidMoneyType: {}, PaidMoney: {}, PaidRemarks: {}, UnixTime: {}, Sign: {}",
                method, appId, paidMoneyType, paidMoney, paidRemarks, unixTime, sign);
        log.info("第三方支付宝回调完整参数: {}", params);
        // 从PaidRemarks中提取订单号(out_trade_no)
        // PaidRemarks格式可能是: "订单号+交易号" 或其他格式,需要解析
        String outTradeNo = extractOutTradeNo(paidRemarks);
        String transactionId = extractTransactionId(paidRemarks);
        if (outTradeNo == null || outTradeNo.isEmpty()) {
            log.error("无法从PaidRemarks中提取订单号: {}", paidRemarks);
            return;
        }
        log.info("解析出订单号: {}, 交易号: {}", outTradeNo, transactionId);
        // 检查幂等性(使用订单号或签名)
        String notifyId = transactionId != null ? transactionId : sign;
        if (isNotifyProcessed("ALIPAY_THIRD_PARTY", notifyId)) {
            log.info("第三方支付宝回调已处理过,标识: {}", notifyId);
            return;
        }
        // 记录回调日志
        NotifyLog notifyLog = saveNotifyLog("ALIPAY_THIRD_PARTY", notifyId, JSON.toJSONString(params), true);
        try {
            // 第三方支付宝成功的判断条件(根据实际情况调整)
            // 通常只要能收到回调就表示支付成功
            if (paidMoney != null && Integer.parseInt(paidMoney) > 0) {
                // 查询订单(使用商户订单号,这里的outTradeNo实际是我们的订单ID)
                PaymentOrder order = paymentOrderMapper.selectById(Long.valueOf(outTradeNo));
                if (order == null) {
                    log.error("订单不存在: {}", outTradeNo);
                    updateNotifyLog(notifyLog.getId(), false, "订单不存在");
                    return;
                }
                // 验证金额是否匹配
                if (!order.getAmount().equals(Integer.parseInt(paidMoney))) {
                    log.error("订单金额不匹配,订单金额: {}, 回调金额: {}", order.getAmount(), paidMoney);
                    updateNotifyLog(notifyLog.getId(), false, "金额不匹配");
                    return;
                }
                // 查询待支付交易
                PaymentTransaction transaction = paymentTransactionMapper.selectPendingByOrderId(order.getId());
                if (transaction == null) {
                    // 如果没有待支付交易,尝试查询最新交易
                    transaction = paymentTransactionMapper.selectLatestByOrderId(order.getId());
                    if (transaction == null || "SUCCEEDED".equals(transaction.getStatus())) {
                        log.warn("交易已完成或不存在,订单ID: {}", order.getId());
                        updateNotifyLog(notifyLog.getId(), true, "交易已完成");
                        return;
                    }
                }
                // 更新交易状态
                transaction.setStatus("SUCCEEDED");
                if (transactionId != null) {
                    transaction.setChannelTradeNo(transactionId);
                }
                transaction.setPaidAt(LocalDateTime.now());
                transaction.setResponseSnapshot(JSON.toJSONString(params));
                paymentTransactionMapper.update(transaction);
                // 更新订单状态
                order.setStatus("SUCCEEDED");
                if (transactionId != null) {
                    order.setChannelTradeNo(transactionId);
                }
                order.setPaidAt(LocalDateTime.now());
                order.setLatestTransactionId(transaction.getId());
                paymentOrderMapper.update(order);
                // 更新通知日志
                notifyLog.setOrderId(order.getId());
                notifyLog.setTransactionId(transaction.getId());
                updateNotifyLog(notifyLog.getId(), true, "处理成功");
                // 触发业务回调
                bizCallbackService.triggerCallback(order, transaction);
                log.info("第三方支付宝回调处理成功,订单ID: {}, 交易ID: {}", order.getId(), transaction.getId());
            } else {
                log.warn("第三方支付宝支付金额异常: {}", paidMoney);
                updateNotifyLog(notifyLog.getId(), true, "金额异常: " + paidMoney);
            }
        } catch (Exception e) {
            log.error("处理第三方支付宝回调异常", e);
            updateNotifyLog(notifyLog.getId(), false, "处理异常: " + e.getMessage());
            throw e;
        }
    }
    /**
     * 从PaidRemarks中提取订单号
     * PaidRemarks可能包含订单号和交易号,需要解析
     */
    private String extractOutTradeNo(String paidRemarks) {
        if (paidRemarks == null || paidRemarks.isEmpty()) {
            return null;
        }
        // 假设PaidRemarks格式: "订单号+交易号" 或 "订单号"
        // 根据实际格式调整解析逻辑
        // 这里假设订单号在最前面,可能用某个分隔符分隔
        // 尝试提取纯数字作为订单ID
        String[] parts = paidRemarks.split("[^0-9]+");
        for (String part : parts) {
            if (part.length() > 10) { // 订单ID通常是长整型,长度较长
                return part;
            }
        }
        // 如果没有找到,返回整个字符串的数字部分
        return paidRemarks.replaceAll("[^0-9]", "");
    }
    /**
     * 从PaidRemarks中提取交易号
     */
    private String extractTransactionId(String paidRemarks) {
        if (paidRemarks == null || paidRemarks.isEmpty()) {
            return null;
        }
        // 如果PaidRemarks包含支付宝交易号(通常以2开头的28位数字)
        // 这里简单返回null,可以根据实际格式调整
        return null;
    }
    /**
     * 处理第三方微信回调
     * 第三方微信通过GET方式回调,参数通过URL传递
     *
     * 参数格式:
     * method: 方法名
     * APPID: 应用ID
     * PaidMoneyType: 支付类型
     * PaidMoney: 支付金额(分)
     * PaidRemarks: 支付备注(包含transaction_id)
     * UnixTime: 时间戳
     */
    @Transactional(rollbackFor = Exception.class)
    public void processWechatThirdPartyNotify(Map<String, String> params) {
        String method = params.get("method"); // 方法名
        String appId = params.get("APPID"); // 应用ID
        String paidMoneyType = params.get("PaidMoneyType"); // 支付类型
        String paidMoney = params.get("PaidMoney"); // 支付金额(分)
        String paidRemarks = params.get("PaidRemarks"); // 支付备注(可能包含订单号和交易号)
        String unixTime = params.get("UnixTime"); // 时间戳
        log.info("处理第三方微信回调,method: {}, APPID: {}, PaidMoneyType: {}, PaidMoney: {}, PaidRemarks: {}, UnixTime: {}",
                method, appId, paidMoneyType, paidMoney, paidRemarks, unixTime);
        log.info("第三方微信回调完整参数: {}", params);
        // 从PaidRemarks中提取订单号(out_trade_no)
        String outTradeNo = extractOutTradeNo(paidRemarks);
        String transactionId = extractTransactionId(paidRemarks);
        if (outTradeNo == null || outTradeNo.isEmpty()) {
            log.error("无法从PaidRemarks中提取订单号: {}", paidRemarks);
            return;
        }
        log.info("解析出订单号: {}, 交易号: {}", outTradeNo, transactionId);
        // 检查幂等性(使用订单号或时间戳)
        String notifyId = transactionId != null ? transactionId : (outTradeNo + "_" + unixTime);
        if (isNotifyProcessed("WECHAT_THIRD_PARTY", notifyId)) {
            log.info("第三方微信回调已处理过,标识: {}", notifyId);
            return;
        }
        // 记录回调日志
        NotifyLog notifyLog = saveNotifyLog("WECHAT_THIRD_PARTY", notifyId, JSON.toJSONString(params), true);
        try {
            // 第三方微信成功的判断条件(通常只要能收到回调就表示支付成功)
            if (paidMoney != null && Integer.parseInt(paidMoney) > 0) {
                // 查询订单(使用商户订单号,这里的outTradeNo实际是我们的订单ID)
                PaymentOrder order = paymentOrderMapper.selectById(Long.valueOf(outTradeNo));
                if (order == null) {
                    log.error("订单不存在: {}", outTradeNo);
                    updateNotifyLog(notifyLog.getId(), false, "订单不存在");
                    return;
                }
                // 验证金额是否匹配
                if (!order.getAmount().equals(Integer.parseInt(paidMoney))) {
                    log.error("订单金额不匹配,订单金额: {}, 回调金额: {}", order.getAmount(), paidMoney);
                    updateNotifyLog(notifyLog.getId(), false, "金额不匹配");
                    return;
                }
                // 查询待支付交易
                PaymentTransaction transaction = paymentTransactionMapper.selectPendingByOrderId(order.getId());
                if (transaction == null) {
                    // 如果没有待支付交易,尝试查询最新交易
                    transaction = paymentTransactionMapper.selectLatestByOrderId(order.getId());
                    if (transaction == null || "SUCCEEDED".equals(transaction.getStatus())) {
                        log.warn("交易已完成或不存在,订单ID: {}", order.getId());
                        updateNotifyLog(notifyLog.getId(), true, "交易已完成");
                        return;
                    }
                }
                // 更新交易状态
                transaction.setStatus("SUCCEEDED");
                if (transactionId != null) {
                    transaction.setChannelTradeNo(transactionId);
                }
                transaction.setPaidAt(LocalDateTime.now());
                transaction.setResponseSnapshot(JSON.toJSONString(params));
                paymentTransactionMapper.update(transaction);
                // 更新订单状态
                order.setStatus("SUCCEEDED");
                if (transactionId != null) {
                    order.setChannelTradeNo(transactionId);
                }
                order.setPaidAt(LocalDateTime.now());
                order.setLatestTransactionId(transaction.getId());
                paymentOrderMapper.update(order);
                // 更新通知日志
                notifyLog.setOrderId(order.getId());
                notifyLog.setTransactionId(transaction.getId());
                updateNotifyLog(notifyLog.getId(), true, "处理成功");
                // 触发业务回调
                bizCallbackService.triggerCallback(order, transaction);
                log.info("第三方微信回调处理成功,订单ID: {}, 交易ID: {}", order.getId(), transaction.getId());
            } else {
                log.warn("第三方微信支付金额异常: {}", paidMoney);
                updateNotifyLog(notifyLog.getId(), true, "金额异常: " + paidMoney);
            }
        } catch (Exception e) {
            log.error("处理第三方微信回调异常", e);
            updateNotifyLog(notifyLog.getId(), false, "处理异常: " + e.getMessage());
            throw e;
        }
    }
    /**
     * 检查通知是否已处理(幂等性)
     */
    private boolean isNotifyProcessed(String channel, String notifyId) {