Commit 423c0b7ea7ca2dcf938c80207c6a4a6a39f93a21

Authored by YunaiV
1 parent d2b668a6

feat:【MALL 商城】佣金提现,优化字段,以及支持更多 API 自动打款

Showing 17 changed files with 285 additions and 111 deletions
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
@@ -101,5 +101,11 @@ public interface ErrorCodeConstants { @@ -101,5 +101,11 @@ public interface ErrorCodeConstants {
101 ErrorCode BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING = new ErrorCode(1_011_008_001, "佣金提现记录状态不是审核中"); 101 ErrorCode BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING = new ErrorCode(1_011_008_001, "佣金提现记录状态不是审核中");
102 ErrorCode BROKERAGE_WITHDRAW_MIN_PRICE = new ErrorCode(1_011_008_002, "提现金额不能低于 {} 元"); 102 ErrorCode BROKERAGE_WITHDRAW_MIN_PRICE = new ErrorCode(1_011_008_002, "提现金额不能低于 {} 元");
103 ErrorCode BROKERAGE_WITHDRAW_USER_BALANCE_NOT_ENOUGH = new ErrorCode(1_011_008_003, "您当前最多可提现 {} 元"); 103 ErrorCode BROKERAGE_WITHDRAW_USER_BALANCE_NOT_ENOUGH = new ErrorCode(1_011_008_003, "您当前最多可提现 {} 元");
  104 + ErrorCode BROKERAGE_WITHDRAW_TRANSFER_FAIL_WECHAT_NOT_BIND = new ErrorCode(1_011_008_004, "提现失败,原因:用户未绑定微信");
  105 + ErrorCode BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_TRANSFER_ID_ERROR = new ErrorCode(1_011_008_005, "提现单更新转账状态失败,转账单不匹配");
  106 + ErrorCode BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_TRANSFER_STATUS_NOT_SUCCESS_OR_CLOSED = new ErrorCode(1_011_008_006, "提现单更新转账状态失败,转账单状态不是成功或关闭状态");
  107 + ErrorCode BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_PRICE_NOT_MATCH = new ErrorCode(1_011_008_007, "提现单更新转账状态失败,转账单金额不匹配");
  108 + ErrorCode BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_MERCHANT_EXISTS = new ErrorCode(1_011_008_008, "提现单更新转账状态失败,转账单的商户订单不匹配");
  109 + ErrorCode BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_CHANNEL_NOT_MATCH = new ErrorCode(1_011_008_009, "提现单更新转账状态失败,转账渠道不匹配");
104 110
105 } 111 }
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageWithdrawTypeEnum.java
1 package cn.iocoder.yudao.module.trade.enums.brokerage; 1 package cn.iocoder.yudao.module.trade.enums.brokerage;
2 2
3 import cn.iocoder.yudao.framework.common.core.ArrayValuable; 3 import cn.iocoder.yudao.framework.common.core.ArrayValuable;
  4 +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
