Commit 8ffe9272e80ec9b07fce6b29d8f041bc5ac7a01b

Authored by YunaiV
1 parent ae9e35f1

feat:【pay 支付】增加 userid、usertype,并额外支持权限校验

Showing 20 changed files with 141 additions and 25 deletions
yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/AfterSaleConvert.java
@@ -43,7 +43,7 @@ public interface AfterSaleConvert { @@ -43,7 +43,7 @@ public interface AfterSaleConvert {
43 @Mapping(source = "afterSale.id", target = "merchantRefundId"), 43 @Mapping(source = "afterSale.id", target = "merchantRefundId"),
44 @Mapping(source = "afterSale.applyReason", target = "reason"), 44 @Mapping(source = "afterSale.applyReason", target = "reason"),
45 @Mapping(source = "afterSale.refundPrice", target = "price"), 45 @Mapping(source = "afterSale.refundPrice", target = "price"),
46 - @Mapping(source = "orderProperties.payAppKey", target = "appKey") 46 + @Mapping(source = "orderProperties.payAppKey", target = "appKey"),
47 }) 47 })
48 PayRefundCreateReqDTO convert(String userIp, AfterSaleDO afterSale, TradeOrderProperties orderProperties); 48 PayRefundCreateReqDTO convert(String userIp, AfterSaleDO afterSale, TradeOrderProperties orderProperties);
49 49
yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.convert.order; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.convert.order;
2 2
3 import cn.hutool.core.util.BooleanUtil; 3 import cn.hutool.core.util.BooleanUtil;
4 import cn.hutool.core.util.StrUtil; 4 import cn.hutool.core.util.StrUtil;
  5 +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 7 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
7 import cn.iocoder.yudao.framework.common.util.string.StrUtils; 8 import cn.iocoder.yudao.framework.common.util.string.StrUtils;
@@ -101,7 +102,8 @@ public interface TradeOrderConvert { @@ -101,7 +102,8 @@ public interface TradeOrderConvert {
101 default PayOrderCreateReqDTO convert(TradeOrderDO order, List<TradeOrderItemDO> orderItems, 102 default PayOrderCreateReqDTO convert(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
102 TradeOrderProperties orderProperties) { 103 TradeOrderProperties orderProperties) {
103 PayOrderCreateReqDTO createReqDTO = new PayOrderCreateReqDTO() 104 PayOrderCreateReqDTO createReqDTO = new PayOrderCreateReqDTO()
104 - .setAppKey(orderProperties.getPayAppKey()).setUserIp(order.getUserIp()); 105 + .setAppKey(orderProperties.getPayAppKey()).setUserIp(order.getUserIp())
  106 + .setUserId(order.getUserId()).setUserType(UserTypeEnum.MEMBER.getValue());
105 // 商户相关字段 107 // 商户相关字段
106 createReqDTO.setMerchantOrderId(String.valueOf(order.getId())); 108 createReqDTO.setMerchantOrderId(String.valueOf(order.getId()));
107 String subject = orderItems.get(0).getSpuName(); 109 String subject = orderItems.get(0).getSpuName();
yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.service.aftersale; @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.service.aftersale;
3 import cn.hutool.core.map.MapUtil; 3 import cn.hutool.core.map.MapUtil;
4 import cn.hutool.core.util.ObjectUtil; 4 import cn.hutool.core.util.ObjectUtil;
5 import cn.hutool.core.util.StrUtil; 5 import cn.hutool.core.util.StrUtil;
  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;
7 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; 8 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
8 import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi; 9 import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi;
@@ -362,6 +363,7 @@ public class AfterSaleServiceImpl implements AfterSaleService { @@ -362,6 +363,7 @@ public class AfterSaleServiceImpl implements AfterSaleService {
362 private void createPayRefund(String userIp, AfterSaleDO afterSale) { 363 private void createPayRefund(String userIp, AfterSaleDO afterSale) {
363 // 创建退款单 364 // 创建退款单
364 PayRefundCreateReqDTO createReqDTO = AfterSaleConvert.INSTANCE.convert(userIp, afterSale, tradeOrderProperties) 365 PayRefundCreateReqDTO createReqDTO = AfterSaleConvert.INSTANCE.convert(userIp, afterSale, tradeOrderProperties)
  366 + .setUserId(afterSale.getUserId()).setUserType(UserTypeEnum.MEMBER.getValue())
365 .setReason(StrUtil.format("退款【{}】", afterSale.getSpuName())); 367 .setReason(StrUtil.format("退款【{}】", afterSale.getSpuName()));
366 Long payRefundId = payRefundApi.createRefund(createReqDTO); 368 Long payRefundId = payRefundApi.createRefund(createReqDTO);
367 369
yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java
@@ -151,6 +151,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { @@ -151,6 +151,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService {
151 .setAppKey(tradeOrderProperties.getPayAppKey()).setChannelCode(channelCode) 151 .setAppKey(tradeOrderProperties.getPayAppKey()).setChannelCode(channelCode)
152 .setMerchantTransferId(withdraw.getId().toString()).setSubject("佣金提现").setPrice(withdraw.getPrice()) 152 .setMerchantTransferId(withdraw.getId().toString()).setSubject("佣金提现").setPrice(withdraw.getPrice())
153 .setUserAccount(userAccount).setUserName(userName).setUserIp(getClientIP()) 153 .setUserAccount(userAccount).setUserName(userName).setUserIp(getClientIP())
  154 + .setUserId(withdraw.getUserId()).setUserType(UserTypeEnum.MEMBER.getValue()) // 用户信息
154 .setChannelExtras(channelExtras); 155 .setChannelExtras(channelExtras);
155 // 1.3 发起请求 156 // 1.3 发起请求
156 PayTransferCreateRespDTO transferRespDTO = payTransferApi.createTransfer(transferReqDTO); 157 PayTransferCreateRespDTO transferRespDTO = payTransferApi.createTransfer(transferReqDTO);
yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
@@ -952,6 +952,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -952,6 +952,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
952 payRefundApi.createRefund(new PayRefundCreateReqDTO() 952 payRefundApi.createRefund(new PayRefundCreateReqDTO()
953 .setAppKey(tradeOrderProperties.getPayAppKey()) // 支付应用 953 .setAppKey(tradeOrderProperties.getPayAppKey()) // 支付应用
954 .setUserIp(NetUtil.getLocalhostStr()) // 使用本机 IP,因为是服务器发起退款的 954 .setUserIp(NetUtil.getLocalhostStr()) // 使用本机 IP,因为是服务器发起退款的
  955 + .setUserId(order.getUserId()).setUserType(UserTypeEnum.MEMBER.getValue()) // 用户信息
955 .setMerchantOrderId(String.valueOf(order.getId())) // 支付单号 956 .setMerchantOrderId(String.valueOf(order.getId())) // 支付单号
956 // 特殊:因为订单支持 AfterSale 单个售后退款,也支持整单退款,所以需要通过 order- 进行下区分 957 // 特殊:因为订单支持 AfterSale 单个售后退款,也支持整单退款,所以需要通过 order- 进行下区分
957 // 具体可见 AfterSaleController 的 updateAfterSaleRefunded 方法 958 // 具体可见 AfterSaleController 的 updateAfterSaleRefunded 方法
yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/api/order/dto/PayOrderCreateReqDTO.java
1 package cn.iocoder.yudao.module.pay.api.order.dto; 1 package cn.iocoder.yudao.module.pay.api.order.dto;
2 2
  3 +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
3 import jakarta.validation.constraints.DecimalMin; 5 import jakarta.validation.constraints.DecimalMin;
4 import jakarta.validation.constraints.NotEmpty; 6 import jakarta.validation.constraints.NotEmpty;
5 import jakarta.validation.constraints.NotNull; 7 import jakarta.validation.constraints.NotNull;
@@ -22,12 +24,23 @@ public class PayOrderCreateReqDTO implements Serializable { @@ -22,12 +24,23 @@ public class PayOrderCreateReqDTO implements Serializable {
22 */ 24 */
23 @NotNull(message = "应用标识不能为空") 25 @NotNull(message = "应用标识不能为空")
24 private String appKey; 26 private String appKey;
  27 +
25 /** 28 /**
26 * 用户 IP 29 * 用户 IP
27 */ 30 */
28 @NotEmpty(message = "用户 IP 不能为空") 31 @NotEmpty(message = "用户 IP 不能为空")
29 private String userIp; 32 private String userIp;
30 33
  34 + /**
  35 + * 用户编号
  36 + */
  37 + private Long userId;
  38 + /**
  39 + * 用户类型
  40 + */
  41 + @InEnum(UserTypeEnum.class)
  42 + private Integer userType;
  43 +
31 // ========== 商户相关字段 ========== 44 // ========== 商户相关字段 ==========
32 45
33 /** 46 /**
yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/api/refund/dto/PayRefundCreateReqDTO.java
1 package cn.iocoder.yudao.module.pay.api.refund.dto; 1 package cn.iocoder.yudao.module.pay.api.refund.dto;
2 2
  3 +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
3 import jakarta.validation.constraints.Min; 5 import jakarta.validation.constraints.Min;
4 import jakarta.validation.constraints.NotEmpty; 6 import jakarta.validation.constraints.NotEmpty;
5 import jakarta.validation.constraints.NotNull; 7 import jakarta.validation.constraints.NotNull;
@@ -19,12 +21,23 @@ public class PayRefundCreateReqDTO { @@ -19,12 +21,23 @@ public class PayRefundCreateReqDTO {
19 */ 21 */
20 @NotNull(message = "应用标识不能为空") 22 @NotNull(message = "应用标识不能为空")
21 private String appKey; 23 private String appKey;
  24 +
22 /** 25 /**
23 * 用户 IP 26 * 用户 IP
24 */ 27 */
25 @NotEmpty(message = "用户 IP 不能为空") 28 @NotEmpty(message = "用户 IP 不能为空")
26 private String userIp; 29 private String userIp;
27 30
  31 + /**
  32 + * 用户编号
  33 + */
  34 + private Long userId;
  35 + /**
  36 + * 用户类型
  37 + */
  38 + @InEnum(UserTypeEnum.class)
  39 + private Integer userType;
  40 +
28 // ========== 商户相关字段 ========== 41 // ========== 商户相关字段 ==========
29 /** 42 /**
30 * 商户订单编号 43 * 商户订单编号
yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java
1 package cn.iocoder.yudao.module.pay.api.transfer.dto; 1 package cn.iocoder.yudao.module.pay.api.transfer.dto;
2 2
3 import cn.hutool.core.util.StrUtil; 3 import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
4 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 5 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  6 +import cn.iocoder.yudao.framework.common.validation.InEnum;
5 import jakarta.validation.constraints.Min; 7 import jakarta.validation.constraints.Min;
6 import jakarta.validation.constraints.NotEmpty; 8 import jakarta.validation.constraints.NotEmpty;
7 import jakarta.validation.constraints.NotNull; 9 import jakarta.validation.constraints.NotNull;
@@ -27,22 +29,22 @@ public class PayTransferCreateReqDTO { @@ -27,22 +29,22 @@ public class PayTransferCreateReqDTO {
27 private String appKey; 29 private String appKey;
28 30
29 /** 31 /**
30 - * 转账渠道 32 + * 用户 IP
31 */ 33 */
32 - @NotEmpty(message = "转账渠道不能为空")  
33 - private String channelCode; 34 + @NotEmpty(message = "用户 IP 不能为空")
  35 + private String userIp;
34 36
35 /** 37 /**
36 - * 转账渠道的额外参数 38 + * 用户编号
37 */ 39 */
38 - private Map<String, String> channelExtras;  
39 - 40 + private Long userId;
40 /** 41 /**
41 - * 用户 IP 42 + * 用户类型
42 */ 43 */
43 - @NotEmpty(message = "用户 IP 不能为空")  
44 - private String userIp; 44 + @InEnum(UserTypeEnum.class)
  45 + private Integer userType;
45 46
  47 + // ========== 商户相关字段 ==========
46 /** 48 /**
47 * 商户转账单编号 49 * 商户转账单编号
48 */ 50 */
@@ -76,6 +78,17 @@ public class PayTransferCreateReqDTO { @@ -76,6 +78,17 @@ public class PayTransferCreateReqDTO {
76 private String userName; 78 private String userName;
77 79
78 /** 80 /**
  81 + * 转账渠道
  82 + */
  83 + @NotEmpty(message = "转账渠道不能为空")
  84 + private String channelCode;
  85 +
  86 + /**
  87 + * 转账渠道的额外参数
  88 + */
  89 + private Map<String, String> channelExtras;
  90 +
  91 + /**
79 * 【微信】现金营销场景 92 * 【微信】现金营销场景
80 * 93 *
81 * @param activityName 活动名称 94 * @param activityName 活动名称
yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java
@@ -19,6 +19,7 @@ import org.springframework.validation.annotation.Validated; @@ -19,6 +19,7 @@ import org.springframework.validation.annotation.Validated;
19 import org.springframework.web.bind.annotation.*; 19 import org.springframework.web.bind.annotation.*;
20 20
21 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 21 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  22 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
22 23
23 @Tag(name = "管理后台 - 示例提现订单") // 目的:演示转账功能 24 @Tag(name = "管理后台 - 示例提现订单") // 目的:演示转账功能
24 @RestController 25 @RestController
@@ -40,7 +41,7 @@ public class PayDemoWithdrawController { @@ -40,7 +41,7 @@ public class PayDemoWithdrawController {
40 @Operation(summary = "提现单转账") 41 @Operation(summary = "提现单转账")
41 @Parameter(name = "id", required = true, description = "提现单编号", example = "1024") 42 @Parameter(name = "id", required = true, description = "提现单编号", example = "1024")
42 public CommonResult<Long> transferDemoWithdraw(@RequestParam("id") Long id) { 43 public CommonResult<Long> transferDemoWithdraw(@RequestParam("id") Long id) {
43 - Long payTransferId = demoWithdrawService.transferDemoWithdraw(id); 44 + Long payTransferId = demoWithdrawService.transferDemoWithdraw(id, getLoginUserId());
44 return success(payTransferId); 45 return success(payTransferId);
45 } 46 }
46 47
yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java
1 package cn.iocoder.yudao.module.pay.controller.app.order; 1 package cn.iocoder.yudao.module.pay.controller.app.order;
2 2
  3 +import cn.hutool.core.util.ObjUtil;
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
5 import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderRespVO; 6 import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderRespVO;
6 import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitRespVO; 7 import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitRespVO;
7 import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO; 8 import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO;
8 import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO; 9 import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO;
9 -import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert;  
10 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; 10 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
11 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; 11 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO;
12 import cn.iocoder.yudao.module.pay.enums.PayChannelEnum; 12 import cn.iocoder.yudao.module.pay.enums.PayChannelEnum;
@@ -52,6 +52,15 @@ public class AppPayOrderController { @@ -52,6 +52,15 @@ public class AppPayOrderController {
52 public CommonResult<PayOrderRespVO> getOrder(@RequestParam("id") Long id, 52 public CommonResult<PayOrderRespVO> getOrder(@RequestParam("id") Long id,
53 @RequestParam(value = "sync", required = false) Boolean sync) { 53 @RequestParam(value = "sync", required = false) Boolean sync) {
54 PayOrderDO order = payOrderService.getOrder(id); 54 PayOrderDO order = payOrderService.getOrder(id);
  55 + if (order== null) {
  56 + return success(null);
  57 + }
  58 + // 重要:校验订单是否是当前用户,避免越权
  59 + if (order.getUserId() != null // 特殊:早期订单未存储 userId,所以忽略
  60 + && ObjUtil.notEqual(order.getUserId(), getLoginUserId())) {
  61 + return success(null);
  62 + }
  63 +
55 // sync 仅在等待支付 64 // sync 仅在等待支付
56 if (Boolean.TRUE.equals(sync) && PayOrderStatusEnum.isWaiting(order.getStatus())) { 65 if (Boolean.TRUE.equals(sync) && PayOrderStatusEnum.isWaiting(order.getStatus())) {
57 payOrderService.syncOrderQuietly(order.getId()); 66 payOrderService.syncOrderQuietly(order.getId());
@@ -75,7 +84,7 @@ public class AppPayOrderController { @@ -75,7 +84,7 @@ public class AppPayOrderController {
75 84
76 // 2. 提交支付 85 // 2. 提交支付
77 PayOrderSubmitRespVO respVO = payOrderService.submitOrder(reqVO, getClientIP()); 86 PayOrderSubmitRespVO respVO = payOrderService.submitOrder(reqVO, getClientIP());
78 - return success(PayOrderConvert.INSTANCE.convert3(respVO)); 87 + return success(BeanUtils.toBean(respVO, AppPayOrderSubmitRespVO.class));
79 } 88 }
80 89
81 } 90 }
yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/convert/order/PayOrderConvert.java
@@ -3,14 +3,13 @@ package cn.iocoder.yudao.module.pay.convert.order; @@ -3,14 +3,13 @@ package cn.iocoder.yudao.module.pay.convert.order;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5 import cn.iocoder.yudao.framework.common.util.collection.MapUtils; 5 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
6 -import cn.iocoder.yudao.module.pay.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;  
7 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; 6 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
8 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; 7 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO;
9 import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*; 8 import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*;
10 -import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO;  
11 import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; 9 import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO;
12 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; 10 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
13 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; 11 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;
  12 +import cn.iocoder.yudao.module.pay.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
14 import org.mapstruct.Mapper; 13 import org.mapstruct.Mapper;
15 import org.mapstruct.Mapping; 14 import org.mapstruct.Mapping;
16 import org.mapstruct.factory.Mappers; 15 import org.mapstruct.factory.Mappers;
@@ -69,6 +68,4 @@ public interface PayOrderConvert { @@ -69,6 +68,4 @@ public interface PayOrderConvert {
69 @Mapping(source = "order.status", target = "status") 68 @Mapping(source = "order.status", target = "status")
70 PayOrderSubmitRespVO convert(PayOrderDO order, cn.iocoder.yudao.module.pay.framework.pay.core.client.dto.order.PayOrderRespDTO respDTO); 69 PayOrderSubmitRespVO convert(PayOrderDO order, cn.iocoder.yudao.module.pay.framework.pay.core.client.dto.order.PayOrderRespDTO respDTO);
71 70
72 - AppPayOrderSubmitRespVO convert3(PayOrderSubmitRespVO bean);  
73 -  
74 } 71 }
yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/order/PayOrderDO.java
@@ -49,6 +49,15 @@ public class PayOrderDO extends BaseDO { @@ -49,6 +49,15 @@ public class PayOrderDO extends BaseDO {
49 */ 49 */
50 private String channelCode; 50 private String channelCode;
51 51
  52 + /**
  53 + * 用户编号
  54 + */
  55 + private Long userId;
  56 + /**
  57 + * 用户类型
  58 + */
  59 + private Integer userType;
  60 +
52 // ========== 商户相关字段 ========== 61 // ========== 商户相关字段 ==========
53 62
54 /** 63 /**
yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/refund/PayRefundDO.java
@@ -77,6 +77,15 @@ public class PayRefundDO extends BaseDO { @@ -77,6 +77,15 @@ public class PayRefundDO extends BaseDO {
77 */ 77 */
78 private String orderNo; 78 private String orderNo;
79 79
  80 + /**
  81 + * 用户编号
  82 + */
  83 + private Long userId;
  84 + /**
  85 + * 用户类型
  86 + */
  87 + private Integer userType;
  88 +
80 // ========== 商户相关字段 ========== 89 // ========== 商户相关字段 ==========
81 /** 90 /**
82 * 商户订单编号 91 * 商户订单编号
yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java
@@ -30,7 +30,6 @@ public class PayTransferDO extends BaseDO { @@ -30,7 +30,6 @@ public class PayTransferDO extends BaseDO {
30 */ 30 */
31 @TableId 31 @TableId
32 private Long id; 32 private Long id;
33 -  
34 /** 33 /**
35 * 转账单号 34 * 转账单号
36 */ 35 */
@@ -42,14 +41,12 @@ public class PayTransferDO extends BaseDO { @@ -42,14 +41,12 @@ public class PayTransferDO extends BaseDO {
42 * 关联 {@link PayAppDO#getId()} 41 * 关联 {@link PayAppDO#getId()}
43 */ 42 */
44 private Long appId; 43 private Long appId;
45 -  
46 /** 44 /**
47 * 转账渠道编号 45 * 转账渠道编号
48 * 46 *
49 * 关联 {@link PayChannelDO#getId()} 47 * 关联 {@link PayChannelDO#getId()}
50 */ 48 */
51 private Long channelId; 49 private Long channelId;
52 -  
53 /** 50 /**
54 * 转账渠道编码 51 * 转账渠道编码
55 * 52 *
@@ -57,6 +54,15 @@ public class PayTransferDO extends BaseDO { @@ -57,6 +54,15 @@ public class PayTransferDO extends BaseDO {
57 */ 54 */
58 private String channelCode; 55 private String channelCode;
59 56
  57 + /**
  58 + * 用户编号
  59 + */
  60 + private Long userId;
  61 + /**
  62 + * 用户类型
  63 + */
  64 + private Integer userType;
  65 +
60 // ========== 商户相关字段 ========== 66 // ========== 商户相关字段 ==========
61 /** 67 /**
62 * 商户转账单编号 68 * 商户转账单编号
yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.pay.service.demo; @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.pay.service.demo;
3 import cn.hutool.core.lang.Assert; 3 import cn.hutool.core.lang.Assert;
4 import cn.hutool.core.util.ObjUtil; 4 import cn.hutool.core.util.ObjUtil;
5 import cn.hutool.core.util.ObjectUtil; 5 import cn.hutool.core.util.ObjectUtil;
  6 +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
6 import cn.iocoder.yudao.framework.common.pojo.PageParam; 7 import cn.iocoder.yudao.framework.common.pojo.PageParam;
7 import cn.iocoder.yudao.framework.common.pojo.PageResult; 8 import cn.iocoder.yudao.framework.common.pojo.PageResult;
8 import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; 9 import cn.iocoder.yudao.module.pay.api.order.PayOrderApi;
@@ -90,6 +91,7 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { @@ -90,6 +91,7 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService {
90 // 2.1 创建支付单 91 // 2.1 创建支付单
91 Long payOrderId = payOrderApi.createOrder(new PayOrderCreateReqDTO() 92 Long payOrderId = payOrderApi.createOrder(new PayOrderCreateReqDTO()
92 .setAppKey(PAY_APP_KEY).setUserIp(getClientIP()) // 支付应用 93 .setAppKey(PAY_APP_KEY).setUserIp(getClientIP()) // 支付应用
  94 + .setUserId(userId).setUserType(UserTypeEnum.ADMIN.getValue()) // 用户信息
93 .setMerchantOrderId(demoOrder.getId().toString()) // 业务的订单编号 95 .setMerchantOrderId(demoOrder.getId().toString()) // 业务的订单编号
94 .setSubject(spuName).setBody("").setPrice(price) // 价格信息 96 .setSubject(spuName).setBody("").setPrice(price) // 价格信息
95 .setExpireTime(addTime(Duration.ofHours(2L)))); // 支付的过期时间 97 .setExpireTime(addTime(Duration.ofHours(2L)))); // 支付的过期时间
@@ -189,6 +191,7 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { @@ -189,6 +191,7 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService {
189 // 2.2 创建退款单 191 // 2.2 创建退款单
190 Long payRefundId = payRefundApi.createRefund(new PayRefundCreateReqDTO() 192 Long payRefundId = payRefundApi.createRefund(new PayRefundCreateReqDTO()
191 .setAppKey(PAY_APP_KEY).setUserIp(getClientIP()) // 支付应用 193 .setAppKey(PAY_APP_KEY).setUserIp(getClientIP()) // 支付应用
  194 + .setUserId(order.getUserId()).setUserType(UserTypeEnum.ADMIN.getValue()) // 用户信息
192 .setMerchantOrderId(String.valueOf(order.getId())) // 支付单号 195 .setMerchantOrderId(String.valueOf(order.getId())) // 支付单号
193 .setMerchantRefundId(refundId) 196 .setMerchantRefundId(refundId)
194 .setReason("想退钱").setPrice(order.getPrice()));// 价格信息 197 .setReason("想退钱").setPrice(order.getPrice()));// 价格信息
yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawService.java
@@ -26,9 +26,10 @@ public interface PayDemoWithdrawService { @@ -26,9 +26,10 @@ public interface PayDemoWithdrawService {
26 * 提现单转账 26 * 提现单转账
27 * 27 *
28 * @param id 提现单编号 28 * @param id 提现单编号
  29 + * @param userId 用户编号
29 * @return 转账编号 30 * @return 转账编号
30 */ 31 */
31 - Long transferDemoWithdraw(Long id); 32 + Long transferDemoWithdraw(Long id, Long userId);
32 33
33 /** 34 /**
34 * 获得示例提现单分页 35 * 获得示例提现单分页
yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawServiceImpl.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.pay.service.demo; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.pay.service.demo;
2 2
3 import cn.hutool.core.lang.Assert; 3 import cn.hutool.core.lang.Assert;
4 import cn.hutool.core.util.ObjectUtil; 4 import cn.hutool.core.util.ObjectUtil;
  5 +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
5 import cn.iocoder.yudao.framework.common.pojo.PageParam; 6 import cn.iocoder.yudao.framework.common.pojo.PageParam;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 8 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
@@ -60,7 +61,7 @@ public class PayDemoWithdrawServiceImpl implements PayDemoWithdrawService { @@ -60,7 +61,7 @@ public class PayDemoWithdrawServiceImpl implements PayDemoWithdrawService {
60 } 61 }
61 62
62 @Override 63 @Override
63 - public Long transferDemoWithdraw(Long id) { 64 + public Long transferDemoWithdraw(Long id, Long userId) {
64 // 1.1 校验提现单 65 // 1.1 校验提现单
65 PayDemoWithdrawDO withdraw = validateDemoWithdrawCanTransfer(id); 66 PayDemoWithdrawDO withdraw = validateDemoWithdrawCanTransfer(id);
66 // 1.2 特殊:如果是转账失败的情况,需要充值下 67 // 1.2 特殊:如果是转账失败的情况,需要充值下
@@ -76,6 +77,7 @@ public class PayDemoWithdrawServiceImpl implements PayDemoWithdrawService { @@ -76,6 +77,7 @@ public class PayDemoWithdrawServiceImpl implements PayDemoWithdrawService {
76 // 2.1 创建支付单 77 // 2.1 创建支付单
77 PayTransferCreateReqDTO transferReqDTO = new PayTransferCreateReqDTO() 78 PayTransferCreateReqDTO transferReqDTO = new PayTransferCreateReqDTO()
78 .setAppKey(PAY_APP_KEY).setChannelCode(withdraw.getTransferChannelCode()).setUserIp(getClientIP()) // 支付应用 79 .setAppKey(PAY_APP_KEY).setChannelCode(withdraw.getTransferChannelCode()).setUserIp(getClientIP()) // 支付应用
  80 + .setUserId(userId).setUserType(UserTypeEnum.ADMIN.getValue()) // 用户信息
79 .setMerchantTransferId(String.valueOf(withdraw.getId())) // 业务的订单编号 81 .setMerchantTransferId(String.valueOf(withdraw.getId())) // 业务的订单编号
80 .setSubject(withdraw.getSubject()).setPrice(withdraw.getPrice()) // 价格信息 82 .setSubject(withdraw.getSubject()).setPrice(withdraw.getPrice()) // 价格信息
81 .setUserAccount(withdraw.getUserAccount()).setUserName(withdraw.getUserName()); // 收款信息 83 .setUserAccount(withdraw.getUserAccount()).setUserName(withdraw.getUserName()); // 收款信息
yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java
@@ -64,8 +64,6 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { @@ -64,8 +64,6 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
64 private PayWalletService payWalletService; 64 private PayWalletService payWalletService;
65 @Resource 65 @Resource
66 private PayOrderService payOrderService; 66 private PayOrderService payOrderService;
67 -// @Resource  
68 -// private PayRefundService payRefundService;  
69 @Resource 67 @Resource
70 private PayWalletRechargePackageService payWalletRechargePackageService; 68 private PayWalletRechargePackageService payWalletRechargePackageService;
71 69
@@ -99,6 +97,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { @@ -99,6 +97,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
99 // 2.1 创建支付单 97 // 2.1 创建支付单
100 Long payOrderId = payOrderService.createOrder(new PayOrderCreateReqDTO() 98 Long payOrderId = payOrderService.createOrder(new PayOrderCreateReqDTO()
101 .setAppKey(payProperties.getWalletPayAppKey()).setUserIp(userIp) 99 .setAppKey(payProperties.getWalletPayAppKey()).setUserIp(userIp)
  100 + .setUserId(userId).setUserType(userType) // 用户信息
102 .setMerchantOrderId(recharge.getId().toString()) // 业务的订单编号 101 .setMerchantOrderId(recharge.getId().toString()) // 业务的订单编号
103 .setSubject(WALLET_RECHARGE_ORDER_SUBJECT).setBody("") 102 .setSubject(WALLET_RECHARGE_ORDER_SUBJECT).setBody("")
104 .setPrice(recharge.getPayPrice()) 103 .setPrice(recharge.getPayPrice())
@@ -209,6 +208,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { @@ -209,6 +208,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
209 String refundId = walletRechargeId + "-refund"; 208 String refundId = walletRechargeId + "-refund";
210 Long payRefundId = payRefundApi.createRefund(new PayRefundCreateReqDTO() 209 Long payRefundId = payRefundApi.createRefund(new PayRefundCreateReqDTO()
211 .setAppKey(payProperties.getWalletPayAppKey()).setUserIp(userIp) 210 .setAppKey(payProperties.getWalletPayAppKey()).setUserIp(userIp)
  211 + .setUserId(wallet.getUserId()).setUserType(wallet.getUserType()) // 用户信息
212 .setMerchantOrderId(walletRechargeId) 212 .setMerchantOrderId(walletRechargeId)
213 .setMerchantRefundId(refundId) 213 .setMerchantRefundId(refundId)
214 .setReason("想退钱").setPrice(walletRecharge.getPayPrice())); 214 .setReason("想退钱").setPrice(walletRecharge.getPayPrice()));
yudao-module-pay/src/test/resources/sql/clean.sql
@@ -3,5 +3,6 @@ DELETE FROM pay_channel; @@ -3,5 +3,6 @@ DELETE FROM pay_channel;
3 DELETE FROM pay_order; 3 DELETE FROM pay_order;
4 DELETE FROM pay_order_extension; 4 DELETE FROM pay_order_extension;
5 DELETE FROM pay_refund; 5 DELETE FROM pay_refund;
  6 +DELETE FROM pay_transfer;
6 DELETE FROM pay_notify_task; 7 DELETE FROM pay_notify_task;
7 DELETE FROM pay_notify_log; 8 DELETE FROM pay_notify_log;
yudao-module-pay/src/test/resources/sql/create_tables.sql
@@ -45,6 +45,8 @@ CREATE TABLE IF NOT EXISTS `pay_order` ( @@ -45,6 +45,8 @@ CREATE TABLE IF NOT EXISTS `pay_order` (
45 `channel_fee_price` bigint(20) DEFAULT 0, 45 `channel_fee_price` bigint(20) DEFAULT 0,
46 `status` tinyint(4) NOT NULL, 46 `status` tinyint(4) NOT NULL,
47 `user_ip` varchar(50) NOT NULL, 47 `user_ip` varchar(50) NOT NULL,
  48 + `user_id` bigint(20) DEFAULT NULL,
  49 + `user_type` tinyint(4) DEFAULT NULL,
48 `expire_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 50 `expire_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
49 `success_time` datetime(0) DEFAULT CURRENT_TIMESTAMP, 51 `success_time` datetime(0) DEFAULT CURRENT_TIMESTAMP,
50 `notify_time` datetime(0) DEFAULT CURRENT_TIMESTAMP, 52 `notify_time` datetime(0) DEFAULT CURRENT_TIMESTAMP,
@@ -97,6 +99,8 @@ CREATE TABLE IF NOT EXISTS `pay_refund` ( @@ -97,6 +99,8 @@ CREATE TABLE IF NOT EXISTS `pay_refund` (
97 `refund_price` bigint(20) NOT NULL, 99 `refund_price` bigint(20) NOT NULL,
98 `reason` varchar(256) NOT NULL, 100 `reason` varchar(256) NOT NULL,
99 `user_ip` varchar(50) NULL DEFAULT NULL, 101 `user_ip` varchar(50) NULL DEFAULT NULL,
  102 + `user_id` bigint(20) NULL DEFAULT NULL,
  103 + `user_type` tinyint(4) NULL DEFAULT NULL,
100 `channel_order_no` varchar(64) NOT NULL, 104 `channel_order_no` varchar(64) NOT NULL,
101 `channel_refund_no` varchar(64) NULL DEFAULT NULL, 105 `channel_refund_no` varchar(64) NULL DEFAULT NULL,
102 `success_time` datetime(0) NULL DEFAULT NULL, 106 `success_time` datetime(0) NULL DEFAULT NULL,
@@ -145,3 +149,32 @@ CREATE TABLE IF NOT EXISTS `pay_notify_log` ( @@ -145,3 +149,32 @@ CREATE TABLE IF NOT EXISTS `pay_notify_log` (
145 `deleted` bit(1) NOT NULL DEFAULT FALSE, 149 `deleted` bit(1) NOT NULL DEFAULT FALSE,
146 PRIMARY KEY ("id") 150 PRIMARY KEY ("id")
147 ) COMMENT = '支付通知日志'; 151 ) COMMENT = '支付通知日志';
  152 +
  153 +CREATE TABLE IF NOT EXISTS `pay_transfer` (
  154 + "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  155 + `no` varchar(64) NOT NULL,
  156 + `app_id` bigint(20) NOT NULL,
  157 + `channel_id` bigint(20) NOT NULL,
  158 + `channel_code` varchar(32) NOT NULL,
  159 + `user_id` bigint(20) NULL DEFAULT NULL,
  160 + `user_type` tinyint(4) NULL DEFAULT NULL,
  161 + `merchant_transfer_id` varchar(64) NOT NULL,
  162 + `price` bigint(20) NOT NULL,
  163 + `subject` varchar(256) NOT NULL,
  164 + `user_account` varchar(256) NOT NULL,
  165 + `user_name` varchar(64) NULL DEFAULT NULL,
  166 + `status` tinyint(4) NOT NULL,
  167 + `notify_url` varchar(1024) NULL DEFAULT NULL,
  168 + `channel_transfer_no` varchar(64) NULL DEFAULT NULL,
  169 + `success_time` datetime(0) NULL DEFAULT NULL,
  170 + `channel_error_code` varchar(128) NULL DEFAULT NULL,
  171 + `channel_error_msg` varchar(256) NULL DEFAULT NULL,
  172 + `channel_notify_data` varchar(1024) NULL DEFAULT NULL,
  173 + `channel_extras` varchar(1024) NULL DEFAULT NULL,
  174 + `creator` varchar(64) NULL DEFAULT '',
  175 + `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
  176 + `updater` varchar(64) NULL DEFAULT '',
  177 + `update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  178 + `deleted` bit(1) NOT NULL DEFAULT FALSE,
  179 + PRIMARY KEY ("id")
  180 +) COMMENT = '转账单';