微信支付小重构

This commit is contained in:
墨大叔 2024-08-01 11:15:23 +08:00
parent f72ca5ecb6
commit 6342d71a89
22 changed files with 158 additions and 258 deletions

View File

@ -1,4 +1,4 @@
package com.ruoyi.ss.wxPay.domain;
package com.ruoyi.common.pay.wx.domain;
import java.math.BigDecimal;

View File

@ -1,4 +1,4 @@
package com.ruoyi.ss.wxPay.domain;
package com.ruoyi.common.pay.wx.domain;
import com.wechat.pay.java.service.refund.model.AmountReq;

View File

@ -1,7 +1,6 @@
package com.ruoyi.ss.wxPay.domain.enums;
package com.ruoyi.common.pay.wx.domain.enums;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
/**

View File

@ -1,4 +1,4 @@
package com.ruoyi.ss.wxPay.domain.enums;
package com.ruoyi.common.pay.wx.domain.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;

View File

@ -1,11 +1,8 @@
package com.ruoyi.ss.wxPay.service;
package com.ruoyi.common.pay.wx.service;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.ss.wxPay.domain.Payable;
import com.ruoyi.ss.wxPay.domain.RefundAble;
import com.ruoyi.ss.wxPay.domain.enums.TransferScene;
import com.wechat.pay.java.core.notification.Notification;
import com.ruoyi.common.pay.wx.domain.Payable;
import com.ruoyi.common.pay.wx.domain.RefundAble;
import com.ruoyi.common.pay.wx.domain.enums.TransferScene;
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.refund.model.Refund;
@ -21,14 +18,7 @@ import java.util.List;
* @author
* 2024/3/11
*/
public interface IWxPayService {
/**
* 生成微信预支付订单并签名
* @param billNo 平台订单编号
* @return JSAPI调用
*/
PrepayWithRequestPaymentResponse prepayWithRequestPayment(String billNo);
public interface WxPayService {
PrepayWithRequestPaymentResponse prepayWithRequestPayment(Payable payable);
@ -57,11 +47,6 @@ public interface IWxPayService {
boolean isSuccess(Transaction transaction);
/**
* 微信支付通知
*/
void payNotify(HttpServletRequest request);
/**
* 提现打款
* @param billId 单号

View File

@ -1,27 +1,19 @@
package com.ruoyi.ss.wxPay.service;
package com.ruoyi.common.pay.wx.service;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.config.WxPayConfig;
import com.ruoyi.common.core.redis.RedisLock;
import com.ruoyi.common.core.redis.enums.RedisLockKey;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.pay.wx.domain.NotifyEventType;
import com.ruoyi.common.pay.wx.domain.TransferBatchStatus;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.common.utils.SnowFlakeUtil;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.ss.transactionBill.domain.TransactionBill;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillPayType;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillStatus;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillType;
import com.ruoyi.ss.transactionBill.service.TransactionBillService;
import com.ruoyi.ss.user.domain.SmUserVo;
import com.ruoyi.ss.user.service.ISmUserService;
import com.ruoyi.ss.wxPay.domain.Payable;
import com.ruoyi.ss.wxPay.domain.RefundAble;
import com.ruoyi.ss.wxPay.domain.enums.TransferScene;
import com.ruoyi.ss.wxPayNotify.domain.SmWxPayNotify;
import com.ruoyi.ss.wxPayNotify.mapper.SmWxPayNotifyMapper;
import com.ruoyi.common.pay.wx.domain.Payable;
import com.ruoyi.common.pay.wx.domain.RefundAble;
import com.ruoyi.common.pay.wx.domain.enums.TransferScene;
import com.wechat.pay.java.core.notification.Notification;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
@ -60,7 +52,7 @@ import java.util.stream.Collectors;
*/
@Service
@Slf4j
public class WxPayService implements IWxPayService {
public class WxPayServiceImpl implements WxPayService {
@Autowired
private JsapiService jsapiService;
@ -71,78 +63,14 @@ public class WxPayService implements IWxPayService {
@Autowired
private WxPayConfig wxPayConfig;
@Autowired
private TransactionBillService transactionBillService;
@Autowired
private ISmUserService smUserService;
@Autowired
private NotificationParser notificationParser;
@Autowired
private SmWxPayNotifyMapper smWxPayNotifyMapper;
@Autowired
private RedisLock redisLock;
@Autowired
private RefundService refundService;
@Autowired
private TransferBatchService transferBatchService;
@Autowired
private ScheduledExecutorService scheduledExecutorService;
private static final String CNY = "CNY";
@Override
@Transactional
public PrepayWithRequestPaymentResponse prepayWithRequestPayment(String billNo) {
try {
ServiceUtil.assertion(!redisLock.lock(RedisLockKey.PREPAY.getKey() + ":" + billNo), "当前订单正在支付,请刷新后重试");
TransactionBill bill = transactionBillService.selectSmTransactionBillByBillNo(billNo);
ServiceUtil.assertion(bill == null, "未查询到相关订单");
ServiceUtil.assertion(!Objects.equals(bill.getChannelId(), TransactionBillPayType.WECHAT.getType()), "该订单不是微信支付订单");
ServiceUtil.assertion(!TransactionBillStatus.UNPAID.getStatus().equals(bill.getStatus()), "只能支付未支付的订单");
ServiceUtil.assertion(!TransactionBillType.RECHARGE.getType().equals(bill.getType()), "只能支付充值订单");
// 获取JSAPI所需参数
// PrepayRequest request = new PrepayRequest();
// request.setAmount(getAmount(bill.getMoney()));
// request.setOutTradeNo(billNo);
// request.setAppid(wxPayConfig.getAppId());
// request.setMchid(wxPayConfig.getMerchantId());
// request.setDescription(getDescription(bill));
// request.setNotifyUrl(wxPayConfig.getNotifyUrl());
// request.setPayer(getPayer(user.getWxOpenId()));
//
// PrepayWithRequestPaymentResponse res = jsapiServiceExtension.prepayWithRequestPayment(request);
PrepayWithRequestPaymentResponse res = this.prepayWithRequestPayment(bill);
try {
// 支付中
transactionBillService.paying(bill.getBillId());
// 每隔20秒查询支付结果直到过期首次10秒查询
scheduledExecutorService.schedule(() -> {
transactionBillService.refreshPayResultBeforeExpire(bill.getBillNo(), 20, TimeUnit.SECONDS);
}, 10, TimeUnit.SECONDS);
} catch (Exception e) {
this.closeOrder(bill.getBillNo());
throw e;
}
return res;
} finally {
redisLock.unlock(RedisLockKey.PREPAY.getKey() + ":" + billNo);
}
}
@Override
public PrepayWithRequestPaymentResponse prepayWithRequestPayment(Payable payable) {
return this.prepayWithRequestPayment(payable.payableOutTradeNo(), payable.payableMoney(), payable.payableDescription(), payable.payableOpenId(), payable.payableAttach());
@ -196,31 +124,6 @@ public class WxPayService implements IWxPayService {
return transaction != null && Transaction.TradeStateEnum.SUCCESS.equals(transaction.getTradeState());
}
/**
* 微信支付通知
* @param request 请求
*/
@Override
public void payNotify(HttpServletRequest request) {
// 获取原始报文body
String body = HttpUtils.getBody(request);
log.info("获取原始报文body: {}", body);
// 解析通知数据
Notification notification = JSON.parseObject(body, Notification.class);
log.info("解析通知数据: {}", notification);
// 支付成功通知
if (NotifyEventType.TRANSACTION_SUCCESS.getValue().equals(notification.getEventType())) {
// 验签解密并转换成 Transaction
Transaction transaction = checkAndParse(request, body, Transaction.class);
log.info("验签、解密并转换成Transaction: {}", transaction);
if (Transaction.TradeStateEnum.SUCCESS.equals(transaction.getTradeState())) {
// 充值成功修改订单状态
transactionBillService.rechargeSuccess(transaction.getOutTradeNo(), DateUtils.getNowDate());
}
}
}
/**
* 提现打款
* @param billId id
@ -228,59 +131,60 @@ public class WxPayService implements IWxPayService {
@Override
@Transactional
public InitiateBatchTransferResponse payWithdraw(Long billId) {
ServiceUtil.assertion(billId == null, "订单id不允许为空");
TransactionBill bill = transactionBillService.selectSmTransactionBillByBillId(billId);
ServiceUtil.assertion(bill == null, "单据不存在");
ServiceUtil.assertion(TransactionBillStatus.WITHDRAW_PASSED.getStatus().equals(bill.getStatus()), "当前提现单据状态异常");
ServiceUtil.assertion(StringUtils.isBlank(bill.getAccountNo()), "提现账号异常");
// 转账明细列表
List<TransferDetailInput> transferDetailList = this.buildTransferDetailList(bill.getArrivalAmount(), bill.getAccountNo(), TransferScene.WITHDRAW);
// 更新微信批次明细单号
transactionBillService.updateWxTransferDetailIds(billId, transferDetailList.stream().map(TransferDetailInput::getOutDetailNo).collect(Collectors.toList()));
// 发起转账请求
InitiateBatchTransferRequest request = new InitiateBatchTransferRequest();
request.setAppid(wxPayConfig.getAppId());
request.setOutBatchNo(bill.getBillNo());
request.setBatchName("提现");
request.setBatchRemark(String.format("用户%s提现%f元", bill.getUserId(), bill.getArrivalAmount()));
request.setTotalAmount(getTransferAmount(bill.getArrivalAmount()));
request.setTotalNum(transferDetailList.size());
request.setTransferDetailList(transferDetailList);
return transferBatchService.initiateBatchTransfer(request);
// ServiceUtil.assertion(billId == null, "订单id不允许为空");
// TransactionBill bill = transactionBillService.selectSmTransactionBillByBillId(billId);
// ServiceUtil.assertion(bill == null, "单据不存在");
// ServiceUtil.assertion(TransactionBillStatus.WITHDRAW_PASSED.getStatus().equals(bill.getStatus()), "当前提现单据状态异常");
// ServiceUtil.assertion(StringUtils.isBlank(bill.getAccountNo()), "提现账号异常");
//
// // 转账明细列表
// List<TransferDetailInput> transferDetailList = this.buildTransferDetailList(bill.getArrivalAmount(), bill.getAccountNo(), TransferScene.WITHDRAW);
//
// // 更新微信批次明细单号
// transactionBillService.updateWxTransferDetailIds(billId, transferDetailList.stream().map(TransferDetailInput::getOutDetailNo).collect(Collectors.toList()));
//
// // 发起转账请求
// InitiateBatchTransferRequest request = new InitiateBatchTransferRequest();
// request.setAppid(wxPayConfig.getAppId());
// request.setOutBatchNo(bill.getBillNo());
// request.setBatchName("提现");
// request.setBatchRemark(String.format("用户%s提现%f元", bill.getUserId(), bill.getArrivalAmount()));
// request.setTotalAmount(getTransferAmount(bill.getArrivalAmount()));
// request.setTotalNum(transferDetailList.size());
// request.setTransferDetailList(transferDetailList);
// return transferBatchService.initiateBatchTransfer(request);
throw new ServiceException("开发中");
}
@Override
@Transactional
public void wxTransferNotify(HttpServletRequest request) {
String body = HttpUtils.getBody(request);
// 解析通知数据
Notification notification = JSON.parseObject(body, Notification.class);
// 判断是否重复通知重复通知则忽略
if (isRepeatNotify(notification.getId())) {
return;
}
// 商户转账成功通知
if (NotifyEventType.MCHTRANSFER_BATCH_FINISHED.getValue().equals(notification.getEventType())) {
// 验签解密并转换成 TransferBatchGet
TransferBatchGet transferBatchGet = checkAndParse(request, body, TransferBatchGet.class);
TransactionBill bill = transactionBillService.selectSmTransactionBillByBillNo(transferBatchGet.getOutBatchNo());
ServiceUtil.assertion(bill == null, "订单不存在");
// 修改订单状态
if (TransferBatchStatus.FINISHED.getStatus().equals(transferBatchGet.getBatchStatus())) {
// 提现成功
transactionBillService.withdrawSuccess(bill.getBillId(), LocalDateTime.now());
} else if (TransferBatchStatus.CLOSED.getStatus().equals(transferBatchGet.getBatchStatus())) {
// 提现失败
transactionBillService.withdrawFailed(bill.getBillId());
}
}
throw new ServiceException("开发中");
// String body = HttpUtils.getBody(request);
// // 解析通知数据
// Notification notification = JSON.parseObject(body, Notification.class);
//
// // 判断是否重复通知重复通知则忽略
// if (isRepeatNotify(notification.getId())) {
// return;
// }
//
// // 商户转账成功通知
// if (NotifyEventType.MCHTRANSFER_BATCH_FINISHED.getValue().equals(notification.getEventType())) {
// // 验签解密并转换成 TransferBatchGet
// TransferBatchGet transferBatchGet = checkAndParse(request, body, TransferBatchGet.class);
// TransactionBill bill = transactionBillService.selectSmTransactionBillByBillNo(transferBatchGet.getOutBatchNo());
// ServiceUtil.assertion(bill == null, "订单不存在");
//
// // 修改订单状态
// if (TransferBatchStatus.FINISHED.getStatus().equals(transferBatchGet.getBatchStatus())) {
// // 提现成功
// transactionBillService.withdrawSuccess(bill.getBillId(), LocalDateTime.now());
// } else if (TransferBatchStatus.CLOSED.getStatus().equals(transferBatchGet.getBatchStatus())) {
// // 提现失败
// transactionBillService.withdrawFailed(bill.getBillId());
// }
// }
}
@ -329,32 +233,6 @@ public class WxPayService implements IWxPayService {
return money.multiply(new BigDecimal(100)).longValue();
}
/**
* 通知是否重复
* @param notifyId 通知id
*/
private boolean isRepeatNotify(String notifyId) {
SmWxPayNotify repeat = smWxPayNotifyMapper.selectSmWxPayNotifyByNotifyId(notifyId);
return repeat != null;
}
/**
* 保存通知数据
* @param billNo 订单编号
* @param body 请求体
* @param plaintext 明文
*/
private void saveNotifyData(String billNo, Notification body, Object plaintext) {
TransactionBill bill = transactionBillService.selectSmTransactionBillByBillNo(billNo);
SmWxPayNotify data = new SmWxPayNotify();
data.setNotifyId(body.getId());
data.setBillId(bill.getBillId());
data.setBody(JSON.toJSONString(body));
data.setPlaintext(JSON.toJSONString(plaintext));
int i = smWxPayNotifyMapper.insertSmWxPayNotify(data);
ServiceUtil.assertion(i != 1, "保存通知数据失败");
}
/**
* 验签并解析
* @param request 请求

View File

@ -1,4 +1,4 @@
package com.ruoyi.common.wx;
package com.ruoyi.common.wx.auth;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;

View File

@ -1,4 +1,4 @@
package com.ruoyi.common.wx;
package com.ruoyi.common.wx.auth;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.alibaba.fastjson2.JSON;
@ -12,7 +12,7 @@ import org.springframework.stereotype.Service;
* 2024/7/29
*/
@Service
public class WxService {
public class WxAuthService {
@Autowired

View File

@ -1,4 +1,4 @@
package com.ruoyi.common.wx.vo;
package com.ruoyi.common.wx.auth.vo;
public class AccessToken {
private String expires_in; //成功有效时间

View File

@ -4,16 +4,14 @@ import javax.annotation.Resource;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.config.WxConfig;
import com.ruoyi.common.core.domain.entity.SmUser;
import com.ruoyi.common.core.domain.model.WxLoginBody;
import com.ruoyi.common.enums.UserStatus;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.wx.AccessTokenUtil;
import com.ruoyi.common.wx.WxService;
import com.ruoyi.common.wx.auth.AccessTokenUtil;
import com.ruoyi.common.wx.auth.WxAuthService;
import com.ruoyi.ss.account.domain.Account;
import com.ruoyi.ss.store.service.IStoreService;
import com.ruoyi.ss.user.service.ISmUserService;
@ -83,7 +81,7 @@ public class SysLoginService
private IStoreService smDeviceGroupService;
@Autowired
private WxService wxService;
private WxAuthService wxAuthService;
/**
* 登录验证
@ -258,7 +256,7 @@ public class SysLoginService
public String wxLogin(WxLoginBody body) {
// 通过登录授权码获取到用户信息
WxMaJscode2SessionResult wxMaJscode2SessionResult = wxService.wxJsCode2Session(body.getLoginCode());
WxMaJscode2SessionResult wxMaJscode2SessionResult = wxAuthService.wxJsCode2Session(body.getLoginCode());
// 通过openId查询用户判断是否微信用户
SmUser user = smUserService.selectSmUserByWxOpenId(wxMaJscode2SessionResult.getOpenid());

View File

@ -1,11 +1,9 @@
package com.ruoyi.ss.account.service.impl;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.common.valid.bank.BankCardInfo;
import com.ruoyi.common.valid.bank.BankValidUtils;
import com.ruoyi.common.wx.WxService;
import com.ruoyi.ss.account.domain.Account;
import com.ruoyi.ss.account.domain.AccountQuery;
import com.ruoyi.ss.account.domain.AccountVO;

View File

@ -2,14 +2,11 @@ package com.ruoyi.ss.payBill.domain;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.ss.wxPay.domain.Payable;
import com.ruoyi.ss.wxPay.domain.enums.AttachEnums;
import com.ruoyi.common.pay.wx.domain.Payable;
import com.ruoyi.common.pay.wx.domain.enums.AttachEnums;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;

View File

@ -15,7 +15,7 @@ import com.ruoyi.ss.timeBill.service.TimeBillService;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillPayType;
import com.ruoyi.ss.user.domain.SmUserVo;
import com.ruoyi.ss.user.service.ISmUserService;
import com.ruoyi.ss.wxPay.service.IWxPayService;
import com.ruoyi.common.pay.wx.service.WxPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -44,7 +44,7 @@ public class PayBillServiceImpl implements PayBillService
private RedisLock redisLock;
@Autowired
private IWxPayService wxPayService;
private WxPayService wxPayService;
@Autowired
private TransactionTemplate transactionTemplate;

View File

@ -2,11 +2,8 @@ package com.ruoyi.ss.refund.domain;
import java.math.BigDecimal;
import com.ruoyi.ss.wxPay.domain.RefundAble;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;

View File

@ -1,6 +1,6 @@
package com.ruoyi.ss.refund.domain;
import com.ruoyi.ss.wxPay.domain.RefundAble;
import com.ruoyi.common.pay.wx.domain.RefundAble;
import com.wechat.pay.java.service.refund.model.AmountReq;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

View File

@ -23,7 +23,7 @@ import com.ruoyi.ss.timeBill.domain.dto.TimeBillPayDTO;
import com.ruoyi.ss.timeBill.domain.enums.TimeBillStatus;
import com.ruoyi.ss.timeBill.service.TimeBillConverter;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillPayType;
import com.ruoyi.ss.wxPay.service.WxPayService;
import com.ruoyi.common.pay.wx.service.WxPayServiceImpl;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -65,7 +65,7 @@ public class TimeBillServiceImpl implements TimeBillService
private PayBillService payBillService;
@Autowired
private WxPayService wxPayService;
private WxPayServiceImpl wxPayService;
/**
* 查询时长订单

View File

@ -8,8 +8,8 @@ import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.core.domain.JsonViewProfile;
import com.ruoyi.common.core.domain.ValidGroup;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillType;
import com.ruoyi.ss.wxPay.domain.Payable;
import com.ruoyi.ss.wxPay.domain.enums.AttachEnums;
import com.ruoyi.common.pay.wx.domain.Payable;
import com.ruoyi.common.pay.wx.domain.enums.AttachEnums;
import com.ruoyi.system.valid.DictValid;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

View File

@ -10,6 +10,7 @@ import com.ruoyi.ss.transactionBill.domain.dto.BillRefundDTO;
import com.ruoyi.ss.transactionBill.domain.dto.WithdrawApprovalDTO;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillStatus;
import com.ruoyi.ss.transactionBill.domain.vo.UserWithdrawServiceVO;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@ -184,9 +185,11 @@ public interface TransactionBillService
/**
* 支付中
*
* @param billId
* @return
*/
void paying(Long billId);
int paying(Long billId);
/**
* 手动设备充值
@ -272,4 +275,9 @@ public interface TransactionBillService
* 获取用户提现手续费信息
*/
UserWithdrawServiceVO getUserWithdrawService(Long userId, Long channelId);
/**
* 微信支付
*/
PrepayWithRequestPaymentResponse wxPay(TransactionBill bill);
}

View File

@ -42,9 +42,10 @@ import com.ruoyi.ss.user.domain.SmUserVo;
import com.ruoyi.common.enums.ServiceType;
import com.ruoyi.ss.user.mapper.SmUserMapper;
import com.ruoyi.ss.user.service.ISmUserService;
import com.ruoyi.ss.wxPay.service.IWxPayService;
import com.ruoyi.common.pay.wx.service.WxPayService;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.task.bill.BillDelayedManager;
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.transferbatch.model.InitiateBatchTransferResponse;
import lombok.extern.slf4j.Slf4j;
@ -85,7 +86,7 @@ public class TransactionBillServiceImpl implements TransactionBillService {
private DeviceService deviceService;
@Autowired
private IWxPayService wxPayService;
private WxPayService wxPayService;
@Autowired
private ISmUserService userService;
@ -234,7 +235,14 @@ public class TransactionBillServiceImpl implements TransactionBillService {
// 若订单金额为0元则直接充值成功
if (order.getMoney().compareTo(BigDecimal.ZERO) == 0) {
TransactionBillVO bill = this.selectSmTransactionBillByBillNo(order.getBillNo());
this.paying(bill.getBillId());
// 更新为支付中
transactionTemplate.execute(status -> {
int paying = this.paying(bill.getBillId());
ServiceUtil.assertion(paying != 1, "更新支付状态失败");
return paying;
});
this.rechargeSuccess(order.getBillNo(), DateUtils.getNowDate());
}
@ -631,13 +639,11 @@ public class TransactionBillServiceImpl implements TransactionBillService {
}
@Override
public void paying(Long billId) {
ServiceUtil.assertion(billId == null, "订单id不允许为空");
transactionTemplate.execute(status -> {
int updateCount = transactionBillMapper.paying(billId);
ServiceUtil.assertion(updateCount != 1, "订单状态发生变化,请刷新后重试");
return updateCount;
});
public int paying(Long billId) {
if (billId == null) {
return 0;
}
return transactionBillMapper.paying(billId);
}
/**
@ -1109,4 +1115,37 @@ public class TransactionBillServiceImpl implements TransactionBillService {
ChannelVO channel = channelService.selectSmChannelByChannelId(channelId);
return this.getUserWithdrawService(user, channel);
}
@Override
public PrepayWithRequestPaymentResponse wxPay(TransactionBill bill) {
ServiceUtil.assertion(bill == null || bill.getBillId() == null, "订单不存在");
Long lockKey = bill.getBillId();
ServiceUtil.assertion(!redisLock.lock(RedisLockKey.PREPAY, lockKey), "当前订单正在支付,请稍后重试");
try {
ServiceUtil.assertion(!Objects.equals(bill.getChannelId(), TransactionBillPayType.WECHAT.getType()), "该订单不是微信支付订单");
ServiceUtil.assertion(!TransactionBillStatus.UNPAID.getStatus().equals(bill.getStatus()), "只能支付未支付的订单");
ServiceUtil.assertion(!TransactionBillType.RECHARGE.getType().equals(bill.getType()), "只能支付充值订单");
PrepayWithRequestPaymentResponse result = transactionTemplate.execute(status -> {
// 修改状态为支付中
int paying = this.paying(bill.getBillId());
ServiceUtil.assertion(paying != 1, "更新支付状态失败");
// 发起支付
return wxPayService.prepayWithRequestPayment(bill);
});
// 每隔20秒查询支付结果直到过期首次10秒查询
if (result != null) {
scheduledExecutorService.schedule(() -> {
this.refreshPayResultBeforeExpire(bill.getBillNo(), 20, TimeUnit.SECONDS);
}, 10, TimeUnit.SECONDS);
}
return result;
} finally {
redisLock.unlock(RedisLockKey.PREPAY, lockKey);
}
}
}

View File

@ -3,12 +3,10 @@ package com.ruoyi.task.bill;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillStatus;
import com.ruoyi.ss.transactionBill.service.TransactionBillService;
import com.ruoyi.ss.wxPay.service.IWxPayService;
import com.ruoyi.ss.wxPay.service.WxPayService;
import com.ruoyi.common.pay.wx.service.WxPayService;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.concurrent.Delayed;
@ -25,7 +23,7 @@ public class BillDelayed implements Delayed {
private TransactionBillService transactionBillService;
private IWxPayService wxPayService = SpringUtils.getBean(WxPayService.class);
private WxPayService wxPayService = SpringUtils.getBean(WxPayService.class);
private String billNo;

View File

@ -6,14 +6,13 @@ import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.ValidGroup;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.wx.WxService;
import com.ruoyi.common.wx.auth.WxAuthService;
import com.ruoyi.ss.account.domain.Account;
import com.ruoyi.ss.account.domain.AccountQuery;
import com.ruoyi.ss.account.domain.AccountVO;
import com.ruoyi.ss.account.domain.enums.AccountType;
import com.ruoyi.ss.account.service.AccountService;
import com.ruoyi.ss.account.service.AccountValidator;
import com.ruoyi.web.core.annotation.MchRequired;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
@ -35,14 +34,14 @@ public class AppAccountController extends BaseController {
private AccountValidator accountValidator;
@Autowired
private WxService wxService;
private WxAuthService wxAuthService;
@ApiOperation("添加收款账户")
@PostMapping
public AjaxResult addAccount(@RequestBody @Validated({ValidGroup.FrontCreate.class}) Account data) {
// 微信获取微信openId并替换数据
if (AccountType.WECHAT.getType().equals(data.getAccountType())) {
WxMaJscode2SessionResult result = wxService.wxJsCode2Session(data.getAccountNo());
WxMaJscode2SessionResult result = wxAuthService.wxJsCode2Session(data.getAccountNo());
ServiceUtil.assertion(result == null, "获取微信信息失败");
data.setAccountNo(result.getOpenid());
}
@ -57,7 +56,7 @@ public class AppAccountController extends BaseController {
// 微信获取微信openId并替换数据
if (AccountType.WECHAT.getType().equals(data.getAccountType()) && StringUtils.hasText(data.getAccountNo())) {
WxMaJscode2SessionResult result = wxService.wxJsCode2Session(data.getAccountNo());
WxMaJscode2SessionResult result = wxAuthService.wxJsCode2Session(data.getAccountNo());
ServiceUtil.assertion(result == null, "获取微信信息失败");
data.setAccountNo(result.getOpenid());
}

View File

@ -2,17 +2,17 @@ package com.ruoyi.web.controller.app;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.pay.wx.domain.NotifyEventType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.ss.payBill.service.PayBillService;
import com.ruoyi.ss.refund.service.RefundService;
import com.ruoyi.ss.transactionBill.domain.TransactionBill;
import com.ruoyi.ss.transactionBill.service.TransactionBillService;
import com.ruoyi.ss.wxPay.domain.enums.AttachEnums;
import com.ruoyi.ss.wxPay.service.IWxPayService;
import com.ruoyi.common.pay.wx.domain.enums.AttachEnums;
import com.ruoyi.common.pay.wx.service.WxPayService;
import com.wechat.pay.java.core.exception.ValidationException;
import com.wechat.pay.java.core.notification.Notification;
import com.wechat.pay.java.service.payments.model.Transaction;
@ -38,10 +38,10 @@ import java.util.Date;
@RestController
@RequestMapping("/app/pay")
@Slf4j
public class AppPayController {
public class AppPayController extends BaseController {
@Autowired
private IWxPayService wxPayService;
private WxPayService wxPayService;
@Autowired
private TransactionBillService transactionBillService;
@ -52,10 +52,14 @@ public class AppPayController {
@Autowired
private PayBillService payBillService;
@ApiOperation("微信支付")
@ApiOperation("微信支付充值订单")
@GetMapping("/wx/{billNo}")
public AjaxResult wxPay(@PathVariable @ApiParam("订单编号") String billNo) {
return AjaxResult.success(wxPayService.prepayWithRequestPayment(billNo));
TransactionBill bill = transactionBillService.selectSmTransactionBillByBillNo(billNo);
if (bill == null || bill.getUserId() == null || !bill.getUserId().equals(getUserId())) {
return error("这不是您的订单");
}
return success(transactionBillService.wxPay(bill));
}
// 微信支付结果通知