1.支付渠道(编码完成)

This commit is contained in:
邱贞招 2024-09-14 15:45:45 +08:00
parent be2091afa7
commit db628d6797
14 changed files with 291 additions and 202 deletions

View File

@ -17,6 +17,7 @@ import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.pay.PaymentResult;
import com.ruoyi.common.utils.CommonUtil; import com.ruoyi.common.utils.CommonUtil;
import com.ruoyi.common.utils.SendAliSmsUtil; import com.ruoyi.common.utils.SendAliSmsUtil;
import com.ruoyi.common.utils.SendSmsVo; import com.ruoyi.common.utils.SendSmsVo;
@ -403,7 +404,7 @@ public class AppController extends BaseController
public AjaxResult queryByOutRefundNo(Long areaId,String outRefundNo) public AjaxResult queryByOutRefundNo(Long areaId,String outRefundNo)
{ {
logger.info("查询退款是否成功【outRefundNo="+outRefundNo+""); logger.info("查询退款是否成功【outRefundNo="+outRefundNo+"");
Refund refund = wxPayService.queryByOutRefundNo(areaId,outRefundNo); Refund refund = wxPayService.queryByOutRefundNo(outRefundNo);
return AjaxResult.success(refund); return AjaxResult.success(refund);
} }
@ -414,8 +415,8 @@ public class AppController extends BaseController
public AjaxResult queryOrderByOutTradeNo(String outTradeNo) public AjaxResult queryOrderByOutTradeNo(String outTradeNo)
{ {
logger.info("查询支付订单信息【outTradeNo="+outTradeNo+""); logger.info("查询支付订单信息【outTradeNo="+outTradeNo+"");
Transaction transaction = wxPayService.queryOrderByOutTradeNo(outTradeNo); PaymentResult paymentResult = wxPayService.queryOrderByOutTradeNo(outTradeNo);
return AjaxResult.success(transaction); return AjaxResult.success(paymentResult);
} }
/** /**

View File

@ -85,8 +85,8 @@ public class SysDept extends BaseEntity
/** 余额 */ /** 余额 */
private BigDecimal balance; private BigDecimal balance;
// /** appSecret */ /** appSecret */
// private String appSecret; private String appSecret;
// //
// /** merchantId */ // /** merchantId */
// private String merchantId; // private String merchantId;
@ -281,14 +281,14 @@ public class SysDept extends BaseEntity
this.appid = appid; this.appid = appid;
} }
// public String getAppSecret() { public String getAppSecret() {
// return appSecret; return appSecret;
// } }
//
// public void setAppSecret(String appSecret) { public void setAppSecret(String appSecret) {
// this.appSecret = appSecret; this.appSecret = appSecret;
// } }
//
// public String getMerchantId() { // public String getMerchantId() {
// return merchantId; // return merchantId;
// } // }

View File

@ -0,0 +1,21 @@
package com.ruoyi.common.pay;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class PaymentResult {
private String outTradeNo; // 商户订单号
private String status;
private String transactionId; // 平台交易ID
private BigDecimal amount; // 交易金额
public PaymentResult(String outTradeNo, String status, String transactionId, BigDecimal amount) {
this.outTradeNo = outTradeNo;
this.status = status;
this.transactionId = transactionId;
this.amount = amount;
}
}

View File

@ -1,5 +1,6 @@
package com.ruoyi.system.mapper; package com.ruoyi.system.mapper;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.system.domain.Channel; import com.ruoyi.system.domain.Channel;
import com.ruoyi.system.domain.ChannelQuery; import com.ruoyi.system.domain.ChannelQuery;
import com.ruoyi.system.domain.ChannelVO; import com.ruoyi.system.domain.ChannelVO;
@ -62,4 +63,13 @@ public interface EtChannelMapper
* @return 结果 * @return 结果
*/ */
public int deleteSmChannelByChannelIds(Long[] channelIds); public int deleteSmChannelByChannelIds(Long[] channelIds);
/**
* 根据证书序列号获取支付渠道
*
* @param wechatpaySerial 证书序列号
* @return 结果
*/
ChannelVO selectChannelBySerialNumber(String wechatpaySerial);
} }

View File

@ -1,5 +1,6 @@
package com.ruoyi.system.service; package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.system.domain.Channel; import com.ruoyi.system.domain.Channel;
import com.ruoyi.system.domain.ChannelQuery; import com.ruoyi.system.domain.ChannelQuery;
import com.ruoyi.system.domain.ChannelVO; import com.ruoyi.system.domain.ChannelVO;
@ -79,4 +80,11 @@ public interface EtChannelService
*/ */
<K> Map<K, ChannelVO> selectMap(ChannelQuery query, Function<? super Channel, ? extends K> keyMapper); <K> Map<K, ChannelVO> selectMap(ChannelQuery query, Function<? super Channel, ? extends K> keyMapper);
/**
* 根据证书序列号获取支付渠道
*
* @param wechatpaySerial 证书序列号
* @return 结果
*/
ChannelVO selectChannelBySerialNumber(String wechatpaySerial);
} }

View File

@ -1,6 +1,8 @@
package com.ruoyi.system.service; package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.entity.SysDept; import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.pay.PaymentResult;
import com.ruoyi.system.domain.ChannelVO;
import com.ruoyi.system.domain.EtOrder; import com.ruoyi.system.domain.EtOrder;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse; import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import com.wechat.pay.java.service.payments.model.Transaction; import com.wechat.pay.java.service.payments.model.Transaction;
@ -55,14 +57,14 @@ public interface IWxPayService {
* @param outTradeNo 商户订单号 * @param outTradeNo 商户订单号
* @return 订单信息 * @return 订单信息
*/ */
Transaction queryOrderByOutTradeNo(String outTradeNo); PaymentResult queryOrderByOutTradeNo(String outTradeNo);
/** /**
* 关闭订单 * 关闭订单
* @param outTradeNo 商户订单号 * @param outTradeNo 商户订单号
* @return 订单信息 * @return 订单信息
*/ */
boolean closeOrder(String outTradeNo,SysDept sysDept); boolean closeOrder(String outTradeNo, ChannelVO channelVO);
/** /**
* 根据订单号查询订单支付结果 * 根据订单号查询订单支付结果
@ -96,7 +98,7 @@ public interface IWxPayService {
* 根据退款单号查询退款信息 * 根据退款单号查询退款信息
* @param outRefundNo 退款单号 * @param outRefundNo 退款单号
*/ */
Refund queryByOutRefundNo(Long areaId,String outRefundNo); Refund queryByOutRefundNo(String outRefundNo);
/** /**
@ -114,18 +116,18 @@ public interface IWxPayService {
*/ */
// public OrdersEntity createOrder(SysDept sysDept, String transactionId, List<CreateOrderReceiver> receivers); // public OrdersEntity createOrder(SysDept sysDept, String transactionId, List<CreateOrderReceiver> receivers);
/** // /**
* 添加分账接收方 // * 添加分账接收方
* @param wxopenid openid // * @param wxopenid openid
* @param deptId 运营商id // * @param deptId 运营商id
*/ // */
AddReceiverResponse addReceiver(String wxopenid,Long deptId,String type); // AddReceiverResponse addReceiver(String wxopenid,Long deptId,String type);
//
/** // /**
* 删除分账接收方 // * 删除分账接收方
* @param wxopenid openid // * @param wxopenid openid
* @param deptId 运营商id // * @param deptId 运营商id
*/ // */
DeleteReceiverResponse deleteReceiver(String wxopenid,Long deptId,String type); // DeleteReceiverResponse deleteReceiver(String wxopenid,Long deptId,String type);
} }

View File

@ -8,7 +8,6 @@ import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException; import com.aliyuncs.exceptions.ClientException;
import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.IotConstants;
import com.ruoyi.common.constant.ServiceConstants; import com.ruoyi.common.constant.ServiceConstants;
import com.ruoyi.common.core.domain.entity.AsUser; import com.ruoyi.common.core.domain.entity.AsUser;
import com.ruoyi.common.core.domain.entity.SysDept; import com.ruoyi.common.core.domain.entity.SysDept;
@ -34,7 +33,6 @@ import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.payments.model.Transaction; import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.profitsharing.model.CreateOrderReceiver; import com.wechat.pay.java.service.profitsharing.model.CreateOrderReceiver;
import com.wechat.pay.java.service.profitsharing.model.ReceiverType; import com.wechat.pay.java.service.profitsharing.model.ReceiverType;
import com.wechat.pay.java.service.refund.model.Refund;
import com.wechat.pay.java.service.refund.model.RefundNotification; import com.wechat.pay.java.service.refund.model.RefundNotification;
import com.wechat.pay.java.service.refund.model.Status; import com.wechat.pay.java.service.refund.model.Status;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -127,6 +125,9 @@ public class CallbackServiceImpl implements CallbackService {
@Autowired @Autowired
private TransactionTemplate transactionTemplate; private TransactionTemplate transactionTemplate;
@Autowired
private EtChannelService etChannelService;
@Value("${aliyun.accessKeyId}") @Value("${aliyun.accessKeyId}")
private String accessKeyId; private String accessKeyId;
@ -1188,15 +1189,15 @@ public class CallbackServiceImpl implements CallbackService {
public NotificationParser getNotificationParser(String wechatpaySerial) { public NotificationParser getNotificationParser(String wechatpaySerial) {
// 根据证书序列号获取运营商 // 根据证书序列号获取运营商
SysDept sysDept = deptService.selectEtOperatingAreaBySerialNumber(wechatpaySerial); ChannelVO channelVO = etChannelService.selectChannelBySerialNumber(wechatpaySerial);
if(ObjectUtil.isNull(sysDept)){ if(ObjectUtil.isNull(channelVO)){
throw new ServiceException("【微信支付回调】根据证书序列号获取运营商失败"); throw new ServiceException("【微信支付回调】根据证书序列号获取支付渠道失败");
}else{ }else{
NotificationConfig config = new RSAAutoCertificateConfig.Builder() NotificationConfig config = new RSAAutoCertificateConfig.Builder()
.merchantId(sysDept.getMerchantId()) .merchantId(channelVO.getMerchantId())
.privateKeyFromPath(sysDept.getPrivateKeyPath()) .privateKeyFromPath(channelVO.getPrivateKeyPath())
.merchantSerialNumber(sysDept.getMerchantSerialNumber()) .merchantSerialNumber(channelVO.getMerchantSerialNumber())
.apiV3Key(sysDept.getApiV3Key()) .apiV3Key(channelVO.getApiV3Key())
.build(); .build();
return new NotificationParser(config); return new NotificationParser(config);
} }

View File

@ -1,5 +1,6 @@
package com.ruoyi.system.service.impl; package com.ruoyi.system.service.impl;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.system.domain.Channel; import com.ruoyi.system.domain.Channel;
import com.ruoyi.system.domain.ChannelQuery; import com.ruoyi.system.domain.ChannelQuery;
import com.ruoyi.system.domain.ChannelVO; import com.ruoyi.system.domain.ChannelVO;
@ -118,4 +119,16 @@ public class EtChannelServiceImpl implements EtChannelService
// } // }
return list.stream().collect(Collectors.toMap(keyMapper, item -> item)); return list.stream().collect(Collectors.toMap(keyMapper, item -> item));
} }
/**
* 根据证书序列号获取支付渠道
*
* @param wechatpaySerial 证书序列号
* @return 结果
*/
@Override
public ChannelVO selectChannelBySerialNumber(String wechatpaySerial) {
ChannelVO channel = etChannelMapper.selectChannelBySerialNumber(wechatpaySerial);
return channel;
}
} }

View File

@ -12,6 +12,7 @@ import com.ruoyi.common.core.domain.entity.AsUser;
import com.ruoyi.common.core.domain.entity.SysDept; import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.enums.BusinessStatus; import com.ruoyi.common.enums.BusinessStatus;
import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.pay.PaymentResult;
import com.ruoyi.common.utils.CommonUtil; import com.ruoyi.common.utils.CommonUtil;
import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.PageUtils; import com.ruoyi.common.utils.PageUtils;
@ -128,6 +129,9 @@ public class EtOrderServiceImpl implements IEtOrderService
@Resource @Resource
private EtCouponClaimLogMapper etCouponClaimLogMapper; private EtCouponClaimLogMapper etCouponClaimLogMapper;
@Autowired
private EtChannelService etChannelService;
/** /**
* 查询订单 * 查询订单
* *
@ -520,9 +524,9 @@ public class EtOrderServiceImpl implements IEtOrderService
String outTradeNo = order.getOutTradeNo(); String outTradeNo = order.getOutTradeNo();
log.info("【押金抵扣】订单【{}】,有outTradeNo = 【{}】", order.getOrderNo(),outTradeNo); log.info("【押金抵扣】订单【{}】,有outTradeNo = 【{}】", order.getOrderNo(),outTradeNo);
// 如果原来有outtradeno去查询一次查询是否支付过 // 如果原来有outtradeno去查询一次查询是否支付过
Transaction transaction = wxPayService.queryOrderByOutTradeNo(outTradeNo); PaymentResult paymentResult = wxPayService.queryOrderByOutTradeNo(outTradeNo);
try { try {
if (Transaction.TradeStateEnum.SUCCESS.equals(transaction.getTradeState())) { if (Transaction.TradeStateEnum.SUCCESS.equals(paymentResult.getStatus())) {
// 订单已支付 // 订单已支付
order.setPaid(ServiceConstants.ORDER_PAY_STATUS_PAID); order.setPaid(ServiceConstants.ORDER_PAY_STATUS_PAID);
order.setPayTime(DateUtils.getNowDate()); order.setPayTime(DateUtils.getNowDate());
@ -536,9 +540,9 @@ public class EtOrderServiceImpl implements IEtOrderService
} }
return 1; return 1;
}else{ }else{
SysDept dept = wxPayService.getDeptObjByAreaId(order.getAreaId()); ChannelVO channelVO = etChannelService.selectSmChannelByChannelId(order.getPayChannel());
// 没有支付则关闭订单 // 没有支付则关闭订单
boolean b = wxPayService.closeOrder(outTradeNo, dept); boolean b = wxPayService.closeOrder(outTradeNo,channelVO);
log.info("【押金抵扣】订单【{}】,有outTradeNo = 【{}】,查询订单未支付,关闭订单:{}", order.getOrderNo(),outTradeNo,b); log.info("【押金抵扣】订单【{}】,有outTradeNo = 【{}】,查询订单未支付,关闭订单:{}", order.getOrderNo(),outTradeNo,b);
} }
} catch (ServiceException e) { } catch (ServiceException e) {

View File

@ -337,19 +337,19 @@ public class SysDeptServiceImpl implements ISysDeptService
if (StrUtil.isNotBlank(dept.getIsUsePlatformApp()) && dept.getIsUsePlatformApp().equals("true")) { if (StrUtil.isNotBlank(dept.getIsUsePlatformApp()) && dept.getIsUsePlatformApp().equals("true")) {
SysDept platform = deptMapper.selectDeptById(100L); SysDept platform = deptMapper.selectDeptById(100L);
dept.setAppid(platform.getAppid()); dept.setAppid(platform.getAppid());
dept.setAppSecret(platform.getAppSecret()); // dept.setAppSecret(platform.getAppSecret());
dept.setAppName(platform.getAppName()); dept.setAppName(platform.getAppName());
dept.setDomain(platform.getDomain()); dept.setDomain(platform.getDomain());
} }
if (dept.getSeparateAccount().equals("N")) { // if (dept.getSeparateAccount().equals("N")) {
SysDept platform = deptMapper.selectDeptById(100L); // SysDept platform = deptMapper.selectDeptById(100L);
dept.setMerchantId(platform.getMerchantId()); // dept.setMerchantId(platform.getMerchantId());
dept.setApiV3Key(platform.getApiV3Key()); // dept.setApiV3Key(platform.getApiV3Key());
dept.setNotifyUrl(platform.getNotifyUrl()); // dept.setNotifyUrl(platform.getNotifyUrl());
dept.setPrivateKeyPath(platform.getPrivateKeyPath()); // dept.setPrivateKeyPath(platform.getPrivateKeyPath());
dept.setMerchantSerialNumber(platform.getMerchantSerialNumber()); // dept.setMerchantSerialNumber(platform.getMerchantSerialNumber());
dept.setRefundNotifyUrl(platform.getRefundNotifyUrl()); // dept.setRefundNotifyUrl(platform.getRefundNotifyUrl());
} // }
int i = deptMapper.insertDept(dept); int i = deptMapper.insertDept(dept);
Long[] areaIds = dept.getAreaIds(); Long[] areaIds = dept.getAreaIds();
if (StringUtils.isNotNull(areaIds)){ if (StringUtils.isNotNull(areaIds)){
@ -386,11 +386,11 @@ public class SysDeptServiceImpl implements ISysDeptService
dept.setAncestors(newAncestors); dept.setAncestors(newAncestors);
updateDeptChildren(dept.getDeptId(), newAncestors, oldAncestors); updateDeptChildren(dept.getDeptId(), newAncestors, oldAncestors);
} }
if (StrUtil.isNotBlank(dept.getIsUsePlatformApp()) && dept.getIsUsePlatformApp().equals("true")) { // if (StrUtil.isNotBlank(dept.getIsUsePlatformApp()) && dept.getIsUsePlatformApp().equals("true")) {
SysDept platform = deptMapper.selectDeptById(100L); // SysDept platform = deptMapper.selectDeptById(100L);
dept.setAppid(platform.getAppid()); // dept.setAppid(platform.getAppid());
dept.setAppSecret(platform.getAppSecret()); // dept.setAppSecret(platform.getAppSecret());
} // }
int result = deptMapper.updateDept(dept); int result = deptMapper.updateDept(dept);
if (UserConstants.DEPT_NORMAL.equals(dept.getStatus()) && StringUtils.isNotEmpty(dept.getAncestors()) if (UserConstants.DEPT_NORMAL.equals(dept.getStatus()) && StringUtils.isNotEmpty(dept.getAncestors())
&& !StringUtils.equals("0", dept.getAncestors())) && !StringUtils.equals("0", dept.getAncestors()))

View File

@ -450,8 +450,8 @@ public class SysUserServiceImpl implements ISysUserService
// 绑定app用户 // 绑定app用户
userMapper.bandAppUser(asUser.getUserId(), user.getUserId()); userMapper.bandAppUser(asUser.getUserId(), user.getUserId());
// 添加分账接收方 // 添加分账接收方
AddReceiverResponse addReceiverResponse = wxPayService.addReceiver(asUser.getWxopenid(),SecurityUtils.getLoginUser().getUser().getDeptId(), ServiceConstants.PROFITSHARING_TYPE_PARTNER); // AddReceiverResponse addReceiverResponse = wxPayService.addReceiver(asUser.getWxopenid(),SecurityUtils.getLoginUser().getUser().getDeptId(), ServiceConstants.PROFITSHARING_TYPE_PARTNER);
log.info("添加分账接收方响应:【{}】", JSON.toJSON(addReceiverResponse)); // log.info("添加分账接收方响应:【{}】", JSON.toJSON(addReceiverResponse));
} }
/** /**
@ -461,8 +461,8 @@ public class SysUserServiceImpl implements ISysUserService
*/ */
private void deleteReceiver(String openid,Long deptId) { private void deleteReceiver(String openid,Long deptId) {
// 添加分账接收方 // 添加分账接收方
DeleteReceiverResponse deleteReceiverResponse = wxPayService.deleteReceiver(openid,deptId,ServiceConstants.PROFITSHARING_TYPE_PARTNER); // DeleteReceiverResponse deleteReceiverResponse = wxPayService.deleteReceiver(openid,deptId,ServiceConstants.PROFITSHARING_TYPE_PARTNER);
log.info("删除分账接收方响应:【{}】", JSON.toJSON(deleteReceiverResponse)); // log.info("删除分账接收方响应:【{}】", JSON.toJSON(deleteReceiverResponse));
} }
/** /**

View File

@ -11,6 +11,7 @@ import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.redis.RedisLock; import com.ruoyi.common.core.redis.RedisLock;
import com.ruoyi.common.enums.PayChannel; import com.ruoyi.common.enums.PayChannel;
import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.pay.PaymentResult;
import com.ruoyi.common.pay.syb.enums.SybTrxStatus; import com.ruoyi.common.pay.syb.enums.SybTrxStatus;
import com.ruoyi.common.pay.syb.service.SybPayService; import com.ruoyi.common.pay.syb.service.SybPayService;
import com.ruoyi.common.pay.wx.Payable; import com.ruoyi.common.pay.wx.Payable;
@ -49,6 +50,7 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
@ -81,9 +83,6 @@ public class WxPayService implements IWxPayService {
@Resource @Resource
private AsUserMapper asUserMapper; private AsUserMapper asUserMapper;
@Autowired
private IEtOrderService orderService;
@Autowired @Autowired
private SybPayService sybPayService; private SybPayService sybPayService;
@ -229,7 +228,7 @@ public class WxPayService implements IWxPayService {
request.setDescription(description); request.setDescription(description);
request.setNotifyUrl(channelVO.getNotifyUrl()); request.setNotifyUrl(channelVO.getNotifyUrl());
request.setPayer(getPayer(user.getWxopenid())); request.setPayer(getPayer(user.getWxopenid()));
JsapiServiceExtension jsapiServiceExtension = getJsapiServiceExtension(sysDept); JsapiServiceExtension jsapiServiceExtension = getJsapiServiceExtension(channelVO);
PrepayWithRequestPaymentResponse res = jsapiServiceExtension.prepayWithRequestPayment(request); PrepayWithRequestPaymentResponse res = jsapiServiceExtension.prepayWithRequestPayment(request);
if(StrUtil.isNotBlank(order.getOutTradeNo())){ if(StrUtil.isNotBlank(order.getOutTradeNo())){
@ -295,21 +294,29 @@ public class WxPayService implements IWxPayService {
* @return * @return
*/ */
@Override @Override
public Transaction queryOrderByOutTradeNo(String outTradeNo) { public PaymentResult queryOrderByOutTradeNo(String outTradeNo) {
EtOrder order = etOrderService.selectEtOrderByOutTradeNo(outTradeNo); EtOrder order = etOrderService.selectEtOrderByOutTradeNo(outTradeNo);
List<EtAreaDept> areaId1 = etAreaDeptMapper.selectList(new QueryWrapper<EtAreaDept>().eq("area_id", order.getAreaId())); ChannelVO channelVO = etChannelService.selectSmChannelByChannelId(order.getPayChannel());
if (ObjectUtil.isNotEmpty(areaId1) && areaId1.size() > 0){ if(PayChannel.CT_WX.equalsCode(channelVO.getCode()) || PayChannel.YS_WX.equalsCode(channelVO.getCode())){
EtAreaDept etAreaDept = areaId1.get(0);
SysDept sysDept = deptService.selectDeptById(etAreaDept.getDeptId());
log.info("获取到运营商对象:【{}】",JSON.toJSON(sysDept));
QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest(); QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
request.setMchid(sysDept.getMerchantId()); request.setMchid(channelVO.getMerchantId());
request.setOutTradeNo(outTradeNo); request.setOutTradeNo(outTradeNo);
JsapiService jsapiService = getJsapiService(sysDept); JsapiService jsapiService = getJsapiService(channelVO);
return jsapiService.queryOrderByOutTradeNo(request); Transaction transaction = jsapiService.queryOrderByOutTradeNo(request);
return new PaymentResult(transaction.getOutTradeNo(), transaction.getTradeState().name(),
transaction.getTransactionId(), new BigDecimal(transaction.getAmount().getTotal()/100));
}else if(PayChannel.TL_WX.equalsCode(channelVO.getCode())){
Map<String, String> result = sybPayService.queryOrderByOutTradeNo(order.getOutTradeNo());
if(SybTrxStatus.isSuccess(result.get("trxstatus"))) {
PaymentResult paymentResult = new PaymentResult(result.get("reqsn"),
result.get("trxstatus"),
result.get("chnltrxid"),
new BigDecimal(result.get("amount")).divide(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP));
return paymentResult;
}
return null;
}else{ }else{
log.info("区域:【{}】没有绑定运营商",order.getAreaId()); throw new ServiceException("支付渠道【"+channelVO.getCode()+"】暂不支持");
throw new ServiceException("区域:【"+order.getAreaId()+"】没有绑定运营商");
} }
} }
@ -319,11 +326,11 @@ public class WxPayService implements IWxPayService {
* @return * @return
*/ */
@Override @Override
public boolean closeOrder(String outTradeNo, SysDept sysDept) { public boolean closeOrder(String outTradeNo,ChannelVO channelVO) {
JsapiServiceExtension jsapiServiceExtension = getJsapiServiceExtension(sysDept); JsapiServiceExtension jsapiServiceExtension = getJsapiServiceExtension(channelVO);
// 关闭订单 // 关闭订单
CloseOrderRequest closeOrderRequest = new CloseOrderRequest(); CloseOrderRequest closeOrderRequest = new CloseOrderRequest();
closeOrderRequest.setMchid(sysDept.getMerchantId()); closeOrderRequest.setMchid(channelVO.getMerchantId());
closeOrderRequest.setOutTradeNo(outTradeNo); closeOrderRequest.setOutTradeNo(outTradeNo);
jsapiServiceExtension.closeOrder(closeOrderRequest); jsapiServiceExtension.closeOrder(closeOrderRequest);
return true; return true;
@ -337,15 +344,15 @@ public class WxPayService implements IWxPayService {
@Override @Override
public Boolean queryResultByOrderNo(String orderNo) { public Boolean queryResultByOrderNo(String orderNo) {
EtOrder order = etOrderService.selectEtOrderByOrderNo(orderNo); EtOrder order = etOrderService.selectEtOrderByOrderNo(orderNo);
SysDept sysDept = getDeptObjByAreaId(order.getAreaId()); ChannelVO channelVO = etChannelService.selectSmChannelByChannelId(order.getPayChannel());
log.info("获取到运营商对象:【{}】",JSON.toJSON(sysDept)); if(PayChannel.CT_WX.equalsCode(channelVO.getCode()) || PayChannel.YS_WX.equalsCode(channelVO.getCode())){
QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest(); QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
request.setMchid(sysDept.getMerchantId()); request.setMchid(channelVO.getMerchantId());
if(StrUtil.isBlank(order.getOutTradeNo())){ if(StrUtil.isBlank(order.getOutTradeNo())){
return false; return false;
} }
request.setOutTradeNo(order.getOutTradeNo()); request.setOutTradeNo(order.getOutTradeNo());
JsapiService jsapiService = getJsapiService(sysDept); JsapiService jsapiService = getJsapiService(channelVO);
Transaction transaction = jsapiService.queryOrderByOutTradeNo(request); Transaction transaction = jsapiService.queryOrderByOutTradeNo(request);
// 订单未支付并且微信支付结果是成功的情况下更新订单状态和用户余额 // 订单未支付并且微信支付结果是成功的情况下更新订单状态和用户余额
if(transaction.getTradeState().equals(Transaction.TradeStateEnum.SUCCESS)){ if(transaction.getTradeState().equals(Transaction.TradeStateEnum.SUCCESS)){
@ -368,7 +375,7 @@ public class WxPayService implements IWxPayService {
throw new ServiceException("【微信支付回调】更新用户押金失败"); throw new ServiceException("【微信支付回调】更新用户押金失败");
} }
} }
int updateEtOrder = orderService.updateEtOrder(order); int updateEtOrder = etOrderService.updateEtOrder(order);
if(updateEtOrder==0){ if(updateEtOrder==0){
log.error("【微信支付回调】更新订单信息失败"); log.error("【微信支付回调】更新订单信息失败");
throw new ServiceException("【微信支付回调】更新订单信息失败"); throw new ServiceException("【微信支付回调】更新订单信息失败");
@ -376,17 +383,25 @@ public class WxPayService implements IWxPayService {
} }
return true; return true;
} }
}else if(PayChannel.TL_WX.equalsCode(channelVO.getCode())){
Map<String, String> result = sybPayService.queryOrderByOutTradeNo(order.getOutTradeNo());
if(SybTrxStatus.isSuccess(result.get("trxstatus"))) {
return true;
}
}else{
throw new ServiceException("支付渠道【"+channelVO.getCode()+"】暂不支持");
}
return false; return false;
} }
private JsapiService getJsapiService(SysDept sysDept) { private JsapiService getJsapiService(ChannelVO channelVO) {
// 初始化商户配置 // 初始化商户配置
Config config = new RSAAutoCertificateConfig.Builder() Config config = new RSAAutoCertificateConfig.Builder()
.merchantId(sysDept.getMerchantId()) .merchantId(channelVO.getMerchantId())
// 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥商户私钥会用来生成请求的签名 // 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥商户私钥会用来生成请求的签名
.privateKeyFromPath(sysDept.getPrivateKeyPath()) .privateKeyFromPath(channelVO.getPrivateKeyPath())
.merchantSerialNumber(sysDept.getMerchantSerialNumber()) .merchantSerialNumber(channelVO.getMerchantSerialNumber())
.apiV3Key(sysDept.getApiV3Key()) .apiV3Key(channelVO.getApiV3Key())
.build(); .build();
// 初始化服务 // 初始化服务
return new JsapiService.Builder().config(config).build(); return new JsapiService.Builder().config(config).build();
@ -401,8 +416,6 @@ public class WxPayService implements IWxPayService {
*/ */
@Override @Override
public void refund(EtOrder etOrder,String reason,BigDecimal amount,String outRefundNo) { public void refund(EtOrder etOrder,String reason,BigDecimal amount,String outRefundNo) {
SysDept sysDept = getDeptObjByAreaId(etOrder.getAreaId());
if(!etOrder.getStatus().equals(ServiceConstants.ORDER_STATUS_ORDER_END)) throw new ServiceException("订单状态异常"); if(!etOrder.getStatus().equals(ServiceConstants.ORDER_STATUS_ORDER_END)) throw new ServiceException("订单状态异常");
ChannelVO channelVO = etChannelService.selectSmChannelByChannelId(etOrder.getPayChannel()); ChannelVO channelVO = etChannelService.selectSmChannelByChannelId(etOrder.getPayChannel());
@ -413,9 +426,9 @@ public class WxPayService implements IWxPayService {
request.setOutRefundNo(outRefundNo); request.setOutRefundNo(outRefundNo);
request.setReason(reason); request.setReason(reason);
request.setAmount(getAmountReq(etOrder.getTotalFee(),amount)); request.setAmount(getAmountReq(etOrder.getTotalFee(),amount));
request.setNotifyUrl(sysDept.getRefundNotifyUrl()); request.setNotifyUrl(channelVO.getRefundNotifyUrl());
log.info("【退款】请求微信参数:【{}】",JSON.toJSONString(request)); log.info("【退款】请求微信参数:【{}】",JSON.toJSONString(request));
RefundService refundService = getRefundService(sysDept); RefundService refundService = getRefundService(channelVO);
Refund refund = refundService.create(request); Refund refund = refundService.create(request);
log.info("【退款】微信返回结果:【{}】",JSON.toJSONString(refund)); log.info("【退款】微信返回结果:【{}】",JSON.toJSONString(refund));
}else if(PayChannel.TL_WX.equalsCode(channelVO.getCode())){ }else if(PayChannel.TL_WX.equalsCode(channelVO.getCode())){
@ -455,14 +468,14 @@ public class WxPayService implements IWxPayService {
} }
} }
private RefundService getRefundService(SysDept sysDept){ private RefundService getRefundService(ChannelVO channelVO){
// 初始化商户配置 // 初始化商户配置
Config config = new RSAAutoCertificateConfig.Builder() Config config = new RSAAutoCertificateConfig.Builder()
.merchantId(sysDept.getMerchantId()) .merchantId(channelVO.getMerchantId())
// 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥商户私钥会用来生成请求的签名 // 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥商户私钥会用来生成请求的签名
.privateKeyFromPath(sysDept.getPrivateKeyPath()) .privateKeyFromPath(channelVO.getPrivateKeyPath())
.merchantSerialNumber(sysDept.getMerchantSerialNumber()) .merchantSerialNumber(channelVO.getMerchantSerialNumber())
.apiV3Key(sysDept.getApiV3Key()) .apiV3Key(channelVO.getApiV3Key())
.build(); .build();
// 初始化服务 // 初始化服务
return new RefundService.Builder().config(config).build(); return new RefundService.Builder().config(config).build();
@ -490,24 +503,25 @@ public class WxPayService implements IWxPayService {
request.setTotalNum(totalNum); request.setTotalNum(totalNum);
request.setTransferDetailList(transferDetailInputs); request.setTransferDetailList(transferDetailInputs);
log.info("【发起商家转账】请求微信参数:【{}】",JSON.toJSONString(request)); log.info("【发起商家转账】请求微信参数:【{}】",JSON.toJSONString(request));
TransferBatchService transferService = getTransferService(sysDept); // TransferBatchService transferService = getTransferService(sysDept);
InitiateBatchTransferResponse initiateBatchTransferResponse = transferService.initiateBatchTransfer(request); // InitiateBatchTransferResponse initiateBatchTransferResponse = transferService.initiateBatchTransfer(request);
log.info("【发起商家转账】微信返回结果:【{}】",JSON.toJSONString(initiateBatchTransferResponse)); // log.info("【发起商家转账】微信返回结果:【{}】",JSON.toJSONString(initiateBatchTransferResponse));
return initiateBatchTransferResponse; // return initiateBatchTransferResponse;
return null;
} }
private TransferBatchService getTransferService(SysDept sysDept){ // private TransferBatchService getTransferService(SysDept sysDept){
// 初始化商户配置 // // 初始化商户配置
Config config = new RSAAutoCertificateConfig.Builder() // Config config = new RSAAutoCertificateConfig.Builder()
.merchantId(sysDept.getMerchantId()) // .merchantId(sysDept.getMerchantId())
// 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥商户私钥会用来生成请求的签名 // // 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥商户私钥会用来生成请求的签名
.privateKeyFromPath(sysDept.getPrivateKeyPath()) // .privateKeyFromPath(sysDept.getPrivateKeyPath())
.merchantSerialNumber(sysDept.getMerchantSerialNumber()) // .merchantSerialNumber(sysDept.getMerchantSerialNumber())
.apiV3Key(sysDept.getApiV3Key()) // .apiV3Key(sysDept.getApiV3Key())
.build(); // .build();
// 初始化服务 // // 初始化服务
return new TransferBatchService.Builder().config(config).build(); // return new TransferBatchService.Builder().config(config).build();
} // }
/** /**
@ -525,76 +539,86 @@ public class WxPayService implements IWxPayService {
log.info("获取到运营商对象:【{}】",JSON.toJSON(sysDept)); log.info("获取到运营商对象:【{}】",JSON.toJSON(sysDept));
}else{ }else{
log.info("区域:【{}】没有绑定运营商",areaId); log.info("区域:【{}】没有绑定运营商",areaId);
// throw new ServiceException("区域:【"+areaId+"】没有绑定运营商");
return null; return null;
} }
return sysDept; return sysDept;
} }
@Override @Override
public Refund queryByOutRefundNo(Long areaId,String outRefundNo) { public Refund queryByOutRefundNo(String outRefundNo) {
SysDept sysDept = getDeptObjByAreaId(areaId); EtRefund refund = etRefundService.selectEtRefundByRefundNo(outRefundNo);
if (refund == null) {
throw new ServiceException("没有找到退款记录: " + outRefundNo);
}
EtOrder order = etOrderService.selectEtOrderByOrderNo(refund.getOrderNo());
if (order == null) {
throw new ServiceException("订单不存在: " + refund.getOrderNo());
}
ChannelVO channelVO = etChannelService.selectSmChannelByChannelId(order.getPayChannel());
if (channelVO == null) {
throw new ServiceException("支付渠道不存在: " + order.getPayChannel());
}
QueryByOutRefundNoRequest request = new QueryByOutRefundNoRequest(); QueryByOutRefundNoRequest request = new QueryByOutRefundNoRequest();
request.setOutRefundNo(outRefundNo); request.setOutRefundNo(outRefundNo);
RefundService refundService = getRefundService(sysDept); RefundService refundService = getRefundService(channelVO);
return refundService.queryByOutRefundNo(request); return refundService.queryByOutRefundNo(request);
} }
/** 请求分账API */ // /** 请求分账API */
public OrdersEntity createOrder(SysDept sysDept,String transactionId,List<CreateOrderReceiver> receivers) { // public OrdersEntity createOrder(SysDept sysDept,String transactionId,List<CreateOrderReceiver> receivers) {
CreateOrderRequest request = new CreateOrderRequest(); // CreateOrderRequest request = new CreateOrderRequest();
request.setAppid(sysDept.getAppid()); // request.setAppid(sysDept.getAppid());
request.setTransactionId(transactionId);// 微信订单号 // request.setTransactionId(transactionId);// 微信订单号
request.setOutOrderNo(IdUtils.getOrderNo("fz"));// 商户系统内部分账单号 // request.setOutOrderNo(IdUtils.getOrderNo("fz"));// 商户系统内部分账单号
request.setReceivers(receivers); // request.setReceivers(receivers);
request.setUnfreezeUnsplit(true); // request.setUnfreezeUnsplit(true);
ProfitsharingService profitsharingService = getProfitsharingService(sysDept); // ProfitsharingService profitsharingService = getProfitsharingService(sysDept);
return profitsharingService.createOrder(request); // return profitsharingService.createOrder(request);
} // }
//
// /** 添加分账接收方 */
// @Override
// public AddReceiverResponse addReceiver(String wxopenid,Long deptId,String type) {
// SysDept sysDept = deptService.selectDeptById(deptId);
// AddReceiverRequest request = new AddReceiverRequest();
// request.setAppid(sysDept.getAppid());
// if(type.equals(ServiceConstants.PROFITSHARING_TYPE_PLATFORM)){
// request.setType(ReceiverType.MERCHANT_ID);
// }else{
// request.setType(ReceiverType.PERSONAL_OPENID);
// }
// request.setAccount(wxopenid);
// request.setRelationType(ReceiverRelationType.PARTNER);
// ProfitsharingService profitsharingService = getProfitsharingService(sysDept);
// return profitsharingService.addReceiver(request);
// }
/** 添加分账接收方 */ // /** 删除分账接收方 */
@Override // public DeleteReceiverResponse deleteReceiver(String wxopenid,Long deptId,String type) {
public AddReceiverResponse addReceiver(String wxopenid,Long deptId,String type) { // SysDept sysDept = deptService.selectDeptById(deptId);
SysDept sysDept = deptService.selectDeptById(deptId); // DeleteReceiverRequest request = new DeleteReceiverRequest();
AddReceiverRequest request = new AddReceiverRequest(); // request.setAppid(sysDept.getAppid());
request.setAppid(sysDept.getAppid()); // if(type.equals(ServiceConstants.PROFITSHARING_TYPE_PLATFORM)){
if(type.equals(ServiceConstants.PROFITSHARING_TYPE_PLATFORM)){ // request.setType(ReceiverType.MERCHANT_ID);
request.setType(ReceiverType.MERCHANT_ID); // }else{
}else{ // request.setType(ReceiverType.PERSONAL_OPENID);
request.setType(ReceiverType.PERSONAL_OPENID); // }
} // request.setAccount(wxopenid);
request.setAccount(wxopenid); // ProfitsharingService profitsharingService = getProfitsharingService(sysDept);
request.setRelationType(ReceiverRelationType.PARTNER); // return profitsharingService.deleteReceiver(request);
ProfitsharingService profitsharingService = getProfitsharingService(sysDept); // }
return profitsharingService.addReceiver(request);
}
/** 删除分账接收方 */ // private ProfitsharingService getProfitsharingService(SysDept sysDept) {
public DeleteReceiverResponse deleteReceiver(String wxopenid,Long deptId,String type) { // Config config = new RSAAutoCertificateConfig.Builder()
SysDept sysDept = deptService.selectDeptById(deptId); // .merchantId(sysDept.getMerchantId())
DeleteReceiverRequest request = new DeleteReceiverRequest(); // // 使用 com.wechat.pay.java.core.util中的函数从本地文件中加载商户私钥商户私钥会用来生成请求的签名
request.setAppid(sysDept.getAppid()); // .privateKeyFromPath(sysDept.getPrivateKeyPath())
if(type.equals(ServiceConstants.PROFITSHARING_TYPE_PLATFORM)){ // .merchantSerialNumber(sysDept.getMerchantSerialNumber())
request.setType(ReceiverType.MERCHANT_ID); // .apiV3Key(sysDept.getApiV3Key())
}else{ // .build();
request.setType(ReceiverType.PERSONAL_OPENID); // // 初始化服务
} // return new ProfitsharingService.Builder().config(config).build();
request.setAccount(wxopenid); // }
ProfitsharingService profitsharingService = getProfitsharingService(sysDept);
return profitsharingService.deleteReceiver(request);
}
private ProfitsharingService getProfitsharingService(SysDept sysDept) {
Config config = new RSAAutoCertificateConfig.Builder()
.merchantId(sysDept.getMerchantId())
// 使用 com.wechat.pay.java.core.util中的函数从本地文件中加载商户私钥商户私钥会用来生成请求的签名
.privateKeyFromPath(sysDept.getPrivateKeyPath())
.merchantSerialNumber(sysDept.getMerchantSerialNumber())
.apiV3Key(sysDept.getApiV3Key())
.build();
// 初始化服务
return new ProfitsharingService.Builder().config(config).build();
}
// /** // /**

View File

@ -167,7 +167,7 @@ public class EtTask {
if(!Constants.SUCCESS2.equals(etRefund.getRefundResult())){ if(!Constants.SUCCESS2.equals(etRefund.getRefundResult())){
log.info("【系统启动】押金退款未成功回调,退款单号:【{}】",etRefund.getRefundNo()); log.info("【系统启动】押金退款未成功回调,退款单号:【{}】",etRefund.getRefundNo());
// 根据退款单号查询退款信息 // 根据退款单号查询退款信息
Refund refund = wxPayService.queryByOutRefundNo(area.getAreaId(),etRefund.getRefundNo()); Refund refund = wxPayService.queryByOutRefundNo(etRefund.getRefundNo());
if(ObjectUtil.isNotNull(refund) && Constants.SUCCESS2.equals(refund.getStatus().name())){ if(ObjectUtil.isNotNull(refund) && Constants.SUCCESS2.equals(refund.getStatus().name())){
// 更新退款记录 // 更新退款记录
etRefund.setRefundResult(Constants.SUCCESS2); etRefund.setRefundResult(Constants.SUCCESS2);

View File

@ -96,4 +96,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#{channelId} #{channelId}
</foreach> </foreach>
</delete> </delete>
<select id="selectChannelBySerialNumber" resultMap="SmChannelResult">
<include refid="selectSmChannelVo"/>
where wechatpay_serial = #{wechatpaySerial}
</select>
</mapper> </mapper>