Commit 252369f9 authored by terrfly's avatar terrfly
Browse files

支付网关支持商户应用配置项的下单操作;

parent bc3a2fa5
...@@ -25,7 +25,7 @@ import com.jeequan.jeepay.pay.rqrs.payorder.payway.YsfBarOrderRQ; ...@@ -25,7 +25,7 @@ import com.jeequan.jeepay.pay.rqrs.payorder.payway.YsfBarOrderRQ;
import com.jeequan.jeepay.pay.rqrs.payorder.payway.YsfBarOrderRS; import com.jeequan.jeepay.pay.rqrs.payorder.payway.YsfBarOrderRS;
import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg; import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.pay.util.ApiResBuilder; import com.jeequan.jeepay.pay.util.ApiResBuilder;
import com.jeequan.jeepay.pay.model.MchConfigContext; import com.jeequan.jeepay.pay.model.MchAppConfigContext;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -50,7 +50,7 @@ public class YsfBar extends YsfpayPaymentService { ...@@ -50,7 +50,7 @@ public class YsfBar extends YsfpayPaymentService {
return null; return null;
} }
public AbstractRS pay(UnifiedOrderRQ rq, PayOrder payOrder, MchConfigContext mchConfigContext) throws Exception { public AbstractRS pay(UnifiedOrderRQ rq, PayOrder payOrder, MchAppConfigContext mchAppConfigContext) throws Exception {
String logPrefix = "【云闪付条码(unionpay)支付】"; String logPrefix = "【云闪付条码(unionpay)支付】";
YsfBarOrderRQ bizRQ = (YsfBarOrderRQ) rq; YsfBarOrderRQ bizRQ = (YsfBarOrderRQ) rq;
...@@ -68,7 +68,7 @@ public class YsfBar extends YsfpayPaymentService { ...@@ -68,7 +68,7 @@ public class YsfBar extends YsfpayPaymentService {
reqParams.put("termInfo", "{\"ip\": \""+StringUtils.defaultIfEmpty(payOrder.getClientIp(), "127.0.0.1")+"\"}"); //终端信息 reqParams.put("termInfo", "{\"ip\": \""+StringUtils.defaultIfEmpty(payOrder.getClientIp(), "127.0.0.1")+"\"}"); //终端信息
// 发送请求 // 发送请求
JSONObject resJSON = packageParamAndReq("/gateway/api/pay/micropay", reqParams, logPrefix, mchConfigContext.getIsvConfigContext(), mchConfigContext); JSONObject resJSON = packageParamAndReq("/gateway/api/pay/micropay", reqParams, logPrefix, mchAppConfigContext.getIsvConfigContext(), mchAppConfigContext);
//请求 & 响应成功, 判断业务逻辑 //请求 & 响应成功, 判断业务逻辑
String respCode = resJSON.getString("respCode"); //应答码 String respCode = resJSON.getString("respCode"); //应答码
String respMsg = resJSON.getString("respMsg"); //应答信息 String respMsg = resJSON.getString("respMsg"); //应答信息
......
...@@ -25,7 +25,7 @@ import com.jeequan.jeepay.pay.rqrs.payorder.payway.YsfJsapiOrderRS; ...@@ -25,7 +25,7 @@ import com.jeequan.jeepay.pay.rqrs.payorder.payway.YsfJsapiOrderRS;
import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg; import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.pay.util.ApiResBuilder; import com.jeequan.jeepay.pay.util.ApiResBuilder;
import com.jeequan.jeepay.pay.model.IsvConfigContext; import com.jeequan.jeepay.pay.model.IsvConfigContext;
import com.jeequan.jeepay.pay.model.MchConfigContext; import com.jeequan.jeepay.pay.model.MchAppConfigContext;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -44,7 +44,7 @@ public class YsfJsapi extends YsfpayPaymentService { ...@@ -44,7 +44,7 @@ public class YsfJsapi extends YsfpayPaymentService {
return null; return null;
} }
public AbstractRS pay(UnifiedOrderRQ rq, PayOrder payOrder, IsvConfigContext isvConfigContext, MchConfigContext mchConfigContext) throws Exception { public AbstractRS pay(UnifiedOrderRQ rq, PayOrder payOrder, IsvConfigContext isvConfigContext, MchAppConfigContext mchAppConfigContext) throws Exception {
String logPrefix = "【云闪付(unionpay)jsapi支付】"; String logPrefix = "【云闪付(unionpay)jsapi支付】";
JSONObject reqParams = new JSONObject(); JSONObject reqParams = new JSONObject();
YsfJsapiOrderRS res = ApiResBuilder.buildSuccess(YsfJsapiOrderRS.class); YsfJsapiOrderRS res = ApiResBuilder.buildSuccess(YsfJsapiOrderRS.class);
...@@ -61,7 +61,7 @@ public class YsfJsapi extends YsfpayPaymentService { ...@@ -61,7 +61,7 @@ public class YsfJsapi extends YsfpayPaymentService {
//客户端IP //客户端IP
reqParams.put("customerIp", StringUtils.defaultIfEmpty(payOrder.getClientIp(), "127.0.0.1")); reqParams.put("customerIp", StringUtils.defaultIfEmpty(payOrder.getClientIp(), "127.0.0.1"));
// 发送请求并返回订单状态 // 发送请求并返回订单状态
JSONObject resJSON = packageParamAndReq("/gateway/api/pay/unifiedorder", reqParams, logPrefix, isvConfigContext, mchConfigContext); JSONObject resJSON = packageParamAndReq("/gateway/api/pay/unifiedorder", reqParams, logPrefix, isvConfigContext, mchAppConfigContext);
//请求 & 响应成功, 判断业务逻辑 //请求 & 响应成功, 判断业务逻辑
String respCode = resJSON.getString("respCode"); //应答码 String respCode = resJSON.getString("respCode"); //应答码
String respMsg = resJSON.getString("respMsg"); //应答信息 String respMsg = resJSON.getString("respMsg"); //应答信息
......
...@@ -18,10 +18,12 @@ package com.jeequan.jeepay.pay.ctrl; ...@@ -18,10 +18,12 @@ package com.jeequan.jeepay.pay.ctrl;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.CS; import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.ctrls.AbstractCtrl; import com.jeequan.jeepay.core.ctrls.AbstractCtrl;
import com.jeequan.jeepay.core.entity.MchApp;
import com.jeequan.jeepay.core.entity.MchInfo; import com.jeequan.jeepay.core.entity.MchInfo;
import com.jeequan.jeepay.core.exception.BizException; import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.utils.JeepayKit; import com.jeequan.jeepay.core.utils.JeepayKit;
import com.jeequan.jeepay.pay.model.MchConfigContext; import com.jeequan.jeepay.pay.model.MchAppConfigContext;
import com.jeequan.jeepay.pay.rqrs.AbstractMchAppRQ;
import com.jeequan.jeepay.pay.rqrs.AbstractRQ; import com.jeequan.jeepay.pay.rqrs.AbstractRQ;
import com.jeequan.jeepay.pay.service.ConfigContextService; import com.jeequan.jeepay.pay.service.ConfigContextService;
import com.jeequan.jeepay.pay.service.ValidateService; import com.jeequan.jeepay.pay.service.ValidateService;
...@@ -59,29 +61,40 @@ public abstract class ApiController extends AbstractCtrl { ...@@ -59,29 +61,40 @@ public abstract class ApiController extends AbstractCtrl {
//获取请求RQ, and 通用验证 //获取请求RQ, and 通用验证
T bizRQ = getRQ(cls); T bizRQ = getRQ(cls);
// 转换为 JSON AbstractMchAppRQ abstractMchAppRQ = (AbstractMchAppRQ)bizRQ;
JSONObject bizReqJSON = (JSONObject)JSONObject.toJSON(bizRQ);
// [2]. 业务校验, 包括: 验签, 商户状态是否可用, 是否支持该支付方式下单等。 //业务校验, 包括: 验签, 商户状态是否可用, 是否支持该支付方式下单等。
String mchNo = bizReqJSON.getString("mchNo"); String mchNo = abstractMchAppRQ.getMchNo();
String appId = abstractMchAppRQ.getAppId();
String sign = bizRQ.getSign(); String sign = bizRQ.getSign();
if(StringUtils.isAnyEmpty(mchNo, sign)){ if(StringUtils.isAnyBlank(mchNo, appId, sign)){
throw new BizException("参数有误!"); throw new BizException("参数有误!");
} }
MchConfigContext mchConfigContext = configContextService.getMchConfigContext(mchNo); MchAppConfigContext mchAppConfigContext = configContextService.getMchAppConfigContext(mchNo, appId);
MchInfo mchInfo = mchConfigContext == null ? null : mchConfigContext.getMchInfo(); MchInfo mchInfo = mchAppConfigContext == null ? null : mchAppConfigContext.getMchInfo();
if(mchInfo == null || mchInfo.getState() != CS.YES){ if(mchInfo == null || mchInfo.getState() != CS.YES){
throw new BizException("商户不存在或商户状态不可用"); throw new BizException("商户不存在或商户状态不可用");
} }
MchApp mchApp = mchAppConfigContext == null ? null : mchAppConfigContext.getMchApp();
if(mchInfo == null || mchInfo.getState() != CS.YES){
throw new BizException("商户应用不存在或商户状态不可用");
}
if(!mchApp.getMchNo().equals(mchNo)){
throw new BizException("商户应用与商户号不匹配");
}
// 验签 // 验签
String privateKey = mchInfo.getPrivateKey(); String appSecret = mchApp.getAppSecret();
// 转换为 JSON
JSONObject bizReqJSON = (JSONObject)JSONObject.toJSON(bizRQ);
bizReqJSON.remove("sign"); bizReqJSON.remove("sign");
if(!sign.equalsIgnoreCase(JeepayKit.getSign(bizReqJSON, privateKey))){ if(!sign.equalsIgnoreCase(JeepayKit.getSign(bizReqJSON, appSecret))){
throw new BizException("验签失败"); throw new BizException("验签失败");
} }
......
...@@ -17,6 +17,7 @@ package com.jeequan.jeepay.pay.ctrl.payorder; ...@@ -17,6 +17,7 @@ package com.jeequan.jeepay.pay.ctrl.payorder;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import com.jeequan.jeepay.core.constants.CS; import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.MchApp;
import com.jeequan.jeepay.core.entity.MchInfo; import com.jeequan.jeepay.core.entity.MchInfo;
import com.jeequan.jeepay.core.entity.MchPayPassage; import com.jeequan.jeepay.core.entity.MchPayPassage;
import com.jeequan.jeepay.core.entity.PayOrder; import com.jeequan.jeepay.core.entity.PayOrder;
...@@ -29,7 +30,7 @@ import com.jeequan.jeepay.pay.channel.IPaymentService; ...@@ -29,7 +30,7 @@ import com.jeequan.jeepay.pay.channel.IPaymentService;
import com.jeequan.jeepay.pay.ctrl.ApiController; import com.jeequan.jeepay.pay.ctrl.ApiController;
import com.jeequan.jeepay.pay.exception.ChannelException; import com.jeequan.jeepay.pay.exception.ChannelException;
import com.jeequan.jeepay.pay.model.IsvConfigContext; import com.jeequan.jeepay.pay.model.IsvConfigContext;
import com.jeequan.jeepay.pay.model.MchConfigContext; import com.jeequan.jeepay.pay.model.MchAppConfigContext;
import com.jeequan.jeepay.pay.mq.queue.MqQueue4ChannelOrderQuery; import com.jeequan.jeepay.pay.mq.queue.MqQueue4ChannelOrderQuery;
import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg; import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRQ; import com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRQ;
...@@ -102,6 +103,7 @@ public abstract class AbstractPayOrderController extends ApiController { ...@@ -102,6 +103,7 @@ public abstract class AbstractPayOrderController extends ApiController {
} }
String mchNo = bizRQ.getMchNo(); String mchNo = bizRQ.getMchNo();
String appId = bizRQ.getAppId();
// 只有新订单模式,进行校验 // 只有新订单模式,进行校验
if(isNewOrder && payOrderService.count(PayOrder.gw().eq(PayOrder::getMchNo, mchNo).eq(PayOrder::getMchOrderNo, bizRQ.getMchOrderNo())) > 0){ if(isNewOrder && payOrderService.count(PayOrder.gw().eq(PayOrder::getMchNo, mchNo).eq(PayOrder::getMchOrderNo, bizRQ.getMchOrderNo())) > 0){
...@@ -116,18 +118,19 @@ public abstract class AbstractPayOrderController extends ApiController { ...@@ -116,18 +118,19 @@ public abstract class AbstractPayOrderController extends ApiController {
} }
//获取支付参数 (缓存数据) 和 商户信息 //获取支付参数 (缓存数据) 和 商户信息
MchConfigContext mchConfigContext = configContextService.getMchConfigContext(mchNo); MchAppConfigContext mchAppConfigContext = configContextService.getMchAppConfigContext(mchNo, appId);
if(mchConfigContext == null){ if(mchAppConfigContext == null){
throw new BizException("获取商户信息失败"); throw new BizException("获取商户应用信息失败");
} }
MchInfo mchInfo = mchConfigContext.getMchInfo(); MchInfo mchInfo = mchAppConfigContext.getMchInfo();
MchApp mchApp = mchAppConfigContext.getMchApp();
//收银台支付并且只有新订单需要走这里, 收银台二次下单的wayCode应该为实际支付方式。 //收银台支付并且只有新订单需要走这里, 收银台二次下单的wayCode应该为实际支付方式。
if(isNewOrder && CS.PAY_WAY_CODE.QR_CASHIER.equals(wayCode)){ if(isNewOrder && CS.PAY_WAY_CODE.QR_CASHIER.equals(wayCode)){
//生成订单 //生成订单
payOrder = genPayOrder(bizRQ, mchInfo, null); payOrder = genPayOrder(bizRQ, mchInfo, mchApp, null);
String payOrderId = payOrder.getPayOrderId(); String payOrderId = payOrder.getPayOrderId();
//订单入库 订单状态: 生成状态 此时没有和任何上游渠道产生交互。 //订单入库 订单状态: 生成状态 此时没有和任何上游渠道产生交互。
payOrderService.save(payOrder); payOrderService.save(payOrder);
...@@ -147,12 +150,12 @@ public abstract class AbstractPayOrderController extends ApiController { ...@@ -147,12 +150,12 @@ public abstract class AbstractPayOrderController extends ApiController {
} }
//获取支付接口 //获取支付接口
IPaymentService paymentService = checkMchWayCodeAndGetService(mchConfigContext, wayCode); IPaymentService paymentService = checkMchWayCodeAndGetService(mchAppConfigContext, wayCode);
String ifCode = paymentService.getIfCode(); String ifCode = paymentService.getIfCode();
//生成订单 //生成订单
if(isNewOrder){ if(isNewOrder){
payOrder = genPayOrder(bizRQ, mchInfo, ifCode); payOrder = genPayOrder(bizRQ, mchInfo, mchApp, ifCode);
}else{ }else{
payOrder.setIfCode(ifCode); payOrder.setIfCode(ifCode);
} }
...@@ -169,7 +172,7 @@ public abstract class AbstractPayOrderController extends ApiController { ...@@ -169,7 +172,7 @@ public abstract class AbstractPayOrderController extends ApiController {
} }
//调起上游支付接口 //调起上游支付接口
bizRS = (UnifiedOrderRS) paymentService.pay(bizRQ, payOrder, mchConfigContext); bizRS = (UnifiedOrderRS) paymentService.pay(bizRQ, payOrder, mchAppConfigContext);
//处理上游返回数据 //处理上游返回数据
this.processChannelMsg(bizRS.getChannelRetMsg(), payOrder); this.processChannelMsg(bizRS.getChannelRetMsg(), payOrder);
...@@ -197,7 +200,7 @@ public abstract class AbstractPayOrderController extends ApiController { ...@@ -197,7 +200,7 @@ public abstract class AbstractPayOrderController extends ApiController {
} }
} }
private PayOrder genPayOrder(UnifiedOrderRQ rq, MchInfo mchInfo, String ifCode){ private PayOrder genPayOrder(UnifiedOrderRQ rq, MchInfo mchInfo, MchApp mchApp, String ifCode){
PayOrder payOrder = new PayOrder(); PayOrder payOrder = new PayOrder();
payOrder.setPayOrderId(SeqKit.genPayOrderId()); //生成订单ID payOrder.setPayOrderId(SeqKit.genPayOrderId()); //生成订单ID
...@@ -206,6 +209,7 @@ public abstract class AbstractPayOrderController extends ApiController { ...@@ -206,6 +209,7 @@ public abstract class AbstractPayOrderController extends ApiController {
payOrder.setMchName(mchInfo.getMchShortName()); //商户名称(简称) payOrder.setMchName(mchInfo.getMchShortName()); //商户名称(简称)
payOrder.setMchType(mchInfo.getType()); //商户类型 payOrder.setMchType(mchInfo.getType()); //商户类型
payOrder.setMchOrderNo(rq.getMchOrderNo()); //商户订单号 payOrder.setMchOrderNo(rq.getMchOrderNo()); //商户订单号
payOrder.setAppId(mchApp.getAppId()); //商户应用appId
payOrder.setIfCode(ifCode); //接口代码 payOrder.setIfCode(ifCode); //接口代码
payOrder.setWayCode(rq.getWayCode()); //支付方式 payOrder.setWayCode(rq.getWayCode()); //支付方式
payOrder.setAmount(rq.getAmount()); //订单金额 payOrder.setAmount(rq.getAmount()); //订单金额
...@@ -233,10 +237,10 @@ public abstract class AbstractPayOrderController extends ApiController { ...@@ -233,10 +237,10 @@ public abstract class AbstractPayOrderController extends ApiController {
* 校验: 商户的支付方式是否可用 * 校验: 商户的支付方式是否可用
* 返回: 支付接口 * 返回: 支付接口
* **/ * **/
private IPaymentService checkMchWayCodeAndGetService(MchConfigContext mchConfigContext, String wayCode){ private IPaymentService checkMchWayCodeAndGetService(MchAppConfigContext mchAppConfigContext, String wayCode){
// 根据支付方式, 查询出 该商户 可用的支付接口 // 根据支付方式, 查询出 该商户 可用的支付接口
MchPayPassage mchPayPassage = mchPayPassageService.findMchPayPassage(mchConfigContext.getMchNo(), wayCode); MchPayPassage mchPayPassage = mchPayPassageService.findMchPayPassage(mchAppConfigContext.getMchNo(), wayCode);
if(mchPayPassage == null){ if(mchPayPassage == null){
throw new BizException("该支付方式商户未开通"); throw new BizException("该支付方式商户未开通");
} }
...@@ -252,20 +256,20 @@ public abstract class AbstractPayOrderController extends ApiController { ...@@ -252,20 +256,20 @@ public abstract class AbstractPayOrderController extends ApiController {
throw new BizException("接口不支持该支付方式"); throw new BizException("接口不支持该支付方式");
} }
if(mchConfigContext.getMchType() == MchInfo.TYPE_NORMAL){ //普通商户 if(mchAppConfigContext.getMchType() == MchInfo.TYPE_NORMAL){ //普通商户
if(mchConfigContext == null || mchConfigContext.getNormalMchParamsByIfCode(ifCode) == null){ if(mchAppConfigContext == null || mchAppConfigContext.getNormalMchParamsByIfCode(ifCode) == null){
throw new BizException("商户参数未配置"); throw new BizException("商户应用参数未配置");
} }
}else if(mchConfigContext.getMchType() == MchInfo.TYPE_ISVSUB){ //特约商户 }else if(mchAppConfigContext.getMchType() == MchInfo.TYPE_ISVSUB){ //特约商户
mchConfigContext = configContextService.getMchConfigContext(mchConfigContext.getMchNo()); mchAppConfigContext = configContextService.getMchAppConfigContext(mchAppConfigContext.getMchNo(), mchAppConfigContext.getAppId());
if(mchConfigContext == null || mchConfigContext.getIsvsubMchParamsByIfCode(ifCode) == null){ if(mchAppConfigContext == null || mchAppConfigContext.getIsvsubMchParamsByIfCode(ifCode) == null){
throw new BizException("特约商户参数未配置"); throw new BizException("特约商户参数未配置");
} }
IsvConfigContext isvConfigContext = configContextService.getIsvConfigContext(mchConfigContext.getMchInfo().getIsvNo()); IsvConfigContext isvConfigContext = configContextService.getIsvConfigContext(mchAppConfigContext.getMchInfo().getIsvNo());
if(isvConfigContext == null || isvConfigContext.getIsvParamsByIfCode(ifCode) == null){ if(isvConfigContext == null || isvConfigContext.getIsvParamsByIfCode(ifCode) == null){
throw new BizException("服务商参数未配置"); throw new BizException("服务商参数未配置");
...@@ -359,7 +363,7 @@ public abstract class AbstractPayOrderController extends ApiController { ...@@ -359,7 +363,7 @@ public abstract class AbstractPayOrderController extends ApiController {
bizRS.setErrMsg(bizRS.getChannelRetMsg() != null ? bizRS.getChannelRetMsg().getChannelErrMsg() : null); bizRS.setErrMsg(bizRS.getChannelRetMsg() != null ? bizRS.getChannelRetMsg().getChannelErrMsg() : null);
} }
return ApiRes.okWithSign(bizRS, configContextService.getMchConfigContext(bizRQ.getMchNo()).getMchInfo().getPrivateKey()); return ApiRes.okWithSign(bizRS, configContextService.getMchAppConfigContext(bizRQ.getMchNo(), bizRQ.getAppId()).getMchApp().getAppSecret());
} }
......
...@@ -21,7 +21,7 @@ import com.jeequan.jeepay.core.exception.BizException; ...@@ -21,7 +21,7 @@ import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.exception.ResponseException; import com.jeequan.jeepay.core.exception.ResponseException;
import com.jeequan.jeepay.core.utils.SpringBeansUtil; import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.pay.channel.IChannelNoticeService; import com.jeequan.jeepay.pay.channel.IChannelNoticeService;
import com.jeequan.jeepay.pay.model.MchConfigContext; import com.jeequan.jeepay.pay.model.MchAppConfigContext;
import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg; import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.pay.service.ConfigContextService; import com.jeequan.jeepay.pay.service.ConfigContextService;
import com.jeequan.jeepay.pay.service.PayMchNotifyService; import com.jeequan.jeepay.pay.service.PayMchNotifyService;
...@@ -102,14 +102,11 @@ public class ChannelNoticeController extends AbstractCtrl { ...@@ -102,14 +102,11 @@ public class ChannelNoticeController extends AbstractCtrl {
return this.toReturnPage("支付订单不存在"); return this.toReturnPage("支付订单不存在");
} }
//查询出商户的配置信息 //查询出商户应用的配置信息
String mchNo = payOrder.getMchNo(); MchAppConfigContext mchAppConfigContext = configContextService.getMchAppConfigContext(payOrder.getMchNo(), payOrder.getAppId());
//查询出商户配置参数
MchConfigContext mchConfigContext = configContextService.getMchConfigContext(mchNo);
//调起接口的回调判断 //调起接口的回调判断
ChannelRetMsg notifyResult = payNotifyService.doNotice(request, mutablePair.getRight(), payOrder, mchConfigContext, IChannelNoticeService.NoticeTypeEnum.DO_RETURN); ChannelRetMsg notifyResult = payNotifyService.doNotice(request, mutablePair.getRight(), payOrder, mchAppConfigContext, IChannelNoticeService.NoticeTypeEnum.DO_RETURN);
// 返回null 表明出现异常, 无需处理通知下游等操作。 // 返回null 表明出现异常, 无需处理通知下游等操作。
if(notifyResult == null || notifyResult.getChannelState() == null || notifyResult.getResponseEntity() == null){ if(notifyResult == null || notifyResult.getChannelState() == null || notifyResult.getResponseEntity() == null){
...@@ -130,7 +127,7 @@ public class ChannelNoticeController extends AbstractCtrl { ...@@ -130,7 +127,7 @@ public class ChannelNoticeController extends AbstractCtrl {
//包含通知地址时 //包含通知地址时
if(hasReturnUrl){ if(hasReturnUrl){
// 重定向 // 重定向
response.sendRedirect(payMchNotifyService.createReturnUrl(payOrder, mchConfigContext.getMchInfo().getPrivateKey())); response.sendRedirect(payMchNotifyService.createReturnUrl(payOrder, mchAppConfigContext.getMchInfo().getPrivateKey()));
return null; return null;
}else{ }else{
...@@ -202,14 +199,11 @@ public class ChannelNoticeController extends AbstractCtrl { ...@@ -202,14 +199,11 @@ public class ChannelNoticeController extends AbstractCtrl {
return payNotifyService.doNotifyOrderNotExists(request); return payNotifyService.doNotifyOrderNotExists(request);
} }
//查询出商户的配置信息 //查询出商户应用的配置信息
String mchNo = payOrder.getMchNo(); MchAppConfigContext mchAppConfigContext = configContextService.getMchAppConfigContext(payOrder.getMchNo(), payOrder.getAppId());
//查询出商户配置参数
MchConfigContext mchConfigContext = configContextService.getMchConfigContext(mchNo);
//调起接口的回调判断 //调起接口的回调判断
ChannelRetMsg notifyResult = payNotifyService.doNotice(request, mutablePair.getRight(), payOrder, mchConfigContext, IChannelNoticeService.NoticeTypeEnum.DO_NOTIFY); ChannelRetMsg notifyResult = payNotifyService.doNotice(request, mutablePair.getRight(), payOrder, mchAppConfigContext, IChannelNoticeService.NoticeTypeEnum.DO_NOTIFY);
// 返回null 表明出现异常, 无需处理通知下游等操作。 // 返回null 表明出现异常, 无需处理通知下游等操作。
if(notifyResult == null || notifyResult.getChannelState() == null || notifyResult.getResponseEntity() == null){ if(notifyResult == null || notifyResult.getChannelState() == null || notifyResult.getResponseEntity() == null){
......
...@@ -61,7 +61,7 @@ public class QueryOrderController extends AbstractPayOrderController { ...@@ -61,7 +61,7 @@ public class QueryOrderController extends AbstractPayOrderController {
} }
QueryPayOrderRS bizRes = QueryPayOrderRS.buildByPayOrder(payOrder); QueryPayOrderRS bizRes = QueryPayOrderRS.buildByPayOrder(payOrder);
return ApiRes.okWithSign(bizRes, configContextService.getMchConfigContext(rq.getMchNo()).getMchInfo().getPrivateKey()); return ApiRes.okWithSign(bizRes, configContextService.getMchAppConfigContext(rq.getMchNo(), rq.getAppId()).getMchApp().getAppSecret());
} }
} }
...@@ -75,7 +75,7 @@ public class UnifiedOrderController extends AbstractPayOrderController { ...@@ -75,7 +75,7 @@ public class UnifiedOrderController extends AbstractPayOrderController {
res.setPayData(bizRes.buildPayData()); res.setPayData(bizRes.buildPayData());
} }
return ApiRes.okWithSign(res, configContextService.getMchConfigContext(rq.getMchNo()).getMchInfo().getPrivateKey()); return ApiRes.okWithSign(res, configContextService.getMchAppConfigContext(rq.getMchNo(), rq.getAppId()).getMchApp().getAppSecret());
} }
......
...@@ -25,7 +25,7 @@ import com.jeequan.jeepay.core.utils.SpringBeansUtil; ...@@ -25,7 +25,7 @@ import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.core.utils.StringKit; import com.jeequan.jeepay.core.utils.StringKit;
import com.jeequan.jeepay.pay.channel.IChannelUserService; import com.jeequan.jeepay.pay.channel.IChannelUserService;
import com.jeequan.jeepay.pay.ctrl.payorder.AbstractPayOrderController; import com.jeequan.jeepay.pay.ctrl.payorder.AbstractPayOrderController;
import com.jeequan.jeepay.pay.model.MchConfigContext; import com.jeequan.jeepay.pay.model.MchAppConfigContext;
import com.jeequan.jeepay.pay.rqrs.ChannelUserIdRQ; import com.jeequan.jeepay.pay.rqrs.ChannelUserIdRQ;
import com.jeequan.jeepay.pay.service.ConfigContextService; import com.jeequan.jeepay.pay.service.ConfigContextService;
import com.jeequan.jeepay.service.impl.SysConfigService; import com.jeequan.jeepay.service.impl.SysConfigService;
...@@ -71,6 +71,7 @@ public class ChannelUserIdController extends AbstractPayOrderController { ...@@ -71,6 +71,7 @@ public class ChannelUserIdController extends AbstractPayOrderController {
JSONObject jsonObject = new JSONObject(); JSONObject jsonObject = new JSONObject();
jsonObject.put("mchNo", rq.getMchNo()); jsonObject.put("mchNo", rq.getMchNo());
jsonObject.put("appId", rq.getAppId());
jsonObject.put("ifCode", ifCode); jsonObject.put("ifCode", ifCode);
jsonObject.put("redirectUrl", rq.getRedirectUrl()); jsonObject.put("redirectUrl", rq.getRedirectUrl());
...@@ -78,8 +79,8 @@ public class ChannelUserIdController extends AbstractPayOrderController { ...@@ -78,8 +79,8 @@ public class ChannelUserIdController extends AbstractPayOrderController {
String callbackUrl = sysConfigService.getDBApplicationConfig().genMchChannelUserIdApiOauth2RedirectUrlEncode(jsonObject); String callbackUrl = sysConfigService.getDBApplicationConfig().genMchChannelUserIdApiOauth2RedirectUrlEncode(jsonObject);
//获取商户配置信息 //获取商户配置信息
MchConfigContext mchConfigContext = configContextService.getMchConfigContext(rq.getMchNo()); MchAppConfigContext mchAppConfigContext = configContextService.getMchAppConfigContext(rq.getMchNo(), rq.getAppId());
String redirectUrl = channelUserService.buildUserRedirectUrl(callbackUrl, mchConfigContext); String redirectUrl = channelUserService.buildUserRedirectUrl(callbackUrl, mchAppConfigContext);
response.sendRedirect(redirectUrl); response.sendRedirect(redirectUrl);
} }
...@@ -92,6 +93,7 @@ public class ChannelUserIdController extends AbstractPayOrderController { ...@@ -92,6 +93,7 @@ public class ChannelUserIdController extends AbstractPayOrderController {
JSONObject callbackData = JSON.parseObject(JeepayKit.aesDecode(aesData)); JSONObject callbackData = JSON.parseObject(JeepayKit.aesDecode(aesData));
String mchNo = callbackData.getString("mchNo"); String mchNo = callbackData.getString("mchNo");
String appId = callbackData.getString("appId");
String ifCode = callbackData.getString("ifCode"); String ifCode = callbackData.getString("ifCode");
String redirectUrl = callbackData.getString("redirectUrl"); String redirectUrl = callbackData.getString("redirectUrl");
...@@ -103,10 +105,10 @@ public class ChannelUserIdController extends AbstractPayOrderController { ...@@ -103,10 +105,10 @@ public class ChannelUserIdController extends AbstractPayOrderController {
} }
//获取商户配置信息 //获取商户配置信息
MchConfigContext mchConfigContext = configContextService.getMchConfigContext(mchNo); MchAppConfigContext mchAppConfigContext = configContextService.getMchAppConfigContext(mchNo, appId);
//获取渠道用户ID //获取渠道用户ID
String channelUserId = channelUserService.getChannelUserId(getReqParamJSON(), mchConfigContext); String channelUserId = channelUserService.getChannelUserId(getReqParamJSON(), mchAppConfigContext);
//同步跳转 //同步跳转
response.sendRedirect(StringKit.appendUrlQuery(redirectUrl, JsonKit.newJson("channelUserId", channelUserId))); response.sendRedirect(StringKit.appendUrlQuery(redirectUrl, JsonKit.newJson("channelUserId", channelUserId)));
......
...@@ -28,7 +28,7 @@ import com.jeequan.jeepay.pay.rqrs.payorder.payway.AliJsapiOrderRQ; ...@@ -28,7 +28,7 @@ import com.jeequan.jeepay.pay.rqrs.payorder.payway.AliJsapiOrderRQ;
import com.jeequan.jeepay.pay.rqrs.payorder.payway.WxJsapiOrderRQ; import com.jeequan.jeepay.pay.rqrs.payorder.payway.WxJsapiOrderRQ;
import com.jeequan.jeepay.pay.service.PayMchNotifyService; import com.jeequan.jeepay.pay.service.PayMchNotifyService;
import com.jeequan.jeepay.pay.service.ConfigContextService; import com.jeequan.jeepay.pay.service.ConfigContextService;
import com.jeequan.jeepay.pay.model.MchConfigContext; import com.jeequan.jeepay.pay.model.MchAppConfigContext;
import com.jeequan.jeepay.service.impl.PayOrderService; import com.jeequan.jeepay.service.impl.PayOrderService;
import com.jeequan.jeepay.service.impl.SysConfigService; import com.jeequan.jeepay.service.impl.SysConfigService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -65,11 +65,11 @@ public class QrCashierController extends AbstractPayOrderController { ...@@ -65,11 +65,11 @@ public class QrCashierController extends AbstractPayOrderController {
String redirectUrlEncode = sysConfigService.getDBApplicationConfig().genOauth2RedirectUrlEncode(payOrder.getPayOrderId()); String redirectUrlEncode = sysConfigService.getDBApplicationConfig().genOauth2RedirectUrlEncode(payOrder.getPayOrderId());
//获取商户配置信息 //获取商户配置信息
MchConfigContext mchConfigContext = configContextService.getMchConfigContext(payOrder.getMchNo()); MchAppConfigContext mchAppConfigContext = configContextService.getMchAppConfigContext(payOrder.getMchNo(), payOrder.getAppId());
//获取接口并返回数据 //获取接口并返回数据
IChannelUserService channelUserService = getServiceByWayCode(getWayCode(), "ChannelUserService", IChannelUserService.class); IChannelUserService channelUserService = getServiceByWayCode(getWayCode(), "ChannelUserService", IChannelUserService.class);
return ApiRes.ok(channelUserService.buildUserRedirectUrl(redirectUrlEncode, mchConfigContext)); return ApiRes.ok(channelUserService.buildUserRedirectUrl(redirectUrlEncode, mchAppConfigContext));
} }
...@@ -85,9 +85,9 @@ public class QrCashierController extends AbstractPayOrderController { ...@@ -85,9 +85,9 @@ public class QrCashierController extends AbstractPayOrderController {
String wayCode = getWayCode(); String wayCode = getWayCode();
//获取商户配置信息 //获取商户配置信息
MchConfigContext mchConfigContext = configContextService.getMchConfigContext(payOrder.getMchNo()); MchAppConfigContext mchAppConfigContext = configContextService.getMchAppConfigContext(payOrder.getMchNo(), payOrder.getAppId());
IChannelUserService channelUserService = getServiceByWayCode(wayCode, "ChannelUserService", IChannelUserService.class); IChannelUserService channelUserService = getServiceByWayCode(wayCode, "ChannelUserService", IChannelUserService.class);
return ApiRes.ok(channelUserService.getChannelUserId(getReqParamJSON(), mchConfigContext)); return ApiRes.ok(channelUserService.getChannelUserId(getReqParamJSON(), mchAppConfigContext));
} }
...@@ -106,7 +106,7 @@ public class QrCashierController extends AbstractPayOrderController { ...@@ -106,7 +106,7 @@ public class QrCashierController extends AbstractPayOrderController {
resOrder.setMchOrderNo(payOrder.getMchOrderNo()); resOrder.setMchOrderNo(payOrder.getMchOrderNo());
resOrder.setMchName(payOrder.getMchName()); resOrder.setMchName(payOrder.getMchName());
resOrder.setAmount(payOrder.getAmount()); resOrder.setAmount(payOrder.getAmount());
resOrder.setReturnUrl(payMchNotifyService.createReturnUrl(payOrder, configContextService.getMchConfigContext(payOrder.getMchNo()).getMchInfo().getPrivateKey())); resOrder.setReturnUrl(payMchNotifyService.createReturnUrl(payOrder, configContextService.getMchAppConfigContext(payOrder.getMchNo(), payOrder.getAppId()).getMchApp().getAppSecret()));
return ApiRes.ok(resOrder); return ApiRes.ok(resOrder);
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
*/ */
package com.jeequan.jeepay.pay.model; package com.jeequan.jeepay.pay.model;
import com.jeequan.jeepay.core.entity.MchApp;
import com.jeequan.jeepay.core.entity.MchInfo; import com.jeequan.jeepay.core.entity.MchInfo;
import com.jeequan.jeepay.core.model.params.IsvsubMchParams; import com.jeequan.jeepay.core.model.params.IsvsubMchParams;
import com.jeequan.jeepay.core.model.params.NormalMchParams; import com.jeequan.jeepay.core.model.params.NormalMchParams;
...@@ -24,23 +25,25 @@ import java.util.HashMap; ...@@ -24,23 +25,25 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
/* /*
* 商户支付参数信息 * 商户应用支付参数信息
* 用户 放置到内存, 避免多次查询操作 * 放置到内存, 避免多次查询操作
* *
* @author terrfly * @author terrfly
* @site https://www.jeepay.vip * @site https://www.jeepay.vip
* @date 2021/6/8 17:29 * @date 2021/6/8 17:29
*/ */
@Data @Data
public class MchConfigContext { public class MchAppConfigContext {
/** 商户信息缓存 */ /** 商户信息缓存 */
private String mchNo; private String mchNo;
private String appId;
private Byte mchType; private Byte mchType;
private MchInfo mchInfo; private MchInfo mchInfo;
private MchApp mchApp;
/** 商户支付配置信息缓存 */ /** 商户支付配置信息缓存, <接口代码, 支付参数> */
private Map<String, NormalMchParams> normalMchParamsMap = new HashMap<>(); private Map<String, NormalMchParams> normalMchParamsMap = new HashMap<>();
private Map<String, IsvsubMchParams> isvsubMchParamsMap = new HashMap<>(); private Map<String, IsvsubMchParams> isvsubMchParamsMap = new HashMap<>();
......
/*
* Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jeequan.jeepay.pay.model;
import com.jeequan.jeepay.core.entity.MchApp;
import com.jeequan.jeepay.core.entity.MchInfo;
import lombok.Data;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/*
* 商户配置信息
* 放置到内存, 避免多次查询操作
*
* @author terrfly
* @site https://www.jeepay.vip
* @date 2021/6/8 17:29
*/
@Data
public class MchInfoConfigContext {
/** 商户信息缓存 */
private String mchNo;
private Byte mchType;
private MchInfo mchInfo;
private Map<String, MchApp> appMap = new ConcurrentHashMap<>();
/** 重置商户APP **/
public void putMchApp(MchApp mchApp){
appMap.put(mchApp.getAppId(), mchApp);
}
/** get商户APP **/
public MchApp getMchApp(String appId){
return appMap.get(appId);
}
}
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
*/ */
package com.jeequan.jeepay.pay.mq.topic; package com.jeequan.jeepay.pay.mq.topic;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.CS; import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.pay.service.ConfigContextService; import com.jeequan.jeepay.pay.service.ConfigContextService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
...@@ -40,14 +41,30 @@ public class MqTopic4ModifyMchInfo extends ActiveMQTopic{ ...@@ -40,14 +41,30 @@ public class MqTopic4ModifyMchInfo extends ActiveMQTopic{
super(CS.MQ.TOPIC_MODIFY_MCH_INFO); super(CS.MQ.TOPIC_MODIFY_MCH_INFO);
} }
/** 接收 更新系统配置项的消息 **/ /** 接收 [商户配置信息] 的消息
* 已知推送节点:
* 1. 更新商户基本资料和状态
* 2. 删除商户时
* **/
@JmsListener(destination = CS.MQ.TOPIC_MODIFY_MCH_INFO, containerFactory = "jmsListenerContainer") @JmsListener(destination = CS.MQ.TOPIC_MODIFY_MCH_INFO, containerFactory = "jmsListenerContainer")
public void receive(String mchNo) { public void receive(String mchNo) {
log.info("重置商户信息, msg={}", mchNo); log.info("接收 [商户配置信息] 的消息, msg={}", mchNo);
configContextService.initMchConfigContext(mchNo); configContextService.initMchInfoConfigContext(mchNo);
} }
/** 接收 [商户应用支付参数配置信息] 的消息
* 已知推送节点:
* 1. 更新商户应用配置
* 2. 删除商户应用配置
* **/
@JmsListener(destination = CS.MQ.TOPIC_MODIFY_MCH_APP, containerFactory = "jmsListenerContainer")
public void receiveMchApp(String mchNoAndAppId) {
log.info("接收 [商户应用支付参数配置信息] 的消息, msg={}", mchNoAndAppId);
JSONObject jsonObject = (JSONObject) JSONObject.parse(mchNoAndAppId);
configContextService.initMchAppConfigContext(jsonObject.getString("mchNo"), jsonObject.getString("appId"));
}
} }
/*
* Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jeequan.jeepay.pay.rqrs;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/*
*
* 通用RQ, 包含mchNo和appId 必填项
*
* @author terrfly
* @site https://www.jeepay.vip
* @date 2021/6/16 10:30
*/
@Data
public class AbstractMchAppRQ extends AbstractRQ {
/** 商户号 **/
@NotBlank(message="商户号不能为空")
private String mchNo;
/** 商户应用ID **/
@NotBlank(message="商户应用ID不能为空")
private String appId;
}
...@@ -27,7 +27,7 @@ import javax.validation.constraints.NotBlank; ...@@ -27,7 +27,7 @@ import javax.validation.constraints.NotBlank;
* @date 2021/6/8 17:40 * @date 2021/6/8 17:40
*/ */
@Data @Data
public class ChannelUserIdRQ extends AbstractRQ{ public class ChannelUserIdRQ extends AbstractMchAppRQ{
/** 商户号 **/ /** 商户号 **/
@NotBlank(message="商户号不能为空") @NotBlank(message="商户号不能为空")
......
...@@ -27,11 +27,7 @@ import javax.validation.constraints.NotBlank; ...@@ -27,11 +27,7 @@ import javax.validation.constraints.NotBlank;
* @date 2021/6/8 17:40 * @date 2021/6/8 17:40
*/ */
@Data @Data
public class QueryPayOrderRQ extends AbstractRQ{ public class QueryPayOrderRQ extends AbstractMchAppRQ{
/** 商户号 **/
@NotBlank(message="商户号不能为空")
private String mchNo;
/** 商户订单号 **/ /** 商户订单号 **/
private String mchOrderNo; private String mchOrderNo;
......
...@@ -17,7 +17,7 @@ package com.jeequan.jeepay.pay.rqrs.payorder; ...@@ -17,7 +17,7 @@ package com.jeequan.jeepay.pay.rqrs.payorder;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.CS; import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.pay.rqrs.AbstractRQ; import com.jeequan.jeepay.pay.rqrs.AbstractMchAppRQ;
import com.jeequan.jeepay.pay.rqrs.payorder.payway.*; import com.jeequan.jeepay.pay.rqrs.payorder.payway.*;
import lombok.Data; import lombok.Data;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
...@@ -36,15 +36,7 @@ import javax.validation.constraints.NotNull; ...@@ -36,15 +36,7 @@ import javax.validation.constraints.NotNull;
* @date 2021/6/8 17:33 * @date 2021/6/8 17:33
*/ */
@Data @Data
public class UnifiedOrderRQ extends AbstractRQ { public class UnifiedOrderRQ extends AbstractMchAppRQ {
/** 商户号 **/
@NotBlank(message="商户号不能为空")
private String mchNo;
/** 商户应用ID **/
@NotBlank(message="商户应用ID不能为空")
private String appId;
/** 商户订单号 **/ /** 商户订单号 **/
@NotBlank(message="商户订单号不能为空") @NotBlank(message="商户订单号不能为空")
......
...@@ -18,7 +18,7 @@ package com.jeequan.jeepay.pay.service; ...@@ -18,7 +18,7 @@ package com.jeequan.jeepay.pay.service;
import com.jeequan.jeepay.core.entity.PayOrder; import com.jeequan.jeepay.core.entity.PayOrder;
import com.jeequan.jeepay.core.utils.SpringBeansUtil; import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.pay.channel.IPayOrderQueryService; import com.jeequan.jeepay.pay.channel.IPayOrderQueryService;
import com.jeequan.jeepay.pay.model.MchConfigContext; import com.jeequan.jeepay.pay.model.MchAppConfigContext;
import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg; import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.service.impl.PayOrderService; import com.jeequan.jeepay.service.impl.PayOrderService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
...@@ -58,11 +58,10 @@ public class ChannelOrderReissueService { ...@@ -58,11 +58,10 @@ public class ChannelOrderReissueService {
return null; return null;
} }
//查询出商户的配置信息 //查询出商户应用的配置信息
String mchNo = payOrder.getMchNo(); MchAppConfigContext mchAppConfigContext = configContextService.getMchAppConfigContext(payOrder.getMchNo(), payOrder.getAppId());
MchConfigContext mchConfigContext = configContextService.getMchConfigContext(mchNo);
ChannelRetMsg channelRetMsg = queryService.query(payOrder, mchConfigContext); ChannelRetMsg channelRetMsg = queryService.query(payOrder, mchAppConfigContext);
if(channelRetMsg == null){ if(channelRetMsg == null){
log.error("channelRetMsg is null"); log.error("channelRetMsg is null");
return null; return null;
......
...@@ -25,6 +25,7 @@ import com.github.binarywang.wxpay.service.WxPayService; ...@@ -25,6 +25,7 @@ import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.jeequan.jeepay.core.constants.CS; import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.IsvInfo; import com.jeequan.jeepay.core.entity.IsvInfo;
import com.jeequan.jeepay.core.entity.MchApp;
import com.jeequan.jeepay.core.entity.MchInfo; import com.jeequan.jeepay.core.entity.MchInfo;
import com.jeequan.jeepay.core.entity.PayInterfaceConfig; import com.jeequan.jeepay.core.entity.PayInterfaceConfig;
import com.jeequan.jeepay.core.model.params.IsvParams; import com.jeequan.jeepay.core.model.params.IsvParams;
...@@ -35,13 +36,10 @@ import com.jeequan.jeepay.core.model.params.alipay.AlipayIsvParams; ...@@ -35,13 +36,10 @@ import com.jeequan.jeepay.core.model.params.alipay.AlipayIsvParams;
import com.jeequan.jeepay.core.model.params.alipay.AlipayNormalMchParams; import com.jeequan.jeepay.core.model.params.alipay.AlipayNormalMchParams;
import com.jeequan.jeepay.core.model.params.wxpay.WxpayIsvParams; import com.jeequan.jeepay.core.model.params.wxpay.WxpayIsvParams;
import com.jeequan.jeepay.core.model.params.wxpay.WxpayNormalMchParams; import com.jeequan.jeepay.core.model.params.wxpay.WxpayNormalMchParams;
import com.jeequan.jeepay.pay.config.SystemYmlConfig; import com.jeequan.jeepay.pay.model.*;
import com.jeequan.jeepay.pay.model.AlipayClientWrapper;
import com.jeequan.jeepay.pay.model.IsvConfigContext;
import com.jeequan.jeepay.pay.model.MchConfigContext;
import com.jeequan.jeepay.pay.model.WxServiceWrapper;
import com.jeequan.jeepay.pay.util.ChannelCertConfigKitBean; import com.jeequan.jeepay.pay.util.ChannelCertConfigKitBean;
import com.jeequan.jeepay.service.impl.IsvInfoService; import com.jeequan.jeepay.service.impl.IsvInfoService;
import com.jeequan.jeepay.service.impl.MchAppService;
import com.jeequan.jeepay.service.impl.MchInfoService; import com.jeequan.jeepay.service.impl.MchInfoService;
import com.jeequan.jeepay.service.impl.PayInterfaceConfigService; import com.jeequan.jeepay.service.impl.PayInterfaceConfigService;
import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.WxMpService;
...@@ -50,7 +48,6 @@ import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; ...@@ -50,7 +48,6 @@ import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.io.File;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
...@@ -65,29 +62,49 @@ import java.util.concurrent.ConcurrentHashMap; ...@@ -65,29 +62,49 @@ import java.util.concurrent.ConcurrentHashMap;
@Service @Service
public class ConfigContextService { public class ConfigContextService {
private static final Map<String, MchConfigContext> mchConfigContextMap = new ConcurrentHashMap<>(); /** <商户ID, 商户配置项> **/
private static final Map<String, MchInfoConfigContext> mchInfoConfigContextMap = new ConcurrentHashMap<>();
/** <应用ID, 商户配置上下文> **/
private static final Map<String, MchAppConfigContext> mchAppConfigContextMap = new ConcurrentHashMap<>();
/** <服务商号, 服务商配置上下文> **/
private static final Map<String, IsvConfigContext> isvConfigContextMap = new ConcurrentHashMap<>(); private static final Map<String, IsvConfigContext> isvConfigContextMap = new ConcurrentHashMap<>();
@Autowired private MchInfoService mchInfoService; @Autowired private MchInfoService mchInfoService;
@Autowired private MchAppService mchAppService;
@Autowired private IsvInfoService isvInfoService; @Autowired private IsvInfoService isvInfoService;
@Autowired private PayInterfaceConfigService payInterfaceConfigService; @Autowired private PayInterfaceConfigService payInterfaceConfigService;
@Autowired private SystemYmlConfig mainConfig;
@Autowired private ChannelCertConfigKitBean channelCertConfigKitBean; @Autowired private ChannelCertConfigKitBean channelCertConfigKitBean;
/** 获取支付参数 **/
public synchronized MchConfigContext getMchConfigContext(String mchNo){
MchConfigContext mchConfigContext = mchConfigContextMap.get(mchNo); /** 获取 [商户配置信息] **/
public synchronized MchInfoConfigContext getMchInfoConfigContext(String mchNo){
MchInfoConfigContext mchInfoConfigContext = mchInfoConfigContextMap.get(mchNo);
//无此数据, 需要初始化 //无此数据, 需要初始化
if(mchConfigContext == null){ if(mchInfoConfigContext == null){
initMchConfigContext(mchNo); initMchInfoConfigContext(mchNo);
}
return mchInfoConfigContextMap.get(mchNo);
} }
return mchConfigContextMap.get(mchNo); /** 获取 [商户应用支付参数配置信息] **/
public synchronized MchAppConfigContext getMchAppConfigContext(String mchNo, String appId){
MchAppConfigContext mchAppConfigContext = mchAppConfigContextMap.get(appId);
//无此数据, 需要初始化
if(mchAppConfigContext == null){
initMchAppConfigContext(mchNo, appId);
} }
/** 获取支付参数 **/ return mchAppConfigContextMap.get(appId);
}
/** 获取 [ISV支付参数配置信息] **/
public synchronized IsvConfigContext getIsvConfigContext(String isvNo){ public synchronized IsvConfigContext getIsvConfigContext(String isvNo){
IsvConfigContext isvConfigContext = isvConfigContextMap.get(isvNo); IsvConfigContext isvConfigContext = isvConfigContextMap.get(isvNo);
...@@ -101,34 +118,80 @@ public class ConfigContextService { ...@@ -101,34 +118,80 @@ public class ConfigContextService {
} }
/** 获取支付参数 **/ /** 初始化 [商户配置信息] **/
public synchronized void initMchConfigContext(String mchNo){ public synchronized void initMchInfoConfigContext(String mchNo){
MchConfigContext mchConfigContext = new MchConfigContext(); //商户主体信息
MchInfo mchInfo = mchInfoService.getById(mchNo); MchInfo mchInfo = mchInfoService.getById(mchNo);
if(mchInfo == null){ if(mchInfo == null){ // 查询不到商户主体, 可能已经删除
mchConfigContextMap.remove(mchNo);
MchInfoConfigContext mchInfoConfigContext = mchInfoConfigContextMap.get(mchNo);
// 删除所有的商户应用
if(mchInfoConfigContext != null){
mchInfoConfigContext.getAppMap().forEach((k, v) -> mchAppConfigContextMap.remove(k));
}
mchInfoConfigContextMap.remove(mchNo);
return ; return ;
} }
MchInfoConfigContext mchInfoConfigContext = new MchInfoConfigContext();
// 设置商户信息
mchInfoConfigContext.setMchNo(mchInfo.getMchNo());
mchInfoConfigContext.setMchType(mchInfo.getType());
mchInfoConfigContext.setMchInfo(mchInfo);
mchAppService.list(MchApp.gw().eq(MchApp::getMchNo, mchNo)).stream().forEach( mchApp -> mchInfoConfigContext.putMchApp(mchApp));
}
/** 初始化 [商户应用支付参数配置信息] **/
public synchronized void initMchAppConfigContext(String mchNo, String appId){
// 获取商户的配置信息
MchInfoConfigContext mchInfoConfigContext = getMchInfoConfigContext(mchNo);
if(mchInfoConfigContext == null){ // 商户信息不存在
return;
}
//商户应用信息
MchApp mchApp = mchInfoConfigContext.getMchApp(appId);
if(mchApp == null){ //说明商户主体信息不存在缓存
mchApp = mchAppService.getById(appId);
if(mchApp == null){ // DB查询为空
mchAppConfigContextMap.remove(appId); //清除缓存信息
return ;
}
//更新商户信息主体中的商户应用
mchInfoConfigContext.putMchApp(mchApp);
}
//商户主体信息
MchInfo mchInfo = mchInfoConfigContext.getMchInfo();
MchAppConfigContext mchAppConfigContext = new MchAppConfigContext();
// 设置商户信息 // 设置商户信息
mchConfigContext.setMchNo(mchInfo.getMchNo()); mchAppConfigContext.setMchNo(mchInfo.getMchNo());
mchConfigContext.setMchType(mchInfo.getType()); mchAppConfigContext.setMchType(mchInfo.getType());
mchConfigContext.setMchInfo(mchInfo); mchAppConfigContext.setMchInfo(mchInfo);
mchAppConfigContext.setMchApp(mchApp);
// 查询商户的所有支持的参数配置 // 查询商户的所有支持的参数配置
List<PayInterfaceConfig> allConfigList = payInterfaceConfigService.list(PayInterfaceConfig.gw() List<PayInterfaceConfig> allConfigList = payInterfaceConfigService.list(PayInterfaceConfig.gw()
.select(PayInterfaceConfig::getIfCode, PayInterfaceConfig::getIfParams) .select(PayInterfaceConfig::getIfCode, PayInterfaceConfig::getIfParams)
.eq(PayInterfaceConfig::getState, CS.YES) .eq(PayInterfaceConfig::getState, CS.YES)
.eq(PayInterfaceConfig::getInfoType, CS.INFO_TYPE_MCH) .eq(PayInterfaceConfig::getInfoType, CS.INFO_TYPE_MCH_APP)
.eq(PayInterfaceConfig::getInfoId, mchNo) .eq(PayInterfaceConfig::getInfoId, appId)
); );
// 普通商户 // 普通商户
if(mchInfo.getType() == CS.MCH_TYPE_NORMAL){ if(mchInfo.getType() == CS.MCH_TYPE_NORMAL){
for (PayInterfaceConfig payInterfaceConfig : allConfigList) { for (PayInterfaceConfig payInterfaceConfig : allConfigList) {
mchConfigContext.getNormalMchParamsMap().put( mchAppConfigContext.getNormalMchParamsMap().put(
payInterfaceConfig.getIfCode(), payInterfaceConfig.getIfCode(),
NormalMchParams.factory(payInterfaceConfig.getIfCode(), payInterfaceConfig.getIfParams()) NormalMchParams.factory(payInterfaceConfig.getIfCode(), payInterfaceConfig.getIfParams())
); );
...@@ -136,10 +199,10 @@ public class ConfigContextService { ...@@ -136,10 +199,10 @@ public class ConfigContextService {
//放置alipay client //放置alipay client
AlipayNormalMchParams alipayParams = mchConfigContext.getNormalMchParamsByIfCode(CS.IF_CODE.ALIPAY, AlipayNormalMchParams.class); AlipayNormalMchParams alipayParams = mchAppConfigContext.getNormalMchParamsByIfCode(CS.IF_CODE.ALIPAY, AlipayNormalMchParams.class);
if(alipayParams != null){ if(alipayParams != null){
mchConfigContext.setAlipayClientWrapper(buildAlipayClientWrapper( mchAppConfigContext.setAlipayClientWrapper(buildAlipayClientWrapper(
alipayParams.getUseCert(), alipayParams.getSandbox(), alipayParams.getAppId(), alipayParams.getPrivateKey(), alipayParams.getUseCert(), alipayParams.getSandbox(), alipayParams.getAppId(), alipayParams.getPrivateKey(),
alipayParams.getAlipayPublicKey(), alipayParams.getSignType(), alipayParams.getAppPublicCert(), alipayParams.getAlipayPublicKey(), alipayParams.getSignType(), alipayParams.getAppPublicCert(),
alipayParams.getAlipayPublicCert(), alipayParams.getAlipayRootCert() alipayParams.getAlipayPublicCert(), alipayParams.getAlipayRootCert()
...@@ -149,9 +212,9 @@ public class ConfigContextService { ...@@ -149,9 +212,9 @@ public class ConfigContextService {
} }
//放置 wxJavaService //放置 wxJavaService
WxpayNormalMchParams wxpayParams = mchConfigContext.getNormalMchParamsByIfCode(CS.IF_CODE.WXPAY, WxpayNormalMchParams.class); WxpayNormalMchParams wxpayParams = mchAppConfigContext.getNormalMchParamsByIfCode(CS.IF_CODE.WXPAY, WxpayNormalMchParams.class);
if(wxpayParams != null){ if(wxpayParams != null){
mchConfigContext.setWxServiceWrapper(buildWxServiceWrapper(wxpayParams.getMchId(), wxpayParams.getAppId(), mchAppConfigContext.setWxServiceWrapper(buildWxServiceWrapper(wxpayParams.getMchId(), wxpayParams.getAppId(),
wxpayParams.getAppSecret(), wxpayParams.getKey(), wxpayParams.getApiVersion(), wxpayParams.getApiV3Key(), wxpayParams.getAppSecret(), wxpayParams.getKey(), wxpayParams.getApiVersion(), wxpayParams.getApiV3Key(),
wxpayParams.getSerialNo(), wxpayParams.getCert(), wxpayParams.getApiClientKey())); wxpayParams.getSerialNo(), wxpayParams.getCert(), wxpayParams.getApiClientKey()));
} }
...@@ -159,22 +222,22 @@ public class ConfigContextService { ...@@ -159,22 +222,22 @@ public class ConfigContextService {
}else{ //服务商模式商户 }else{ //服务商模式商户
for (PayInterfaceConfig payInterfaceConfig : allConfigList) { for (PayInterfaceConfig payInterfaceConfig : allConfigList) {
mchConfigContext.getIsvsubMchParamsMap().put( mchAppConfigContext.getIsvsubMchParamsMap().put(
payInterfaceConfig.getIfCode(), payInterfaceConfig.getIfCode(),
IsvsubMchParams.factory(payInterfaceConfig.getIfCode(), payInterfaceConfig.getIfParams()) IsvsubMchParams.factory(payInterfaceConfig.getIfCode(), payInterfaceConfig.getIfParams())
); );
} }
//放置 当前商户的 服务商信息 //放置 当前商户的 服务商信息
mchConfigContext.setIsvConfigContext(getIsvConfigContext(mchInfo.getIsvNo())); mchAppConfigContext.setIsvConfigContext(getIsvConfigContext(mchInfo.getIsvNo()));
} }
mchConfigContextMap.put(mchNo, mchConfigContext); mchAppConfigContextMap.put(appId, mchAppConfigContext);
} }
/** 初始化 **/ /** 初始化 [ISV支付参数配置信息] **/
public synchronized void initIsvConfigContext(String isvNo){ public synchronized void initIsvConfigContext(String isvNo){
IsvConfigContext isvConfigContext = new IsvConfigContext(); IsvConfigContext isvConfigContext = new IsvConfigContext();
...@@ -185,9 +248,9 @@ public class ConfigContextService { ...@@ -185,9 +248,9 @@ public class ConfigContextService {
mchInfoService.list(MchInfo.gw().select(MchInfo::getMchNo).eq(MchInfo::getIsvNo, isvNo)).forEach(mchInfoItem -> { mchInfoService.list(MchInfo.gw().select(MchInfo::getMchNo).eq(MchInfo::getIsvNo, isvNo)).forEach(mchInfoItem -> {
//将更新已存在缓存的商户配置信息 (每个商户下存储的为同一个 服务商配置的对象指针) //将更新已存在缓存的商户配置信息 (每个商户下存储的为同一个 服务商配置的对象指针)
MchConfigContext mchConfigContext = mchConfigContextMap.get(mchInfoItem.getMchNo()); MchAppConfigContext mchAppConfigContext = mchAppConfigContextMap.get(mchInfoItem.getMchNo());
if(mchConfigContext != null){ if(mchAppConfigContext != null){
mchConfigContext.setIsvConfigContext(null); mchAppConfigContext.setIsvConfigContext(null);
} }
}); });
isvConfigContextMap.remove(isvNo); // 服务商有商户不可删除, 此处不再更新商户下的配置信息 isvConfigContextMap.remove(isvNo); // 服务商有商户不可删除, 此处不再更新商户下的配置信息
...@@ -238,9 +301,9 @@ public class ConfigContextService { ...@@ -238,9 +301,9 @@ public class ConfigContextService {
mchInfoService.list(MchInfo.gw().select(MchInfo::getMchNo).eq(MchInfo::getIsvNo, isvNo)).forEach(mchInfoItem -> { mchInfoService.list(MchInfo.gw().select(MchInfo::getMchNo).eq(MchInfo::getIsvNo, isvNo)).forEach(mchInfoItem -> {
//将更新已存在缓存的商户配置信息 (每个商户下存储的为同一个 服务商配置的对象指针) //将更新已存在缓存的商户配置信息 (每个商户下存储的为同一个 服务商配置的对象指针)
MchConfigContext mchConfigContext = mchConfigContextMap.get(mchInfoItem.getMchNo()); MchAppConfigContext mchAppConfigContext = mchAppConfigContextMap.get(mchInfoItem.getMchNo());
if(mchConfigContext != null){ if(mchAppConfigContext != null){
mchConfigContext.setIsvConfigContext(isvConfigContext); mchAppConfigContext.setIsvConfigContext(isvConfigContext);
} }
}); });
......
...@@ -110,7 +110,7 @@ public class PayMchNotifyService { ...@@ -110,7 +110,7 @@ public class PayMchNotifyService {
/** /**
* 创建响应URL * 创建响应URL
*/ */
public String createReturnUrl(PayOrder payOrder, String mchKey) { public String createReturnUrl(PayOrder payOrder, String appSecret) {
if(StringUtils.isEmpty(payOrder.getReturnUrl())){ if(StringUtils.isEmpty(payOrder.getReturnUrl())){
return ""; return "";
...@@ -121,7 +121,7 @@ public class PayMchNotifyService { ...@@ -121,7 +121,7 @@ public class PayMchNotifyService {
jsonObject.put("reqTime", System.currentTimeMillis()); //添加请求时间 jsonObject.put("reqTime", System.currentTimeMillis()); //添加请求时间
// 报文签名 // 报文签名
jsonObject.put("sign", JeepayKit.getSign(jsonObject, mchKey)); // 签名 jsonObject.put("sign", JeepayKit.getSign(jsonObject, appSecret)); // 签名
// 生成跳转地址 // 生成跳转地址
return StringKit.appendUrlQuery(payOrder.getReturnUrl(), jsonObject); return StringKit.appendUrlQuery(payOrder.getReturnUrl(), jsonObject);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment