Commit 8ffe9272e80ec9b07fce6b29d8f041bc5ac7a01b
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 | 43 | @Mapping(source = "afterSale.id", target = "merchantRefundId"), |
| 44 | 44 | @Mapping(source = "afterSale.applyReason", target = "reason"), |
| 45 | 45 | @Mapping(source = "afterSale.refundPrice", target = "price"), |
| 46 | - @Mapping(source = "orderProperties.payAppKey", target = "appKey") | |
| 46 | + @Mapping(source = "orderProperties.payAppKey", target = "appKey"), | |
| 47 | 47 | }) |
| 48 | 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 | 2 | |
| 3 | 3 | import cn.hutool.core.util.BooleanUtil; |
| 4 | 4 | import cn.hutool.core.util.StrUtil; |
| 5 | +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | |
| 5 | 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | 7 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 7 | 8 | import cn.iocoder.yudao.framework.common.util.string.StrUtils; |
| ... | ... | @@ -101,7 +102,8 @@ public interface TradeOrderConvert { |
| 101 | 102 | default PayOrderCreateReqDTO convert(TradeOrderDO order, List<TradeOrderItemDO> orderItems, |
| 102 | 103 | TradeOrderProperties orderProperties) { |
| 103 | 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 | 108 | createReqDTO.setMerchantOrderId(String.valueOf(order.getId())); |
| 107 | 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 | 3 | import cn.hutool.core.map.MapUtil; |
| 4 | 4 | import cn.hutool.core.util.ObjectUtil; |
| 5 | 5 | import cn.hutool.core.util.StrUtil; |
| 6 | +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | |
| 6 | 7 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 7 | 8 | import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; |
| 8 | 9 | import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi; |
| ... | ... | @@ -362,6 +363,7 @@ public class AfterSaleServiceImpl implements AfterSaleService { |
| 362 | 363 | private void createPayRefund(String userIp, AfterSaleDO afterSale) { |
| 363 | 364 | // 创建退款单 |
| 364 | 365 | PayRefundCreateReqDTO createReqDTO = AfterSaleConvert.INSTANCE.convert(userIp, afterSale, tradeOrderProperties) |
| 366 | + .setUserId(afterSale.getUserId()).setUserType(UserTypeEnum.MEMBER.getValue()) | |
| 365 | 367 | .setReason(StrUtil.format("退款【{}】", afterSale.getSpuName())); |
| 366 | 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 | 151 | .setAppKey(tradeOrderProperties.getPayAppKey()).setChannelCode(channelCode) |
| 152 | 152 | .setMerchantTransferId(withdraw.getId().toString()).setSubject("佣金提现").setPrice(withdraw.getPrice()) |
| 153 | 153 | .setUserAccount(userAccount).setUserName(userName).setUserIp(getClientIP()) |
| 154 | + .setUserId(withdraw.getUserId()).setUserType(UserTypeEnum.MEMBER.getValue()) // 用户信息 | |
| 154 | 155 | .setChannelExtras(channelExtras); |
| 155 | 156 | // 1.3 发起请求 |
| 156 | 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 | 952 | payRefundApi.createRefund(new PayRefundCreateReqDTO() |
| 953 | 953 | .setAppKey(tradeOrderProperties.getPayAppKey()) // 支付应用 |
| 954 | 954 | .setUserIp(NetUtil.getLocalhostStr()) // 使用本机 IP,因为是服务器发起退款的 |
| 955 | + .setUserId(order.getUserId()).setUserType(UserTypeEnum.MEMBER.getValue()) // 用户信息 | |
| 955 | 956 | .setMerchantOrderId(String.valueOf(order.getId())) // 支付单号 |
| 956 | 957 | // 特殊:因为订单支持 AfterSale 单个售后退款,也支持整单退款,所以需要通过 order- 进行下区分 |
| 957 | 958 | // 具体可见 AfterSaleController 的 updateAfterSaleRefunded 方法 | ... | ... |
yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/api/order/dto/PayOrderCreateReqDTO.java
| 1 | 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 | 5 | import jakarta.validation.constraints.DecimalMin; |
| 4 | 6 | import jakarta.validation.constraints.NotEmpty; |
| 5 | 7 | import jakarta.validation.constraints.NotNull; |
| ... | ... | @@ -22,12 +24,23 @@ public class PayOrderCreateReqDTO implements Serializable { |
| 22 | 24 | */ |
| 23 | 25 | @NotNull(message = "应用标识不能为空") |
| 24 | 26 | private String appKey; |
| 27 | + | |
| 25 | 28 | /** |
| 26 | 29 | * 用户 IP |
| 27 | 30 | */ |
| 28 | 31 | @NotEmpty(message = "用户 IP 不能为空") |
| 29 | 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 | 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 | 5 | import jakarta.validation.constraints.Min; |
| 4 | 6 | import jakarta.validation.constraints.NotEmpty; |
| 5 | 7 | import jakarta.validation.constraints.NotNull; |
| ... | ... | @@ -19,12 +21,23 @@ public class PayRefundCreateReqDTO { |
| 19 | 21 | */ |
| 20 | 22 | @NotNull(message = "应用标识不能为空") |
| 21 | 23 | private String appKey; |
| 24 | + | |
| 22 | 25 | /** |
| 23 | 26 | * 用户 IP |
| 24 | 27 | */ |
| 25 | 28 | @NotEmpty(message = "用户 IP 不能为空") |
| 26 | 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 | 1 | package cn.iocoder.yudao.module.pay.api.transfer.dto; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.util.StrUtil; |
| 4 | +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | |
| 4 | 5 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 6 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | |
| 5 | 7 | import jakarta.validation.constraints.Min; |
| 6 | 8 | import jakarta.validation.constraints.NotEmpty; |
| 7 | 9 | import jakarta.validation.constraints.NotNull; |
| ... | ... | @@ -27,22 +29,22 @@ public class PayTransferCreateReqDTO { |
| 27 | 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 | 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 | 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 | 19 | import org.springframework.web.bind.annotation.*; |
| 20 | 20 | |
| 21 | 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 | 24 | @Tag(name = "管理后台 - 示例提现订单") // 目的:演示转账功能 |
| 24 | 25 | @RestController |
| ... | ... | @@ -40,7 +41,7 @@ public class PayDemoWithdrawController { |
| 40 | 41 | @Operation(summary = "提现单转账") |
| 41 | 42 | @Parameter(name = "id", required = true, description = "提现单编号", example = "1024") |
| 42 | 43 | public CommonResult<Long> transferDemoWithdraw(@RequestParam("id") Long id) { |
| 43 | - Long payTransferId = demoWithdrawService.transferDemoWithdraw(id); | |
| 44 | + Long payTransferId = demoWithdrawService.transferDemoWithdraw(id, getLoginUserId()); | |
| 44 | 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 | 1 | package cn.iocoder.yudao.module.pay.controller.app.order; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.util.ObjUtil; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 5 | 6 | import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderRespVO; |
| 6 | 7 | import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitRespVO; |
| 7 | 8 | import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO; |
| 8 | 9 | import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO; |
| 9 | -import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert; | |
| 10 | 10 | import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; |
| 11 | 11 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; |
| 12 | 12 | import cn.iocoder.yudao.module.pay.enums.PayChannelEnum; |
| ... | ... | @@ -52,6 +52,15 @@ public class AppPayOrderController { |
| 52 | 52 | public CommonResult<PayOrderRespVO> getOrder(@RequestParam("id") Long id, |
| 53 | 53 | @RequestParam(value = "sync", required = false) Boolean sync) { |
| 54 | 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 | 64 | // sync 仅在等待支付 |
| 56 | 65 | if (Boolean.TRUE.equals(sync) && PayOrderStatusEnum.isWaiting(order.getStatus())) { |
| 57 | 66 | payOrderService.syncOrderQuietly(order.getId()); |
| ... | ... | @@ -75,7 +84,7 @@ public class AppPayOrderController { |
| 75 | 84 | |
| 76 | 85 | // 2. 提交支付 |
| 77 | 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 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 5 | 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 | 6 | import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; |
| 8 | 7 | import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; |
| 9 | 8 | import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*; |
| 10 | -import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO; | |
| 11 | 9 | import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; |
| 12 | 10 | import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; |
| 13 | 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 | 13 | import org.mapstruct.Mapper; |
| 15 | 14 | import org.mapstruct.Mapping; |
| 16 | 15 | import org.mapstruct.factory.Mappers; |
| ... | ... | @@ -69,6 +68,4 @@ public interface PayOrderConvert { |
| 69 | 68 | @Mapping(source = "order.status", target = "status") |
| 70 | 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
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 | 77 | */ |
| 78 | 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 | 30 | */ |
| 31 | 31 | @TableId |
| 32 | 32 | private Long id; |
| 33 | - | |
| 34 | 33 | /** |
| 35 | 34 | * 转账单号 |
| 36 | 35 | */ |
| ... | ... | @@ -42,14 +41,12 @@ public class PayTransferDO extends BaseDO { |
| 42 | 41 | * 关联 {@link PayAppDO#getId()} |
| 43 | 42 | */ |
| 44 | 43 | private Long appId; |
| 45 | - | |
| 46 | 44 | /** |
| 47 | 45 | * 转账渠道编号 |
| 48 | 46 | * |
| 49 | 47 | * 关联 {@link PayChannelDO#getId()} |
| 50 | 48 | */ |
| 51 | 49 | private Long channelId; |
| 52 | - | |
| 53 | 50 | /** |
| 54 | 51 | * 转账渠道编码 |
| 55 | 52 | * |
| ... | ... | @@ -57,6 +54,15 @@ public class PayTransferDO extends BaseDO { |
| 57 | 54 | */ |
| 58 | 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 | 3 | import cn.hutool.core.lang.Assert; |
| 4 | 4 | import cn.hutool.core.util.ObjUtil; |
| 5 | 5 | import cn.hutool.core.util.ObjectUtil; |
| 6 | +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | |
| 6 | 7 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 7 | 8 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 8 | 9 | import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; |
| ... | ... | @@ -90,6 +91,7 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { |
| 90 | 91 | // 2.1 创建支付单 |
| 91 | 92 | Long payOrderId = payOrderApi.createOrder(new PayOrderCreateReqDTO() |
| 92 | 93 | .setAppKey(PAY_APP_KEY).setUserIp(getClientIP()) // 支付应用 |
| 94 | + .setUserId(userId).setUserType(UserTypeEnum.ADMIN.getValue()) // 用户信息 | |
| 93 | 95 | .setMerchantOrderId(demoOrder.getId().toString()) // 业务的订单编号 |
| 94 | 96 | .setSubject(spuName).setBody("").setPrice(price) // 价格信息 |
| 95 | 97 | .setExpireTime(addTime(Duration.ofHours(2L)))); // 支付的过期时间 |
| ... | ... | @@ -189,6 +191,7 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { |
| 189 | 191 | // 2.2 创建退款单 |
| 190 | 192 | Long payRefundId = payRefundApi.createRefund(new PayRefundCreateReqDTO() |
| 191 | 193 | .setAppKey(PAY_APP_KEY).setUserIp(getClientIP()) // 支付应用 |
| 194 | + .setUserId(order.getUserId()).setUserType(UserTypeEnum.ADMIN.getValue()) // 用户信息 | |
| 192 | 195 | .setMerchantOrderId(String.valueOf(order.getId())) // 支付单号 |
| 193 | 196 | .setMerchantRefundId(refundId) |
| 194 | 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 | 26 | * 提现单转账 |
| 27 | 27 | * |
| 28 | 28 | * @param id 提现单编号 |
| 29 | + * @param userId 用户编号 | |
| 29 | 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 | 2 | |
| 3 | 3 | import cn.hutool.core.lang.Assert; |
| 4 | 4 | import cn.hutool.core.util.ObjectUtil; |
| 5 | +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | |
| 5 | 6 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 6 | 7 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 7 | 8 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| ... | ... | @@ -60,7 +61,7 @@ public class PayDemoWithdrawServiceImpl implements PayDemoWithdrawService { |
| 60 | 61 | } |
| 61 | 62 | |
| 62 | 63 | @Override |
| 63 | - public Long transferDemoWithdraw(Long id) { | |
| 64 | + public Long transferDemoWithdraw(Long id, Long userId) { | |
| 64 | 65 | // 1.1 校验提现单 |
| 65 | 66 | PayDemoWithdrawDO withdraw = validateDemoWithdrawCanTransfer(id); |
| 66 | 67 | // 1.2 特殊:如果是转账失败的情况,需要充值下 |
| ... | ... | @@ -76,6 +77,7 @@ public class PayDemoWithdrawServiceImpl implements PayDemoWithdrawService { |
| 76 | 77 | // 2.1 创建支付单 |
| 77 | 78 | PayTransferCreateReqDTO transferReqDTO = new PayTransferCreateReqDTO() |
| 78 | 79 | .setAppKey(PAY_APP_KEY).setChannelCode(withdraw.getTransferChannelCode()).setUserIp(getClientIP()) // 支付应用 |
| 80 | + .setUserId(userId).setUserType(UserTypeEnum.ADMIN.getValue()) // 用户信息 | |
| 79 | 81 | .setMerchantTransferId(String.valueOf(withdraw.getId())) // 业务的订单编号 |
| 80 | 82 | .setSubject(withdraw.getSubject()).setPrice(withdraw.getPrice()) // 价格信息 |
| 81 | 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 | 64 | private PayWalletService payWalletService; |
| 65 | 65 | @Resource |
| 66 | 66 | private PayOrderService payOrderService; |
| 67 | -// @Resource | |
| 68 | -// private PayRefundService payRefundService; | |
| 69 | 67 | @Resource |
| 70 | 68 | private PayWalletRechargePackageService payWalletRechargePackageService; |
| 71 | 69 | |
| ... | ... | @@ -99,6 +97,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { |
| 99 | 97 | // 2.1 创建支付单 |
| 100 | 98 | Long payOrderId = payOrderService.createOrder(new PayOrderCreateReqDTO() |
| 101 | 99 | .setAppKey(payProperties.getWalletPayAppKey()).setUserIp(userIp) |
| 100 | + .setUserId(userId).setUserType(userType) // 用户信息 | |
| 102 | 101 | .setMerchantOrderId(recharge.getId().toString()) // 业务的订单编号 |
| 103 | 102 | .setSubject(WALLET_RECHARGE_ORDER_SUBJECT).setBody("") |
| 104 | 103 | .setPrice(recharge.getPayPrice()) |
| ... | ... | @@ -209,6 +208,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { |
| 209 | 208 | String refundId = walletRechargeId + "-refund"; |
| 210 | 209 | Long payRefundId = payRefundApi.createRefund(new PayRefundCreateReqDTO() |
| 211 | 210 | .setAppKey(payProperties.getWalletPayAppKey()).setUserIp(userIp) |
| 211 | + .setUserId(wallet.getUserId()).setUserType(wallet.getUserType()) // 用户信息 | |
| 212 | 212 | .setMerchantOrderId(walletRechargeId) |
| 213 | 213 | .setMerchantRefundId(refundId) |
| 214 | 214 | .setReason("想退钱").setPrice(walletRecharge.getPayPrice())); | ... | ... |
yudao-module-pay/src/test/resources/sql/clean.sql
yudao-module-pay/src/test/resources/sql/create_tables.sql
| ... | ... | @@ -45,6 +45,8 @@ CREATE TABLE IF NOT EXISTS `pay_order` ( |
| 45 | 45 | `channel_fee_price` bigint(20) DEFAULT 0, |
| 46 | 46 | `status` tinyint(4) NOT NULL, |
| 47 | 47 | `user_ip` varchar(50) NOT NULL, |
| 48 | + `user_id` bigint(20) DEFAULT NULL, | |
| 49 | + `user_type` tinyint(4) DEFAULT NULL, | |
| 48 | 50 | `expire_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, |
| 49 | 51 | `success_time` datetime(0) DEFAULT CURRENT_TIMESTAMP, |
| 50 | 52 | `notify_time` datetime(0) DEFAULT CURRENT_TIMESTAMP, |
| ... | ... | @@ -97,6 +99,8 @@ CREATE TABLE IF NOT EXISTS `pay_refund` ( |
| 97 | 99 | `refund_price` bigint(20) NOT NULL, |
| 98 | 100 | `reason` varchar(256) NOT NULL, |
| 99 | 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 | 104 | `channel_order_no` varchar(64) NOT NULL, |
| 101 | 105 | `channel_refund_no` varchar(64) NULL DEFAULT NULL, |
| 102 | 106 | `success_time` datetime(0) NULL DEFAULT NULL, |
| ... | ... | @@ -145,3 +149,32 @@ CREATE TABLE IF NOT EXISTS `pay_notify_log` ( |
| 145 | 149 | `deleted` bit(1) NOT NULL DEFAULT FALSE, |
| 146 | 150 | PRIMARY KEY ("id") |
| 147 | 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 = '转账单'; | ... | ... |