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

View File

@ -85,8 +85,8 @@ public class SysDept extends BaseEntity
/** 余额 */
private BigDecimal balance;
// /** appSecret */
// private String appSecret;
/** appSecret */
private String appSecret;
//
// /** merchantId */
// private String merchantId;
@ -281,14 +281,14 @@ public class SysDept extends BaseEntity
this.appid = appid;
}
// public String getAppSecret() {
// return appSecret;
// }
//
// public void setAppSecret(String appSecret) {
// this.appSecret = appSecret;
// }
//
public String getAppSecret() {
return appSecret;
}
public void setAppSecret(String appSecret) {
this.appSecret = appSecret;
}
// public String getMerchantId() {
// 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;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.system.domain.Channel;
import com.ruoyi.system.domain.ChannelQuery;
import com.ruoyi.system.domain.ChannelVO;
@ -62,4 +63,13 @@ public interface EtChannelMapper
* @return 结果
*/
public int deleteSmChannelByChannelIds(Long[] channelIds);
/**
* 根据证书序列号获取支付渠道
*
* @param wechatpaySerial 证书序列号
* @return 结果
*/
ChannelVO selectChannelBySerialNumber(String wechatpaySerial);
}

View File

@ -1,5 +1,6 @@
package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.system.domain.Channel;
import com.ruoyi.system.domain.ChannelQuery;
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);
/**
* 根据证书序列号获取支付渠道
*
* @param wechatpaySerial 证书序列号
* @return 结果
*/
ChannelVO selectChannelBySerialNumber(String wechatpaySerial);
}

View File

@ -1,6 +1,8 @@
package com.ruoyi.system.service;
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.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import com.wechat.pay.java.service.payments.model.Transaction;
@ -55,14 +57,14 @@ public interface IWxPayService {
* @param outTradeNo 商户订单号
* @return 订单信息
*/
Transaction queryOrderByOutTradeNo(String outTradeNo);
PaymentResult queryOrderByOutTradeNo(String outTradeNo);
/**
* 关闭订单
* @param outTradeNo 商户订单号
* @return 订单信息
*/
boolean closeOrder(String outTradeNo,SysDept sysDept);
boolean closeOrder(String outTradeNo, ChannelVO channelVO);
/**
* 根据订单号查询订单支付结果
@ -96,7 +98,7 @@ public interface IWxPayService {
* 根据退款单号查询退款信息
* @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);
/**
* 添加分账接收方
* @param wxopenid openid
* @param deptId 运营商id
*/
AddReceiverResponse addReceiver(String wxopenid,Long deptId,String type);
/**
* 删除分账接收方
* @param wxopenid openid
* @param deptId 运营商id
*/
DeleteReceiverResponse deleteReceiver(String wxopenid,Long deptId,String type);
// /**
// * 添加分账接收方
// * @param wxopenid openid
// * @param deptId 运营商id
// */
// AddReceiverResponse addReceiver(String wxopenid,Long deptId,String type);
//
// /**
// * 删除分账接收方
// * @param wxopenid openid
// * @param deptId 运营商id
// */
// 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.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.IotConstants;
import com.ruoyi.common.constant.ServiceConstants;
import com.ruoyi.common.core.domain.entity.AsUser;
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.profitsharing.model.CreateOrderReceiver;
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.Status;
import org.slf4j.Logger;
@ -127,6 +125,9 @@ public class CallbackServiceImpl implements CallbackService {
@Autowired
private TransactionTemplate transactionTemplate;
@Autowired
private EtChannelService etChannelService;
@Value("${aliyun.accessKeyId}")
private String accessKeyId;
@ -1188,15 +1189,15 @@ public class CallbackServiceImpl implements CallbackService {
public NotificationParser getNotificationParser(String wechatpaySerial) {
// 根据证书序列号获取运营商
SysDept sysDept = deptService.selectEtOperatingAreaBySerialNumber(wechatpaySerial);
if(ObjectUtil.isNull(sysDept)){
throw new ServiceException("【微信支付回调】根据证书序列号获取运营商失败");
ChannelVO channelVO = etChannelService.selectChannelBySerialNumber(wechatpaySerial);
if(ObjectUtil.isNull(channelVO)){
throw new ServiceException("【微信支付回调】根据证书序列号获取支付渠道失败");
}else{
NotificationConfig config = new RSAAutoCertificateConfig.Builder()
.merchantId(sysDept.getMerchantId())
.privateKeyFromPath(sysDept.getPrivateKeyPath())
.merchantSerialNumber(sysDept.getMerchantSerialNumber())
.apiV3Key(sysDept.getApiV3Key())
.merchantId(channelVO.getMerchantId())
.privateKeyFromPath(channelVO.getPrivateKeyPath())
.merchantSerialNumber(channelVO.getMerchantSerialNumber())
.apiV3Key(channelVO.getApiV3Key())
.build();
return new NotificationParser(config);
}

View File

@ -1,5 +1,6 @@
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.ChannelQuery;
import com.ruoyi.system.domain.ChannelVO;
@ -118,4 +119,16 @@ public class EtChannelServiceImpl implements EtChannelService
// }
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.enums.BusinessStatus;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.pay.PaymentResult;
import com.ruoyi.common.utils.CommonUtil;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.PageUtils;
@ -128,6 +129,9 @@ public class EtOrderServiceImpl implements IEtOrderService
@Resource
private EtCouponClaimLogMapper etCouponClaimLogMapper;
@Autowired
private EtChannelService etChannelService;
/**
* 查询订单
*
@ -520,9 +524,9 @@ public class EtOrderServiceImpl implements IEtOrderService
String outTradeNo = order.getOutTradeNo();
log.info("【押金抵扣】订单【{}】,有outTradeNo = 【{}】", order.getOrderNo(),outTradeNo);
// 如果原来有outtradeno去查询一次查询是否支付过
Transaction transaction = wxPayService.queryOrderByOutTradeNo(outTradeNo);
PaymentResult paymentResult = wxPayService.queryOrderByOutTradeNo(outTradeNo);
try {
if (Transaction.TradeStateEnum.SUCCESS.equals(transaction.getTradeState())) {
if (Transaction.TradeStateEnum.SUCCESS.equals(paymentResult.getStatus())) {
// 订单已支付
order.setPaid(ServiceConstants.ORDER_PAY_STATUS_PAID);
order.setPayTime(DateUtils.getNowDate());
@ -536,9 +540,9 @@ public class EtOrderServiceImpl implements IEtOrderService
}
return 1;
}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);
}
} catch (ServiceException e) {

View File

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

View File

@ -450,8 +450,8 @@ public class SysUserServiceImpl implements ISysUserService
// 绑定app用户
userMapper.bandAppUser(asUser.getUserId(), user.getUserId());
// 添加分账接收方
AddReceiverResponse addReceiverResponse = wxPayService.addReceiver(asUser.getWxopenid(),SecurityUtils.getLoginUser().getUser().getDeptId(), ServiceConstants.PROFITSHARING_TYPE_PARTNER);
log.info("添加分账接收方响应:【{}】", JSON.toJSON(addReceiverResponse));
// AddReceiverResponse addReceiverResponse = wxPayService.addReceiver(asUser.getWxopenid(),SecurityUtils.getLoginUser().getUser().getDeptId(), ServiceConstants.PROFITSHARING_TYPE_PARTNER);
// log.info("添加分账接收方响应:【{}】", JSON.toJSON(addReceiverResponse));
}
/**
@ -461,8 +461,8 @@ public class SysUserServiceImpl implements ISysUserService
*/
private void deleteReceiver(String openid,Long deptId) {
// 添加分账接收方
DeleteReceiverResponse deleteReceiverResponse = wxPayService.deleteReceiver(openid,deptId,ServiceConstants.PROFITSHARING_TYPE_PARTNER);
log.info("删除分账接收方响应:【{}】", JSON.toJSON(deleteReceiverResponse));
// DeleteReceiverResponse deleteReceiverResponse = wxPayService.deleteReceiver(openid,deptId,ServiceConstants.PROFITSHARING_TYPE_PARTNER);
// 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.enums.PayChannel;
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.service.SybPayService;
import com.ruoyi.common.pay.wx.Payable;
@ -49,6 +50,7 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
@ -81,9 +83,6 @@ public class WxPayService implements IWxPayService {
@Resource
private AsUserMapper asUserMapper;
@Autowired
private IEtOrderService orderService;
@Autowired
private SybPayService sybPayService;
@ -229,7 +228,7 @@ public class WxPayService implements IWxPayService {
request.setDescription(description);
request.setNotifyUrl(channelVO.getNotifyUrl());
request.setPayer(getPayer(user.getWxopenid()));
JsapiServiceExtension jsapiServiceExtension = getJsapiServiceExtension(sysDept);
JsapiServiceExtension jsapiServiceExtension = getJsapiServiceExtension(channelVO);
PrepayWithRequestPaymentResponse res = jsapiServiceExtension.prepayWithRequestPayment(request);
if(StrUtil.isNotBlank(order.getOutTradeNo())){
@ -295,21 +294,29 @@ public class WxPayService implements IWxPayService {
* @return
*/
@Override
public Transaction queryOrderByOutTradeNo(String outTradeNo) {
public PaymentResult queryOrderByOutTradeNo(String outTradeNo) {
EtOrder order = etOrderService.selectEtOrderByOutTradeNo(outTradeNo);
List<EtAreaDept> areaId1 = etAreaDeptMapper.selectList(new QueryWrapper<EtAreaDept>().eq("area_id", order.getAreaId()));
if (ObjectUtil.isNotEmpty(areaId1) && areaId1.size() > 0){
EtAreaDept etAreaDept = areaId1.get(0);
SysDept sysDept = deptService.selectDeptById(etAreaDept.getDeptId());
log.info("获取到运营商对象:【{}】",JSON.toJSON(sysDept));
ChannelVO channelVO = etChannelService.selectSmChannelByChannelId(order.getPayChannel());
if(PayChannel.CT_WX.equalsCode(channelVO.getCode()) || PayChannel.YS_WX.equalsCode(channelVO.getCode())){
QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
request.setMchid(sysDept.getMerchantId());
request.setMchid(channelVO.getMerchantId());
request.setOutTradeNo(outTradeNo);
JsapiService jsapiService = getJsapiService(sysDept);
return jsapiService.queryOrderByOutTradeNo(request);
JsapiService jsapiService = getJsapiService(channelVO);
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{
log.info("区域:【{}】没有绑定运营商",order.getAreaId());
throw new ServiceException("区域:【"+order.getAreaId()+"】没有绑定运营商");
throw new ServiceException("支付渠道【"+channelVO.getCode()+"】暂不支持");
}
}
@ -319,11 +326,11 @@ public class WxPayService implements IWxPayService {
* @return
*/
@Override
public boolean closeOrder(String outTradeNo, SysDept sysDept) {
JsapiServiceExtension jsapiServiceExtension = getJsapiServiceExtension(sysDept);
public boolean closeOrder(String outTradeNo,ChannelVO channelVO) {
JsapiServiceExtension jsapiServiceExtension = getJsapiServiceExtension(channelVO);
// 关闭订单
CloseOrderRequest closeOrderRequest = new CloseOrderRequest();
closeOrderRequest.setMchid(sysDept.getMerchantId());
closeOrderRequest.setMchid(channelVO.getMerchantId());
closeOrderRequest.setOutTradeNo(outTradeNo);
jsapiServiceExtension.closeOrder(closeOrderRequest);
return true;
@ -337,56 +344,64 @@ public class WxPayService implements IWxPayService {
@Override
public Boolean queryResultByOrderNo(String orderNo) {
EtOrder order = etOrderService.selectEtOrderByOrderNo(orderNo);
SysDept sysDept = getDeptObjByAreaId(order.getAreaId());
log.info("获取到运营商对象:【{}】",JSON.toJSON(sysDept));
QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
request.setMchid(sysDept.getMerchantId());
if(StrUtil.isBlank(order.getOutTradeNo())){
return false;
}
request.setOutTradeNo(order.getOutTradeNo());
JsapiService jsapiService = getJsapiService(sysDept);
Transaction transaction = jsapiService.queryOrderByOutTradeNo(request);
// 订单未支付并且微信支付结果是成功的情况下更新订单状态和用户余额
if(transaction.getTradeState().equals(Transaction.TradeStateEnum.SUCCESS)){
if(order.getPaid().equals(ServiceConstants.ORDER_PAY_STATUS_NON_PAYMENT)){
order.setPaid("1");
order.setPayTime(DateUtils.parseTime(transaction.getSuccessTime()));
order.setPayType(ServiceConstants.PAY_TYPE_WX);
log.info("【主动查询】押金支付");
order.setStatus(ServiceConstants.ORDER_STATUS_ORDER_END);
if(ServiceConstants.ORDER_TYPE_RIDING.equals(order.getType())){
order.setMark("主动查询-骑行支付");
}else{
order.setMark("押金支付");
// 更新用户余额
AsUser asUser = asUserMapper.selectUserById(order.getUserId());
asUser.setBalance(order.getTotalFee());
int updateUser = asUserMapper.updateUser(asUser);
if(updateUser==0){
log.error("【微信支付回调】更新用户押金失败");
throw new ServiceException("【微信支付回调】更新用户押金失败");
ChannelVO channelVO = etChannelService.selectSmChannelByChannelId(order.getPayChannel());
if(PayChannel.CT_WX.equalsCode(channelVO.getCode()) || PayChannel.YS_WX.equalsCode(channelVO.getCode())){
QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
request.setMchid(channelVO.getMerchantId());
if(StrUtil.isBlank(order.getOutTradeNo())){
return false;
}
request.setOutTradeNo(order.getOutTradeNo());
JsapiService jsapiService = getJsapiService(channelVO);
Transaction transaction = jsapiService.queryOrderByOutTradeNo(request);
// 订单未支付并且微信支付结果是成功的情况下更新订单状态和用户余额
if(transaction.getTradeState().equals(Transaction.TradeStateEnum.SUCCESS)){
if(order.getPaid().equals(ServiceConstants.ORDER_PAY_STATUS_NON_PAYMENT)){
order.setPaid("1");
order.setPayTime(DateUtils.parseTime(transaction.getSuccessTime()));
order.setPayType(ServiceConstants.PAY_TYPE_WX);
log.info("【主动查询】押金支付");
order.setStatus(ServiceConstants.ORDER_STATUS_ORDER_END);
if(ServiceConstants.ORDER_TYPE_RIDING.equals(order.getType())){
order.setMark("主动查询-骑行支付");
}else{
order.setMark("押金支付");
// 更新用户余额
AsUser asUser = asUserMapper.selectUserById(order.getUserId());
asUser.setBalance(order.getTotalFee());
int updateUser = asUserMapper.updateUser(asUser);
if(updateUser==0){
log.error("【微信支付回调】更新用户押金失败");
throw new ServiceException("【微信支付回调】更新用户押金失败");
}
}
int updateEtOrder = etOrderService.updateEtOrder(order);
if(updateEtOrder==0){
log.error("【微信支付回调】更新订单信息失败");
throw new ServiceException("【微信支付回调】更新订单信息失败");
}
}
int updateEtOrder = orderService.updateEtOrder(order);
if(updateEtOrder==0){
log.error("【微信支付回调】更新订单信息失败");
throw new ServiceException("【微信支付回调】更新订单信息失败");
}
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;
}
private JsapiService getJsapiService(SysDept sysDept) {
private JsapiService getJsapiService(ChannelVO channelVO) {
// 初始化商户配置
Config config = new RSAAutoCertificateConfig.Builder()
.merchantId(sysDept.getMerchantId())
.merchantId(channelVO.getMerchantId())
// 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥商户私钥会用来生成请求的签名
.privateKeyFromPath(sysDept.getPrivateKeyPath())
.merchantSerialNumber(sysDept.getMerchantSerialNumber())
.apiV3Key(sysDept.getApiV3Key())
.privateKeyFromPath(channelVO.getPrivateKeyPath())
.merchantSerialNumber(channelVO.getMerchantSerialNumber())
.apiV3Key(channelVO.getApiV3Key())
.build();
// 初始化服务
return new JsapiService.Builder().config(config).build();
@ -401,8 +416,6 @@ public class WxPayService implements IWxPayService {
*/
@Override
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("订单状态异常");
ChannelVO channelVO = etChannelService.selectSmChannelByChannelId(etOrder.getPayChannel());
@ -413,9 +426,9 @@ public class WxPayService implements IWxPayService {
request.setOutRefundNo(outRefundNo);
request.setReason(reason);
request.setAmount(getAmountReq(etOrder.getTotalFee(),amount));
request.setNotifyUrl(sysDept.getRefundNotifyUrl());
request.setNotifyUrl(channelVO.getRefundNotifyUrl());
log.info("【退款】请求微信参数:【{}】",JSON.toJSONString(request));
RefundService refundService = getRefundService(sysDept);
RefundService refundService = getRefundService(channelVO);
Refund refund = refundService.create(request);
log.info("【退款】微信返回结果:【{}】",JSON.toJSONString(refund));
}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()
.merchantId(sysDept.getMerchantId())
.merchantId(channelVO.getMerchantId())
// 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥商户私钥会用来生成请求的签名
.privateKeyFromPath(sysDept.getPrivateKeyPath())
.merchantSerialNumber(sysDept.getMerchantSerialNumber())
.apiV3Key(sysDept.getApiV3Key())
.privateKeyFromPath(channelVO.getPrivateKeyPath())
.merchantSerialNumber(channelVO.getMerchantSerialNumber())
.apiV3Key(channelVO.getApiV3Key())
.build();
// 初始化服务
return new RefundService.Builder().config(config).build();
@ -490,24 +503,25 @@ public class WxPayService implements IWxPayService {
request.setTotalNum(totalNum);
request.setTransferDetailList(transferDetailInputs);
log.info("【发起商家转账】请求微信参数:【{}】",JSON.toJSONString(request));
TransferBatchService transferService = getTransferService(sysDept);
InitiateBatchTransferResponse initiateBatchTransferResponse = transferService.initiateBatchTransfer(request);
log.info("【发起商家转账】微信返回结果:【{}】",JSON.toJSONString(initiateBatchTransferResponse));
return initiateBatchTransferResponse;
// TransferBatchService transferService = getTransferService(sysDept);
// InitiateBatchTransferResponse initiateBatchTransferResponse = transferService.initiateBatchTransfer(request);
// log.info("【发起商家转账】微信返回结果:【{}】",JSON.toJSONString(initiateBatchTransferResponse));
// return initiateBatchTransferResponse;
return null;
}
private TransferBatchService getTransferService(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 TransferBatchService.Builder().config(config).build();
}
// private TransferBatchService getTransferService(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 TransferBatchService.Builder().config(config).build();
// }
/**
@ -525,76 +539,86 @@ public class WxPayService implements IWxPayService {
log.info("获取到运营商对象:【{}】",JSON.toJSON(sysDept));
}else{
log.info("区域:【{}】没有绑定运营商",areaId);
// throw new ServiceException("区域:【"+areaId+"】没有绑定运营商");
return null;
}
return sysDept;
}
@Override
public Refund queryByOutRefundNo(Long areaId,String outRefundNo) {
SysDept sysDept = getDeptObjByAreaId(areaId);
public Refund queryByOutRefundNo(String outRefundNo) {
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();
request.setOutRefundNo(outRefundNo);
RefundService refundService = getRefundService(sysDept);
RefundService refundService = getRefundService(channelVO);
return refundService.queryByOutRefundNo(request);
}
/** 请求分账API */
public OrdersEntity createOrder(SysDept sysDept,String transactionId,List<CreateOrderReceiver> receivers) {
CreateOrderRequest request = new CreateOrderRequest();
request.setAppid(sysDept.getAppid());
request.setTransactionId(transactionId);// 微信订单号
request.setOutOrderNo(IdUtils.getOrderNo("fz"));// 商户系统内部分账单号
request.setReceivers(receivers);
request.setUnfreezeUnsplit(true);
ProfitsharingService profitsharingService = getProfitsharingService(sysDept);
return profitsharingService.createOrder(request);
}
// /** 请求分账API */
// public OrdersEntity createOrder(SysDept sysDept,String transactionId,List<CreateOrderReceiver> receivers) {
// CreateOrderRequest request = new CreateOrderRequest();
// request.setAppid(sysDept.getAppid());
// request.setTransactionId(transactionId);// 微信订单号
// request.setOutOrderNo(IdUtils.getOrderNo("fz"));// 商户系统内部分账单号
// request.setReceivers(receivers);
// request.setUnfreezeUnsplit(true);
// ProfitsharingService profitsharingService = getProfitsharingService(sysDept);
// 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 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);
}
// /** 删除分账接收方 */
// public DeleteReceiverResponse deleteReceiver(String wxopenid,Long deptId,String type) {
// SysDept sysDept = deptService.selectDeptById(deptId);
// DeleteReceiverRequest request = new DeleteReceiverRequest();
// 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);
// ProfitsharingService profitsharingService = getProfitsharingService(sysDept);
// return profitsharingService.deleteReceiver(request);
// }
/** 删除分账接收方 */
public DeleteReceiverResponse deleteReceiver(String wxopenid,Long deptId,String type) {
SysDept sysDept = deptService.selectDeptById(deptId);
DeleteReceiverRequest request = new DeleteReceiverRequest();
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);
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();
}
// 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())){
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())){
// 更新退款记录
etRefund.setRefundResult(Constants.SUCCESS2);

View File

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