银行支付对接
This commit is contained in:
@@ -1,91 +1,263 @@
|
|||||||
package io.v.nutz.pay.bank.china.controller;
|
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.Api;
|
||||||
import io.v.nutz.pay.annotations.ApiOperation;
|
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.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.bank.china.sign.BankPaySign;
|
||||||
|
import io.v.nutz.pay.cache.ChinaBankOrderPayNotifyCacheService;
|
||||||
import io.v.nutz.pay.cache.ChinaBankOrderWaitPayCacheService;
|
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.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 lombok.extern.slf4j.Slf4j;
|
||||||
import org.nutz.integration.jedis.RedisService;
|
|
||||||
import org.nutz.ioc.loader.annotation.Inject;
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
import org.nutz.mvc.annotation.At;
|
import org.nutz.mvc.annotation.At;
|
||||||
import org.nutz.mvc.annotation.Ok;
|
import org.nutz.mvc.annotation.Ok;
|
||||||
import org.w3c.dom.Document;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中国银行支付通知 controller
|
||||||
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@IocBean
|
@IocBean
|
||||||
@Api("支付通知")
|
@Api("中国银行支付通知")
|
||||||
@At("/notify")
|
@At("/notify/china/bank/new")
|
||||||
public class BankNotifyController
|
public class BankNotifyController {
|
||||||
{
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private IMemberPayRecordService memberPayRecordService;
|
private IMemberPayRecordService memberPayRecordService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private RedisService redisService;
|
private ChinaBankOrderWaitPayCacheService chinaBankOrderWaitPayCacheService;
|
||||||
|
|
||||||
private final static String SSK_MEMBER_PAY_ORDER_RECORD = "SSK:MEMBER:PAY:ORDER:RECORD:";
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ChinaBankOrderWaitPayCacheService chinaBankOrderWaitPayCacheService;
|
private ChinaBankOrderPayNotifyCacheService chinaBankOrderPayNotifyCacheService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ChinaPayProperties chinaPayProperties;
|
private ChinaPayProperties chinaPayProperties;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private IChinaBankPayNotifyRecordService chinaBankPayNotifyRecordService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private MemberPaymentService memberPaymentService;
|
||||||
|
|
||||||
|
@At("/pay")
|
||||||
@Ok("json")
|
@Ok("json")
|
||||||
@At("/china/bank/pay")
|
@ApiOperation("中国银行支付通知")
|
||||||
@ApiOperation("通过支付商品交易单号查询支付记录")
|
public Result payResultNotify(HttpServletRequest req, HttpServletResponse resp) {
|
||||||
public void cashRecvDcepNotify(HttpServletRequest request) {
|
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 ----------");
|
log.info("收到中行银行支付结果通知new: merchantNo->{}, orderNo->{}, orderSeq->{}, cardTyp->{}, payTime->{}, orderStatus->{}, payAmount->{}, orderIp->{}, orderRefer->{}, bankTranSeq->{}, returnActFlag->{}, phoneNum->{}, unionPaySeq->{}",
|
||||||
String message = request.getParameter("message");
|
merchantNo, orderNo, orderSeq, cardTyp, payTime, orderStatus, payAmount, orderIp, orderRefer, bankTranSeq, returnActFlag, phoneNum, unionPaySeq);
|
||||||
String signature = request.getParameter("signature");
|
if (StrUtil.isBlank(merchantNo)) {
|
||||||
log.info("[message]=[" + message + "]");
|
log.error("orderNo 为空");
|
||||||
log.info("[signature]=[" + signature + "]");
|
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
|
try {
|
||||||
{
|
// 关键数据空值校验
|
||||||
String plainText = new String(io.v.nutz.pay.util.Base64.decode(message), "UTF-8");
|
if (StrUtil.isBlank(orderNo)) {
|
||||||
log.debug("[base64解码后message]=[" + plainText + "]");
|
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();
|
chinaPayProperties.load();
|
||||||
boolean isValid = BankPaySign.getInstance().verifySignature(
|
|
||||||
chinaPayProperties.getVerifyCerFile(),
|
|
||||||
signature,
|
|
||||||
plainText
|
|
||||||
);
|
|
||||||
|
|
||||||
if(!isValid) {
|
if (StrUtil.isNotBlank(merchantNo) && !chinaPayProperties.getMerchantNo().equals(merchantNo)) {
|
||||||
log.error("[VERIFY FAILED] 中国银行支付通知验签失败");
|
log.error("商户号不匹配: 通知中的商户号->{}, 配置中的商户号->{}", merchantNo, chinaPayProperties.getMerchantNo());
|
||||||
throw new RuntimeException("签名验证失败");
|
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);
|
// boolean verified = BankPaySign.getInstance().verifySignData(
|
||||||
String responseCode = XmlUtil.getNodeText(document, "responseCode");
|
// chinaPayProperties.getVerifyCerFile(),
|
||||||
if("OK".equals(responseCode)){
|
// verifyData,
|
||||||
String orderNo = XmlUtil.getNodeText(document, "orderNo");
|
// signData);
|
||||||
String tranStatus = XmlUtil.getNodeText(document, "tranStatus");
|
|
||||||
String payCatalog = XmlUtil.getNodeText(document, "payCatalog");
|
// notifyRecord.setVerifyResult(verified ? 1 : 0);
|
||||||
log.debug("[orderNo]=["+orderNo+"] [tranStatus]=["+ tranStatus+"] [payCatalog]=["+payCatalog+"]");
|
//
|
||||||
request.setAttribute("result",responseCode+",Notice Success!");
|
// 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;
|
package io.v.nutz.pay.notify;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.wizzer.framework.base.Result;
|
import cn.wizzer.framework.base.Result;
|
||||||
import io.v.nutz.pay.annotations.Api;
|
import io.v.nutz.pay.annotations.Api;
|
||||||
import io.v.nutz.pay.annotations.ApiOperation;
|
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.ChinaBankOrderPayNotifyCacheService;
|
||||||
import io.v.nutz.pay.cache.ChinaBankOrderWaitPayCacheService;
|
import io.v.nutz.pay.cache.ChinaBankOrderWaitPayCacheService;
|
||||||
import io.v.nutz.pay.notify.enums.PayNotifyOrderStatusEnum;
|
import io.v.nutz.pay.notify.enums.PayNotifyOrderStatusEnum;
|
||||||
import io.v.nutz.pay.notify.enums.PayNotifyReturnActFlagEnum;
|
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.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 lombok.extern.slf4j.Slf4j;
|
||||||
import org.nutz.integration.jedis.RedisService;
|
import org.nutz.integration.jedis.RedisService;
|
||||||
import org.nutz.ioc.loader.annotation.Inject;
|
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.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 中国银行支付通知 controller
|
* 中国银行支付通知 controller
|
||||||
@@ -36,52 +44,219 @@ public class ChinaBankPayResultNotify {
|
|||||||
@Inject
|
@Inject
|
||||||
private ChinaBankOrderPayNotifyCacheService chinaBankOrderPayNotifyCacheService;
|
private ChinaBankOrderPayNotifyCacheService chinaBankOrderPayNotifyCacheService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ChinaPayProperties chinaPayProperties;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private IChinaBankPayNotifyRecordService chinaBankPayNotifyRecordService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private MemberPaymentService memberPaymentService;
|
||||||
|
|
||||||
@At("/pay")
|
@At("/pay")
|
||||||
@Ok("json")
|
@Ok("json")
|
||||||
@ApiOperation("中国银行支付通知")
|
@ApiOperation("中国银行支付通知")
|
||||||
public Result payResultNotify(HttpServletRequest req, HttpServletResponse resp) {
|
public Result payResultNotify(HttpServletRequest req, HttpServletResponse resp) {
|
||||||
// 商户订单号
|
String merchantNo = req.getParameter("merchantNo");
|
||||||
String orderNo = req.getParameter("orderNo");
|
String orderNo = req.getParameter("orderNo");
|
||||||
// 银行订单流水号
|
|
||||||
String orderSeq = req.getParameter("orderSeq");
|
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 orderStatus = req.getParameter("orderStatus");
|
||||||
// 银行交易流水号
|
|
||||||
String bankTranSeq = req.getParameter("bankTranSeq");
|
|
||||||
// 中行签名数据
|
|
||||||
String signData = req.getParameter("signData");
|
|
||||||
// 支付金额
|
|
||||||
String payAmount = req.getParameter("payAmount");
|
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");
|
String returnActFlag = req.getParameter("returnActFlag");
|
||||||
log.info("收到中行银行支付结果通知: orderNo->{}, orderSeq->{}, orderStatus->{}, bankTranSeq->{}, payAmount->{}, signData->{}", orderNo, orderSeq, orderStatus, bankTranSeq, payAmount, signData);
|
String phoneNum = req.getParameter("phoneNum");
|
||||||
log.info("收到中行银行支付结果通知: returnActFlag->{}", returnActFlag);
|
String unionPaySeq = req.getParameter("unionPaySeq");
|
||||||
|
String signData = req.getParameter("signData");
|
||||||
|
|
||||||
try{
|
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(PayNotifyReturnActFlagEnum.PAY_RESULT_NOTIFY.getCode().equals(returnActFlag)) {
|
if (StrUtil.isBlank(merchantNo)) {
|
||||||
// 设置30秒内同一个商户订单 不可重复接收到通知
|
log.error("orderNo 为空");
|
||||||
if(chinaBankOrderPayNotifyCacheService.exists(orderNo)) {
|
return Result.error("merchantNo 为空");
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
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();
|
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=cluster
|
||||||
redis.mode=normal
|
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
|
#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.driver=dm.jdbc.driver.DmDriver
|
||||||
#jdbc.url=jdbc:dm://127.0.0.1:5236?databaseProductName=dm mysql&compatibleMode=mysql
|
#jdbc.url=jdbc:dm://127.0.0.1:5236?databaseProductName=dm mysql&compatibleMode=mysql
|
||||||
jdbc.username=root
|
jdbc.username=root
|
||||||
@@ -141,4 +141,29 @@ logback.exts.loglevel.enabled=true
|
|||||||
logback.exts.loglevel.heartbeat=15
|
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