Commit 7653be9d48bcc7dcb3d0804e0dccf40546d57f9f
1 parent
1e7f22cd
feat:【PAY 支付】示例转账单,改成示例提现单,理解成本更低
Showing
32 changed files
with
385 additions
and
197 deletions
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java
| ... | ... | @@ -89,7 +89,7 @@ public class BrokerageWithdrawController { |
| 89 | 89 | public CommonResult<Boolean> updateBrokerageWithdrawTransferred(@RequestBody PayTransferNotifyReqDTO notifyReqDTO) { |
| 90 | 90 | log.info("[updateAfterRefund][notifyReqDTO({})]", notifyReqDTO); |
| 91 | 91 | brokerageWithdrawService.updateBrokerageWithdrawTransferred( |
| 92 | - Long.parseLong(notifyReqDTO.getMerchantTransferId()), notifyReqDTO.getPayTransferId()); | |
| 92 | + Long.parseLong(notifyReqDTO.getMerchantOrderId()), notifyReqDTO.getPayTransferId()); | |
| 93 | 93 | return success(true); |
| 94 | 94 | } |
| 95 | 95 | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java
| ... | ... | @@ -141,7 +141,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { |
| 141 | 141 | PayTransferCreateReqDTO payTransferCreateReqDTO = new PayTransferCreateReqDTO() |
| 142 | 142 | .setAppKey(tradeOrderProperties.getPayAppKey()) |
| 143 | 143 | .setChannelCode("wx_lite") // TODO @芋艿:【转账】这里要处理下; |
| 144 | - .setMerchantTransferId(withdraw.getId().toString()) | |
| 144 | + .setMerchantOrderId(withdraw.getId().toString()) | |
| 145 | 145 | .setPrice(withdraw.getPrice()) |
| 146 | 146 | .setSubject("佣金提现") |
| 147 | 147 | .setUserAccount(socialUser.getOpenid()).setUserIp(getClientIP()); | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
| ... | ... | @@ -280,7 +280,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 280 | 280 | TradeOrderDO order = validateOrderExists(id); |
| 281 | 281 | // 1.2 校验订单已支付 |
| 282 | 282 | if (!TradeOrderStatusEnum.isUnpaid(order.getStatus()) || order.getPayStatus()) { |
| 283 | - // 特殊:如果订单已支付,且支付单号相同,直接返回,说明重复回调 | |
| 283 | + // 特殊:支付单号相同,直接返回,说明重复回调 | |
| 284 | 284 | if (ObjectUtil.equals(order.getPayOrderId(), payOrderId)) { |
| 285 | 285 | log.warn("[updateOrderPaid][order({}) 已支付,且支付单号相同({}),直接返回]", order, payOrderId); |
| 286 | 286 | return; | ... | ... |
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayRefundNotifyReqDTO.java
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayTransferNotifyReqDTO.java
| 1 | 1 | package cn.iocoder.yudao.module.pay.api.notify.dto; |
| 2 | 2 | |
| 3 | +import lombok.AllArgsConstructor; | |
| 4 | +import lombok.Builder; | |
| 3 | 5 | import lombok.Data; |
| 4 | 6 | |
| 5 | 7 | import jakarta.validation.constraints.NotEmpty; |
| 6 | 8 | import jakarta.validation.constraints.NotNull; |
| 9 | +import lombok.NoArgsConstructor; | |
| 7 | 10 | |
| 8 | 11 | /** |
| 9 | 12 | * 转账单的通知 Request DTO |
| ... | ... | @@ -11,14 +14,16 @@ import jakarta.validation.constraints.NotNull; |
| 11 | 14 | * @author jason |
| 12 | 15 | */ |
| 13 | 16 | @Data |
| 17 | +@Builder | |
| 18 | +@NoArgsConstructor | |
| 19 | +@AllArgsConstructor | |
| 14 | 20 | public class PayTransferNotifyReqDTO { |
| 15 | 21 | |
| 16 | - // TODO 芋艿:要不要改成 orderId 待定; | |
| 17 | 22 | /** |
| 18 | 23 | * 商户转账单号 |
| 19 | 24 | */ |
| 20 | 25 | @NotEmpty(message = "商户转账单号不能为空") |
| 21 | - private String merchantTransferId; | |
| 26 | + private String merchantOrderId; | |
| 22 | 27 | |
| 23 | 28 | /** |
| 24 | 29 | * 转账订单编号 | ... | ... |
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java
| 1 | 1 | package cn.iocoder.yudao.module.pay.api.transfer.dto; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.module.pay.enums.PayChannelEnum; | |
| 3 | 4 | import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum; |
| 4 | 5 | import lombok.Data; |
| 5 | 6 | |
| 7 | +import java.time.LocalDateTime; | |
| 8 | + | |
| 6 | 9 | @Data |
| 7 | 10 | public class PayTransferRespDTO { |
| 8 | 11 | |
| ... | ... | @@ -17,6 +20,22 @@ public class PayTransferRespDTO { |
| 17 | 20 | private String no; |
| 18 | 21 | |
| 19 | 22 | /** |
| 23 | + * 转账渠道编码 | |
| 24 | + * | |
| 25 | + * 枚举 {@link PayChannelEnum} | |
| 26 | + */ | |
| 27 | + private String channelCode; | |
| 28 | + | |
| 29 | + // ========== 商户相关字段 ========== | |
| 30 | + | |
| 31 | + /** | |
| 32 | + * 商户转账单编号 | |
| 33 | + */ | |
| 34 | + private String merchantOrderId; | |
| 35 | + | |
| 36 | + // ========== 转账相关字段 ========== | |
| 37 | + | |
| 38 | + /** | |
| 20 | 39 | * 转账金额,单位:分 |
| 21 | 40 | */ |
| 22 | 41 | private Integer price; |
| ... | ... | @@ -28,4 +47,10 @@ public class PayTransferRespDTO { |
| 28 | 47 | */ |
| 29 | 48 | private Integer status; |
| 30 | 49 | |
| 50 | + /** | |
| 51 | + * 订单转账成功时间 | |
| 52 | + */ | |
| 53 | + private LocalDateTime successTime; | |
| 54 | + | |
| 55 | + | |
| 31 | 56 | } | ... | ... |
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java
| ... | ... | @@ -85,8 +85,12 @@ public interface ErrorCodeConstants { |
| 85 | 85 | ErrorCode DEMO_ORDER_REFUND_FAIL_REFUND_ORDER_ID_ERROR = new ErrorCode(1_007_900_009, "发起退款失败,退款单编号不匹配"); |
| 86 | 86 | ErrorCode DEMO_ORDER_REFUND_FAIL_REFUND_PRICE_NOT_MATCH = new ErrorCode(1_007_900_010, "发起退款失败,退款单金额不匹配"); |
| 87 | 87 | |
| 88 | - // ========== 示例转账订单 1-007-901-001 ========== | |
| 89 | - ErrorCode DEMO_TRANSFER_NOT_FOUND = new ErrorCode(1_007_901_001, "示例转账单不存在"); | |
| 90 | - ErrorCode DEMO_TRANSFER_FAIL_TRANSFER_ID_ERROR = new ErrorCode(1_007_901_002, "转账失败,转账单编号不匹配"); | |
| 91 | - ErrorCode DEMO_TRANSFER_FAIL_PRICE_NOT_MATCH = new ErrorCode(1_007_901_003, "转账失败,转账单金额不匹配"); | |
| 88 | + // ========== 示例提现单 1-007-901-000 ========== | |
| 89 | + ErrorCode DEMO_WITHDRAW_NOT_FOUND = new ErrorCode(1_007_901_000, "示例提现单不存在"); | |
| 90 | + ErrorCode DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_TRANSFER_ID_ERROR = new ErrorCode(1_007_901_001, "更新示例提现单状态失败,支付转账单编号不匹配"); | |
| 91 | + ErrorCode DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_TRANSFER_STATUS_NOT_SUCCESS_OR_CLOSED = new ErrorCode(1_007_901_002, "更新示例提现单状态失败,支付转账单状态不是【转账成功】或【转账失败】状态"); | |
| 92 | + ErrorCode DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_PRICE_NOT_MATCH = new ErrorCode(1_007_901_003, "更新示例提现单状态失败,支付转账单金额不匹配"); | |
| 93 | + ErrorCode DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_MERCHANT_EXISTS = new ErrorCode(1_007_901_004, "更新示例提现单状态失败,支付转账单商户订单号不匹配"); | |
| 94 | + ErrorCode DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_CHANNEL_NOT_MATCH = new ErrorCode(1_007_901_005, "更新示例提现单状态失败,支付转账单渠道不匹配"); | |
| 95 | + | |
| 92 | 96 | } | ... | ... |
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/PayChannelEnum.java
| 1 | 1 | package cn.iocoder.yudao.module.pay.enums; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.core.ArrayValuable; | |
| 3 | 4 | import lombok.AllArgsConstructor; |
| 4 | 5 | import lombok.Getter; |
| 5 | 6 | |
| 7 | +import java.util.Arrays; | |
| 8 | + | |
| 6 | 9 | /** |
| 7 | 10 | * 支付渠道的编码的枚举 |
| 8 | 11 | * |
| ... | ... | @@ -10,7 +13,7 @@ import lombok.Getter; |
| 10 | 13 | */ |
| 11 | 14 | @Getter |
| 12 | 15 | @AllArgsConstructor |
| 13 | -public enum PayChannelEnum { | |
| 16 | +public enum PayChannelEnum implements ArrayValuable<String> { | |
| 14 | 17 | |
| 15 | 18 | WX_PUB("wx_pub", "微信 JSAPI 支付"), // 公众号网页 |
| 16 | 19 | WX_LITE("wx_lite", "微信小程序支付"), |
| ... | ... | @@ -28,6 +31,8 @@ public enum PayChannelEnum { |
| 28 | 31 | |
| 29 | 32 | WALLET("wallet", "钱包支付"); |
| 30 | 33 | |
| 34 | + public static final String[] ARRAYS = Arrays.stream(values()).map(PayChannelEnum::getCode).toArray(String[]::new); | |
| 35 | + | |
| 31 | 36 | /** |
| 32 | 37 | * 编码 |
| 33 | 38 | * |
| ... | ... | @@ -39,4 +44,9 @@ public enum PayChannelEnum { |
| 39 | 44 | */ |
| 40 | 45 | private final String name; |
| 41 | 46 | |
| 47 | + @Override | |
| 48 | + public String[] array() { | |
| 49 | + return ARRAYS; | |
| 50 | + } | |
| 51 | + | |
| 42 | 52 | } | ... | ... |
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/demo/PayDemoWithdrawStatusEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.pay.enums.demo; | |
| 2 | + | |
| 3 | +import lombok.AllArgsConstructor; | |
| 4 | +import lombok.Getter; | |
| 5 | + | |
| 6 | +import java.util.Objects; | |
| 7 | + | |
| 8 | +/** | |
| 9 | + * 示例提现单的状态枚举 | |
| 10 | + * | |
| 11 | + * @author jason | |
| 12 | + */ | |
| 13 | +@Getter | |
| 14 | +@AllArgsConstructor | |
| 15 | +public enum PayDemoWithdrawStatusEnum { | |
| 16 | + | |
| 17 | + WAITING(0, "等待提现"), | |
| 18 | + SUCCESS(10, "提现成功"), | |
| 19 | + CLOSED(20, "提现关闭"); | |
| 20 | + | |
| 21 | + /** | |
| 22 | + * 状态 | |
| 23 | + */ | |
| 24 | + private final Integer status; | |
| 25 | + /** | |
| 26 | + * 状态名 | |
| 27 | + */ | |
| 28 | + private final String name; | |
| 29 | + | |
| 30 | + public static boolean isSuccess(Integer status) { | |
| 31 | + return Objects.equals(status, SUCCESS.getStatus()); | |
| 32 | + } | |
| 33 | + | |
| 34 | + public static boolean isClosed(Integer status) { | |
| 35 | + return Objects.equals(status, CLOSED.getStatus()); | |
| 36 | + } | |
| 37 | + | |
| 38 | + public static boolean isWaiting(Integer status) { | |
| 39 | + return Objects.equals(status, WAITING.getStatus()); | |
| 40 | + } | |
| 41 | + | |
| 42 | +} | ... | ... |
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/demo/PayDemoWithdrawTypeEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.pay.enums.demo; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.core.ArrayValuable; | |
| 4 | +import lombok.AllArgsConstructor; | |
| 5 | +import lombok.Getter; | |
| 6 | + | |
| 7 | +import java.util.Arrays; | |
| 8 | + | |
| 9 | +/** | |
| 10 | + * 示例提现单的类型枚举 | |
| 11 | + * | |
| 12 | + * @author owen | |
| 13 | + */ | |
| 14 | +@AllArgsConstructor | |
| 15 | +@Getter | |
| 16 | +public enum PayDemoWithdrawTypeEnum implements ArrayValuable<Integer> { | |
| 17 | + | |
| 18 | + WECHAT(2, "微信"), | |
| 19 | + ALIPAY(1, "支付宝"), | |
| 20 | + WALLET(3, "钱包"), | |
| 21 | + ; | |
| 22 | + | |
| 23 | + public static final Integer[] ARRAYS = Arrays.stream(values()).map(PayDemoWithdrawTypeEnum::getType).toArray(Integer[]::new); | |
| 24 | + | |
| 25 | + /** | |
| 26 | + * 类型 | |
| 27 | + */ | |
| 28 | + private final Integer type; | |
| 29 | + /** | |
| 30 | + * 名字 | |
| 31 | + */ | |
| 32 | + private final String name; | |
| 33 | + | |
| 34 | + @Override | |
| 35 | + public Integer[] array() { | |
| 36 | + return ARRAYS; | |
| 37 | + } | |
| 38 | + | |
| 39 | +} | ... | ... |
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/transfer/PayTransferStatusEnum.java
| ... | ... | @@ -48,9 +48,20 @@ public enum PayTransferStatusEnum { |
| 48 | 48 | * 是否处于待转账或者转账中的状态 |
| 49 | 49 | * |
| 50 | 50 | * @param status 状态 |
| 51 | + * @return 是否 | |
| 51 | 52 | */ |
| 52 | 53 | public static boolean isWaitingOrProcessing(Integer status) { |
| 53 | 54 | return isWaiting(status) || isProgressing(status); |
| 54 | 55 | } |
| 55 | 56 | |
| 57 | + /** | |
| 58 | + * 是否处于成功或者关闭中的状态 | |
| 59 | + * | |
| 60 | + * @param status 状态 | |
| 61 | + * @return 是否 | |
| 62 | + */ | |
| 63 | + public static boolean isSuccessOrClosed(Integer status) { | |
| 64 | + return isSuccess(status) || isClosed(status); | |
| 65 | + } | |
| 66 | + | |
| 56 | 67 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java
| ... | ... | @@ -23,7 +23,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 23 | 23 | import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; |
| 24 | 24 | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| 25 | 25 | |
| 26 | -@Tag(name = "管理后台 - 示例订单") | |
| 26 | +@Tag(name = "管理后台 - 示例订单") // 目的:演示支付、退款功能 | |
| 27 | 27 | @RestController |
| 28 | 28 | @RequestMapping("/pay/demo-order") |
| 29 | 29 | @Validated | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoTransferController.http renamed to yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.http
| 1 | 1 | ### 请求 /pay/pay/demo-order 接口 => 成功 |
| 2 | -POST {{baseUrl}}/pay/demo-transfer/create | |
| 2 | +POST {{baseUrl}}/pay/demo-withdraw/create | |
| 3 | 3 | Authorization: Bearer {{token}} |
| 4 | 4 | Content-Type: application/json |
| 5 | 5 | tenant-id: {{adminTenantId}} |
| 6 | 6 | |
| 7 | 7 | { |
| 8 | - "channelCode": "alipay_pc", | |
| 8 | + "type": 1, | |
| 9 | 9 | "subject": "测试转账", |
| 10 | 10 | "price": 10, |
| 11 | 11 | "userAccount": "oespxk7368@sandbox.com", | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoTransferController.java renamed to yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java
| ... | ... | @@ -5,10 +5,10 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 7 | 7 | import cn.iocoder.yudao.module.pay.api.notify.dto.PayTransferNotifyReqDTO; |
| 8 | -import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer.PayDemoTransferCreateReqVO; | |
| 9 | -import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer.PayDemoTransferRespVO; | |
| 10 | -import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoTransferDO; | |
| 11 | -import cn.iocoder.yudao.module.pay.service.demo.PayDemoTransferService; | |
| 8 | +import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.withdraw.PayDemoWithdrawCreateReqVO; | |
| 9 | +import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.withdraw.PayDemoWithdrawRespVO; | |
| 10 | +import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoWithdrawDO; | |
| 11 | +import cn.iocoder.yudao.module.pay.service.demo.PayDemoWithdrawService; | |
| 12 | 12 | import io.swagger.v3.oas.annotations.Operation; |
| 13 | 13 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 14 | 14 | import jakarta.annotation.Resource; |
| ... | ... | @@ -19,33 +19,34 @@ import org.springframework.web.bind.annotation.*; |
| 19 | 19 | |
| 20 | 20 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 21 | 21 | |
| 22 | -@Tag(name = "管理后台 - 示例转账单") | |
| 22 | +@Tag(name = "管理后台 - 示例提现订单") // 目的:演示转账功能 | |
| 23 | 23 | @RestController |
| 24 | -@RequestMapping("/pay/demo-transfer") | |
| 24 | +@RequestMapping("/pay/demo-withdraw") | |
| 25 | 25 | @Validated |
| 26 | -public class PayDemoTransferController { | |
| 26 | +public class PayDemoWithdrawController { | |
| 27 | + | |
| 27 | 28 | @Resource |
| 28 | - private PayDemoTransferService demoTransferService; | |
| 29 | + private PayDemoWithdrawService demoWithdrawService; | |
| 29 | 30 | |
| 30 | 31 | @PostMapping("/create") |
| 31 | - @Operation(summary = "创建示例转账订单") | |
| 32 | - public CommonResult<Long> createDemoTransfer(@Valid @RequestBody PayDemoTransferCreateReqVO createReqVO) { | |
| 33 | - Long id = demoTransferService.createDemoTransfer(createReqVO); | |
| 32 | + @Operation(summary = "创建示例提现单") | |
| 33 | + public CommonResult<Long> createDemoTransfer(@Valid @RequestBody PayDemoWithdrawCreateReqVO createReqVO) { | |
| 34 | + Long id = demoWithdrawService.createDemoWithdraw(createReqVO); | |
| 34 | 35 | return success(id); |
| 35 | 36 | } |
| 36 | 37 | |
| 37 | 38 | @GetMapping("/page") |
| 38 | - @Operation(summary = "获得示例转账订单分页") | |
| 39 | - public CommonResult<PageResult<PayDemoTransferRespVO>> getDemoTransferPage(@Valid PageParam pageVO) { | |
| 40 | - PageResult<PayDemoTransferDO> pageResult = demoTransferService.getDemoTransferPage(pageVO); | |
| 41 | - return success(BeanUtils.toBean(pageResult, PayDemoTransferRespVO.class)); | |
| 39 | + @Operation(summary = "获得示例提现单分页") | |
| 40 | + public CommonResult<PageResult<PayDemoWithdrawRespVO>> getDemoTransferPage(@Valid PageParam pageVO) { | |
| 41 | + PageResult<PayDemoWithdrawDO> pageResult = demoWithdrawService.getDemoWithdrawPage(pageVO); | |
| 42 | + return success(BeanUtils.toBean(pageResult, PayDemoWithdrawRespVO.class)); | |
| 42 | 43 | } |
| 43 | 44 | |
| 44 | 45 | @PostMapping("/update-status") |
| 45 | - @Operation(summary = "更新示例转账订单的转账状态") // 由 pay-module 转账服务,进行回调 | |
| 46 | + @Operation(summary = "更新示例提现单的转账状态") // 由 pay-module 转账服务,进行回调 | |
| 46 | 47 | @PermitAll // 无需登录,安全由 PayDemoTransferService 内部校验实现 |
| 47 | 48 | public CommonResult<Boolean> updateDemoTransferStatus(@RequestBody PayTransferNotifyReqDTO notifyReqDTO) { |
| 48 | - demoTransferService.updateDemoTransferStatus(Long.valueOf(notifyReqDTO.getMerchantTransferId()), | |
| 49 | + demoWithdrawService.updateDemoWithdrawStatus(Long.valueOf(notifyReqDTO.getMerchantOrderId()), | |
| 49 | 50 | notifyReqDTO.getPayTransferId()); |
| 50 | 51 | return success(true); |
| 51 | 52 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferRespVO.java deleted
| 1 | -package cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer; | |
| 2 | - | |
| 3 | -import io.swagger.v3.oas.annotations.media.Schema; | |
| 4 | -import lombok.Data; | |
| 5 | - | |
| 6 | -import java.time.LocalDateTime; | |
| 7 | - | |
| 8 | -/** | |
| 9 | - * 示例业务转账订单 Base VO,提供给添加、修改、详细的子 VO 使用 | |
| 10 | - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 | |
| 11 | - */ | |
| 12 | -@Data | |
| 13 | -public class PayDemoTransferRespVO { | |
| 14 | - | |
| 15 | - @Schema(description = "订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | |
| 16 | - private Long id; | |
| 17 | - | |
| 18 | - @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 19 | - private Long appId; | |
| 20 | - | |
| 21 | - @Schema(description = "转账金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "22338") | |
| 22 | - private Integer price; | |
| 23 | - | |
| 24 | - @Schema(description = "转账类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 25 | - private Integer type; | |
| 26 | - | |
| 27 | - @Schema(description = "收款人姓名", example = "test") | |
| 28 | - private String userName; | |
| 29 | - | |
| 30 | - @Schema(description = "支付宝登录号", example = "32167") | |
| 31 | - private String alipayLogonId; | |
| 32 | - | |
| 33 | - @Schema(description = "微信 openId", example = "31139") | |
| 34 | - private String openid; | |
| 35 | - | |
| 36 | - @Schema(description = "转账状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") | |
| 37 | - private Integer transferStatus; | |
| 38 | - | |
| 39 | - @Schema(description = "转账订单编号", example = "23695") | |
| 40 | - private Long payTransferId; | |
| 41 | - | |
| 42 | - @Schema(description = "转账支付成功渠道") | |
| 43 | - private String payChannelCode; | |
| 44 | - | |
| 45 | - @Schema(description = "转账支付时间") | |
| 46 | - private LocalDateTime transferTime; | |
| 47 | -} |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferCreateReqVO.java renamed to yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/withdraw/PayDemoWithdrawCreateReqVO.java
| 1 | -package cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer; | |
| 1 | +package cn.iocoder.yudao.module.pay.controller.admin.demo.vo.withdraw; | |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | |
| 4 | +import cn.iocoder.yudao.module.pay.enums.demo.PayDemoWithdrawTypeEnum; | |
| 3 | 5 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | 6 | import jakarta.validation.constraints.Min; |
| 5 | 7 | import jakarta.validation.constraints.NotBlank; |
| ... | ... | @@ -7,21 +9,17 @@ import jakarta.validation.constraints.NotEmpty; |
| 7 | 9 | import jakarta.validation.constraints.NotNull; |
| 8 | 10 | import lombok.Data; |
| 9 | 11 | |
| 10 | -@Schema(description = "管理后台 - 示例转账单创建 Request VO") | |
| 12 | +@Schema(description = "管理后台 - 示例提现单创建 Request VO") | |
| 11 | 13 | @Data |
| 12 | -public class PayDemoTransferCreateReqVO { | |
| 14 | +public class PayDemoWithdrawCreateReqVO { | |
| 13 | 15 | |
| 14 | - @Schema(description = "转账渠道", requiredMode = Schema.RequiredMode.REQUIRED, example = "wx_lite") | |
| 15 | - @NotEmpty(message = "转账渠道不能为空") | |
| 16 | - private String channelCode; | |
| 17 | - | |
| 18 | - @Schema(description = "转账标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿是一种菜") | |
| 19 | - @NotEmpty(message = "转账标题不能为空") | |
| 16 | + @Schema(description = "提现标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿是一种菜") | |
| 17 | + @NotEmpty(message = "提现标题不能为空") | |
| 20 | 18 | private String subject; |
| 21 | 19 | |
| 22 | - @Schema(description = "转账金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") | |
| 23 | - @NotNull(message = "转账金额不能为空") | |
| 24 | - @Min(value = 1, message = "转账金额必须大于零") | |
| 20 | + @Schema(description = "提现金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") | |
| 21 | + @NotNull(message = "提现金额不能为空") | |
| 22 | + @Min(value = 1, message = "提现金额必须大于零") | |
| 25 | 23 | private Integer price; |
| 26 | 24 | |
| 27 | 25 | @Schema(description = "收款人账号", requiredMode= Schema.RequiredMode.REQUIRED, example = "test1") |
| ... | ... | @@ -32,4 +30,9 @@ public class PayDemoTransferCreateReqVO { |
| 32 | 30 | @NotBlank(message = "收款人姓名不能为空") |
| 33 | 31 | private String userName; |
| 34 | 32 | |
| 33 | + @Schema(description = "提现方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 34 | + @NotNull(message = "提现方式不能为空") | |
| 35 | + @InEnum(PayDemoWithdrawTypeEnum.class) | |
| 36 | + private Integer type; | |
| 37 | + | |
| 35 | 38 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/withdraw/PayDemoWithdrawRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.pay.controller.admin.demo.vo.withdraw; | |
| 2 | + | |
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | |
| 4 | +import lombok.Data; | |
| 5 | + | |
| 6 | +import java.time.LocalDateTime; | |
| 7 | + | |
| 8 | +@Schema(description = "管理后台 - 示例转账单创建 Request VO") | |
| 9 | +@Data | |
| 10 | +public class PayDemoWithdrawRespVO { | |
| 11 | + | |
| 12 | + @Schema(description = "转账单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | |
| 13 | + private Long id; | |
| 14 | + | |
| 15 | + @Schema(description = "提现标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "吃饭报销") | |
| 16 | + private String subject; | |
| 17 | + | |
| 18 | + @Schema(description = "提现金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "22338") | |
| 19 | + private Integer price; | |
| 20 | + | |
| 21 | + @Schema(description = "收款人姓名", example = "test") | |
| 22 | + private String userName; | |
| 23 | + | |
| 24 | + @Schema(description = "收款人账号", example = "32167") | |
| 25 | + private String userAccount; | |
| 26 | + | |
| 27 | + @Schema(description = "提现类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 28 | + private Integer type; | |
| 29 | + | |
| 30 | + @Schema(description = "提现状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") | |
| 31 | + private Integer status; | |
| 32 | + | |
| 33 | + // ========== 转账相关字段 ========== | |
| 34 | + | |
| 35 | + @Schema(description = "转账单编号", example = "23695") | |
| 36 | + private Long payTransferId; | |
| 37 | + | |
| 38 | + @Schema(description = "转账渠道") | |
| 39 | + private String transferChannelCode; | |
| 40 | + | |
| 41 | + @Schema(description = "转账成功时间") | |
| 42 | + private LocalDateTime transferTime; | |
| 43 | + | |
| 44 | +} | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferPageItemRespVO.java
| ... | ... | @@ -28,7 +28,7 @@ public class PayTransferPageItemRespVO { |
| 28 | 28 | private String channelCode; |
| 29 | 29 | |
| 30 | 30 | @Schema(description = "商户转账单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17481") |
| 31 | - private String merchantTransferId; | |
| 31 | + private String merchantOrderId; | |
| 32 | 32 | |
| 33 | 33 | @Schema(description = "类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") |
| 34 | 34 | private Integer type; | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferPageReqVO.java
| ... | ... | @@ -24,7 +24,7 @@ public class PayTransferPageReqVO extends PageParam { |
| 24 | 24 | private String channelCode; |
| 25 | 25 | |
| 26 | 26 | @Schema(description = "商户转账单编号", example = "17481") |
| 27 | - private String merchantTransferId; | |
| 27 | + private String merchantOrderId; | |
| 28 | 28 | |
| 29 | 29 | @Schema(description = "转账状态", example = "2") |
| 30 | 30 | private Integer status; | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferRespVO.java
| ... | ... | @@ -25,7 +25,7 @@ public class PayTransferRespVO { |
| 25 | 25 | private String channelCode; |
| 26 | 26 | |
| 27 | 27 | @Schema(description = "商户转账单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17481") |
| 28 | - private String merchantTransferId; | |
| 28 | + private String merchantOrderId; | |
| 29 | 29 | |
| 30 | 30 | @Schema(description = "类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") |
| 31 | 31 | private Integer type; | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoTransferDO.java renamed to yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoWithdrawDO.java
| ... | ... | @@ -2,7 +2,8 @@ package cn.iocoder.yudao.module.pay.dal.dataobject.demo; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 4 | 4 | import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO; |
| 5 | -import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum; | |
| 5 | +import cn.iocoder.yudao.module.pay.enums.demo.PayDemoWithdrawStatusEnum; | |
| 6 | +import cn.iocoder.yudao.module.pay.enums.demo.PayDemoWithdrawTypeEnum; | |
| 6 | 7 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 7 | 8 | import com.baomidou.mybatisplus.annotation.TableId; |
| 8 | 9 | import com.baomidou.mybatisplus.annotation.TableName; |
| ... | ... | @@ -11,35 +12,27 @@ import lombok.Data; |
| 11 | 12 | import java.time.LocalDateTime; |
| 12 | 13 | |
| 13 | 14 | /** |
| 14 | - * 示例转账订单 | |
| 15 | + * 示例提现订单 | |
| 15 | 16 | * |
| 16 | 17 | * 演示业务系统的转账业务 |
| 17 | 18 | */ |
| 18 | -@TableName(value ="pay_demo_transfer", autoResultMap = true) | |
| 19 | -@KeySequence("pay_demo_transfer_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 | |
| 19 | +@TableName(value ="pay_demo_withdraw", autoResultMap = true) | |
| 20 | +@KeySequence("pay_demo_withdraw_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 | |
| 20 | 21 | @Data |
| 21 | -public class PayDemoTransferDO extends BaseDO { | |
| 22 | +public class PayDemoWithdrawDO extends BaseDO { | |
| 22 | 23 | |
| 23 | 24 | /** |
| 24 | - * 编号,自增 | |
| 25 | + * 提现单编号,自增 | |
| 25 | 26 | */ |
| 26 | 27 | @TableId |
| 27 | 28 | private Long id; |
| 28 | 29 | |
| 29 | 30 | /** |
| 30 | - * 转账渠道 | |
| 31 | - * | |
| 32 | - * 枚举 {@link cn.iocoder.yudao.module.pay.enums.PayChannelEnum} | |
| 33 | - */ | |
| 34 | - private String channelCode; | |
| 35 | - | |
| 36 | - /** | |
| 37 | - * 转账标题 | |
| 31 | + * 提现标题 | |
| 38 | 32 | */ |
| 39 | 33 | private String subject; |
| 40 | - | |
| 41 | 34 | /** |
| 42 | - * 转账金额,单位:分 | |
| 35 | + * 提现金额,单位:分 | |
| 43 | 36 | */ |
| 44 | 37 | private Integer price; |
| 45 | 38 | |
| ... | ... | @@ -53,11 +46,19 @@ public class PayDemoTransferDO extends BaseDO { |
| 53 | 46 | private String userName; |
| 54 | 47 | |
| 55 | 48 | /** |
| 56 | - * 转账状态 | |
| 49 | + * 提现方式 | |
| 50 | + * | |
| 51 | + * 枚举 {@link PayDemoWithdrawTypeEnum} | |
| 52 | + */ | |
| 53 | + private Integer type; | |
| 54 | + /** | |
| 55 | + * 提现状态 | |
| 57 | 56 | * |
| 58 | - * 枚举 {@link PayTransferStatusEnum} | |
| 57 | + * 枚举 {@link PayDemoWithdrawStatusEnum} | |
| 59 | 58 | */ |
| 60 | - private Integer transferStatus; | |
| 59 | + private Integer status; | |
| 60 | + | |
| 61 | + // ========== 转账相关字段 ========== | |
| 61 | 62 | |
| 62 | 63 | /** |
| 63 | 64 | * 转账单编号 |
| ... | ... | @@ -66,6 +67,12 @@ public class PayDemoTransferDO extends BaseDO { |
| 66 | 67 | */ |
| 67 | 68 | private Long payTransferId; |
| 68 | 69 | /** |
| 70 | + * 转账渠道 | |
| 71 | + * | |
| 72 | + * 枚举 {@link cn.iocoder.yudao.module.pay.enums.PayChannelEnum} | |
| 73 | + */ | |
| 74 | + private String transferChannelCode; | |
| 75 | + /** | |
| 69 | 76 | * 转账成功时间 |
| 70 | 77 | */ |
| 71 | 78 | private LocalDateTime transferTime; | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/demo/PayDemoTransferMapper.java renamed to yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/demo/PayDemoWithdrawMapper.java
| ... | ... | @@ -4,14 +4,21 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | 5 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 6 | 6 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 7 | -import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoTransferDO; | |
| 7 | +import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoWithdrawDO; | |
| 8 | 8 | import org.apache.ibatis.annotations.Mapper; |
| 9 | 9 | |
| 10 | 10 | @Mapper |
| 11 | -public interface PayDemoTransferMapper extends BaseMapperX<PayDemoTransferDO> { | |
| 11 | +public interface PayDemoWithdrawMapper extends BaseMapperX<PayDemoWithdrawDO> { | |
| 12 | 12 | |
| 13 | - default PageResult<PayDemoTransferDO> selectPage(PageParam pageParam){ | |
| 14 | - return selectPage(pageParam, new LambdaQueryWrapperX<PayDemoTransferDO>() | |
| 15 | - .orderByDesc(PayDemoTransferDO::getId)); | |
| 13 | + default PageResult<PayDemoWithdrawDO> selectPage(PageParam pageParam){ | |
| 14 | + return selectPage(pageParam, new LambdaQueryWrapperX<PayDemoWithdrawDO>() | |
| 15 | + .orderByDesc(PayDemoWithdrawDO::getId)); | |
| 16 | 16 | } |
| 17 | + | |
| 18 | + default int updateByIdAndStatus(Long id, Integer status, PayDemoWithdrawDO updateObj) { | |
| 19 | + return update(updateObj, new LambdaQueryWrapperX<PayDemoWithdrawDO>() | |
| 20 | + .eq(PayDemoWithdrawDO::getId, id) | |
| 21 | + .eq(PayDemoWithdrawDO::getStatus, status)); | |
| 22 | + } | |
| 23 | + | |
| 17 | 24 | } |
| 18 | 25 | \ No newline at end of file | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java
| ... | ... | @@ -26,9 +26,9 @@ public interface PayTransferMapper extends BaseMapperX<PayTransferDO> { |
| 26 | 26 | .eq(PayTransferDO::getStatus, whereStatus)); |
| 27 | 27 | } |
| 28 | 28 | |
| 29 | - default PayTransferDO selectByAppIdAndMerchantTransferId(Long appId, String merchantTransferId){ | |
| 29 | + default PayTransferDO selectByAppIdAndMerchantOrderId(Long appId, String merchantOrderId) { | |
| 30 | 30 | return selectOne(PayTransferDO::getAppId, appId, |
| 31 | - PayTransferDO::getMerchantTransferId, merchantTransferId); | |
| 31 | + PayTransferDO::getMerchantOrderId, merchantOrderId); | |
| 32 | 32 | } |
| 33 | 33 | |
| 34 | 34 | default PageResult<PayTransferDO> selectPage(PayTransferPageReqVO reqVO) { |
| ... | ... | @@ -36,7 +36,7 @@ public interface PayTransferMapper extends BaseMapperX<PayTransferDO> { |
| 36 | 36 | .eqIfPresent(PayTransferDO::getNo, reqVO.getNo()) |
| 37 | 37 | .eqIfPresent(PayTransferDO::getAppId, reqVO.getAppId()) |
| 38 | 38 | .eqIfPresent(PayTransferDO::getChannelCode, reqVO.getChannelCode()) |
| 39 | - .eqIfPresent(PayTransferDO::getMerchantTransferId, reqVO.getMerchantTransferId()) | |
| 39 | + .eqIfPresent(PayTransferDO::getMerchantOrderId, reqVO.getMerchantOrderId()) | |
| 40 | 40 | .eqIfPresent(PayTransferDO::getStatus, reqVO.getStatus()) |
| 41 | 41 | .likeIfPresent(PayTransferDO::getUserName, reqVO.getUserName()) |
| 42 | 42 | .eqIfPresent(PayTransferDO::getChannelTransferNo, reqVO.getChannelTransferNo()) | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java
| ... | ... | @@ -119,14 +119,14 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { |
| 119 | 119 | } |
| 120 | 120 | // 1.2 校验订单已支付 |
| 121 | 121 | if (order.getPayStatus()) { |
| 122 | - // 特殊:如果订单已支付,且支付单号相同,直接返回,说明重复回调 | |
| 122 | + // 特殊:支付单号相同,直接返回,说明重复回调 | |
| 123 | 123 | if (ObjectUtil.equals(order.getPayOrderId(), payOrderId)) { |
| 124 | 124 | log.warn("[updateDemoOrderPaid][order({}) 已支付,且支付单号相同({}),直接返回]", order, payOrderId); |
| 125 | 125 | return; |
| 126 | 126 | } |
| 127 | 127 | // 异常:支付单号不同,说明支付单号错误 |
| 128 | - log.error("[updateDemoOrderPaid][order({}) 支付单不匹配({}),请进行处理!order 数据是:{}]", | |
| 129 | - order, payOrderId, toJsonString(order)); | |
| 128 | + log.error("[updateDemoOrderPaid][order({}) 支付单不匹配({}),请进行处理!]", | |
| 129 | + order, payOrderId); | |
| 130 | 130 | throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR); |
| 131 | 131 | } |
| 132 | 132 | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java
| ... | ... | @@ -3,22 +3,24 @@ package cn.iocoder.yudao.module.pay.service.demo; |
| 3 | 3 | import cn.hutool.core.util.ObjectUtil; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | |
| 6 | 7 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 7 | 8 | import cn.iocoder.yudao.module.pay.api.transfer.PayTransferApi; |
| 8 | 9 | import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; |
| 9 | -import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer.PayDemoTransferCreateReqVO; | |
| 10 | -import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoTransferDO; | |
| 11 | -import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO; | |
| 12 | -import cn.iocoder.yudao.module.pay.dal.mysql.demo.PayDemoTransferMapper; | |
| 10 | +import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO; | |
| 11 | +import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.withdraw.PayDemoWithdrawCreateReqVO; | |
| 12 | +import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoWithdrawDO; | |
| 13 | +import cn.iocoder.yudao.module.pay.dal.mysql.demo.PayDemoWithdrawMapper; | |
| 14 | +import cn.iocoder.yudao.module.pay.enums.PayChannelEnum; | |
| 15 | +import cn.iocoder.yudao.module.pay.enums.demo.PayDemoWithdrawStatusEnum; | |
| 16 | +import cn.iocoder.yudao.module.pay.enums.demo.PayDemoWithdrawTypeEnum; | |
| 13 | 17 | import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum; |
| 14 | -import cn.iocoder.yudao.module.pay.service.transfer.PayTransferService; | |
| 15 | 18 | import jakarta.annotation.Resource; |
| 16 | 19 | import jakarta.validation.Valid; |
| 20 | +import lombok.extern.slf4j.Slf4j; | |
| 17 | 21 | import org.springframework.stereotype.Service; |
| 18 | 22 | import org.springframework.validation.annotation.Validated; |
| 19 | 23 | |
| 20 | -import java.util.Objects; | |
| 21 | - | |
| 22 | 24 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 23 | 25 | import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; |
| 24 | 26 | import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; |
| ... | ... | @@ -30,7 +32,8 @@ import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; |
| 30 | 32 | */ |
| 31 | 33 | @Service |
| 32 | 34 | @Validated |
| 33 | -public class PayDemoTransferServiceImpl implements PayDemoTransferService { | |
| 35 | +@Slf4j | |
| 36 | +public class PayDemoTransferServiceImpl implements PayDemoWithdrawService { | |
| 34 | 37 | |
| 35 | 38 | /** |
| 36 | 39 | * 接入的支付应用标识 |
| ... | ... | @@ -40,75 +43,113 @@ public class PayDemoTransferServiceImpl implements PayDemoTransferService { |
| 40 | 43 | private static final String PAY_APP_KEY = "demo"; |
| 41 | 44 | |
| 42 | 45 | @Resource |
| 43 | - private PayDemoTransferMapper demoTransferMapper; | |
| 44 | - | |
| 45 | - @Resource | |
| 46 | - private PayTransferService payTransferService; | |
| 46 | + private PayDemoWithdrawMapper demoTransferMapper; | |
| 47 | 47 | |
| 48 | 48 | @Resource |
| 49 | 49 | private PayTransferApi payTransferApi; |
| 50 | 50 | |
| 51 | 51 | @Override |
| 52 | - public Long createDemoTransfer(@Valid PayDemoTransferCreateReqVO reqVO) { | |
| 53 | - // 1. 保存示例转账业务表 | |
| 54 | - PayDemoTransferDO demoTransfer = BeanUtils.toBean(reqVO, PayDemoTransferDO.class) | |
| 55 | - .setTransferStatus(PayTransferStatusEnum.WAITING.getStatus()); | |
| 56 | - demoTransferMapper.insert(demoTransfer); | |
| 52 | + public Long createDemoWithdraw(@Valid PayDemoWithdrawCreateReqVO reqVO) { | |
| 53 | + // 1. 保存示例提现单 | |
| 54 | + PayDemoWithdrawDO withdraw = BeanUtils.toBean(reqVO, PayDemoWithdrawDO.class) | |
| 55 | + .setTransferChannelCode(getTransferChannelCode(reqVO.getType())) | |
| 56 | + .setStatus(PayTransferStatusEnum.WAITING.getStatus()); | |
| 57 | + demoTransferMapper.insert(withdraw); | |
| 57 | 58 | |
| 58 | 59 | // 2.1 创建支付单 |
| 59 | 60 | Long payTransferId = payTransferApi.createTransfer(new PayTransferCreateReqDTO() |
| 60 | - .setChannelCode(reqVO.getChannelCode()) | |
| 61 | - .setAppKey(PAY_APP_KEY).setUserIp(getClientIP()) // 支付应用 | |
| 62 | - .setMerchantTransferId(String.valueOf(demoTransfer.getId())) // 业务的订单编号 | |
| 63 | - .setSubject(reqVO.getSubject()).setPrice(demoTransfer.getPrice()) // 价格信息 | |
| 61 | + .setAppKey(PAY_APP_KEY).setChannelCode(withdraw.getTransferChannelCode()).setUserIp(getClientIP()) // 支付应用 | |
| 62 | + .setMerchantOrderId(String.valueOf(withdraw.getId())) // 业务的订单编号 | |
| 63 | + .setSubject(reqVO.getSubject()).setPrice(withdraw.getPrice()) // 价格信息 | |
| 64 | 64 | .setUserAccount(reqVO.getUserAccount()).setUserName(reqVO.getUserName())); // 收款信息 |
| 65 | - // 2.2 更新转账单到 demo 示例转账业务表 | |
| 66 | - demoTransferMapper.updateById(new PayDemoTransferDO().setId(demoTransfer.getId()) | |
| 65 | + // 2.2 更新转账单到 demo 示例提现单 | |
| 66 | + demoTransferMapper.updateById(new PayDemoWithdrawDO().setId(withdraw.getId()) | |
| 67 | 67 | .setPayTransferId(payTransferId)); |
| 68 | - return demoTransfer.getId(); | |
| 68 | + return withdraw.getId(); | |
| 69 | + } | |
| 70 | + | |
| 71 | + private String getTransferChannelCode(Integer type) { | |
| 72 | + if (ObjectUtil.equal(type, PayDemoWithdrawTypeEnum.ALIPAY.getType())) { | |
| 73 | + return PayChannelEnum.ALIPAY_PC.getCode(); | |
| 74 | + } | |
| 75 | + if (ObjectUtil.equal(type, PayDemoWithdrawTypeEnum.WECHAT.getType())) { | |
| 76 | + return PayChannelEnum.WX_LITE.getCode(); | |
| 77 | + } | |
| 78 | + if (ObjectUtil.equal(type, PayDemoWithdrawTypeEnum.WALLET.getType())) { | |
| 79 | + return PayChannelEnum.WALLET.getCode(); | |
| 80 | + } | |
| 81 | + throw new IllegalArgumentException("未知提现方式:" + type); | |
| 69 | 82 | } |
| 70 | 83 | |
| 71 | 84 | @Override |
| 72 | - public PageResult<PayDemoTransferDO> getDemoTransferPage(PageParam pageVO) { | |
| 85 | + public PageResult<PayDemoWithdrawDO> getDemoWithdrawPage(PageParam pageVO) { | |
| 73 | 86 | return demoTransferMapper.selectPage(pageVO); |
| 74 | 87 | } |
| 75 | 88 | |
| 76 | 89 | @Override |
| 77 | - public void updateDemoTransferStatus(Long id, Long payTransferId) { | |
| 78 | - PayTransferDO payTransfer = validateDemoTransferStatusCanUpdate(id, payTransferId); | |
| 79 | - // TODO @芋艿:这块,需要在优化下; | |
| 80 | - // 更新示例订单状态 | |
| 81 | - if (payTransfer != null) { | |
| 82 | - demoTransferMapper.updateById(new PayDemoTransferDO().setId(id) | |
| 83 | - .setPayTransferId(payTransferId) | |
| 84 | - .setTransferStatus(payTransfer.getStatus()) | |
| 85 | - .setTransferTime(payTransfer.getSuccessTime())); | |
| 90 | + public void updateDemoWithdrawStatus(Long id, Long payTransferId) { | |
| 91 | + // 1.1 校验转账单是否存在 | |
| 92 | + PayDemoWithdrawDO withdraw = demoTransferMapper.selectById(id); | |
| 93 | + if (withdraw == null) { | |
| 94 | + log.error("[updateDemoWithdrawStatus][withdraw({}) payOrder({}) 不存在提现单,请进行处理!]", id, payTransferId); | |
| 95 | + throw exception(DEMO_WITHDRAW_NOT_FOUND); | |
| 96 | + } | |
| 97 | + // 1.2 校验转账单已成结束(成功或失败) | |
| 98 | + if (PayDemoWithdrawStatusEnum.isSuccess(withdraw.getStatus()) | |
| 99 | + || PayDemoWithdrawStatusEnum.isClosed(withdraw.getStatus())) { | |
| 100 | + // 特殊:转账单编号相同,直接返回,说明重复回调 | |
| 101 | + if (ObjectUtil.equal(withdraw.getPayTransferId(), payTransferId)) { | |
| 102 | + log.warn("[updateDemoWithdrawStatus][withdraw({}) 已结束,且转账单编号相同({}),直接返回]", withdraw, payTransferId); | |
| 103 | + return; | |
| 104 | + } | |
| 105 | + // 异常:转账单编号不同,说明转账单编号错误 | |
| 106 | + log.error("[updateDemoWithdrawStatus][withdraw({}) 转账单不匹配({}),请进行处理!]", withdraw, payTransferId); | |
| 107 | + throw exception(DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_TRANSFER_ID_ERROR); | |
| 86 | 108 | } |
| 109 | + | |
| 110 | + // 2. 校验提现单的合法性 | |
| 111 | + PayTransferRespDTO payTransfer = validateDemoTransferStatusCanUpdate(withdraw, payTransferId); | |
| 112 | + | |
| 113 | + // 3. 更新示例订单状态 | |
| 114 | + demoTransferMapper.updateById(new PayDemoWithdrawDO().setId(id) | |
| 115 | + .setPayTransferId(payTransferId) | |
| 116 | + .setStatus(payTransfer.getStatus()) | |
| 117 | + .setTransferTime(payTransfer.getSuccessTime())); | |
| 87 | 118 | } |
| 88 | 119 | |
| 89 | - private PayTransferDO validateDemoTransferStatusCanUpdate(Long id, Long payTransferId) { | |
| 90 | - PayDemoTransferDO demoTransfer = demoTransferMapper.selectById(id); | |
| 91 | - if (demoTransfer == null) { | |
| 92 | - throw exception(DEMO_TRANSFER_NOT_FOUND); | |
| 120 | + private PayTransferRespDTO validateDemoTransferStatusCanUpdate(PayDemoWithdrawDO withdraw, Long payTransferId) { | |
| 121 | + // 1. 校验转账单是否存在 | |
| 122 | + PayTransferRespDTO payTransfer = payTransferApi.getTransfer(payTransferId); | |
| 123 | + if (payTransfer == null) { | |
| 124 | + log.error("[validateDemoTransferStatusCanUpdate][withdraw({}) payTransfer({}) 不存在,请进行处理!]", withdraw.getId(), payTransferId); | |
| 125 | + throw exception(PAY_TRANSFER_NOT_FOUND); | |
| 93 | 126 | } |
| 94 | - // TODO @芋艿:这里也要更新下; | |
| 95 | - // 无需更新返回 null | |
| 96 | - if (PayTransferStatusEnum.isSuccess(demoTransfer.getTransferStatus()) | |
| 97 | - || PayTransferStatusEnum.isClosed(demoTransfer.getTransferStatus())) { | |
| 98 | - return null; | |
| 127 | + | |
| 128 | + // 2.1 校验转账单已成功 | |
| 129 | + if (!PayTransferStatusEnum.isSuccessOrClosed(payTransfer.getStatus())) { | |
| 130 | + log.error("[validateDemoTransferStatusCanUpdate][withdraw({}) payTransfer({}) 未结束,请进行处理!payTransfer 数据是:{}]", | |
| 131 | + withdraw.getId(), payTransferId, JsonUtils.toJsonString(payTransfer)); | |
| 132 | + throw exception(DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_TRANSFER_STATUS_NOT_SUCCESS_OR_CLOSED); | |
| 99 | 133 | } |
| 100 | - PayTransferDO transfer = payTransferService.getTransfer(payTransferId); | |
| 101 | - if (transfer == null) { | |
| 102 | - throw exception(PAY_TRANSFER_NOT_FOUND); | |
| 134 | + // 2.2 校验转账金额一致 | |
| 135 | + if (ObjectUtil.notEqual(payTransfer.getPrice(), withdraw.getPrice())) { | |
| 136 | + log.error("[validateDemoTransferStatusCanUpdate][withdraw({}) payTransfer({}) 转账金额不匹配,请进行处理!withdraw 数据是:{},payTransfer 数据是:{}]", | |
| 137 | + withdraw.getId(), payTransferId, JsonUtils.toJsonString(withdraw), JsonUtils.toJsonString(payTransfer)); | |
| 138 | + throw exception(DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_PRICE_NOT_MATCH); | |
| 103 | 139 | } |
| 104 | - if (!Objects.equals(demoTransfer.getPrice(), transfer.getPrice())) { | |
| 105 | - throw exception(DEMO_TRANSFER_FAIL_PRICE_NOT_MATCH); | |
| 140 | + // 2.3 校验转账订单匹配(二次) | |
| 141 | + if (ObjectUtil.notEqual(payTransfer.getMerchantOrderId(), withdraw.getId().toString())) { | |
| 142 | + log.error("[validateDemoTransferStatusCanUpdate][withdraw({}) 转账单不匹配({}),请进行处理!payTransfer 数据是:{}]", | |
| 143 | + withdraw.getId(), payTransferId, JsonUtils.toJsonString(payTransfer)); | |
| 144 | + throw exception(DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_MERCHANT_EXISTS); | |
| 106 | 145 | } |
| 107 | - if (ObjectUtil.notEqual(transfer.getMerchantTransferId(), id.toString())) { | |
| 108 | - throw exception(DEMO_TRANSFER_FAIL_TRANSFER_ID_ERROR); | |
| 146 | + // 2.4 校验转账渠道一致 | |
| 147 | + if (ObjectUtil.notEqual(payTransfer.getChannelCode(), withdraw.getTransferChannelCode())) { | |
| 148 | + log.error("[validateDemoTransferStatusCanUpdate][withdraw({}) payTransfer({}) 转账渠道不匹配,请进行处理!withdraw 数据是:{},payTransfer 数据是:{}]", | |
| 149 | + withdraw.getId(), payTransferId, JsonUtils.toJsonString(withdraw), JsonUtils.toJsonString(payTransfer)); | |
| 150 | + throw exception(DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_CHANNEL_NOT_MATCH); | |
| 109 | 151 | } |
| 110 | - // TODO 校验账号 | |
| 111 | - return transfer; | |
| 152 | + return payTransfer; | |
| 112 | 153 | } |
| 113 | 154 | |
| 114 | 155 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferService.java renamed to yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawService.java
| ... | ... | @@ -2,38 +2,39 @@ package cn.iocoder.yudao.module.pay.service.demo; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | -import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer.PayDemoTransferCreateReqVO; | |
| 6 | -import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoTransferDO; | |
| 5 | +import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.withdraw.PayDemoWithdrawCreateReqVO; | |
| 6 | +import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoWithdrawDO; | |
| 7 | 7 | |
| 8 | 8 | import jakarta.validation.Valid; |
| 9 | 9 | |
| 10 | 10 | /** |
| 11 | - * 示例转账业务 Service 接口 | |
| 11 | + * 示例提现单 Service 接口 | |
| 12 | 12 | * |
| 13 | 13 | * @author jason |
| 14 | 14 | */ |
| 15 | -public interface PayDemoTransferService { | |
| 15 | +public interface PayDemoWithdrawService { | |
| 16 | 16 | |
| 17 | 17 | /** |
| 18 | - * 创建转账业务示例订单 | |
| 18 | + * 创建示例提现单 | |
| 19 | 19 | * |
| 20 | 20 | * @param createReqVO 创建信息 |
| 21 | 21 | * @return 编号 |
| 22 | 22 | */ |
| 23 | - Long createDemoTransfer(@Valid PayDemoTransferCreateReqVO createReqVO); | |
| 23 | + Long createDemoWithdraw(@Valid PayDemoWithdrawCreateReqVO createReqVO); | |
| 24 | 24 | |
| 25 | 25 | /** |
| 26 | - * 获得转账业务示例订单分页 | |
| 26 | + * 获得示例提现单分页 | |
| 27 | 27 | * |
| 28 | 28 | * @param pageVO 分页查询参数 |
| 29 | 29 | */ |
| 30 | - PageResult<PayDemoTransferDO> getDemoTransferPage(PageParam pageVO); | |
| 30 | + PageResult<PayDemoWithdrawDO> getDemoWithdrawPage(PageParam pageVO); | |
| 31 | 31 | |
| 32 | 32 | /** |
| 33 | - * 更新转账业务示例订单的转账状态 | |
| 33 | + * 更新示例提现单的状态 | |
| 34 | 34 | * |
| 35 | 35 | * @param id 编号 |
| 36 | 36 | * @param payTransferId 转账单编号 |
| 37 | 37 | */ |
| 38 | - void updateDemoTransferStatus(Long id, Long payTransferId); | |
| 38 | + void updateDemoWithdrawStatus(Long id, Long payTransferId); | |
| 39 | + | |
| 39 | 40 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java
| ... | ... | @@ -108,8 +108,8 @@ public class PayNotifyServiceImpl implements PayNotifyService { |
| 108 | 108 | .setMerchantOrderId(refundDO.getMerchantOrderId()).setNotifyUrl(refundDO.getNotifyUrl()); |
| 109 | 109 | } else if (Objects.equals(task.getType(), PayNotifyTypeEnum.TRANSFER.getType())) { |
| 110 | 110 | PayTransferDO transfer = transferService.getTransfer(task.getDataId()); |
| 111 | - task.setAppId(transfer.getAppId()).setMerchantTransferId(transfer.getMerchantTransferId()) | |
| 112 | - .setNotifyUrl(transfer.getNotifyUrl()); | |
| 111 | + task.setAppId(transfer.getAppId()) | |
| 112 | + .setMerchantOrderId(transfer.getMerchantOrderId()).setNotifyUrl(transfer.getNotifyUrl()); | |
| 113 | 113 | } |
| 114 | 114 | |
| 115 | 115 | // 执行插入 |
| ... | ... | @@ -225,8 +225,8 @@ public class PayNotifyServiceImpl implements PayNotifyService { |
| 225 | 225 | request = PayRefundNotifyReqDTO.builder().merchantOrderId(task.getMerchantOrderId()) |
| 226 | 226 | .payRefundId(task.getDataId()).build(); |
| 227 | 227 | } else if (Objects.equals(task.getType(), PayNotifyTypeEnum.TRANSFER.getType())) { |
| 228 | - request = new PayTransferNotifyReqDTO().setMerchantTransferId(task.getMerchantTransferId()) | |
| 229 | - .setPayTransferId(task.getDataId()); | |
| 228 | + request = PayTransferNotifyReqDTO.builder().merchantOrderId(task.getMerchantOrderId()) | |
| 229 | + .payTransferId(task.getDataId()).build(); | |
| 230 | 230 | } else { |
| 231 | 231 | throw new RuntimeException("未知的通知任务类型:" + JsonUtils.toJsonString(task)); |
| 232 | 232 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java
| ... | ... | @@ -112,7 +112,7 @@ public class PayTransferServiceImpl implements PayTransferService { |
| 112 | 112 | } |
| 113 | 113 | |
| 114 | 114 | private PayTransferDO validateTransferCanCreate(PayTransferCreateReqDTO reqDTO, Long appId) { |
| 115 | - PayTransferDO transfer = transferMapper.selectByAppIdAndMerchantTransferId(appId, reqDTO.getMerchantTransferId()); | |
| 115 | + PayTransferDO transfer = transferMapper.selectByAppIdAndMerchantOrderId(appId, reqDTO.getMerchantOrderId()); | |
| 116 | 116 | if (transfer != null) { |
| 117 | 117 | // 已经存在,并且状态不为等待状态:说明已经调用渠道转账并返回结果 |
| 118 | 118 | if (!PayTransferStatusEnum.isWaiting(transfer.getStatus())) { | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java
| ... | ... | @@ -122,7 +122,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { |
| 122 | 122 | } |
| 123 | 123 | // 1.2 校验钱包充值是否可以支付 |
| 124 | 124 | if (recharge.getPayStatus()) { |
| 125 | - // 特殊:如果订单已支付,且支付单号相同,直接返回,说明重复回调 | |
| 125 | + // 特殊:支付单号相同,直接返回,说明重复回调 | |
| 126 | 126 | if (ObjectUtil.equals(recharge.getPayOrderId(), payOrderId)) { |
| 127 | 127 | log.warn("[updateWalletRechargerPaid][recharge({}) 已支付,且支付单号相同({}),直接返回]", recharge, payOrderId); |
| 128 | 128 | return; | ... | ... |