| | |
| | | // 通信成功且业务成功 |
| | | 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, "订单不存在"); |
| | |
| | | // 交易成功 |
| | | 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, "订单不存在"); |
| | |
| | | } |
| | | |
| | | /** |
| | | * 处理第三方支付宝回调 |
| | | * 第三方支付宝通过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) { |