4 import lombok.AllArgsConstructor; 5 import lombok.AllArgsConstructor;
5 import lombok.Getter; 6 import lombok.Getter;
6 7
@@ -17,9 +18,10 @@ public enum BrokerageWithdrawTypeEnum implements ArrayValuable<Integer> { @@ -17,9 +18,10 @@ public enum BrokerageWithdrawTypeEnum implements ArrayValuable<Integer> {
17 18
18 WALLET(1, "钱包"), 19 WALLET(1, "钱包"),
19 BANK(2, "银行卡"), 20 BANK(2, "银行卡"),
20 - WECHAT(3, "微信"), // 手动打款  
21 - ALIPAY(4, "支付宝"), 21 + WECHAT_QR(3, "微信收款码"), // 手动打款
  22 + ALIPAY_QR(4, "支付宝收款码"), // 手动打款
22 WECHAT_API(5, "微信零钱"), // 自动打款,通过微信转账 API 23 WECHAT_API(5, "微信零钱"), // 自动打款,通过微信转账 API
  24 + ALIPAY_API(6, "支付宝余额"), // 自动打款,通过支付宝转账 API
23 ; 25 ;
24 26
25 public static final Integer[] ARRAYS = Arrays.stream(values()).map(BrokerageWithdrawTypeEnum::getType).toArray(Integer[]::new); 27 public static final Integer[] ARRAYS = Arrays.stream(values()).map(BrokerageWithdrawTypeEnum::getType).toArray(Integer[]::new);
@@ -45,7 +47,7 @@ public enum BrokerageWithdrawTypeEnum implements ArrayValuable<Integer> { @@ -45,7 +47,7 @@ public enum BrokerageWithdrawTypeEnum implements ArrayValuable<Integer> {
45 * @return 是否 47 * @return 是否
46 */ 48 */
47 public static boolean isApi(Integer type) { 49 public static boolean isApi(Integer type) {
48 - return WECHAT_API.getType().equals(type); 50 + return ObjectUtils.equalsAny(type, WALLET.getType(), ALIPAY_API.getType(), WECHAT_API.getType());
49 } 51 }
50 52
51 } 53 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java
@@ -82,10 +82,9 @@ public class BrokerageWithdrawController { @@ -82,10 +82,9 @@ public class BrokerageWithdrawController {
82 return success(BrokerageWithdrawConvert.INSTANCE.convertPage(pageResult, userMap)); 82 return success(BrokerageWithdrawConvert.INSTANCE.convertPage(pageResult, userMap));
83 } 83 }
84 84
85 - // TODO @luchi:update-transferred,url 改成这个。和 update-paid 、update-refunded 保持一致  
86 - @PostMapping("/update-transfer")  
87 - @Operation(summary = "更新转账订单为转账成功") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob  
88 - @PermitAll // 无需登录,安全由 PayDemoOrderService 内部校验实现 85 + @PostMapping("/update-transferred")
  86 + @Operation(summary = "更新佣金提现的转账结果") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob
  87 + @PermitAll // 无需登录,安全由 BrokerageWithdrawService 内部校验实现
89 public CommonResult<Boolean> updateBrokerageWithdrawTransferred(@RequestBody PayTransferNotifyReqDTO notifyReqDTO) { 88 public CommonResult<Boolean> updateBrokerageWithdrawTransferred(@RequestBody PayTransferNotifyReqDTO notifyReqDTO) {
90 log.info("[updateAfterRefund][notifyReqDTO({})]", notifyReqDTO); 89 log.info("[updateAfterRefund][notifyReqDTO({})]", notifyReqDTO);
91 brokerageWithdrawService.updateBrokerageWithdrawTransferred( 90 brokerageWithdrawService.updateBrokerageWithdrawTransferred(
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawBaseVO.java
@@ -37,10 +37,10 @@ public class BrokerageWithdrawBaseVO { @@ -37,10 +37,10 @@ public class BrokerageWithdrawBaseVO {
37 private Integer type; 37 private Integer type;
38 38
39 @Schema(description = "真实姓名", example = "赵六") 39 @Schema(description = "真实姓名", example = "赵六")
40 - private String name; 40 + private String userName;
41 41
42 - @Schema(description = "账号", example = "88677912132")  
43 - private String accountNo; 42 + @Schema(description = "收款账号", example = "88677912132")
  43 + private String userAccount;
44 44
45 @Schema(description = "银行名称", example = "1") 45 @Schema(description = "银行名称", example = "1")
46 private String bankName; 46 private String bankName;
@@ -49,7 +49,7 @@ public class BrokerageWithdrawBaseVO { @@ -49,7 +49,7 @@ public class BrokerageWithdrawBaseVO {
49 private String bankAddress; 49 private String bankAddress;
50 50
51 @Schema(description = "收款码", example = "https://www.iocoder.cn") 51 @Schema(description = "收款码", example = "https://www.iocoder.cn")
52 - private String accountQrCodeUrl; 52 + private String qrCodeUrl;
53 53
54 @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 54 @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
55 @NotNull(message = "状态不能为空") 55 @NotNull(message = "状态不能为空")
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawPageReqVO.java
@@ -28,10 +28,10 @@ public class BrokerageWithdrawPageReqVO extends PageParam { @@ -28,10 +28,10 @@ public class BrokerageWithdrawPageReqVO extends PageParam {
28 private Integer type; 28 private Integer type;
29 29
30 @Schema(description = "真实姓名", example = "赵六") 30 @Schema(description = "真实姓名", example = "赵六")
31 - private String name; 31 + private String userName;
32 32
33 @Schema(description = "账号", example = "886779132") 33 @Schema(description = "账号", example = "886779132")
34 - private String accountNo; 34 + private String userAccount;
35 35
36 @Schema(description = "银行名称", example = "1") 36 @Schema(description = "银行名称", example = "1")
37 private String bankName; 37 private String bankName;
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawCreateReqVO.java
@@ -25,23 +25,18 @@ public class AppBrokerageWithdrawCreateReqVO { @@ -25,23 +25,18 @@ public class AppBrokerageWithdrawCreateReqVO {
25 @NotNull(message = "提现金额不能为空") 25 @NotNull(message = "提现金额不能为空")
26 private Integer price; 26 private Integer price;
27 27
28 - // ========== 银行卡、微信、支付宝 提现相关字段 ==========  
29 -  
30 @Schema(description = "提现账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456789") 28 @Schema(description = "提现账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456789")
31 - @NotBlank(message = "提现账号不能为空", groups = {Bank.class, Wechat.class, Alipay.class})  
32 - private String accountNo; 29 + @NotBlank(message = "提现账号不能为空", groups = {Bank.class, WechatApi.class, AlipayApi.class})
  30 + private String userAccount;
33 31
34 - // ========== 微信、支付宝 提现相关字段 ========== 32 + @Schema(description = "提现姓名", example = "张三")
  33 + @NotBlank(message = "提现姓名不能为空", groups = {Bank.class, WechatApi.class, AlipayApi.class})
  34 + private String userName;
35 35
36 @Schema(description = "收款码的图片", example = "https://www.iocoder.cn/1.png") 36 @Schema(description = "收款码的图片", example = "https://www.iocoder.cn/1.png")
37 - @URL(message = "收款码的图片,必须是一个 URL")  
38 - private String accountQrCodeUrl;  
39 -  
40 - // ========== 银行卡 提现相关字段 ========== 37 + @URL(message = "收款码的图片,必须是一个 URL", groups = {WechatQR.class, AlipayQR.class})
  38 + private String qrCodeUrl;
41 39
42 - @Schema(description = "持卡人姓名", example = "张三")  
43 - @NotBlank(message = "持卡人姓名不能为空", groups = {Bank.class})  
44 - private String name;  
45 @Schema(description = "提现银行", example = "1") 40 @Schema(description = "提现银行", example = "1")
46 @NotNull(message = "提现银行不能为空", groups = {Bank.class}) 41 @NotNull(message = "提现银行不能为空", groups = {Bank.class})
47 private String bankName; 42 private String bankName;
@@ -54,10 +49,16 @@ public class AppBrokerageWithdrawCreateReqVO { @@ -54,10 +49,16 @@ public class AppBrokerageWithdrawCreateReqVO {
54 public interface Bank { 49 public interface Bank {
55 } 50 }
56 51
57 - public interface Wechat { 52 + public interface WechatQR {
  53 + }
  54 +
  55 + public interface WechatApi {
  56 + }
  57 +
  58 + public interface AlipayQR {
58 } 59 }
59 60
60 - public interface Alipay { 61 + public interface AlipayApi {
61 } 62 }
62 63
63 public void validate(Validator validator) { 64 public void validate(Validator validator) {
@@ -65,10 +66,14 @@ public class AppBrokerageWithdrawCreateReqVO { @@ -65,10 +66,14 @@ public class AppBrokerageWithdrawCreateReqVO {
65 ValidationUtils.validate(validator, this, Wallet.class); 66 ValidationUtils.validate(validator, this, Wallet.class);
66 } else if (BrokerageWithdrawTypeEnum.BANK.getType().equals(type)) { 67 } else if (BrokerageWithdrawTypeEnum.BANK.getType().equals(type)) {
67 ValidationUtils.validate(validator, this, Bank.class); 68 ValidationUtils.validate(validator, this, Bank.class);
68 - } else if (BrokerageWithdrawTypeEnum.WECHAT.getType().equals(type)) {  
69 - ValidationUtils.validate(validator, this, Wechat.class);  
70 - } else if (BrokerageWithdrawTypeEnum.ALIPAY.getType().equals(type)) {  
71 - ValidationUtils.validate(validator, this, Alipay.class); 69 + } else if (BrokerageWithdrawTypeEnum.WECHAT_QR.getType().equals(type)) {
  70 + ValidationUtils.validate(validator, this, WechatQR.class);
  71 + } else if (BrokerageWithdrawTypeEnum.WECHAT_API.getType().equals(type)) {
  72 + ValidationUtils.validate(validator, this, WechatApi.class);
  73 + } else if (BrokerageWithdrawTypeEnum.ALIPAY_QR.getType().equals(type)) {
  74 + ValidationUtils.validate(validator, this, AlipayQR.class);
  75 + } else if (BrokerageWithdrawTypeEnum.ALIPAY_API.getType().equals(type)) {
  76 + ValidationUtils.validate(validator, this, AlipayApi.class);
72 } 77 }
73 } 78 }
74 79
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageWithdrawDO.java
@@ -57,13 +57,25 @@ public class BrokerageWithdrawDO extends BaseDO { @@ -57,13 +57,25 @@ public class BrokerageWithdrawDO extends BaseDO {
57 private Integer type; 57 private Integer type;
58 58
59 /** 59 /**
60 - * 真实姓名 60 + * 提现姓名
  61 + * 1. {@link BrokerageWithdrawTypeEnum#BANK}:银行开户人
  62 + * 2. {@link BrokerageWithdrawTypeEnum#WECHAT_API}:微信真名
  63 + * 3. {@link BrokerageWithdrawTypeEnum#ALIPAY_API}:支付宝真名
61 */ 64 */
62 - private String name; 65 + private String userName;
63 /** 66 /**
64 - * 账号 67 + * 提现账号
  68 + * 1. {@link BrokerageWithdrawTypeEnum#BANK}:银行账号
  69 + * 2. {@link BrokerageWithdrawTypeEnum#WECHAT_API}:微信 openid
  70 + * 3. {@link BrokerageWithdrawTypeEnum#ALIPAY_API}:支付宝账号
65 */ 71 */
66 - private String accountNo; 72 + private String userAccount;
  73 +
  74 + /**
  75 + * 收款码
  76 + */
  77 + private String qrCodeUrl;
  78 +
67 /** 79 /**
68 * 银行名称 80 * 银行名称
69 */ 81 */
@@ -72,10 +84,7 @@ public class BrokerageWithdrawDO extends BaseDO { @@ -72,10 +84,7 @@ public class BrokerageWithdrawDO extends BaseDO {
72 * 开户地址 84 * 开户地址
73 */ 85 */
74 private String bankAddress; 86 private String bankAddress;
75 - /**  
76 - * 收款码  
77 - */  
78 - private String accountQrCodeUrl; 87 +
79 /** 88 /**
80 * 状态 89 * 状态
81 * <p> 90 * <p>
@@ -95,4 +104,27 @@ public class BrokerageWithdrawDO extends BaseDO { @@ -95,4 +104,27 @@ public class BrokerageWithdrawDO extends BaseDO {
95 */ 104 */
96 private String remark; 105 private String remark;
97 106
  107 + // ========== 转账相关字段 ==========
  108 +
  109 + /**
  110 + * 转账单编号
  111 + *
  112 + * 关联 {@link cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO#getId()}
  113 + */
  114 + private Long payTransferId;
  115 + /**
  116 + * 转账渠道
  117 + *
  118 + * 枚举 {@link cn.iocoder.yudao.module.pay.enums.PayChannelEnum}
  119 + */
  120 + private String transferChannelCode;
  121 + /**
  122 + * 转账成功时间
  123 + */
  124 + private LocalDateTime transferTime;
  125 + /**
  126 + * 转账错误提示
  127 + */
  128 + private String transferErrorMsg;
  129 +
98 } 130 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageWithdrawMapper.java
@@ -27,8 +27,8 @@ public interface BrokerageWithdrawMapper extends BaseMapperX&lt;BrokerageWithdrawDO @@ -27,8 +27,8 @@ public interface BrokerageWithdrawMapper extends BaseMapperX&lt;BrokerageWithdrawDO
27 return selectPage(reqVO, new LambdaQueryWrapperX<BrokerageWithdrawDO>() 27 return selectPage(reqVO, new LambdaQueryWrapperX<BrokerageWithdrawDO>()
28 .eqIfPresent(BrokerageWithdrawDO::getUserId, reqVO.getUserId()) 28 .eqIfPresent(BrokerageWithdrawDO::getUserId, reqVO.getUserId())
29 .eqIfPresent(BrokerageWithdrawDO::getType, reqVO.getType()) 29 .eqIfPresent(BrokerageWithdrawDO::getType, reqVO.getType())
30 - .likeIfPresent(BrokerageWithdrawDO::getName, reqVO.getName())  
31 - .eqIfPresent(BrokerageWithdrawDO::getAccountNo, reqVO.getAccountNo()) 30 + .likeIfPresent(BrokerageWithdrawDO::getUserName, reqVO.getUserName())
  31 + .eqIfPresent(BrokerageWithdrawDO::getUserAccount, reqVO.getUserAccount())
32 .likeIfPresent(BrokerageWithdrawDO::getBankName, reqVO.getBankName()) 32 .likeIfPresent(BrokerageWithdrawDO::getBankName, reqVO.getBankName())
33 .eqIfPresent(BrokerageWithdrawDO::getStatus, reqVO.getStatus()) 33 .eqIfPresent(BrokerageWithdrawDO::getStatus, reqVO.getStatus())
34 .betweenIfPresent(BrokerageWithdrawDO::getCreateTime, reqVO.getCreateTime()) 34 .betweenIfPresent(BrokerageWithdrawDO::getCreateTime, reqVO.getCreateTime())
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java
1 package cn.iocoder.yudao.module.trade.service.brokerage; 1 package cn.iocoder.yudao.module.trade.service.brokerage;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.lang.Assert;
4 import cn.hutool.core.util.ObjectUtil; 5 import cn.hutool.core.util.ObjectUtil;
5 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; 6 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  8 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
7 import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; 9 import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
  10 +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
8 import cn.iocoder.yudao.module.pay.api.transfer.PayTransferApi; 11 import cn.iocoder.yudao.module.pay.api.transfer.PayTransferApi;
9 import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; 12 import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO;
10 import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO; 13 import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO;
11 import cn.iocoder.yudao.module.pay.api.wallet.PayWalletApi; 14 import cn.iocoder.yudao.module.pay.api.wallet.PayWalletApi;
12 -import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletAddBalanceReqDTO; 15 +import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletRespDTO;
  16 +import cn.iocoder.yudao.module.pay.enums.PayChannelEnum;
13 import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum; 17 import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum;
14 -//import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferTypeEnum;  
15 -import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum;  
16 -import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;  
17 import cn.iocoder.yudao.module.system.api.social.SocialUserApi; 18 import cn.iocoder.yudao.module.system.api.social.SocialUserApi;
18 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; 19 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO;
19 import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; 20 import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
@@ -29,6 +30,7 @@ import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawTypeEnum; @@ -29,6 +30,7 @@ import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawTypeEnum;
29 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; 30 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
30 import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageWithdrawSummaryRespBO; 31 import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageWithdrawSummaryRespBO;
31 import cn.iocoder.yudao.module.trade.service.config.TradeConfigService; 32 import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
  33 +import com.google.common.base.Objects;
32 import jakarta.annotation.Resource; 34 import jakarta.annotation.Resource;
33 import jakarta.validation.Validator; 35 import jakarta.validation.Validator;
34 import lombok.extern.slf4j.Slf4j; 36 import lombok.extern.slf4j.Slf4j;
@@ -40,10 +42,12 @@ import java.time.LocalDateTime; @@ -40,10 +42,12 @@ import java.time.LocalDateTime;
40 import java.util.Collection; 42 import java.util.Collection;
41 import java.util.Collections; 43 import java.util.Collections;
42 import java.util.List; 44 import java.util.List;
  45 +import java.util.Map;
43 46
44 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 47 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
45 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 48 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
46 import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; 49 import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
  50 +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_TRANSFER_NOT_FOUND;
47 import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; 51 import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
48 52
49 /** 53 /**
@@ -65,8 +69,6 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { @@ -65,8 +69,6 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService {
65 private TradeConfigService tradeConfigService; 69 private TradeConfigService tradeConfigService;
66 70
67 @Resource 71 @Resource
68 - private NotifyMessageSendApi notifyMessageSendApi;  
69 - @Resource  
70 private PayTransferApi payTransferApi; 72 private PayTransferApi payTransferApi;
71 @Resource 73 @Resource
72 private SocialUserApi socialUserApi; 74 private SocialUserApi socialUserApi;
@@ -109,44 +111,53 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { @@ -109,44 +111,53 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService {
109 } 111 }
110 112
111 private void auditBrokerageWithdrawSuccess(BrokerageWithdrawDO withdraw) { 113 private void auditBrokerageWithdrawSuccess(BrokerageWithdrawDO withdraw) {
112 - // 1.1 钱包  
113 - if (BrokerageWithdrawTypeEnum.WALLET.getType().equals(withdraw.getType())) {  
114 - payWalletApi.addWalletBalance(new PayWalletAddBalanceReqDTO()  
115 - .setUserId(withdraw.getUserId()).setUserType(UserTypeEnum.MEMBER.getValue())  
116 - .setBizType(PayWalletBizTypeEnum.TRANSFER.getType()).setBizId(withdraw.getId().toString())  
117 - .setPrice(withdraw.getPrice()));  
118 - // 1.2 微信 API  
119 - } else if (BrokerageWithdrawTypeEnum.WECHAT_API.getType().equals(withdraw.getType())) {  
120 - // TODO @luchi:这里,要加个转账单号的记录;另外,调用 API 转账,是立马成功,还是有延迟的哈?  
121 - Long payTransferId = createPayTransfer(withdraw);  
122 - // 1.3 剩余类型,都是手动打款,所以不处理  
123 - } else {  
124 - // TODO 可优化:未来可以考虑,接入支付宝、银联等 API 转账,实现自动打款  
125 - log.info("[auditBrokerageWithdrawSuccess][withdraw({}) 类型({}) 手动打款,无需处理]", withdraw.getId(), withdraw.getType()); 114 + // 情况一:通过 API 转账
  115 + if (BrokerageWithdrawTypeEnum.isApi(withdraw.getType())) {
  116 + createPayTransfer(withdraw);
  117 + return;
126 } 118 }
127 119
128 - // 2. 非支付 API,则直接体现成功  
129 - if (!BrokerageWithdrawTypeEnum.isApi(withdraw.getType())) {  
130 - brokerageWithdrawMapper.updateByIdAndStatus(withdraw.getId(), BrokerageWithdrawStatusEnum.AUDIT_SUCCESS.getStatus(),  
131 - new BrokerageWithdrawDO().setStatus(BrokerageWithdrawStatusEnum.WITHDRAW_SUCCESS.getStatus()));  
132 - } 120 + // 情况二:非 API 转账(手动打款)
  121 + brokerageWithdrawMapper.updateByIdAndStatus(withdraw.getId(), BrokerageWithdrawStatusEnum.AUDIT_SUCCESS.getStatus(),
  122 + new BrokerageWithdrawDO().setStatus(BrokerageWithdrawStatusEnum.WITHDRAW_SUCCESS.getStatus()));
133 } 123 }
134 124
135 - private Long createPayTransfer(BrokerageWithdrawDO withdraw) {  
136 - // 1.1 获取微信 openid  
137 - SocialUserRespDTO socialUser = socialUserApi.getSocialUserByUserId(  
138 - UserTypeEnum.MEMBER.getValue(), withdraw.getUserId(), SocialTypeEnum.WECHAT_MINI_PROGRAM.getType());  
139 - // TODO @luchi:这里,需要校验非空。如果空的话,要有业务异常哈; 125 + private void createPayTransfer(BrokerageWithdrawDO withdraw) {
  126 + // 1.1 获取基础信息
  127 + String userAccount = withdraw.getUserAccount();
  128 + String userName = withdraw.getUserName();
  129 + String channelCode = null;
  130 + Map<String, String> channelExtras = null;
  131 + if (Objects.equal(withdraw.getType(), BrokerageWithdrawTypeEnum.ALIPAY_API.getType())) {
  132 + channelCode = PayChannelEnum.ALIPAY_PC.getCode();
  133 + } else if (Objects.equal(withdraw.getType(), BrokerageWithdrawTypeEnum.WECHAT_API.getType())) {
  134 + SocialUserRespDTO socialUser = socialUserApi.getSocialUserByUserId(
  135 + UserTypeEnum.MEMBER.getValue(), withdraw.getUserId(), SocialTypeEnum.WECHAT_MINI_PROGRAM.getType());
  136 + if (socialUser == null) {
  137 + throw exception(BROKERAGE_WITHDRAW_TRANSFER_FAIL_WECHAT_NOT_BIND);
  138 + }
  139 + channelCode = PayChannelEnum.WX_LITE.getCode();
  140 + userAccount = socialUser.getOpenid();
  141 + // 特殊:微信需要有报备信息
  142 + channelExtras = PayTransferCreateReqDTO.buildWeiXinChannelExtra1000("佣金提现", "佣金提现");
  143 + } else if (Objects.equal(withdraw.getType(), BrokerageWithdrawTypeEnum.WALLET.getType())) {
  144 + PayWalletRespDTO wallet = payWalletApi.getOrCreateWallet(withdraw.getUserId(), UserTypeEnum.MEMBER.getValue());
  145 + Assert.notNull(wallet, "钱包不存在");
  146 + channelCode = PayChannelEnum.WALLET.getCode();
  147 + userAccount = wallet.getId().toString();
  148 + }
140 // 1.2 构建请求 149 // 1.2 构建请求
141 - PayTransferCreateReqDTO payTransferCreateReqDTO = new PayTransferCreateReqDTO()  
142 - .setAppKey(tradeOrderProperties.getPayAppKey())  
143 - .setChannelCode("wx_lite") // TODO @芋艿:【转账】这里要处理下;  
144 - .setMerchantOrderId(withdraw.getId().toString())  
145 - .setPrice(withdraw.getPrice())  
146 - .setSubject("佣金提现")  
147 - .setUserAccount(socialUser.getOpenid()).setUserIp(getClientIP());  
148 - // 2. 发起请求  
149 - return payTransferApi.createTransfer(payTransferCreateReqDTO); 150 + PayTransferCreateReqDTO transferReqDTO = new PayTransferCreateReqDTO()
  151 + .setAppKey(tradeOrderProperties.getPayAppKey()).setChannelCode(channelCode)
  152 + .setMerchantOrderId(withdraw.getId().toString()).setSubject("佣金提现").setPrice(withdraw.getPrice())
  153 + .setUserAccount(userAccount).setUserName(userName).setUserIp(getClientIP())
  154 + .setChannelExtras(channelExtras);
  155 + // 1.3 发起请求
  156 + Long payTransferId = payTransferApi.createTransfer(transferReqDTO);
  157 +
  158 + // 2. 更新提现记录
  159 + brokerageWithdrawMapper.updateById(new BrokerageWithdrawDO().setId(withdraw.getId())
  160 + .setPayTransferId(payTransferId).setTransferChannelCode(channelCode));
150 } 161 }
151 162
152 private BrokerageWithdrawDO validateBrokerageWithdrawExists(Long id) { 163 private BrokerageWithdrawDO validateBrokerageWithdrawExists(Long id) {
@@ -220,22 +231,71 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { @@ -220,22 +231,71 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService {
220 @Override 231 @Override
221 @Transactional(rollbackFor = Exception.class) 232 @Transactional(rollbackFor = Exception.class)
222 public void updateBrokerageWithdrawTransferred(Long id, Long payTransferId) { 233 public void updateBrokerageWithdrawTransferred(Long id, Long payTransferId) {
223 - BrokerageWithdrawDO withdraw = validateBrokerageWithdrawExists(id);  
224 - PayTransferRespDTO transfer = payTransferApi.getTransfer(payTransferId);  
225 - // TODO @luchi:建议参考支付那,即使成功的情况下,也要各种校验;金额是否匹配、转账单号是否匹配、是否重复调用;  
226 - if (PayTransferStatusEnum.isSuccess(transfer.getStatus())) {  
227 - withdraw.setStatus(BrokerageWithdrawStatusEnum.WITHDRAW_SUCCESS.getStatus());  
228 - // TODO @luchi:发送站内信  
229 - } else if (PayTransferStatusEnum.isWaitingOrProcessing(transfer.getStatus())) {  
230 - // TODO @luchi:这里,是不是不用更新哈?  
231 - withdraw.setStatus(BrokerageWithdrawStatusEnum.AUDIT_SUCCESS.getStatus());  
232 - } else {  
233 - withdraw.setStatus(BrokerageWithdrawStatusEnum.WITHDRAW_FAIL.getStatus());  
234 - // 3.2 驳回时需要退还用户佣金  
235 - brokerageRecordService.addBrokerage(withdraw.getUserId(), BrokerageRecordBizTypeEnum.WITHDRAW_REJECT,  
236 - String.valueOf(withdraw.getId()), withdraw.getPrice(), BrokerageRecordBizTypeEnum.WITHDRAW_REJECT.getTitle()); 234 + // 1.1 校验提现单是否存在
  235 + BrokerageWithdrawDO withdraw = brokerageWithdrawMapper.selectById(id);
  236 + if (withdraw == null) {
  237 + log.error("[updateBrokerageWithdrawTransferred][withdraw({}) payTransfer({}) 不存在提现单,请进行处理!]", id, payTransferId);
  238 + throw exception(BROKERAGE_WITHDRAW_NOT_EXISTS);
  239 + }
  240 + // 1.2 校验提现单已经结束(成功或失败)
  241 + if (ObjectUtils.equalsAny(withdraw.getStatus(), BrokerageWithdrawStatusEnum.WITHDRAW_SUCCESS.getStatus(),
  242 + BrokerageWithdrawStatusEnum.WITHDRAW_FAIL.getStatus())) {
  243 + // 特殊:转账单编号相同,直接返回,说明重复回调
  244 + if (ObjectUtil.equal(withdraw.getPayTransferId(), payTransferId)) {
  245 + log.warn("[updateBrokerageWithdrawTransferred][withdraw({}) 已结束,且转账单编号相同({}),直接返回]", withdraw, payTransferId);
  246 + return;
  247 + }
  248 + // 异常:转账单编号不同,说明转账单编号错误
  249 + log.error("[updateBrokerageWithdrawTransferred][withdraw({}) 转账单不匹配({}),请进行处理!]", withdraw, payTransferId);
  250 + throw exception(BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_TRANSFER_ID_ERROR);
  251 + }
  252 +
  253 + // 2. 校验转账单的合法性
  254 + PayTransferRespDTO payTransfer = validateBrokerageTransferStatusCanUpdate(withdraw, payTransferId);
  255 +
  256 + // 3. 更新提现单状态
  257 + Integer newStatus = PayTransferStatusEnum.isSuccess(payTransfer.getStatus()) ? BrokerageWithdrawStatusEnum.WITHDRAW_SUCCESS.getStatus() :
  258 + PayTransferStatusEnum.isClosed(payTransfer.getStatus()) ? BrokerageWithdrawStatusEnum.WITHDRAW_FAIL.getStatus() : null;
  259 + Assert.notNull(newStatus, "转账单状态({}) 不合法", payTransfer.getStatus());
  260 + brokerageWithdrawMapper.updateByIdAndStatus(withdraw.getId(), withdraw.getStatus(),
  261 + new BrokerageWithdrawDO().setStatus(newStatus)
  262 + .setTransferTime(payTransfer.getSuccessTime())
  263 + .setTransferErrorMsg(payTransfer.getChannelErrorMsg()));
  264 + }
  265 +
  266 + private PayTransferRespDTO validateBrokerageTransferStatusCanUpdate(BrokerageWithdrawDO withdraw, Long payTransferId) {
  267 + // 1. 校验转账单是否存在
  268 + PayTransferRespDTO payTransfer = payTransferApi.getTransfer(payTransferId);
  269 + if (payTransfer == null) {
  270 + log.error("[validateBrokerageTransferStatusCanUpdate][withdraw({}) payTransfer({}) 不存在,请进行处理!]", withdraw.getId(), payTransferId);
  271 + throw exception(PAY_TRANSFER_NOT_FOUND);
  272 + }
  273 +
  274 + // 2.1 校验转账单已成功或关闭
  275 + if (!PayTransferStatusEnum.isSuccessOrClosed(payTransfer.getStatus())) {
  276 + log.error("[validateBrokerageTransferStatusCanUpdate][withdraw({}) payTransfer({}) 未结束,请进行处理!payTransfer 数据是:{}]",
  277 + withdraw.getId(), payTransferId, JsonUtils.toJsonString(payTransfer));
  278 + throw exception(BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_TRANSFER_STATUS_NOT_SUCCESS_OR_CLOSED);
  279 + }
  280 + // 2.2 校验转账金额一致
  281 + if (ObjectUtil.notEqual(payTransfer.getPrice(), withdraw.getPrice())) {
  282 + log.error("[validateBrokerageTransferStatusCanUpdate][withdraw({}) payTransfer({}) 转账金额不匹配,请进行处理!withdraw 数据是:{},payTransfer 数据是:{}]",
  283 + withdraw.getId(), payTransferId, JsonUtils.toJsonString(withdraw), JsonUtils.toJsonString(payTransfer));
  284 + throw exception(BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_PRICE_NOT_MATCH);
  285 + }
  286 + // 2.3 校验转账订单匹配
  287 + if (ObjectUtil.notEqual(payTransfer.getMerchantOrderId(), withdraw.getId().toString())) {
  288 + log.error("[validateBrokerageTransferStatusCanUpdate][withdraw({}) 转账单不匹配({}),请进行处理!payTransfer 数据是:{}]",
  289 + withdraw.getId(), payTransferId, JsonUtils.toJsonString(payTransfer));
  290 + throw exception(BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_MERCHANT_EXISTS);
  291 + }
  292 + // 2.4 校验转账渠道一致
  293 + if (ObjectUtil.notEqual(payTransfer.getChannelCode(), withdraw.getTransferChannelCode())) {
  294 + log.error("[validateBrokerageTransferStatusCanUpdate][withdraw({}) payTransfer({}) 转账渠道不匹配,请进行处理!withdraw 数据是:{},payTransfer 数据是:{}]",
  295 + withdraw.getId(), payTransferId, JsonUtils.toJsonString(withdraw), JsonUtils.toJsonString(payTransfer));
  296 + throw exception(BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_CHANNEL_NOT_MATCH);
237 } 297 }
238 - brokerageWithdrawMapper.updateById(withdraw); 298 + return payTransfer;
239 } 299 }
240 300
241 @Override 301 @Override
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImplTest.java
@@ -56,8 +56,8 @@ public class BrokerageWithdrawServiceImplTest extends BaseDbUnitTest { @@ -56,8 +56,8 @@ public class BrokerageWithdrawServiceImplTest extends BaseDbUnitTest {
56 BrokerageWithdrawDO dbBrokerageWithdraw = randomPojo(BrokerageWithdrawDO.class, o -> { // 等会查询到 56 BrokerageWithdrawDO dbBrokerageWithdraw = randomPojo(BrokerageWithdrawDO.class, o -> { // 等会查询到
57 o.setUserId(null); 57 o.setUserId(null);
58 o.setType(null); 58 o.setType(null);
59 - o.setName(null);  
60 - o.setAccountNo(null); 59 + o.setUserName(null);
  60 + o.setUserAccount(null);
61 o.setBankName(null); 61 o.setBankName(null);
62 o.setStatus(null); 62 o.setStatus(null);
63 o.setCreateTime(null); 63 o.setCreateTime(null);
@@ -68,9 +68,9 @@ public class BrokerageWithdrawServiceImplTest extends BaseDbUnitTest { @@ -68,9 +68,9 @@ public class BrokerageWithdrawServiceImplTest extends BaseDbUnitTest {
68 // 测试 type 不匹配 68 // 测试 type 不匹配
69 brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setType(null))); 69 brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setType(null)));
70 // 测试 name 不匹配 70 // 测试 name 不匹配
71 - brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setName(null))); 71 + brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setUserName(null)));
72 // 测试 accountNo 不匹配 72 // 测试 accountNo 不匹配
73 - brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setAccountNo(null))); 73 + brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setUserAccount(null)));
74 // 测试 bankName 不匹配 74 // 测试 bankName 不匹配
75 brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setBankName(null))); 75 brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setBankName(null)));
76 // 测试 status 不匹配 76 // 测试 status 不匹配
@@ -87,8 +87,8 @@ public class BrokerageWithdrawServiceImplTest extends BaseDbUnitTest { @@ -87,8 +87,8 @@ public class BrokerageWithdrawServiceImplTest extends BaseDbUnitTest {
87 BrokerageWithdrawPageReqVO reqVO = new BrokerageWithdrawPageReqVO(); 87 BrokerageWithdrawPageReqVO reqVO = new BrokerageWithdrawPageReqVO();
88 reqVO.setUserId(null); 88 reqVO.setUserId(null);
89 reqVO.setType(null); 89 reqVO.setType(null);
90 - reqVO.setName(null);  
91 - reqVO.setAccountNo(null); 90 + reqVO.setUserName(null);
  91 + reqVO.setUserAccount(null);
92 reqVO.setBankName(null); 92 reqVO.setBankName(null);
93 reqVO.setStatus(null); 93 reqVO.setStatus(null);
94 reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); 94 reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApi.java
1 package cn.iocoder.yudao.module.pay.api.wallet; 1 package cn.iocoder.yudao.module.pay.api.wallet;
2 2
3 import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletAddBalanceReqDTO; 3 import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletAddBalanceReqDTO;
  4 +import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletRespDTO;
4 5
5 /** 6 /**
6 * 钱包 API 接口 7 * 钱包 API 接口
@@ -16,4 +17,13 @@ public interface PayWalletApi { @@ -16,4 +17,13 @@ public interface PayWalletApi {
16 */ 17 */
17 void addWalletBalance(PayWalletAddBalanceReqDTO reqDTO); 18 void addWalletBalance(PayWalletAddBalanceReqDTO reqDTO);
18 19
  20 + /**
  21 + * 获取钱包信息
  22 + *
  23 + * @param userId 用户编号
  24 + * @param userType 用户类型
  25 + * @return 钱包信息
  26 + */
  27 + PayWalletRespDTO getOrCreateWallet(Long userId, Integer userType);
  28 +
19 } 29 }
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/dto/PayWalletRespDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.pay.api.wallet.dto;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
  4 +import lombok.Data;
  5 +
  6 +/**
  7 + * 钱包 Response DTO
  8 + *
  9 + * @author jason
  10 + */
  11 +@Data
  12 +public class PayWalletRespDTO {
  13 +
  14 + /**
  15 + * 编号
  16 + */
  17 + private Long id;
  18 +
  19 + /**
  20 + * 用户 id
  21 + *
  22 + * 关联 MemberUserDO 的 id 编号
  23 + * 关联 AdminUserDO 的 id 编号
  24 + */
  25 + private Long userId;
  26 + /**
  27 + * 用户类型, 预留 多商户转帐可能需要用到
  28 + *
  29 + * 关联 {@link UserTypeEnum}
  30 + */
  31 + private Integer userType;
  32 +
  33 + /**
  34 + * 余额,单位分
  35 + */
  36 + private Integer balance;
  37 +
  38 + /**
  39 + * 冻结金额,单位分
  40 + */
  41 + private Integer freezePrice;
  42 +
  43 + /**
  44 + * 累计支出,单位分
  45 + */
  46 + private Integer totalExpense;
  47 + /**
  48 + * 累计充值,单位分
  49 + */
  50 + private Integer totalRecharge;
  51 +
  52 +}
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApiImpl.java
1 package cn.iocoder.yudao.module.pay.api.wallet; 1 package cn.iocoder.yudao.module.pay.api.wallet;
2 2
3 import cn.hutool.core.lang.Assert; 3 import cn.hutool.core.lang.Assert;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
4 import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletAddBalanceReqDTO; 5 import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletAddBalanceReqDTO;
  6 +import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletRespDTO;
5 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; 7 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO;
6 import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; 8 import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum;
7 import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService; 9 import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService;
@@ -30,4 +32,10 @@ public class PayWalletApiImpl implements PayWalletApi { @@ -30,4 +32,10 @@ public class PayWalletApiImpl implements PayWalletApi {
30 payWalletService.addWalletBalance(wallet.getId(), reqDTO.getBizId(), bizType, reqDTO.getPrice()); 32 payWalletService.addWalletBalance(wallet.getId(), reqDTO.getBizId(), bizType, reqDTO.getPrice());
31 } 33 }
32 34
  35 + @Override
  36 + public PayWalletRespDTO getOrCreateWallet(Long userId, Integer userType) {
  37 + PayWalletDO wallet = payWalletService.getOrCreateWallet(userId, userType);
  38 + return BeanUtils.toBean(wallet, PayWalletRespDTO.class);
  39 + }
  40 +
33 } 41 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.http
1 -### 请求 /pay/demo-withdraw/create 接口(支付宝) => 成功 1 +### 请求 /pay/demo-withdraw/create 接口(支付宝)
2 POST {{baseUrl}}/pay/demo-withdraw/create 2 POST {{baseUrl}}/pay/demo-withdraw/create
3 Authorization: Bearer {{token}} 3 Authorization: Bearer {{token}}
4 Content-Type: application/json 4 Content-Type: application/json
@@ -12,7 +12,7 @@ tenant-id: {{adminTenantId}} @@ -12,7 +12,7 @@ tenant-id: {{adminTenantId}}
12 "userName": "oespxk7368" 12 "userName": "oespxk7368"
13 } 13 }
14 14
15 -### 请求 /pay/demo-withdraw/create 接口(微信余额) => 成功 15 +### 请求 /pay/demo-withdraw/create 接口(微信余额)
16 POST {{baseUrl}}/pay/demo-withdraw/create 16 POST {{baseUrl}}/pay/demo-withdraw/create
17 Authorization: Bearer {{token}} 17 Authorization: Bearer {{token}}
18 Content-Type: application/json 18 Content-Type: application/json
@@ -26,7 +26,7 @@ tenant-id: {{adminTenantId}} @@ -26,7 +26,7 @@ tenant-id: {{adminTenantId}}
26 "userName": "芋艿" 26 "userName": "芋艿"
27 } 27 }
28 28
29 -### 请求 /pay/demo-withdraw/create 接口(钱包余额) => 成功 29 +### 请求 /pay/demo-withdraw/create 接口(钱包余额)
30 POST {{baseUrl}}/pay/demo-withdraw/create 30 POST {{baseUrl}}/pay/demo-withdraw/create
31 Authorization: Bearer {{token}} 31 Authorization: Bearer {{token}}
32 Content-Type: application/json 32 Content-Type: application/json
@@ -39,12 +39,12 @@ tenant-id: {{adminTenantId}} @@ -39,12 +39,12 @@ tenant-id: {{adminTenantId}}
39 "userAccount": "1" 39 "userAccount": "1"
40 } 40 }
41 41
42 -### 请求 /pay/demo-withdraw/transfer 接口(发起转账) => 成功 42 +### 请求 /pay/demo-withdraw/transfer 接口(发起转账)
43 POST {{baseUrl}}/pay/demo-withdraw/transfer?id=1 43 POST {{baseUrl}}/pay/demo-withdraw/transfer?id=1
44 Authorization: Bearer {{token}} 44 Authorization: Bearer {{token}}
45 tenant-id: {{adminTenantId}} 45 tenant-id: {{adminTenantId}}
46 46
47 -### 请求 /pay/demo-withdraw/page 接口(查询分页) => 成功 47 +### 请求 /pay/demo-withdraw/page 接口(查询分页)
48 GET {{baseUrl}}/pay/demo-withdraw/page?pageNo=1&pageSize=10 48 GET {{baseUrl}}/pay/demo-withdraw/page?pageNo=1&pageSize=10
49 Authorization: Bearer {{token}} 49 Authorization: Bearer {{token}}
50 tenant-id: {{adminTenantId}} 50 tenant-id: {{adminTenantId}}
51 \ No newline at end of file 51 \ No newline at end of file
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java
@@ -51,11 +51,11 @@ public class PayDemoWithdrawController { @@ -51,11 +51,11 @@ public class PayDemoWithdrawController {
51 return success(BeanUtils.toBean(pageResult, PayDemoWithdrawRespVO.class)); 51 return success(BeanUtils.toBean(pageResult, PayDemoWithdrawRespVO.class));
52 } 52 }
53 53
54 - @PostMapping("/update-status") 54 + @PostMapping("/update-transferred")
55 @Operation(summary = "更新示例提现单的转账状态") // 由 pay-module 转账服务,进行回调 55 @Operation(summary = "更新示例提现单的转账状态") // 由 pay-module 转账服务,进行回调
56 @PermitAll // 无需登录,安全由 PayDemoTransferService 内部校验实现 56 @PermitAll // 无需登录,安全由 PayDemoTransferService 内部校验实现
57 - public CommonResult<Boolean> updateDemoWithdrawStatus(@RequestBody PayTransferNotifyReqDTO notifyReqDTO) {  
58 - demoWithdrawService.updateDemoWithdrawStatus(Long.valueOf(notifyReqDTO.getMerchantOrderId()), 57 + public CommonResult<Boolean> updateDemoWithdrawTransferred(@RequestBody PayTransferNotifyReqDTO notifyReqDTO) {
  58 + demoWithdrawService.updateDemoWithdrawTransferred(Long.valueOf(notifyReqDTO.getMerchantOrderId()),
59 notifyReqDTO.getPayTransferId()); 59 notifyReqDTO.getPayTransferId());
60 return success(true); 60 return success(true);
61 } 61 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java
@@ -124,7 +124,7 @@ public class PayDemoTransferServiceImpl implements PayDemoWithdrawService { @@ -124,7 +124,7 @@ public class PayDemoTransferServiceImpl implements PayDemoWithdrawService {
124 } 124 }
125 125
126 @Override 126 @Override
127 - public void updateDemoWithdrawStatus(Long id, Long payTransferId) { 127 + public void updateDemoWithdrawTransferred(Long id, Long payTransferId) {
128 // 1.1 校验转账单是否存在 128 // 1.1 校验转账单是否存在
129 PayDemoWithdrawDO withdraw = demoTransferMapper.selectById(id); 129 PayDemoWithdrawDO withdraw = demoTransferMapper.selectById(id);
130 if (withdraw == null) { 130 if (withdraw == null) {
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawService.java
@@ -43,6 +43,6 @@ public interface PayDemoWithdrawService { @@ -43,6 +43,6 @@ public interface PayDemoWithdrawService {
43 * @param id 编号 43 * @param id 编号
44 * @param payTransferId 转账单编号 44 * @param payTransferId 转账单编号
45 */ 45 */
46 - void updateDemoWithdrawStatus(Long id, Long payTransferId); 46 + void updateDemoWithdrawTransferred(Long id, Long payTransferId);
47 47
48 } 48 }