【代码评审】商城:分销提现时,支持余额自动添加,以及微信提现到余额里
This commit is contained in:
parent
602bd5f93c
commit
081ef0502c
|
@ -17,9 +17,9 @@ public enum BrokerageWithdrawTypeEnum implements IntArrayValuable {
|
||||||
|
|
||||||
WALLET(1, "钱包"),
|
WALLET(1, "钱包"),
|
||||||
BANK(2, "银行卡"),
|
BANK(2, "银行卡"),
|
||||||
WECHAT(3, "微信"),
|
WECHAT(3, "微信"), // 手动打款
|
||||||
ALIPAY(4, "支付宝"),
|
ALIPAY(4, "支付宝"),
|
||||||
ALIPAY_SMALL(5, "微信零钱"),
|
WECHAT_API(5, "微信零钱"), // 自动打款,通过微信转账 API
|
||||||
;
|
;
|
||||||
|
|
||||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageWithdrawTypeEnum::getType).toArray();
|
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageWithdrawTypeEnum::getType).toArray();
|
||||||
|
|
|
@ -46,7 +46,8 @@ public class BrokerageWithdrawController {
|
||||||
@Operation(summary = "通过申请")
|
@Operation(summary = "通过申请")
|
||||||
@PreAuthorize("@ss.hasPermission('trade:brokerage-withdraw:audit')")
|
@PreAuthorize("@ss.hasPermission('trade:brokerage-withdraw:audit')")
|
||||||
public CommonResult<Boolean> approveBrokerageWithdraw(@RequestParam("id") Long id) {
|
public CommonResult<Boolean> approveBrokerageWithdraw(@RequestParam("id") Long id) {
|
||||||
brokerageWithdrawService.auditBrokerageWithdraw(id, BrokerageWithdrawStatusEnum.AUDIT_SUCCESS, "", getClientIP());
|
brokerageWithdrawService.auditBrokerageWithdraw(id,
|
||||||
|
BrokerageWithdrawStatusEnum.AUDIT_SUCCESS, "", getClientIP());
|
||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +55,8 @@ public class BrokerageWithdrawController {
|
||||||
@Operation(summary = "驳回申请")
|
@Operation(summary = "驳回申请")
|
||||||
@PreAuthorize("@ss.hasPermission('trade:brokerage-withdraw:audit')")
|
@PreAuthorize("@ss.hasPermission('trade:brokerage-withdraw:audit')")
|
||||||
public CommonResult<Boolean> rejectBrokerageWithdraw(@Valid @RequestBody BrokerageWithdrawRejectReqVO reqVO) {
|
public CommonResult<Boolean> rejectBrokerageWithdraw(@Valid @RequestBody BrokerageWithdrawRejectReqVO reqVO) {
|
||||||
brokerageWithdrawService.auditBrokerageWithdraw(reqVO.getId(), BrokerageWithdrawStatusEnum.AUDIT_FAIL, reqVO.getAuditReason(), getClientIP());
|
brokerageWithdrawService.auditBrokerageWithdraw(reqVO.getId(),
|
||||||
|
BrokerageWithdrawStatusEnum.AUDIT_FAIL, reqVO.getAuditReason(), getClientIP());
|
||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,14 +82,14 @@ public class BrokerageWithdrawController {
|
||||||
return success(BrokerageWithdrawConvert.INSTANCE.convertPage(pageResult, userMap));
|
return success(BrokerageWithdrawConvert.INSTANCE.convertPage(pageResult, userMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO @luchi:update-transferred,url 改成这个。和 update-paid 、update-refunded 保持一致
|
||||||
@PostMapping("/update-transfer")
|
@PostMapping("/update-transfer")
|
||||||
@Operation(summary = "更新转账订单为转账成功") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob
|
@Operation(summary = "更新转账订单为转账成功") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob
|
||||||
@PermitAll // 无需登录,安全由 PayDemoOrderService 内部校验实现
|
@PermitAll // 无需登录,安全由 PayDemoOrderService 内部校验实现
|
||||||
public CommonResult<Boolean> updateAfterRefund(@RequestBody PayTransferNotifyReqDTO notifyReqDTO) {
|
public CommonResult<Boolean> updateBrokerageWithdrawTransferred(@RequestBody PayTransferNotifyReqDTO notifyReqDTO) {
|
||||||
// 目前业务逻辑,不需要做任何事情
|
|
||||||
// 当然,退款会有小概率会失败的情况,可以监控失败状态,进行告警
|
|
||||||
log.info("[updateAfterRefund][notifyReqDTO({})]", notifyReqDTO);
|
log.info("[updateAfterRefund][notifyReqDTO({})]", notifyReqDTO);
|
||||||
brokerageWithdrawService.updateTransfer(Long.parseLong(notifyReqDTO.getMerchantTransferId()), notifyReqDTO.getPayTransferId());
|
brokerageWithdrawService.updateBrokerageWithdrawTransferred(
|
||||||
|
Long.parseLong(notifyReqDTO.getMerchantTransferId()), notifyReqDTO.getPayTransferId());
|
||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ public interface BrokerageWithdrawService {
|
||||||
* @param id 佣金编号
|
* @param id 佣金编号
|
||||||
* @param status 审核状态
|
* @param status 审核状态
|
||||||
* @param auditReason 驳回原因
|
* @param auditReason 驳回原因
|
||||||
|
* @param userIp 操作 IP
|
||||||
*/
|
*/
|
||||||
void auditBrokerageWithdraw(Long id, BrokerageWithdrawStatusEnum status, String auditReason, String userIp);
|
void auditBrokerageWithdraw(Long id, BrokerageWithdrawStatusEnum status, String auditReason, String userIp);
|
||||||
|
|
||||||
|
@ -55,6 +56,16 @@ public interface BrokerageWithdrawService {
|
||||||
*/
|
*/
|
||||||
Long createBrokerageWithdraw(Long userId, AppBrokerageWithdrawCreateReqVO createReqVO);
|
Long createBrokerageWithdraw(Long userId, AppBrokerageWithdrawCreateReqVO createReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【API】更新佣金提现的转账结果
|
||||||
|
*
|
||||||
|
* 目前用于支付回调,标记提现转账结果
|
||||||
|
*
|
||||||
|
* @param id 提现编号
|
||||||
|
* @param payTransferId 转账订单编号
|
||||||
|
*/
|
||||||
|
void updateBrokerageWithdrawTransferred(Long id, Long payTransferId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按照 userId,汇总每个用户的提现
|
* 按照 userId,汇总每个用户的提现
|
||||||
*
|
*
|
||||||
|
@ -77,10 +88,4 @@ public interface BrokerageWithdrawService {
|
||||||
return convertMap(getWithdrawSummaryListByUserId(userIds, status), BrokerageWithdrawSummaryRespBO::getUserId);
|
return convertMap(getWithdrawSummaryListByUserId(userIds, status), BrokerageWithdrawSummaryRespBO::getUserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param merchantTransferId 提现编号
|
|
||||||
* @param payTransferId 转账订单编号
|
|
||||||
*/
|
|
||||||
void updateTransfer(Long merchantTransferId, Long payTransferId);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package cn.iocoder.yudao.module.trade.service.brokerage;
|
package cn.iocoder.yudao.module.trade.service.brokerage;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
|
||||||
import cn.hutool.core.map.MapUtil;
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
@ -17,7 +15,6 @@ import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum;
|
||||||
import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferTypeEnum;
|
import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferTypeEnum;
|
||||||
import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum;
|
import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum;
|
||||||
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
|
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
|
||||||
import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
|
|
||||||
import cn.iocoder.yudao.module.system.api.social.SocialUserApi;
|
import cn.iocoder.yudao.module.system.api.social.SocialUserApi;
|
||||||
import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO;
|
import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO;
|
||||||
import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
|
import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
|
||||||
|
@ -27,7 +24,6 @@ import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageWithdrawConvert;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageWithdrawMapper;
|
import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageWithdrawMapper;
|
||||||
import cn.iocoder.yudao.module.trade.dal.redis.no.TradeNoRedisDAO;
|
|
||||||
import cn.iocoder.yudao.module.trade.enums.MessageTemplateConstants;
|
import cn.iocoder.yudao.module.trade.enums.MessageTemplateConstants;
|
||||||
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
|
||||||
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum;
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum;
|
||||||
|
@ -35,14 +31,16 @@ import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawTypeEnum;
|
||||||
import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
|
import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
|
||||||
import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageWithdrawSummaryRespBO;
|
import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageWithdrawSummaryRespBO;
|
||||||
import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
|
import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import jakarta.validation.Validator;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import jakarta.validation.Validator;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
|
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
|
||||||
|
@ -58,8 +56,6 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private BrokerageWithdrawMapper brokerageWithdrawMapper;
|
private BrokerageWithdrawMapper brokerageWithdrawMapper;
|
||||||
@Resource
|
|
||||||
private TradeNoRedisDAO tradeNoRedisDAO;
|
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private BrokerageRecordService brokerageRecordService;
|
private BrokerageRecordService brokerageRecordService;
|
||||||
|
@ -104,6 +100,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService {
|
||||||
templateCode = MessageTemplateConstants.SMS_BROKERAGE_WITHDRAW_AUDIT_APPROVE;
|
templateCode = MessageTemplateConstants.SMS_BROKERAGE_WITHDRAW_AUDIT_APPROVE;
|
||||||
// 3.1 通过时佣金转余额
|
// 3.1 通过时佣金转余额
|
||||||
if (BrokerageWithdrawTypeEnum.WALLET.getType().equals(withdraw.getType())) {
|
if (BrokerageWithdrawTypeEnum.WALLET.getType().equals(withdraw.getType())) {
|
||||||
|
// TODO 改成直接调用 addWallet 增加余额,不用查询 wallet
|
||||||
PayWalletRespDTO wallet = payWalletApi.getWalletByUserId(withdraw.getUserId());
|
PayWalletRespDTO wallet = payWalletApi.getWalletByUserId(withdraw.getUserId());
|
||||||
payWalletApi.addWallet(new PayWalletCreateReqDto()
|
payWalletApi.addWallet(new PayWalletCreateReqDto()
|
||||||
.setWalletId(wallet.getId())
|
.setWalletId(wallet.getId())
|
||||||
|
@ -116,12 +113,9 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService {
|
||||||
if (rows == 0) {
|
if (rows == 0) {
|
||||||
throw exception(BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING);
|
throw exception(BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING);
|
||||||
}
|
}
|
||||||
}else if (BrokerageWithdrawTypeEnum.ALIPAY_SMALL.getType().equals(withdraw.getType())){
|
} else if (BrokerageWithdrawTypeEnum.WECHAT_API.getType().equals(withdraw.getType())) {
|
||||||
//获取openid
|
// TODO @luchi:这里,要加个转账单号的记录;另外,调用 API 转账,是立马成功,还是有延迟的哈?
|
||||||
SocialUserRespDTO socialUser = socialUserApi.getSocialUserByUserId(UserTypeEnum.MEMBER.getValue(), withdraw.getUserId(), SocialTypeEnum.WECHAT_MINI_APP.getType());
|
Long payTransferId = createPayTransfer(userIp, withdraw);
|
||||||
// 微信提现
|
|
||||||
PayTransferCreateReqDTO payTransferCreateReqDTO = getPayTransferCreateReqDTO(userIp, withdraw, socialUser);
|
|
||||||
payTransferApi.createTransfer(payTransferCreateReqDTO);
|
|
||||||
}
|
}
|
||||||
} else if (BrokerageWithdrawStatusEnum.AUDIT_FAIL.equals(status)) {
|
} else if (BrokerageWithdrawStatusEnum.AUDIT_FAIL.equals(status)) {
|
||||||
templateCode = MessageTemplateConstants.SMS_BROKERAGE_WITHDRAW_AUDIT_REJECT;
|
templateCode = MessageTemplateConstants.SMS_BROKERAGE_WITHDRAW_AUDIT_REJECT;
|
||||||
|
@ -132,6 +126,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService {
|
||||||
throw new IllegalArgumentException("不支持的提现状态:" + status);
|
throw new IllegalArgumentException("不支持的提现状态:" + status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO @luchi:这个通知,还是要的呀~~~
|
||||||
// 4. 通知用户
|
// 4. 通知用户
|
||||||
// Map<String, Object> templateParams = MapUtil.<String, Object>builder()
|
// Map<String, Object> templateParams = MapUtil.<String, Object>builder()
|
||||||
// .put("createTime", LocalDateTimeUtil.formatNormal(withdraw.getCreateTime()))
|
// .put("createTime", LocalDateTimeUtil.formatNormal(withdraw.getCreateTime()))
|
||||||
|
@ -142,17 +137,21 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService {
|
||||||
// .setUserId(withdraw.getUserId()).setTemplateCode(templateCode).setTemplateParams(templateParams));
|
// .setUserId(withdraw.getUserId()).setTemplateCode(templateCode).setTemplateParams(templateParams));
|
||||||
}
|
}
|
||||||
|
|
||||||
private PayTransferCreateReqDTO getPayTransferCreateReqDTO(String userIp, BrokerageWithdrawDO withdraw, SocialUserRespDTO socialUser) {
|
private Long createPayTransfer(String userIp, BrokerageWithdrawDO withdraw) {
|
||||||
PayTransferCreateReqDTO payTransferCreateReqDTO = new PayTransferCreateReqDTO();
|
// 1.1 获取微信 openid
|
||||||
payTransferCreateReqDTO.setAppKey(tradeOrderProperties.getPayAppKey());
|
SocialUserRespDTO socialUser = socialUserApi.getSocialUserByUserId(
|
||||||
payTransferCreateReqDTO.setChannelCode("wx_lite");
|
UserTypeEnum.MEMBER.getValue(), withdraw.getUserId(), SocialTypeEnum.WECHAT_MINI_APP.getType());
|
||||||
payTransferCreateReqDTO.setUserIp(userIp);
|
// TODO @luchi:这里,需要校验非空。如果空的话,要有业务异常哈;
|
||||||
payTransferCreateReqDTO.setType(PayTransferTypeEnum.WX_BALANCE.getType());
|
// 1.2 构建请求
|
||||||
payTransferCreateReqDTO.setMerchantTransferId(withdraw.getId().toString());
|
PayTransferCreateReqDTO payTransferCreateReqDTO = new PayTransferCreateReqDTO()
|
||||||
payTransferCreateReqDTO.setPrice(withdraw.getPrice());
|
.setAppKey(tradeOrderProperties.getPayAppKey())
|
||||||
payTransferCreateReqDTO.setSubject("佣金提现");
|
.setChannelCode("wx_lite").setType(PayTransferTypeEnum.WX_BALANCE.getType())
|
||||||
payTransferCreateReqDTO.setOpenid(socialUser.getOpenid());
|
.setMerchantTransferId(withdraw.getId().toString())
|
||||||
return payTransferCreateReqDTO;
|
.setPrice(withdraw.getPrice())
|
||||||
|
.setSubject("佣金提现")
|
||||||
|
.setOpenid(socialUser.getOpenid()).setUserIp(userIp);
|
||||||
|
// 2. 发起请求
|
||||||
|
return payTransferApi.createTransfer(payTransferCreateReqDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BrokerageWithdrawDO validateBrokerageWithdrawExists(Long id) {
|
private BrokerageWithdrawDO validateBrokerageWithdrawExists(Long id) {
|
||||||
|
@ -194,32 +193,6 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService {
|
||||||
return withdraw.getId();
|
return withdraw.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<BrokerageWithdrawSummaryRespBO> getWithdrawSummaryListByUserId(Collection<Long> userIds,
|
|
||||||
BrokerageWithdrawStatusEnum status) {
|
|
||||||
if (CollUtil.isEmpty(userIds)) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
return brokerageWithdrawMapper.selectCountAndSumPriceByUserIdAndStatus(userIds, status.getStatus());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateTransfer(Long id, Long payTransferId) {
|
|
||||||
BrokerageWithdrawDO withdraw = validateBrokerageWithdrawExists(id);
|
|
||||||
PayTransferRespDTO transfer = payTransferApi.getTransfer(payTransferId);
|
|
||||||
if(PayTransferStatusEnum.isSuccess(transfer.getStatus())){
|
|
||||||
withdraw.setStatus(BrokerageWithdrawStatusEnum.WITHDRAW_SUCCESS.getStatus());
|
|
||||||
}else if(PayTransferStatusEnum.isPendingStatus(transfer.getStatus())){
|
|
||||||
withdraw.setStatus(BrokerageWithdrawStatusEnum.AUDIT_SUCCESS.getStatus());
|
|
||||||
}else{
|
|
||||||
withdraw.setStatus(BrokerageWithdrawStatusEnum.WITHDRAW_FAIL.getStatus());
|
|
||||||
// 3.2 驳回时需要退还用户佣金
|
|
||||||
brokerageRecordService.addBrokerage(withdraw.getUserId(), BrokerageRecordBizTypeEnum.WITHDRAW_REJECT,
|
|
||||||
String.valueOf(withdraw.getId()), withdraw.getPrice(), BrokerageRecordBizTypeEnum.WITHDRAW_REJECT.getTitle());
|
|
||||||
}
|
|
||||||
brokerageWithdrawMapper.updateById(withdraw);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算提现手续费
|
* 计算提现手续费
|
||||||
*
|
*
|
||||||
|
@ -227,7 +200,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService {
|
||||||
* @param percent 手续费百分比
|
* @param percent 手续费百分比
|
||||||
* @return 提现手续费
|
* @return 提现手续费
|
||||||
*/
|
*/
|
||||||
Integer calculateFeePrice(Integer withdrawPrice, Integer percent) {
|
private Integer calculateFeePrice(Integer withdrawPrice, Integer percent) {
|
||||||
Integer feePrice = 0;
|
Integer feePrice = 0;
|
||||||
if (percent != null && percent > 0) {
|
if (percent != null && percent > 0) {
|
||||||
feePrice = MoneyUtils.calculateRatePrice(withdrawPrice, Double.valueOf(percent));
|
feePrice = MoneyUtils.calculateRatePrice(withdrawPrice, Double.valueOf(percent));
|
||||||
|
@ -241,11 +214,41 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService {
|
||||||
* @param withdrawPrice 提现金额
|
* @param withdrawPrice 提现金额
|
||||||
* @return 分销配置
|
* @return 分销配置
|
||||||
*/
|
*/
|
||||||
TradeConfigDO validateWithdrawPrice(Integer withdrawPrice) {
|
private TradeConfigDO validateWithdrawPrice(Integer withdrawPrice) {
|
||||||
TradeConfigDO tradeConfig = tradeConfigService.getTradeConfig();
|
TradeConfigDO tradeConfig = tradeConfigService.getTradeConfig();
|
||||||
if (tradeConfig.getBrokerageWithdrawMinPrice() != null && withdrawPrice < tradeConfig.getBrokerageWithdrawMinPrice()) {
|
if (tradeConfig.getBrokerageWithdrawMinPrice() != null && withdrawPrice < tradeConfig.getBrokerageWithdrawMinPrice()) {
|
||||||
throw exception(BROKERAGE_WITHDRAW_MIN_PRICE, MoneyUtils.fenToYuanStr(tradeConfig.getBrokerageWithdrawMinPrice()));
|
throw exception(BROKERAGE_WITHDRAW_MIN_PRICE, MoneyUtils.fenToYuanStr(tradeConfig.getBrokerageWithdrawMinPrice()));
|
||||||
}
|
}
|
||||||
return tradeConfig;
|
return tradeConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void updateBrokerageWithdrawTransferred(Long id, Long payTransferId) {
|
||||||
|
BrokerageWithdrawDO withdraw = validateBrokerageWithdrawExists(id);
|
||||||
|
PayTransferRespDTO transfer = payTransferApi.getTransfer(payTransferId);
|
||||||
|
// TODO @luchi:建议参考支付那,即使成功的情况下,也要各种校验;金额是否匹配、转账单号是否匹配、是否重复调用;
|
||||||
|
if (PayTransferStatusEnum.isSuccess(transfer.getStatus())) {
|
||||||
|
withdraw.setStatus(BrokerageWithdrawStatusEnum.WITHDRAW_SUCCESS.getStatus());
|
||||||
|
} else if (PayTransferStatusEnum.isPendingStatus(transfer.getStatus())) {
|
||||||
|
// TODO @luchi:这里,是不是不用更新哈?
|
||||||
|
withdraw.setStatus(BrokerageWithdrawStatusEnum.AUDIT_SUCCESS.getStatus());
|
||||||
|
} else {
|
||||||
|
withdraw.setStatus(BrokerageWithdrawStatusEnum.WITHDRAW_FAIL.getStatus());
|
||||||
|
// 3.2 驳回时需要退还用户佣金
|
||||||
|
brokerageRecordService.addBrokerage(withdraw.getUserId(), BrokerageRecordBizTypeEnum.WITHDRAW_REJECT,
|
||||||
|
String.valueOf(withdraw.getId()), withdraw.getPrice(), BrokerageRecordBizTypeEnum.WITHDRAW_REJECT.getTitle());
|
||||||
|
}
|
||||||
|
brokerageWithdrawMapper.updateById(withdraw);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<BrokerageWithdrawSummaryRespBO> getWithdrawSummaryListByUserId(Collection<Long> userIds,
|
||||||
|
BrokerageWithdrawStatusEnum status) {
|
||||||
|
if (CollUtil.isEmpty(userIds)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return brokerageWithdrawMapper.selectCountAndSumPriceByUserIdAndStatus(userIds, status.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import jakarta.validation.constraints.NotNull;
|
||||||
@Data
|
@Data
|
||||||
public class PayTransferNotifyReqDTO {
|
public class PayTransferNotifyReqDTO {
|
||||||
|
|
||||||
|
// TODO 芋艿:要不要改成 orderId 待定;
|
||||||
/**
|
/**
|
||||||
* 商户转账单号
|
* 商户转账单号
|
||||||
*/
|
*/
|
||||||
|
@ -24,4 +25,5 @@ public class PayTransferNotifyReqDTO {
|
||||||
*/
|
*/
|
||||||
@NotNull(message = "转账订单编号不能为空")
|
@NotNull(message = "转账订单编号不能为空")
|
||||||
private Long payTransferId;
|
private Long payTransferId;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,11 @@ public interface PayTransferApi {
|
||||||
Long createTransfer(@Valid PayTransferCreateReqDTO reqDTO);
|
Long createTransfer(@Valid PayTransferCreateReqDTO reqDTO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取转账单详细
|
* 获得转账单
|
||||||
|
*
|
||||||
* @param id 转账单编号
|
* @param id 转账单编号
|
||||||
* @return 转账单详细
|
* @return 转账单
|
||||||
*/
|
*/
|
||||||
PayTransferRespDTO getTransfer(Long id);
|
PayTransferRespDTO getTransfer(Long id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package cn.iocoder.yudao.module.pay.api.transfer.dto;
|
package cn.iocoder.yudao.module.pay.api.transfer.dto;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@ -12,7 +13,6 @@ public class PayTransferRespDTO {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转账单号
|
* 转账单号
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
private String no;
|
private String no;
|
||||||
|
|
||||||
|
@ -24,9 +24,8 @@ public class PayTransferRespDTO {
|
||||||
/**
|
/**
|
||||||
* 转账状态
|
* 转账状态
|
||||||
*
|
*
|
||||||
* 枚举 {@link PayTransferStatusRespEnum}
|
* 枚举 {@link PayTransferStatusEnum}
|
||||||
*/
|
*/
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,16 +10,21 @@ import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletRespDTO;
|
||||||
*/
|
*/
|
||||||
public interface PayWalletApi {
|
public interface PayWalletApi {
|
||||||
|
|
||||||
|
// TODO @luchi:1)改成 addWalletBalance;2)PayWalletCreateReqDto 搞成 userId、userType;3)bizType 使用 integer,不然后续挪到 cloud 不好弄,因为枚举不好序列化
|
||||||
/**
|
/**
|
||||||
* 添加钱包
|
* 添加钱包
|
||||||
|
*
|
||||||
* @param reqDTO 创建请求
|
* @param reqDTO 创建请求
|
||||||
*/
|
*/
|
||||||
void addWallet(PayWalletCreateReqDto reqDTO);
|
void addWallet(PayWalletCreateReqDto reqDTO);
|
||||||
|
|
||||||
|
// TODO @luchi:不用去 getWalletByUserId 钱包,直接添加余额就好。里面内部去创建。如果删除掉的化,PayWalletRespDTO 也删除哈。
|
||||||
/**
|
/**
|
||||||
* 根据用户id获取钱包信息
|
* 根据用户编号,获取钱包信息
|
||||||
|
*
|
||||||
* @param userId 用户id
|
* @param userId 用户id
|
||||||
* @return 钱包信息
|
* @return 钱包信息
|
||||||
*/
|
*/
|
||||||
PayWalletRespDTO getWalletByUserId(Long userId);
|
PayWalletRespDTO getWalletByUserId(Long userId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
package cn.iocoder.yudao.module.pay.api.transfer;
|
package cn.iocoder.yudao.module.pay.api.transfer;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO;
|
import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO;
|
||||||
import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO;
|
import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO;
|
||||||
import cn.iocoder.yudao.module.pay.convert.transfer.PayTransferConvert;
|
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO;
|
||||||
import cn.iocoder.yudao.module.pay.service.transfer.PayTransferService;
|
import cn.iocoder.yudao.module.pay.service.transfer.PayTransferService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转账单 API 实现类
|
* 转账单 API 实现类
|
||||||
*
|
*
|
||||||
|
@ -30,7 +29,7 @@ public class PayTransferApiImpl implements PayTransferApi {
|
||||||
@Override
|
@Override
|
||||||
public PayTransferRespDTO getTransfer(Long id) {
|
public PayTransferRespDTO getTransfer(Long id) {
|
||||||
PayTransferDO transfer = payTransferService.getTransfer(id);
|
PayTransferDO transfer = payTransferService.getTransfer(id);
|
||||||
return PayTransferConvert.INSTANCE.convert3(transfer);
|
return BeanUtils.toBean(transfer, PayTransferRespDTO.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package cn.iocoder.yudao.module.pay.api.wallet;
|
package cn.iocoder.yudao.module.pay.api.wallet;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletCreateReqDto;
|
import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletCreateReqDto;
|
||||||
import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletRespDTO;
|
import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletRespDTO;
|
||||||
import cn.iocoder.yudao.module.pay.convert.wallet.PayWalletConvert;
|
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO;
|
||||||
import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService;
|
import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
@ -22,13 +22,12 @@ public class PayWalletApiImpl implements PayWalletApi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addWallet(PayWalletCreateReqDto reqDTO) {
|
public void addWallet(PayWalletCreateReqDto reqDTO) {
|
||||||
//添加钱包金额
|
|
||||||
payWalletService.addWalletBalance(reqDTO.getWalletId(), reqDTO.getBizId(), reqDTO.getBizType(), reqDTO.getPrice());
|
payWalletService.addWalletBalance(reqDTO.getWalletId(), reqDTO.getBizId(), reqDTO.getBizType(), reqDTO.getPrice());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PayWalletRespDTO getWalletByUserId(Long userId) {
|
public PayWalletRespDTO getWalletByUserId(Long userId) {
|
||||||
PayWalletDO orCreateWallet = payWalletService.getOrCreateWallet(userId, UserTypeEnum.MEMBER.getValue());
|
PayWalletDO orCreateWallet = payWalletService.getOrCreateWallet(userId, UserTypeEnum.MEMBER.getValue());
|
||||||
return PayWalletConvert.INSTANCE.convert03(orCreateWallet);
|
return BeanUtils.toBean(orCreateWallet, PayWalletRespDTO.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,8 +40,7 @@ public class PayAppBaseVO {
|
||||||
@URL(message = "退款结果的回调地址必须为 URL 格式")
|
@URL(message = "退款结果的回调地址必须为 URL 格式")
|
||||||
private String refundNotifyUrl;
|
private String refundNotifyUrl;
|
||||||
|
|
||||||
@Schema(description = "转账结果的回调地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "http://127.0.0.1:48080/refund-callback")
|
@Schema(description = "转账结果的回调地址", example = "http://127.0.0.1:48080/transfer-callback")
|
||||||
@NotNull(message = "转账结果的回调地址不能为空")
|
|
||||||
@URL(message = "转账结果的回调地址必须为 URL 格式")
|
@URL(message = "转账结果的回调地址必须为 URL 格式")
|
||||||
private String transferNotifyUrl;
|
private String transferNotifyUrl;
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ public class PayNotifyController {
|
||||||
// 1. 校验支付渠道是否存在
|
// 1. 校验支付渠道是否存在
|
||||||
PayClient payClient = channelService.getPayClient(channelId);
|
PayClient payClient = channelService.getPayClient(channelId);
|
||||||
if (payClient == null) {
|
if (payClient == null) {
|
||||||
log.error("[notifyCallback][渠道编号({}) 找不到对应的支付客户端]", channelId);
|
log.error("[notifyOrder][渠道编号({}) 找不到对应的支付客户端]", channelId);
|
||||||
throw exception(CHANNEL_NOT_FOUND);
|
throw exception(CHANNEL_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ public class PayNotifyController {
|
||||||
// 1. 校验支付渠道是否存在
|
// 1. 校验支付渠道是否存在
|
||||||
PayClient payClient = channelService.getPayClient(channelId);
|
PayClient payClient = channelService.getPayClient(channelId);
|
||||||
if (payClient == null) {
|
if (payClient == null) {
|
||||||
log.error("[notifyCallback][渠道编号({}) 找不到对应的支付客户端]", channelId);
|
log.error("[notifyRefund][渠道编号({}) 找不到对应的支付客户端]", channelId);
|
||||||
throw exception(CHANNEL_NOT_FOUND);
|
throw exception(CHANNEL_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,11 +105,11 @@ public class PayNotifyController {
|
||||||
public String notifyTransfer(@PathVariable("channelId") Long channelId,
|
public String notifyTransfer(@PathVariable("channelId") Long channelId,
|
||||||
@RequestParam(required = false) Map<String, String> params,
|
@RequestParam(required = false) Map<String, String> params,
|
||||||
@RequestBody(required = false) String body) {
|
@RequestBody(required = false) String body) {
|
||||||
log.info("[notifyRefund][channelId({}) 回调数据({}/{})]", channelId, params, body);
|
log.info("[notifyTransfer][channelId({}) 回调数据({}/{})]", channelId, params, body);
|
||||||
// 1. 校验支付渠道是否存在
|
// 1. 校验支付渠道是否存在
|
||||||
PayClient payClient = channelService.getPayClient(channelId);
|
PayClient payClient = channelService.getPayClient(channelId);
|
||||||
if (payClient == null) {
|
if (payClient == null) {
|
||||||
log.error("[notifyCallback][渠道编号({}) 找不到对应的支付客户端]", channelId);
|
log.error("[notifyTransfer][渠道编号({}) 找不到对应的支付客户端]", channelId);
|
||||||
throw exception(CHANNEL_NOT_FOUND);
|
throw exception(CHANNEL_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.pay.convert.transfer;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO;
|
||||||
import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO;
|
import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO;
|
||||||
import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO;
|
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer.PayDemoTransferCreateReqVO;
|
import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer.PayDemoTransferCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferCreateReqVO;
|
import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferPageItemRespVO;
|
import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferPageItemRespVO;
|
||||||
|
@ -27,7 +26,6 @@ public interface PayTransferConvert {
|
||||||
|
|
||||||
PayTransferRespVO convert(PayTransferDO bean);
|
PayTransferRespVO convert(PayTransferDO bean);
|
||||||
|
|
||||||
PayTransferRespDTO convert3(PayTransferDO bean);
|
|
||||||
|
|
||||||
PageResult<PayTransferPageItemRespVO> convertPage(PageResult<PayTransferDO> pageResult);
|
PageResult<PayTransferPageItemRespVO> convertPage(PageResult<PayTransferDO> pageResult);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package cn.iocoder.yudao.module.pay.convert.wallet;
|
package cn.iocoder.yudao.module.pay.convert.wallet;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletCreateReqDto;
|
|
||||||
import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletRespDTO;
|
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletRespVO;
|
import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletRespVO;
|
||||||
import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.wallet.AppPayWalletRespVO;
|
import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.wallet.AppPayWalletRespVO;
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO;
|
||||||
|
@ -20,6 +18,4 @@ public interface PayWalletConvert {
|
||||||
|
|
||||||
PageResult<PayWalletRespVO> convertPage(PageResult<PayWalletDO> page);
|
PageResult<PayWalletRespVO> convertPage(PageResult<PayWalletDO> page);
|
||||||
|
|
||||||
PayWalletRespDTO convert03(PayWalletDO orCreateWallet);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferPageReqVO;
|
import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferPageReqVO;
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO;
|
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
@ -24,10 +23,6 @@ public interface PayTransferMapper extends BaseMapperX<PayTransferDO> {
|
||||||
PayTransferDO::getMerchantTransferId, merchantTransferId);
|
PayTransferDO::getMerchantTransferId, merchantTransferId);
|
||||||
}
|
}
|
||||||
|
|
||||||
default PayTransferDO selectByNo(String no){
|
|
||||||
return selectOne(PayTransferDO::getNo, no);
|
|
||||||
}
|
|
||||||
|
|
||||||
default PageResult<PayTransferDO> selectPage(PayTransferPageReqVO reqVO) {
|
default PageResult<PayTransferDO> selectPage(PayTransferPageReqVO reqVO) {
|
||||||
return selectPage(reqVO, new LambdaQueryWrapperX<PayTransferDO>()
|
return selectPage(reqVO, new LambdaQueryWrapperX<PayTransferDO>()
|
||||||
.eqIfPresent(PayTransferDO::getNo, reqVO.getNo())
|
.eqIfPresent(PayTransferDO::getNo, reqVO.getNo())
|
||||||
|
@ -42,15 +37,15 @@ public interface PayTransferMapper extends BaseMapperX<PayTransferDO> {
|
||||||
.orderByDesc(PayTransferDO::getId));
|
.orderByDesc(PayTransferDO::getId));
|
||||||
}
|
}
|
||||||
|
|
||||||
default List<PayTransferDO> selectListByStatus(Integer status){
|
default List<PayTransferDO> selectListByStatus(Integer status) {
|
||||||
return selectList(PayTransferDO::getStatus, status);
|
return selectList(PayTransferDO::getStatus, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
default PayTransferDO selectByAppIdAndNo(Long appId, String no){
|
default PayTransferDO selectByAppIdAndNo(Long appId, String no) {
|
||||||
return selectOne(new LambdaQueryWrapperX<PayTransferDO>()
|
return selectOne(PayTransferDO::getAppId, appId,
|
||||||
.eq(PayTransferDO::getAppId, appId)
|
PayTransferDO::getNo, no);
|
||||||
.eq(PayTransferDO::getNo, no));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,6 @@ public interface PayWalletMapper extends BaseMapperX<PayWalletDO> {
|
||||||
return update(null, lambdaUpdateWrapper);
|
return update(null, lambdaUpdateWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -78,4 +78,5 @@ public interface PayRefundService {
|
||||||
* @return 同步到状态的退款数量,包括退款成功、退款失败
|
* @return 同步到状态的退款数量,包括退款成功、退款失败
|
||||||
*/
|
*/
|
||||||
int syncRefund();
|
int syncRefund();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,8 +193,6 @@ public class PayRefundServiceImpl implements PayRefundService {
|
||||||
TenantUtils.execute(channel.getTenantId(), () -> getSelf().notifyRefund(channel, notify));
|
TenantUtils.execute(channel.getTenantId(), () -> getSelf().notifyRefund(channel, notify));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通知并更新订单的退款结果
|
* 通知并更新订单的退款结果
|
||||||
*
|
*
|
||||||
|
|
|
@ -63,4 +63,5 @@ public interface PayTransferService {
|
||||||
* @param notify 通知
|
* @param notify 通知
|
||||||
*/
|
*/
|
||||||
void notifyTransfer(Long channelId, PayTransferRespDTO notify);
|
void notifyTransfer(Long channelId, PayTransferRespDTO notify);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ import jakarta.annotation.Resource;
|
||||||
import jakarta.validation.Validator;
|
import jakarta.validation.Validator;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Propagation;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -171,8 +170,7 @@ public class PayTransferServiceImpl implements PayTransferService {
|
||||||
|
|
||||||
private void notifyTransferInProgress(PayChannelDO channel, PayTransferRespDTO notify) {
|
private void notifyTransferInProgress(PayChannelDO channel, PayTransferRespDTO notify) {
|
||||||
// 1.校验
|
// 1.校验
|
||||||
PayTransferDO transfer = transferMapper.selectByAppIdAndNo(
|
PayTransferDO transfer = transferMapper.selectByAppIdAndNo(channel.getAppId(), notify.getOutTransferNo());
|
||||||
channel.getAppId(), notify.getOutTransferNo());
|
|
||||||
if (transfer == null) {
|
if (transfer == null) {
|
||||||
throw exception(PAY_TRANSFER_NOT_FOUND);
|
throw exception(PAY_TRANSFER_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
@ -195,8 +193,7 @@ public class PayTransferServiceImpl implements PayTransferService {
|
||||||
|
|
||||||
private void notifyTransferSuccess(PayChannelDO channel, PayTransferRespDTO notify) {
|
private void notifyTransferSuccess(PayChannelDO channel, PayTransferRespDTO notify) {
|
||||||
// 1.校验
|
// 1.校验
|
||||||
PayTransferDO transfer = transferMapper.selectByAppIdAndNo(
|
PayTransferDO transfer = transferMapper.selectByAppIdAndNo(channel.getAppId(), notify.getOutTransferNo());
|
||||||
channel.getAppId(), notify.getOutTransferNo());
|
|
||||||
if (transfer == null) {
|
if (transfer == null) {
|
||||||
throw exception(PAY_TRANSFER_NOT_FOUND);
|
throw exception(PAY_TRANSFER_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
@ -225,8 +222,7 @@ public class PayTransferServiceImpl implements PayTransferService {
|
||||||
|
|
||||||
private void notifyTransferClosed(PayChannelDO channel, PayTransferRespDTO notify) {
|
private void notifyTransferClosed(PayChannelDO channel, PayTransferRespDTO notify) {
|
||||||
// 1.校验
|
// 1.校验
|
||||||
PayTransferDO transfer = transferMapper.selectByAppIdAndNo(
|
PayTransferDO transfer = transferMapper.selectByAppIdAndNo(channel.getAppId(), notify.getOutTransferNo());
|
||||||
channel.getAppId(), notify.getOutTransferNo());
|
|
||||||
if (transfer == null) {
|
if (transfer == null) {
|
||||||
throw exception(PAY_TRANSFER_NOT_FOUND);
|
throw exception(PAY_TRANSFER_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,6 +200,7 @@ public class PayWalletServiceImpl implements PayWalletService {
|
||||||
case UPDATE_BALANCE: // 更新余额
|
case UPDATE_BALANCE: // 更新余额
|
||||||
walletMapper.updateWhenRecharge(payWallet.getId(), price);
|
walletMapper.updateWhenRecharge(payWallet.getId(), price);
|
||||||
break;
|
break;
|
||||||
|
// TODO @luchi:1)不能使用 updateWhenRecharge,它是充值哈。应该增加余额就 ok 了。。ps:顺便帮我把 UPDATE_BALANCE 也改改哈;2)其实不用 WITHDRAW 枚举,复用 UPDATE_BALANCE 就好了。
|
||||||
case WITHDRAW:
|
case WITHDRAW:
|
||||||
walletMapper.updateWhenRecharge(payWallet.getId(), price);
|
walletMapper.updateWhenRecharge(payWallet.getId(), price);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -64,10 +64,6 @@
|
||||||
<groupId>com.github.binarywang</groupId>
|
<groupId>com.github.binarywang</groupId>
|
||||||
<artifactId>weixin-java-pay</artifactId>
|
<artifactId>weixin-java-pay</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>com.github.binarywang</groupId>
|
|
||||||
<artifactId>wx-java-miniapp-spring-boot-starter</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Test 测试相关 -->
|
<!-- Test 测试相关 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -106,4 +106,5 @@ public interface PayClient {
|
||||||
* @return 转账信息
|
* @return 转账信息
|
||||||
*/
|
*/
|
||||||
PayTransferRespDTO parseTransferNotify(Map<String, String> params, String body);
|
PayTransferRespDTO parseTransferNotify(Map<String, String> params, String body);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,4 +84,5 @@ public class PayTransferUnifiedReqDTO {
|
||||||
@NotEmpty(message = "转账结果的回调地址不能为空")
|
@NotEmpty(message = "转账结果的回调地址不能为空")
|
||||||
@URL(message = "转账结果的 notify 回调地址必须是 URL 格式")
|
@URL(message = "转账结果的 notify 回调地址必须是 URL 格式")
|
||||||
private String notifyUrl;
|
private String notifyUrl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
// TODO @luchi:这个可以复用 wxjava 里的类么?
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class WxPayTransferPartnerNotifyV3Result implements Serializable, WxPayBaseNotifyV3Result<WxPayTransferPartnerNotifyV3Result.TransferNotifyResult> {
|
public class WxPayTransferPartnerNotifyV3Result implements Serializable, WxPayBaseNotifyV3Result<WxPayTransferPartnerNotifyV3Result.TransferNotifyResult> {
|
||||||
|
|
||||||
|
|
|
@ -325,6 +325,7 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO @chihuo:这里是不是也要实现,支付宝的。
|
||||||
@Override
|
@Override
|
||||||
protected PayTransferRespDTO doParseTransferNotify(Map<String, String> params, String body) throws Throwable {
|
protected PayTransferRespDTO doParseTransferNotify(Map<String, String> params, String body) throws Throwable {
|
||||||
throw new UnsupportedOperationException("未实现");
|
throw new UnsupportedOperationException("未实现");
|
||||||
|
|
|
@ -18,21 +18,23 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.WxPayTransferPart
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
|
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
|
||||||
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum;
|
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum;
|
||||||
import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum;
|
import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum;
|
||||||
import com.github.binarywang.wxpay.bean.notify.*;
|
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyV3Result;
|
||||||
|
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
|
||||||
|
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
|
||||||
|
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyV3Result;
|
||||||
import com.github.binarywang.wxpay.bean.request.*;
|
import com.github.binarywang.wxpay.bean.request.*;
|
||||||
import com.github.binarywang.wxpay.bean.result.*;
|
import com.github.binarywang.wxpay.bean.result.*;
|
||||||
import com.github.binarywang.wxpay.bean.transfer.TransferBatchesRequest;
|
import com.github.binarywang.wxpay.bean.transfer.TransferBatchesRequest;
|
||||||
import com.github.binarywang.wxpay.bean.transfer.TransferBatchesResult;
|
import com.github.binarywang.wxpay.bean.transfer.TransferBatchesResult;
|
||||||
import com.github.binarywang.wxpay.config.WxPayConfig;
|
import com.github.binarywang.wxpay.config.WxPayConfig;
|
||||||
import com.github.binarywang.wxpay.exception.WxPayException;
|
import com.github.binarywang.wxpay.exception.WxPayException;
|
||||||
import com.github.binarywang.wxpay.service.TransferService;
|
|
||||||
import com.github.binarywang.wxpay.service.WxPayService;
|
import com.github.binarywang.wxpay.service.WxPayService;
|
||||||
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
|
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.util.ArrayList;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
@ -356,17 +358,21 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
|
||||||
switch (config.getApiVersion()) {
|
switch (config.getApiVersion()) {
|
||||||
case API_VERSION_V3:
|
case API_VERSION_V3:
|
||||||
return parseTransferNotifyV3(body);
|
return parseTransferNotifyV3(body);
|
||||||
|
case API_VERSION_V2:
|
||||||
|
throw new UnsupportedOperationException("V2 版本暂不支持,建议使用 V3 版本");
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
|
throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private PayTransferRespDTO parseTransferNotifyV3(String body) throws WxPayException {
|
private PayTransferRespDTO parseTransferNotifyV3(String body) throws WxPayException {
|
||||||
|
// 1. 解析回调
|
||||||
|
// TODO @luchi:这个可以复用 wxjava 里的类么?
|
||||||
WxPayTransferPartnerNotifyV3Result response = client.baseParseOrderNotifyV3Result(body, null, WxPayTransferPartnerNotifyV3Result.class, WxPayTransferPartnerNotifyV3Result.TransferNotifyResult.class);
|
WxPayTransferPartnerNotifyV3Result response = client.baseParseOrderNotifyV3Result(body, null, WxPayTransferPartnerNotifyV3Result.class, WxPayTransferPartnerNotifyV3Result.TransferNotifyResult.class);
|
||||||
WxPayTransferPartnerNotifyV3Result.TransferNotifyResult result = response.getResult();
|
WxPayTransferPartnerNotifyV3Result.TransferNotifyResult result = response.getResult();
|
||||||
// 2. 构建结果
|
// 2. 构建结果
|
||||||
if (Objects.equals("FINISHED", result.getBatchStatus())) {
|
if (Objects.equals("FINISHED", result.getBatchStatus())) {
|
||||||
if(result.getFailNum() <= 0){
|
if (result.getFailNum() <= 0) {
|
||||||
return PayTransferRespDTO.successOf(result.getBatchId(), parseDateV3(result.getUpdateTime()),
|
return PayTransferRespDTO.successOf(result.getBatchId(), parseDateV3(result.getUpdateTime()),
|
||||||
result.getOutBatchNo(), response);
|
result.getOutBatchNo(), response);
|
||||||
}
|
}
|
||||||
|
@ -453,29 +459,33 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) throws WxPayException {
|
protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) throws WxPayException {
|
||||||
TransferService transferService = client.getTransferService();
|
// 1. 构建 TransferBatchesRequest 请求
|
||||||
List<TransferBatchesRequest.TransferDetail> transferDetailList = new ArrayList<>();
|
List<TransferBatchesRequest.TransferDetail> transferDetailList = Collections.singletonList(
|
||||||
transferDetailList.add(TransferBatchesRequest.TransferDetail.newBuilder()
|
TransferBatchesRequest.TransferDetail.newBuilder()
|
||||||
.outDetailNo(reqDTO.getOutTransferNo())
|
.outDetailNo(reqDTO.getOutTransferNo())
|
||||||
.transferAmount(reqDTO.getPrice())
|
.transferAmount(reqDTO.getPrice())
|
||||||
.transferRemark(reqDTO.getSubject())
|
.transferRemark(reqDTO.getSubject())
|
||||||
.openid(reqDTO.getOpenid())
|
.openid(reqDTO.getOpenid())
|
||||||
.build());
|
.build());
|
||||||
|
// TODO @luchi:能不能我们搞个 TransferBatchesRequestX extends TransferBatchesRequest,这样更简洁一点。
|
||||||
TransferBatchesRequest transferBatches = TransferBatchesRequest.newBuilder()
|
TransferBatchesRequest transferBatches = TransferBatchesRequest.newBuilder()
|
||||||
.appid(this.config.getAppId())
|
.appid(this.config.getAppId())
|
||||||
.outBatchNo(reqDTO.getOutTransferNo())
|
.outBatchNo(reqDTO.getOutTransferNo())
|
||||||
.batchName(reqDTO.getSubject())
|
.batchName(reqDTO.getSubject())
|
||||||
.batchRemark(reqDTO.getSubject())
|
.batchRemark(reqDTO.getSubject())
|
||||||
.totalAmount(reqDTO.getPrice())
|
.totalAmount(reqDTO.getPrice())
|
||||||
.totalNum(1)
|
.totalNum(transferDetailList.size())
|
||||||
.transferDetailList(transferDetailList).build();
|
.transferDetailList(transferDetailList).build()
|
||||||
transferBatches.setNotifyUrl(reqDTO.getNotifyUrl());
|
.setNotifyUrl(reqDTO.getNotifyUrl());
|
||||||
TransferBatchesResult transferBatchesResult = transferService.transferBatches(transferBatches);
|
// 2.1 执行请求
|
||||||
|
TransferBatchesResult transferBatchesResult = client.getTransferService().transferBatches(transferBatches);
|
||||||
|
// 2.2 创建返回结果
|
||||||
return PayTransferRespDTO.dealingOf(transferBatchesResult.getBatchId(), reqDTO.getOutTransferNo(), transferBatchesResult);
|
return PayTransferRespDTO.dealingOf(transferBatchesResult.getBatchId(), reqDTO.getOutTransferNo(), transferBatchesResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PayTransferRespDTO doGetTransfer(String outTradeNo, PayTransferTypeEnum type) {
|
protected PayTransferRespDTO doGetTransfer(String outTradeNo, PayTransferTypeEnum type) {
|
||||||
|
// TODO luchi:这个最好实现下。因为可能要主动轮询转账结果
|
||||||
throw new UnsupportedOperationException("待实现");
|
throw new UnsupportedOperationException("待实现");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue