银行支付对接
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user