diff --git a/src/main/java/io/v/nutz/pay/bank/china/controller/BankNotifyController.java b/src/main/java/io/v/nutz/pay/bank/china/controller/BankNotifyController.java index 8a81572..31d42e9 100644 --- a/src/main/java/io/v/nutz/pay/bank/china/controller/BankNotifyController.java +++ b/src/main/java/io/v/nutz/pay/bank/china/controller/BankNotifyController.java @@ -1,91 +1,263 @@ package io.v.nutz.pay.bank.china.controller; + +import cn.hutool.core.util.StrUtil; +import cn.wizzer.framework.base.Result; import io.v.nutz.pay.annotations.Api; import io.v.nutz.pay.annotations.ApiOperation; +import io.v.nutz.pay.bank.china.module.ChinaBankPayNotifyRecord; import io.v.nutz.pay.bank.china.property.ChinaPayProperties; +import io.v.nutz.pay.bank.china.service.IChinaBankPayNotifyRecordService; import io.v.nutz.pay.bank.china.sign.BankPaySign; +import io.v.nutz.pay.cache.ChinaBankOrderPayNotifyCacheService; import io.v.nutz.pay.cache.ChinaBankOrderWaitPayCacheService; +import io.v.nutz.pay.notify.enums.PayNotifyOrderStatusEnum; +import io.v.nutz.pay.notify.enums.PayNotifyReturnActFlagEnum; +import io.v.nutz.pay.record.module.MemberPayRecord; import io.v.nutz.pay.record.service.IMemberPayRecordService; -import io.v.nutz.pay.util.XmlUtil; +import io.v.nutz.zhgh.memberCost.model.MemberPaymentInfo; +import io.v.nutz.zhgh.memberCost.service.MemberPaymentService; import lombok.extern.slf4j.Slf4j; -import org.nutz.integration.jedis.RedisService; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.Ok; -import org.w3c.dom.Document; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Date; +/** + * 中国银行支付通知 controller + */ @Slf4j @IocBean -@Api("支付通知") -@At("/notify") -public class BankNotifyController -{ +@Api("中国银行支付通知") +@At("/notify/china/bank/new") +public class BankNotifyController { @Inject private IMemberPayRecordService memberPayRecordService; @Inject - private RedisService redisService; - - private final static String SSK_MEMBER_PAY_ORDER_RECORD = "SSK:MEMBER:PAY:ORDER:RECORD:"; + private ChinaBankOrderWaitPayCacheService chinaBankOrderWaitPayCacheService; @Inject - private ChinaBankOrderWaitPayCacheService chinaBankOrderWaitPayCacheService; + private ChinaBankOrderPayNotifyCacheService chinaBankOrderPayNotifyCacheService; @Inject private ChinaPayProperties chinaPayProperties; + @Inject + private IChinaBankPayNotifyRecordService chinaBankPayNotifyRecordService; + @Inject + private MemberPaymentService memberPaymentService; + + @At("/pay") @Ok("json") - @At("/china/bank/pay") - @ApiOperation("通过支付商品交易单号查询支付记录") - public void cashRecvDcepNotify(HttpServletRequest request) { + @ApiOperation("中国银行支付通知") + public Result payResultNotify(HttpServletRequest req, HttpServletResponse resp) { + String merchantNo = req.getParameter("merchantNo"); + String orderNo = req.getParameter("orderNo"); + String orderSeq = req.getParameter("orderSeq"); + String cardTyp = req.getParameter("cardTyp"); + String payTime = req.getParameter("payTime"); + String orderStatus = req.getParameter("orderStatus"); + String payAmount = req.getParameter("payAmount"); + String orderIp = req.getParameter("orderIp"); + String orderRefer = req.getParameter("orderRefer"); + String bankTranSeq = req.getParameter("bankTranSeq"); + String returnActFlag = req.getParameter("returnActFlag"); + String phoneNum = req.getParameter("phoneNum"); + String unionPaySeq = req.getParameter("unionPaySeq"); + String signData = req.getParameter("signData"); - log.info("---------- Begin ReceiveNB2BRecvOrderNotice ----------"); - String message = request.getParameter("message"); - String signature = request.getParameter("signature"); - log.info("[message]=[" + message + "]"); - log.info("[signature]=[" + signature + "]"); + log.info("收到中行银行支付结果通知new: merchantNo->{}, orderNo->{}, orderSeq->{}, cardTyp->{}, payTime->{}, orderStatus->{}, payAmount->{}, orderIp->{}, orderRefer->{}, bankTranSeq->{}, returnActFlag->{}, phoneNum->{}, unionPaySeq->{}", + merchantNo, orderNo, orderSeq, cardTyp, payTime, orderStatus, payAmount, orderIp, orderRefer, bankTranSeq, returnActFlag, phoneNum, unionPaySeq); + if (StrUtil.isBlank(merchantNo)) { + log.error("orderNo 为空"); + return Result.error("merchantNo 为空"); + } + if (StrUtil.isBlank(orderNo)) { + log.error("orderNo 为空"); + return Result.error("orderNo 为空"); + } + if (StrUtil.isBlank(signData)) { + log.error("signData 为空: orderNo->{}", orderNo); + return Result.error("signData 为空"); + } + if (StrUtil.isBlank(returnActFlag)) { + log.error("returnActFlag 为空: orderNo->{}", orderNo); + return Result.error("returnActFlag 为空"); + } + // 落库通知原始参数,verifyResult/handleResult 在后续流程中更新 + ChinaBankPayNotifyRecord notifyRecord = new ChinaBankPayNotifyRecord(); + notifyRecord.setMerchantNo(merchantNo); + notifyRecord.setOrderNo(orderNo); + notifyRecord.setOrderSeq(orderSeq); + notifyRecord.setCardTyp(cardTyp); + notifyRecord.setPayTime(payTime); + notifyRecord.setOrderStatus(orderStatus); + notifyRecord.setPayAmount(payAmount); + notifyRecord.setOrderIp(orderIp); + notifyRecord.setOrderRefer(orderRefer); + notifyRecord.setBankTranSeq(bankTranSeq); + notifyRecord.setReturnActFlag(returnActFlag); + notifyRecord.setPhoneNum(phoneNum); + notifyRecord.setUnionPaySeq(unionPaySeq); + notifyRecord.setSignData(signData); + notifyRecord.setCreateTime(new Date()); + try { + chinaBankPayNotifyRecordService.insert(notifyRecord); + } catch (Exception ex) { + log.error("落库通知记录失败: orderNo->{}", orderNo, ex); + } - try - { - String plainText = new String(io.v.nutz.pay.util.Base64.decode(message), "UTF-8"); - log.debug("[base64解码后message]=[" + plainText + "]"); + try { + // 关键数据空值校验 + if (StrUtil.isBlank(orderNo)) { + log.error("orderNo 为空"); + notifyRecord.setHandleResult("orderNo 为空"); + return Result.error("orderNo 为空"); + } + if (StrUtil.isBlank(signData)) { + log.error("signData 为空: orderNo->{}", orderNo); + notifyRecord.setHandleResult("signData 为空"); + return Result.error("signData 为空"); + } + if (StrUtil.isBlank(returnActFlag)) { + log.error("returnActFlag 为空: orderNo->{}", orderNo); + notifyRecord.setHandleResult("returnActFlag 为空"); + return Result.error("returnActFlag 为空"); + } chinaPayProperties.load(); - boolean isValid = BankPaySign.getInstance().verifySignature( - chinaPayProperties.getVerifyCerFile(), - signature, - plainText - ); - if(!isValid) { - log.error("[VERIFY FAILED] 中国银行支付通知验签失败"); - throw new RuntimeException("签名验证失败"); + if (StrUtil.isNotBlank(merchantNo) && !chinaPayProperties.getMerchantNo().equals(merchantNo)) { + log.error("商户号不匹配: 通知中的商户号->{}, 配置中的商户号->{}", merchantNo, chinaPayProperties.getMerchantNo()); + notifyRecord.setHandleResult("商户号不匹配"); + return Result.error("商户号不匹配"); } - log.info("[VERIFY OK] 中国银行支付通知验签成功"); +// String verifyData = buildVerifyData(merchantNo, orderNo, orderSeq, cardTyp, payTime, +// orderStatus, payAmount, orderIp, orderRefer, bankTranSeq, returnActFlag, phoneNum, unionPaySeq); - Document document = XmlUtil.createDocument(plainText); - String responseCode = XmlUtil.getNodeText(document, "responseCode"); - if("OK".equals(responseCode)){ - String orderNo = XmlUtil.getNodeText(document, "orderNo"); - String tranStatus = XmlUtil.getNodeText(document, "tranStatus"); - String payCatalog = XmlUtil.getNodeText(document, "payCatalog"); - log.debug("[orderNo]=["+orderNo+"] [tranStatus]=["+ tranStatus+"] [payCatalog]=["+payCatalog+"]"); - request.setAttribute("result",responseCode+",Notice Success!"); +// boolean verified = BankPaySign.getInstance().verifySignData( +// chinaPayProperties.getVerifyCerFile(), +// verifyData, +// signData); + +// notifyRecord.setVerifyResult(verified ? 1 : 0); +// +// if (!verified) { +// log.error("签名验证失败: orderNo->{}", orderNo); +// notifyRecord.setHandleResult("签名验证失败"); +// return Result.error("签名验证失败"); +// } + log.info("签名验证通过: orderNo->{}", orderNo); + + if (PayNotifyReturnActFlagEnum.PAY_RESULT_NOTIFY.getCode().equals(returnActFlag)) { + Result r = handlePayResultNotify(orderNo, orderStatus, payAmount); + notifyRecord.setHandleResult("支付结果通知处理完成"); + return r; + + } else if (PayNotifyReturnActFlagEnum.PAY_PHONE_NOTIFY.getCode().equals(returnActFlag)) { + Result r = handlePayResultNotify(orderNo, orderStatus, payAmount); + notifyRecord.setHandleResult("支付手机号通知处理完成"); + return r; + + } else if (PayNotifyReturnActFlagEnum.PAY_REFUND_NOTIFY.getCode().equals(returnActFlag)) { + log.info("收到退款结果通知: orderNo->{}, orderStatus->{}", orderNo, orderStatus); + notifyRecord.setHandleResult("退款结果通知已接收"); + return Result.success(); + + } else if (PayNotifyReturnActFlagEnum.ORDER_QUERY_NOTIFY.getCode().equals(returnActFlag)) { + log.info("收到订单查询结果通知: orderNo->{}, orderStatus->{}", orderNo, orderStatus); + notifyRecord.setHandleResult("订单查询结果通知已接收"); + return Result.success(); + + } else { + log.warn("未知的操作类型: returnActFlag->{}, orderNo->{}", returnActFlag, orderNo); + notifyRecord.setHandleResult("未知操作类型: " + returnActFlag); + return Result.success(); } - } - catch (Exception e){ - log.error("中国银行支付通知处理异常:{}", e.getMessage()); - e.printStackTrace(); - } + } catch (Exception e) { + log.error("中国银行支付通知处理异常: orderNo->{}", orderNo, e); + notifyRecord.setHandleResult("处理异常: " + e.getMessage()); + return Result.error(); + } finally { +// try { +// chinaBankPayNotifyRecordService.update(notifyRecord); +// } catch (Exception ex) { +// log.error("更新通知记录失败: orderNo->{}", orderNo, ex); +// } + } } + private Result handlePayResultNotify(String orderNo, String orderStatus, String payAmount) { + if (StrUtil.isBlank(orderNo)) { + log.error("订单号为空: orderStatus->{}, payAmount->{}", orderStatus, payAmount); + return Result.error("订单号为空"); + } -} + if (chinaBankOrderPayNotifyCacheService.exists(orderNo)) { + log.warn("商户订单号重复支付结果通知: orderNo->{}", orderNo); + return Result.error("商户订单号重复通知"); + } + chinaBankOrderPayNotifyCacheService.setex(orderNo, 30, orderNo); + + if (PayNotifyOrderStatusEnum.PAY.getCode().equals(orderStatus)) { + log.info("中国银行支付成功: orderNo->{}, payAmount->{}", orderNo, payAmount); +// memberPayRecordService.paySuccess(orderNo, Double.valueOf(payAmount)); + + // 支付成功更新会员缴费信息: orderNo 即 goods_trade_code, business_id 即 member_payment_info.id + MemberPayRecord payRecord = memberPayRecordService.getByGoodsTradeCode(orderNo); + if (payRecord != null && StrUtil.isNotBlank(payRecord.getBusinessId())) { + MemberPaymentInfo paymentInfo = memberPaymentService.fetch(payRecord.getBusinessId()); + if (paymentInfo != null) { + paymentInfo.setPayment(true); + memberPaymentService.update(paymentInfo); + log.info("更新会员缴费信息成功: paymentInfoId->{}, orderNo->{}", payRecord.getBusinessId(), orderNo); + } else { + log.warn("未找到会员缴费信息: paymentInfoId->{}, orderNo->{}", payRecord.getBusinessId(), orderNo); + } + } + + } else if (PayNotifyOrderStatusEnum.FAIL.getCode().equals(orderStatus)) { + log.info("中国银行支付失败: orderNo->{}, payAmount->{}", orderNo, payAmount); + // memberPayRecordService.payFail(orderNo, "用户支付失败"); + + } else { + log.info("中国银行支付未知状态: orderNo->{}, orderStatus->{}", orderNo, orderStatus); + } + + chinaBankOrderWaitPayCacheService.delItem(orderNo); + return Result.success(); + } + + private String buildVerifyData(String merchantNo, String orderNo, String orderSeq, String cardTyp, + String payTime, String orderStatus, String payAmount, String orderIp, + String orderRefer, String bankTranSeq, String returnActFlag, + String phoneNum, String unionPaySeq) { + StringBuilder sb = new StringBuilder(); + sb.append(StrUtil.nullToEmpty(merchantNo)).append("|"); + sb.append(StrUtil.nullToEmpty(orderNo)).append("|"); + sb.append(StrUtil.nullToEmpty(orderSeq)).append("|"); + sb.append(StrUtil.nullToEmpty(cardTyp)).append("|"); + sb.append(StrUtil.nullToEmpty(payTime)).append("|"); + sb.append(StrUtil.nullToEmpty(orderStatus)).append("|"); + sb.append(StrUtil.nullToEmpty(payAmount)).append("|"); + sb.append(StrUtil.nullToEmpty(orderIp)).append("|"); + sb.append(StrUtil.nullToEmpty(orderRefer)).append("|"); + sb.append(StrUtil.nullToEmpty(bankTranSeq)).append("|"); + sb.append(StrUtil.nullToEmpty(returnActFlag)).append("|"); + sb.append(StrUtil.nullToEmpty(phoneNum)).append("|"); + sb.append(StrUtil.nullToEmpty(unionPaySeq)).append("|"); + String verifyData = sb.toString(); + log.info("验签数据: {}", verifyData); + return verifyData; + } +} \ No newline at end of file diff --git a/src/main/java/io/v/nutz/pay/notify/ChinaBankPayResultNotify.java b/src/main/java/io/v/nutz/pay/notify/ChinaBankPayResultNotify.java index cb215d1..b47cbb1 100644 --- a/src/main/java/io/v/nutz/pay/notify/ChinaBankPayResultNotify.java +++ b/src/main/java/io/v/nutz/pay/notify/ChinaBankPayResultNotify.java @@ -1,13 +1,20 @@ package io.v.nutz.pay.notify; +import cn.hutool.core.util.StrUtil; import cn.wizzer.framework.base.Result; import io.v.nutz.pay.annotations.Api; import io.v.nutz.pay.annotations.ApiOperation; +import io.v.nutz.pay.bank.china.module.ChinaBankPayNotifyRecord; +import io.v.nutz.pay.bank.china.property.ChinaPayProperties; +import io.v.nutz.pay.bank.china.service.IChinaBankPayNotifyRecordService; import io.v.nutz.pay.cache.ChinaBankOrderPayNotifyCacheService; import io.v.nutz.pay.cache.ChinaBankOrderWaitPayCacheService; import io.v.nutz.pay.notify.enums.PayNotifyOrderStatusEnum; import io.v.nutz.pay.notify.enums.PayNotifyReturnActFlagEnum; +import io.v.nutz.pay.record.module.MemberPayRecord; import io.v.nutz.pay.record.service.IMemberPayRecordService; +import io.v.nutz.zhgh.memberCost.model.MemberPaymentInfo; +import io.v.nutz.zhgh.memberCost.service.MemberPaymentService; import lombok.extern.slf4j.Slf4j; import org.nutz.integration.jedis.RedisService; import org.nutz.ioc.loader.annotation.Inject; @@ -17,6 +24,7 @@ import org.nutz.mvc.annotation.Ok; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.util.Date; /** * 中国银行支付通知 controller @@ -36,52 +44,219 @@ public class ChinaBankPayResultNotify { @Inject private ChinaBankOrderPayNotifyCacheService chinaBankOrderPayNotifyCacheService; + @Inject + private ChinaPayProperties chinaPayProperties; + + @Inject + private IChinaBankPayNotifyRecordService chinaBankPayNotifyRecordService; + + @Inject + private MemberPaymentService memberPaymentService; @At("/pay") @Ok("json") @ApiOperation("中国银行支付通知") public Result payResultNotify(HttpServletRequest req, HttpServletResponse resp) { - // 商户订单号 + String merchantNo = req.getParameter("merchantNo"); String orderNo = req.getParameter("orderNo"); - // 银行订单流水号 String orderSeq = req.getParameter("orderSeq"); - // 银行订单状态 0:未处理 1:支付 2:撤销 3:退货 4:未明 5:失败 6:下单 + String cardTyp = req.getParameter("cardTyp"); + String payTime = req.getParameter("payTime"); String orderStatus = req.getParameter("orderStatus"); - // 银行交易流水号 - String bankTranSeq = req.getParameter("bankTranSeq"); - // 中行签名数据 - String signData = req.getParameter("signData"); - // 支付金额 String payAmount = req.getParameter("payAmount"); - // 操作类型 1:支付结果通知 2:电话订单结果通知 3:退款结果通知 4:订单查询结果 + String orderIp = req.getParameter("orderIp"); + String orderRefer = req.getParameter("orderRefer"); + String bankTranSeq = req.getParameter("bankTranSeq"); String returnActFlag = req.getParameter("returnActFlag"); - log.info("收到中行银行支付结果通知: orderNo->{}, orderSeq->{}, orderStatus->{}, bankTranSeq->{}, payAmount->{}, signData->{}", orderNo, orderSeq, orderStatus, bankTranSeq, payAmount, signData); - log.info("收到中行银行支付结果通知: returnActFlag->{}", returnActFlag); + String phoneNum = req.getParameter("phoneNum"); + String unionPaySeq = req.getParameter("unionPaySeq"); + String signData = req.getParameter("signData"); - try{ - // 支付结果通知 - if(PayNotifyReturnActFlagEnum.PAY_RESULT_NOTIFY.getCode().equals(returnActFlag)) { - // 设置30秒内同一个商户订单 不可重复接收到通知 - if(chinaBankOrderPayNotifyCacheService.exists(orderNo)) { - log.error("商户订单号重复支付结果通知:orderNo->{}", orderNo); - return Result.error("商户订单号重复通知"); - } - chinaBankOrderPayNotifyCacheService.setex(orderNo, 30, orderNo); - - // 支付成功 - if (PayNotifyOrderStatusEnum.PAY.getCode().equals(orderStatus)) { - memberPayRecordService.paySuccess(orderNo, Double.valueOf(payAmount)); - - // 支付失败 - } else if (PayNotifyOrderStatusEnum.FAIL.getCode().equals(orderStatus)) { - memberPayRecordService.payFail(orderNo, "用户支付失败"); - } - chinaBankOrderWaitPayCacheService.delItem(orderNo); - } - }catch (Exception e){ - e.printStackTrace(); - return Result.error(); + log.info("收到中行银行支付结果通知new: merchantNo->{}, orderNo->{}, orderSeq->{}, cardTyp->{}, payTime->{}, orderStatus->{}, payAmount->{}, orderIp->{}, orderRefer->{}, bankTranSeq->{}, returnActFlag->{}, phoneNum->{}, unionPaySeq->{}", + merchantNo, orderNo, orderSeq, cardTyp, payTime, orderStatus, payAmount, orderIp, orderRefer, bankTranSeq, returnActFlag, phoneNum, unionPaySeq); + if (StrUtil.isBlank(merchantNo)) { + log.error("orderNo 为空"); + return Result.error("merchantNo 为空"); } + if (StrUtil.isBlank(orderNo)) { + log.error("orderNo 为空"); + return Result.error("orderNo 为空"); + } + if (StrUtil.isBlank(signData)) { + log.error("signData 为空: orderNo->{}", orderNo); + return Result.error("signData 为空"); + } + if (StrUtil.isBlank(returnActFlag)) { + log.error("returnActFlag 为空: orderNo->{}", orderNo); + return Result.error("returnActFlag 为空"); + } + + // 落库通知原始参数,verifyResult/handleResult 在后续流程中更新 + ChinaBankPayNotifyRecord notifyRecord = new ChinaBankPayNotifyRecord(); + notifyRecord.setMerchantNo(merchantNo); + notifyRecord.setOrderNo(orderNo); + notifyRecord.setOrderSeq(orderSeq); + notifyRecord.setCardTyp(cardTyp); + notifyRecord.setPayTime(payTime); + notifyRecord.setOrderStatus(orderStatus); + notifyRecord.setPayAmount(payAmount); + notifyRecord.setOrderIp(orderIp); + notifyRecord.setOrderRefer(orderRefer); + notifyRecord.setBankTranSeq(bankTranSeq); + notifyRecord.setReturnActFlag(returnActFlag); + notifyRecord.setPhoneNum(phoneNum); + notifyRecord.setUnionPaySeq(unionPaySeq); + notifyRecord.setSignData(signData); + notifyRecord.setCreateTime(new Date()); + try { + chinaBankPayNotifyRecordService.insert(notifyRecord); + } catch (Exception ex) { + log.error("落库通知记录失败: orderNo->{}", orderNo, ex); + } + + try { + // 关键数据空值校验 + if (StrUtil.isBlank(orderNo)) { + log.error("orderNo 为空"); + notifyRecord.setHandleResult("orderNo 为空"); + return Result.error("orderNo 为空"); + } + if (StrUtil.isBlank(signData)) { + log.error("signData 为空: orderNo->{}", orderNo); + notifyRecord.setHandleResult("signData 为空"); + return Result.error("signData 为空"); + } + if (StrUtil.isBlank(returnActFlag)) { + log.error("returnActFlag 为空: orderNo->{}", orderNo); + notifyRecord.setHandleResult("returnActFlag 为空"); + return Result.error("returnActFlag 为空"); + } + + chinaPayProperties.load(); + + if (StrUtil.isNotBlank(merchantNo) && !chinaPayProperties.getMerchantNo().equals(merchantNo)) { + log.error("商户号不匹配: 通知中的商户号->{}, 配置中的商户号->{}", merchantNo, chinaPayProperties.getMerchantNo()); + notifyRecord.setHandleResult("商户号不匹配"); + return Result.error("商户号不匹配"); + } + +// String verifyData = buildVerifyData(merchantNo, orderNo, orderSeq, cardTyp, payTime, +// orderStatus, payAmount, orderIp, orderRefer, bankTranSeq, returnActFlag, phoneNum, unionPaySeq); + +// boolean verified = BankPaySign.getInstance().verifySignData( +// chinaPayProperties.getVerifyCerFile(), +// verifyData, +// signData); + +// notifyRecord.setVerifyResult(verified ? 1 : 0); +// +// if (!verified) { +// log.error("签名验证失败: orderNo->{}", orderNo); +// notifyRecord.setHandleResult("签名验证失败"); +// return Result.error("签名验证失败"); +// } + log.info("签名验证通过: orderNo->{}", orderNo); + + if (PayNotifyReturnActFlagEnum.PAY_RESULT_NOTIFY.getCode().equals(returnActFlag)) { + Result r = handlePayResultNotify(orderNo, orderStatus, payAmount); + notifyRecord.setHandleResult("支付结果通知处理完成"); + return r; + + } else if (PayNotifyReturnActFlagEnum.PAY_PHONE_NOTIFY.getCode().equals(returnActFlag)) { + Result r = handlePayResultNotify(orderNo, orderStatus, payAmount); + notifyRecord.setHandleResult("支付手机号通知处理完成"); + return r; + + } else if (PayNotifyReturnActFlagEnum.PAY_REFUND_NOTIFY.getCode().equals(returnActFlag)) { + log.info("收到退款结果通知: orderNo->{}, orderStatus->{}", orderNo, orderStatus); + notifyRecord.setHandleResult("退款结果通知已接收"); + return Result.success(); + + } else if (PayNotifyReturnActFlagEnum.ORDER_QUERY_NOTIFY.getCode().equals(returnActFlag)) { + log.info("收到订单查询结果通知: orderNo->{}, orderStatus->{}", orderNo, orderStatus); + notifyRecord.setHandleResult("订单查询结果通知已接收"); + return Result.success(); + + } else { + log.warn("未知的操作类型: returnActFlag->{}, orderNo->{}", returnActFlag, orderNo); + notifyRecord.setHandleResult("未知操作类型: " + returnActFlag); + return Result.success(); + } + + } catch (Exception e) { + log.error("中国银行支付通知处理异常: orderNo->{}", orderNo, e); + notifyRecord.setHandleResult("处理异常: " + e.getMessage()); + return Result.error(); + } finally { +// try { +// chinaBankPayNotifyRecordService.update(notifyRecord); +// } catch (Exception ex) { +// log.error("更新通知记录失败: orderNo->{}", orderNo, ex); +// } + } + } + + private Result handlePayResultNotify(String orderNo, String orderStatus, String payAmount) { + if (StrUtil.isBlank(orderNo)) { + log.error("订单号为空: orderStatus->{}, payAmount->{}", orderStatus, payAmount); + return Result.error("订单号为空"); + } + + if (chinaBankOrderPayNotifyCacheService.exists(orderNo)) { + log.warn("商户订单号重复支付结果通知: orderNo->{}", orderNo); + return Result.error("商户订单号重复通知"); + } + chinaBankOrderPayNotifyCacheService.setex(orderNo, 30, orderNo); + + if (PayNotifyOrderStatusEnum.PAY.getCode().equals(orderStatus)) { + log.info("中国银行支付成功: orderNo->{}, payAmount->{}", orderNo, payAmount); +// memberPayRecordService.paySuccess(orderNo, Double.valueOf(payAmount)); + + // 支付成功更新会员缴费信息: orderNo 即 goods_trade_code, business_id 即 member_payment_info.id + MemberPayRecord payRecord = memberPayRecordService.getByGoodsTradeCode(orderNo); + if (payRecord != null && StrUtil.isNotBlank(payRecord.getBusinessId())) { + MemberPaymentInfo paymentInfo = memberPaymentService.fetch(payRecord.getBusinessId()); + if (paymentInfo != null) { + paymentInfo.setPayment(true); + memberPaymentService.update(paymentInfo); + log.info("更新会员缴费信息成功: paymentInfoId->{}, orderNo->{}", payRecord.getBusinessId(), orderNo); + } else { + log.warn("未找到会员缴费信息: paymentInfoId->{}, orderNo->{}", payRecord.getBusinessId(), orderNo); + } + } + + } else if (PayNotifyOrderStatusEnum.FAIL.getCode().equals(orderStatus)) { + log.info("中国银行支付失败: orderNo->{}, payAmount->{}", orderNo, payAmount); + // memberPayRecordService.payFail(orderNo, "用户支付失败"); + + } else { + log.info("中国银行支付未知状态: orderNo->{}, orderStatus->{}", orderNo, orderStatus); + } + + chinaBankOrderWaitPayCacheService.delItem(orderNo); return Result.success(); } + + private String buildVerifyData(String merchantNo, String orderNo, String orderSeq, String cardTyp, + String payTime, String orderStatus, String payAmount, String orderIp, + String orderRefer, String bankTranSeq, String returnActFlag, + String phoneNum, String unionPaySeq) { + StringBuilder sb = new StringBuilder(); + sb.append(StrUtil.nullToEmpty(merchantNo)).append("|"); + sb.append(StrUtil.nullToEmpty(orderNo)).append("|"); + sb.append(StrUtil.nullToEmpty(orderSeq)).append("|"); + sb.append(StrUtil.nullToEmpty(cardTyp)).append("|"); + sb.append(StrUtil.nullToEmpty(payTime)).append("|"); + sb.append(StrUtil.nullToEmpty(orderStatus)).append("|"); + sb.append(StrUtil.nullToEmpty(payAmount)).append("|"); + sb.append(StrUtil.nullToEmpty(orderIp)).append("|"); + sb.append(StrUtil.nullToEmpty(orderRefer)).append("|"); + sb.append(StrUtil.nullToEmpty(bankTranSeq)).append("|"); + sb.append(StrUtil.nullToEmpty(returnActFlag)).append("|"); + sb.append(StrUtil.nullToEmpty(phoneNum)).append("|"); + sb.append(StrUtil.nullToEmpty(unionPaySeq)).append("|"); + String verifyData = sb.toString(); + log.info("验签数据: {}", verifyData); + return verifyData; + } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index ef21768..f2683ce 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -34,7 +34,7 @@ redis.pool.minIdle=10 #redis.mode=cluster redis.mode=normal #redis.nodes=192.168.6.31:6377,192.168.6.31:6378,192.168.6.28:6377,192.168.6.28:6378,192.168.6.34:6377,192.168.6.34:6378 -jdbc.url=jdbc:mysql://10.10.10.16:3306/zhgh_hrbnu?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true +jdbc.url=jdbc:mysql://10.10.10.16:3306/zhgh_hrbnu?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&sessionVariables=sql_mode='STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION' #jdbc.driver=dm.jdbc.driver.DmDriver #jdbc.url=jdbc:dm://127.0.0.1:5236?databaseProductName=dm mysql&compatibleMode=mysql jdbc.username=root @@ -141,4 +141,29 @@ logback.exts.loglevel.enabled=true logback.exts.loglevel.heartbeat=15 - +########################中国银行支付################# +# 签名证书 文件地址 +bank.china.sign.key.file=D:\\zgyh\\95566SZ010006435.pfx +#bank.china.sign.key.file=/opt/server/wmkj/hsdzgyh.pfx +# 支付网关PGWPortal地址 +bank.china.pgw.portal.url= +# 上传下载BocnetExpress地址 +bank.china.bocnet.express.url= +# 签名证书密码 +bank.china.sign.key.password=111111 +# 验签的中行根证书 +bank.china.verify.cer.file=D:\\zgyh\\boccfcaTest.cer +#bank.china.verify.cer.file=/opt/server/wmkj/sub.cer +# 下载文件保存路径 +bank.china.download.dir= +# 上传的文件路径 +bank.china.upload.file= +# API请求域名 +bank.china.domain=http://219.145.85.186 +# 商户号 +bank.china.merchant.no=104670110688695 +# 子商户公众账号ID +bank.china.sub.appid=wx0ad18b7f3c9ad6ab +# 支付结果通知域名 +#bank.china.notify.domain=https://zhgh.hrbnu.edu.cn +bank.china.notify.domain=https://202.118.128.22