Commit 3f410c273577498634b0588f8907eb5d34225b3d
1 parent
1c282bd3
by gateway:
1. 补全 channel 单元测试 2. 完善部分 order 单元测试
Showing
16 changed files
with
489 additions
and
226 deletions
yudao-framework/yudao-spring-boot-starter-test/src/main/java/cn/iocoder/yudao/framework/test/core/util/RandomUtils.java
| ... | ... | @@ -55,6 +55,9 @@ public class RandomUtils { |
| 55 | 55 | } |
| 56 | 56 | return RandomUtil.randomInt(); |
| 57 | 57 | }); |
| 58 | + // LocalDateTime | |
| 59 | + PODAM_FACTORY.getStrategy().addOrReplaceTypeManufacturer(LocalDateTime.class, | |
| 60 | + (dataProviderStrategy, attributeMetadata, map) -> randomLocalDateTime()); | |
| 58 | 61 | // Boolean |
| 59 | 62 | PODAM_FACTORY.getStrategy().addOrReplaceTypeManufacturer(Boolean.class, (dataProviderStrategy, attributeMetadata, map) -> { |
| 60 | 63 | // 如果是 deleted 的字段,返回非删除 |
| ... | ... | @@ -82,7 +85,8 @@ public class RandomUtils { |
| 82 | 85 | } |
| 83 | 86 | |
| 84 | 87 | public static LocalDateTime randomLocalDateTime() { |
| 85 | - return LocalDateTimeUtil.of(randomDate()); | |
| 88 | + // 设置 Nano 为零的原因,避免 MySQL、H2 存储不到时间戳 | |
| 89 | + return LocalDateTimeUtil.of(randomDate()).withNano(0); | |
| 86 | 90 | } |
| 87 | 91 | |
| 88 | 92 | public static Short randomShort() { | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java
| ... | ... | @@ -57,7 +57,7 @@ import java.util.*; |
| 57 | 57 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 58 | 58 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| 59 | 59 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; |
| 60 | -import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_ORDER_NOT_FOUND; | |
| 60 | +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.ORDER_NOT_FOUND; | |
| 61 | 61 | import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; |
| 62 | 62 | |
| 63 | 63 | /** |
| ... | ... | @@ -308,7 +308,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { |
| 308 | 308 | PayOrderRespDTO payOrder = payOrderApi.getOrder(payOrderId); |
| 309 | 309 | if (payOrder == null) { |
| 310 | 310 | log.error("[validateOrderPaid][order({}) payOrder({}) 不存在,请进行处理!]", id, payOrderId); |
| 311 | - throw exception(PAY_ORDER_NOT_FOUND); | |
| 311 | + throw exception(cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.ORDER_NOT_FOUND); | |
| 312 | 312 | } |
| 313 | 313 | // 校验支付单已支付 |
| 314 | 314 | if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) { | ... | ... |
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java
| ... | ... | @@ -10,48 +10,46 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode; |
| 10 | 10 | public interface ErrorCodeConstants { |
| 11 | 11 | |
| 12 | 12 | // ========== APP 模块 1007000000 ========== |
| 13 | - ErrorCode PAY_APP_NOT_FOUND = new ErrorCode(1007000000, "App 不存在"); | |
| 14 | - ErrorCode PAY_APP_IS_DISABLE = new ErrorCode(1007000002, "App 已经被禁用"); | |
| 15 | - ErrorCode PAY_APP_EXIST_ORDER_CANT_DELETE = new ErrorCode(1007000003, "支付应用存在支付订单,无法删除"); | |
| 16 | - ErrorCode PAY_APP_EXIST_REFUND_CANT_DELETE = new ErrorCode(1007000004, "支付应用存在退款订单,无法删除"); | |
| 13 | + ErrorCode APP_NOT_FOUND = new ErrorCode(1007000000, "App 不存在"); | |
| 14 | + ErrorCode APP_IS_DISABLE = new ErrorCode(1007000002, "App 已经被禁用"); | |
| 15 | + ErrorCode APP_EXIST_ORDER_CANT_DELETE = new ErrorCode(1007000003, "支付应用存在支付订单,无法删除"); | |
| 16 | + ErrorCode APP_EXIST_REFUND_CANT_DELETE = new ErrorCode(1007000004, "支付应用存在退款订单,无法删除"); | |
| 17 | 17 | |
| 18 | 18 | // ========== CHANNEL 模块 1007001000 ========== |
| 19 | - ErrorCode PAY_CHANNEL_NOT_FOUND = new ErrorCode(1007001000, "支付渠道的配置不存在"); | |
| 20 | - ErrorCode PAY_CHANNEL_IS_DISABLE = new ErrorCode(1007001001, "支付渠道已经禁用"); | |
| 21 | - ErrorCode PAY_CHANNEL_CLIENT_NOT_FOUND = new ErrorCode(1007001002, "支付渠道的客户端不存在"); | |
| 22 | - ErrorCode CHANNEL_NOT_EXISTS = new ErrorCode(1007001003, "支付渠道不存在"); | |
| 23 | - ErrorCode CHANNEL_EXIST_SAME_CHANNEL_ERROR = new ErrorCode(1007001005, "已存在相同的渠道"); | |
| 19 | + ErrorCode CHANNEL_NOT_FOUND = new ErrorCode(1007001000, "支付渠道的配置不存在"); | |
| 20 | + ErrorCode CHANNEL_IS_DISABLE = new ErrorCode(1007001001, "支付渠道已经禁用"); | |
| 21 | + ErrorCode CHANNEL_EXIST_SAME_CHANNEL_ERROR = new ErrorCode(1007001004, "已存在相同的渠道"); | |
| 24 | 22 | |
| 25 | 23 | // ========== ORDER 模块 1007002000 ========== |
| 26 | - ErrorCode PAY_ORDER_NOT_FOUND = new ErrorCode(1007002000, "支付订单不存在"); | |
| 27 | - ErrorCode PAY_ORDER_STATUS_IS_NOT_WAITING = new ErrorCode(1007002001, "支付订单不处于待支付"); | |
| 28 | - ErrorCode PAY_ORDER_STATUS_IS_NOT_SUCCESS = new ErrorCode(1007002002, "支付订单不处于已支付"); | |
| 29 | - ErrorCode PAY_ORDER_IS_EXPIRED = new ErrorCode(1007002003, "支付订单已经过期"); | |
| 30 | - ErrorCode PAY_ORDER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1007002004, "发起支付报错,错误码:{},错误提示:{}"); | |
| 24 | + ErrorCode ORDER_NOT_FOUND = new ErrorCode(1007002000, "支付订单不存在"); | |
| 25 | + ErrorCode ORDER_STATUS_IS_NOT_WAITING = new ErrorCode(1007002001, "支付订单不处于待支付"); | |
| 26 | + ErrorCode ORDER_STATUS_IS_NOT_SUCCESS = new ErrorCode(1007002002, "支付订单不处于已支付"); | |
| 27 | + ErrorCode ORDER_IS_EXPIRED = new ErrorCode(1007002003, "支付订单已经过期"); | |
| 28 | + ErrorCode ORDER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1007002004, "发起支付报错,错误码:{},错误提示:{}"); | |
| 31 | 29 | |
| 32 | 30 | // ========== ORDER 模块(拓展单) 1007003000 ========== |
| 33 | - ErrorCode PAY_ORDER_EXTENSION_NOT_FOUND = new ErrorCode(1007003000, "支付交易拓展单不存在"); | |
| 34 | - ErrorCode PAY_ORDER_EXTENSION_STATUS_IS_NOT_WAITING = new ErrorCode(1007003001, "支付交易拓展单不处于待支付"); | |
| 31 | + ErrorCode ORDER_EXTENSION_NOT_FOUND = new ErrorCode(1007003000, "支付交易拓展单不存在"); | |
| 32 | + ErrorCode ORDER_EXTENSION_STATUS_IS_NOT_WAITING = new ErrorCode(1007003001, "支付交易拓展单不处于待支付"); | |
| 35 | 33 | |
| 36 | 34 | // ========== 支付模块(退款) 1007006000 ========== |
| 37 | - ErrorCode PAY_REFUND_PRICE_EXCEED = new ErrorCode(1007006000, "退款金额超过订单可退款金额"); | |
| 38 | - ErrorCode PAY_REFUND_ALL_REFUNDED = new ErrorCode(1007006001, "订单已经全额退款"); | |
| 39 | - ErrorCode PAY_REFUND_HAS_REFUNDING = new ErrorCode(1007006002, "已经有退款在处理中"); | |
| 40 | - ErrorCode PAY_REFUND_EXISTS = new ErrorCode(1007006003, "已经存在退款单"); | |
| 41 | - ErrorCode PAY_REFUND_NOT_FOUND = new ErrorCode(1007006004, "支付退款单不存在"); | |
| 42 | - ErrorCode PAY_REFUND_STATUS_IS_NOT_WAITING = new ErrorCode(1007006005, "支付退款单不处于待退款"); | |
| 35 | + ErrorCode REFUND_PRICE_EXCEED = new ErrorCode(1007006000, "退款金额超过订单可退款金额"); | |
| 36 | + ErrorCode REFUND_ALL_REFUNDED = new ErrorCode(1007006001, "订单已经全额退款"); | |
| 37 | + ErrorCode REFUND_HAS_REFUNDING = new ErrorCode(1007006002, "已经有退款在处理中"); | |
| 38 | + ErrorCode REFUND_EXISTS = new ErrorCode(1007006003, "已经存在退款单"); | |
| 39 | + ErrorCode REFUND_NOT_FOUND = new ErrorCode(1007006004, "支付退款单不存在"); | |
| 40 | + ErrorCode REFUND_STATUS_IS_NOT_WAITING = new ErrorCode(1007006005, "支付退款单不处于待退款"); | |
| 43 | 41 | |
| 44 | 42 | // ========== 示例订单 1007900000 ========== |
| 45 | - ErrorCode PAY_DEMO_ORDER_NOT_FOUND = new ErrorCode(1007900000, "示例订单不存在"); | |
| 46 | - ErrorCode PAY_DEMO_ORDER_UPDATE_PAID_STATUS_NOT_UNPAID = new ErrorCode(1007900001, "示例订单更新支付状态失败,订单不是【未支付】状态"); | |
| 47 | - ErrorCode PAY_DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR = new ErrorCode(1007900002, "示例订单更新支付状态失败,支付单编号不匹配"); | |
| 48 | - ErrorCode PAY_DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS = new ErrorCode(1007900003, "示例订单更新支付状态失败,支付单状态不是【支付成功】状态"); | |
| 49 | - ErrorCode PAY_DEMO_ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH = new ErrorCode(1007900004, "示例订单更新支付状态失败,支付单金额不匹配"); | |
| 50 | - ErrorCode PAY_DEMO_ORDER_REFUND_FAIL_NOT_PAID = new ErrorCode(1007900005, "发起退款失败,示例订单未支付"); | |
| 51 | - ErrorCode PAY_DEMO_ORDER_REFUND_FAIL_REFUNDED = new ErrorCode(1007900006, "发起退款失败,示例订单已退款"); | |
| 52 | - ErrorCode PAY_DEMO_ORDER_REFUND_FAIL_REFUND_NOT_FOUND = new ErrorCode(1007900007, "发起退款失败,退款订单不存在"); | |
| 53 | - ErrorCode PAY_DEMO_ORDER_REFUND_FAIL_REFUND_NOT_SUCCESS = new ErrorCode(1007900008, "发起退款失败,退款订单未退款成功"); | |
| 54 | - ErrorCode PAY_DEMO_ORDER_REFUND_FAIL_REFUND_ORDER_ID_ERROR = new ErrorCode(1007900009, "发起退款失败,退款单编号不匹配"); | |
| 55 | - ErrorCode PAY_DEMO_ORDER_REFUND_FAIL_REFUND_PRICE_NOT_MATCH = new ErrorCode(1007900010, "发起退款失败,退款单金额不匹配"); | |
| 43 | + ErrorCode DEMO_ORDER_NOT_FOUND = new ErrorCode(1007900000, "示例订单不存在"); | |
| 44 | + ErrorCode DEMO_ORDER_UPDATE_PAID_STATUS_NOT_UNPAID = new ErrorCode(1007900001, "示例订单更新支付状态失败,订单不是【未支付】状态"); | |
| 45 | + ErrorCode DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR = new ErrorCode(1007900002, "示例订单更新支付状态失败,支付单编号不匹配"); | |
| 46 | + ErrorCode DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS = new ErrorCode(1007900003, "示例订单更新支付状态失败,支付单状态不是【支付成功】状态"); | |
| 47 | + ErrorCode DEMO_ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH = new ErrorCode(1007900004, "示例订单更新支付状态失败,支付单金额不匹配"); | |
| 48 | + ErrorCode DEMO_ORDER_REFUND_FAIL_NOT_PAID = new ErrorCode(1007900005, "发起退款失败,示例订单未支付"); | |
| 49 | + ErrorCode DEMO_ORDER_REFUND_FAIL_REFUNDED = new ErrorCode(1007900006, "发起退款失败,示例订单已退款"); | |
| 50 | + ErrorCode DEMO_ORDER_REFUND_FAIL_REFUND_NOT_FOUND = new ErrorCode(1007900007, "发起退款失败,退款订单不存在"); | |
| 51 | + ErrorCode DEMO_ORDER_REFUND_FAIL_REFUND_NOT_SUCCESS = new ErrorCode(1007900008, "发起退款失败,退款订单未退款成功"); | |
| 52 | + ErrorCode DEMO_ORDER_REFUND_FAIL_REFUND_ORDER_ID_ERROR = new ErrorCode(1007900009, "发起退款失败,退款单编号不匹配"); | |
| 53 | + ErrorCode DEMO_ORDER_REFUND_FAIL_REFUND_PRICE_NOT_MATCH = new ErrorCode(1007900010, "发起退款失败,退款单金额不匹配"); | |
| 56 | 54 | |
| 57 | 55 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java
| ... | ... | @@ -17,8 +17,7 @@ import javax.annotation.Resource; |
| 17 | 17 | import javax.annotation.security.PermitAll; |
| 18 | 18 | import java.util.Map; |
| 19 | 19 | |
| 20 | -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 21 | -import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_CHANNEL_CLIENT_NOT_FOUND; | |
| 20 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_NOT_FOUND; | |
| 22 | 21 | |
| 23 | 22 | @Tag(name = "管理后台 - 支付通知") |
| 24 | 23 | @RestController |
| ... | ... | @@ -47,7 +46,7 @@ public class PayNotifyController { |
| 47 | 46 | PayClient payClient = payClientFactory.getPayClient(channelId); |
| 48 | 47 | if (payClient == null) { |
| 49 | 48 | log.error("[notifyCallback][渠道编号({}) 找不到对应的支付客户端]", channelId); |
| 50 | - throw exception(PAY_CHANNEL_CLIENT_NOT_FOUND); | |
| 49 | + throw exception(CHANNEL_NOT_FOUND); | |
| 51 | 50 | } |
| 52 | 51 | |
| 53 | 52 | // 2. 解析通知数据 |
| ... | ... | @@ -68,7 +67,7 @@ public class PayNotifyController { |
| 68 | 67 | PayClient payClient = payClientFactory.getPayClient(channelId); |
| 69 | 68 | if (payClient == null) { |
| 70 | 69 | log.error("[notifyCallback][渠道编号({}) 找不到对应的支付客户端]", channelId); |
| 71 | - throw exception(PAY_CHANNEL_CLIENT_NOT_FOUND); | |
| 70 | + throw exception(CHANNEL_NOT_FOUND); | |
| 72 | 71 | } |
| 73 | 72 | |
| 74 | 73 | // 2. 解析通知数据 | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/order/PayOrderExtensionDO.java
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderMapper.java
| ... | ... | @@ -44,12 +44,6 @@ public interface PayOrderMapper extends BaseMapperX<PayOrderDO> { |
| 44 | 44 | .orderByDesc("id")); |
| 45 | 45 | } |
| 46 | 46 | |
| 47 | - default List<PayOrderDO> findByIdListQueryOrderSubject(Collection<Long> idList) { | |
| 48 | - return selectList(new LambdaQueryWrapper<PayOrderDO>() | |
| 49 | - .select(PayOrderDO::getId, PayOrderDO::getSubject) | |
| 50 | - .in(PayOrderDO::getId, idList)); | |
| 51 | - } | |
| 52 | - | |
| 53 | 47 | default Long selectCountByAppId(Long appId) { |
| 54 | 48 | return selectCount(PayOrderDO::getAppId, appId); |
| 55 | 49 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/app/PayAppServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.pay.service.app; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 4 | -import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; | |
| 5 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | 5 | import cn.iocoder.yudao.module.pay.controller.admin.app.vo.PayAppCreateReqVO; |
| 7 | 6 | import cn.iocoder.yudao.module.pay.controller.admin.app.vo.PayAppPageReqVO; |
| ... | ... | @@ -9,10 +8,7 @@ import cn.iocoder.yudao.module.pay.controller.admin.app.vo.PayAppUpdateReqVO; |
| 9 | 8 | import cn.iocoder.yudao.module.pay.convert.app.PayAppConvert; |
| 10 | 9 | import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; |
| 11 | 10 | import cn.iocoder.yudao.module.pay.dal.mysql.app.PayAppMapper; |
| 12 | -import cn.iocoder.yudao.module.pay.dal.mysql.refund.PayRefundMapper; | |
| 13 | 11 | import cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants; |
| 14 | -import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; | |
| 15 | -import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum; | |
| 16 | 12 | import cn.iocoder.yudao.module.pay.service.order.PayOrderService; |
| 17 | 13 | import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; |
| 18 | 14 | import org.springframework.context.annotation.Lazy; |
| ... | ... | @@ -77,10 +73,10 @@ public class PayAppServiceImpl implements PayAppService { |
| 77 | 73 | validateAppExists(id); |
| 78 | 74 | // 校验关联数据是否存在 |
| 79 | 75 | if (orderService.getOrderCountByAppId(id) > 0) { |
| 80 | - throw exception(PAY_APP_EXIST_ORDER_CANT_DELETE); | |
| 76 | + throw exception(APP_EXIST_ORDER_CANT_DELETE); | |
| 81 | 77 | } |
| 82 | 78 | if (refundService.getRefundCountByAppId(id) > 0) { |
| 83 | - throw exception(PAY_APP_EXIST_REFUND_CANT_DELETE); | |
| 79 | + throw exception(APP_EXIST_REFUND_CANT_DELETE); | |
| 84 | 80 | } |
| 85 | 81 | |
| 86 | 82 | // 删除 |
| ... | ... | @@ -89,7 +85,7 @@ public class PayAppServiceImpl implements PayAppService { |
| 89 | 85 | |
| 90 | 86 | private void validateAppExists(Long id) { |
| 91 | 87 | if (appMapper.selectById(id) == null) { |
| 92 | - throw exception(PAY_APP_NOT_FOUND); | |
| 88 | + throw exception(APP_NOT_FOUND); | |
| 93 | 89 | } |
| 94 | 90 | } |
| 95 | 91 | |
| ... | ... | @@ -113,11 +109,11 @@ public class PayAppServiceImpl implements PayAppService { |
| 113 | 109 | PayAppDO app = appMapper.selectById(id); |
| 114 | 110 | // 校验是否存在 |
| 115 | 111 | if (app == null) { |
| 116 | - throw exception(ErrorCodeConstants.PAY_APP_NOT_FOUND); | |
| 112 | + throw exception(ErrorCodeConstants.APP_NOT_FOUND); | |
| 117 | 113 | } |
| 118 | 114 | // 校验是否禁用 |
| 119 | 115 | if (CommonStatusEnum.DISABLE.getStatus().equals(app.getStatus())) { |
| 120 | - throw exception(ErrorCodeConstants.PAY_APP_IS_DISABLE); | |
| 116 | + throw exception(ErrorCodeConstants.APP_IS_DISABLE); | |
| 121 | 117 | } |
| 122 | 118 | return app; |
| 123 | 119 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceImpl.java
| ... | ... | @@ -32,8 +32,7 @@ import java.util.List; |
| 32 | 32 | import java.util.concurrent.TimeUnit; |
| 33 | 33 | |
| 34 | 34 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 35 | -import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_EXIST_SAME_CHANNEL_ERROR; | |
| 36 | -import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_NOT_EXISTS; | |
| 35 | +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; | |
| 37 | 36 | |
| 38 | 37 | /** |
| 39 | 38 | * 支付渠道 Service 实现类 |
| ... | ... | @@ -142,7 +141,7 @@ public class PayChannelServiceImpl implements PayChannelService { |
| 142 | 141 | // 解析配置 |
| 143 | 142 | Class<? extends PayClientConfig> payClass = PayChannelEnum.getByCode(code).getConfigClass(); |
| 144 | 143 | if (ObjectUtil.isNull(payClass)) { |
| 145 | - throw exception(CHANNEL_NOT_EXISTS); | |
| 144 | + throw exception(CHANNEL_NOT_FOUND); | |
| 146 | 145 | } |
| 147 | 146 | PayClientConfig config = JsonUtils.parseObject2(configStr, payClass); |
| 148 | 147 | Assert.notNull(config); |
| ... | ... | @@ -167,7 +166,7 @@ public class PayChannelServiceImpl implements PayChannelService { |
| 167 | 166 | private PayChannelDO validateChannelExists(Long id) { |
| 168 | 167 | PayChannelDO channel = channelMapper.selectById(id); |
| 169 | 168 | if (channel == null) { |
| 170 | - throw exception(CHANNEL_NOT_EXISTS); | |
| 169 | + throw exception(CHANNEL_NOT_FOUND); | |
| 171 | 170 | } |
| 172 | 171 | return channel; |
| 173 | 172 | } |
| ... | ... | @@ -203,10 +202,10 @@ public class PayChannelServiceImpl implements PayChannelService { |
| 203 | 202 | |
| 204 | 203 | private void validPayChannel(PayChannelDO channel) { |
| 205 | 204 | if (channel == null) { |
| 206 | - throw exception(ErrorCodeConstants.PAY_CHANNEL_NOT_FOUND); | |
| 205 | + throw exception(CHANNEL_NOT_FOUND); | |
| 207 | 206 | } |
| 208 | 207 | if (CommonStatusEnum.DISABLE.getStatus().equals(channel.getStatus())) { |
| 209 | - throw exception(ErrorCodeConstants.PAY_CHANNEL_IS_DISABLE); | |
| 208 | + throw exception(CHANNEL_IS_DISABLE); | |
| 210 | 209 | } |
| 211 | 210 | } |
| 212 | 211 | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java
| ... | ... | @@ -119,7 +119,7 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { |
| 119 | 119 | new PayDemoOrderDO().setPayStatus(true).setPayTime(LocalDateTime.now()) |
| 120 | 120 | .setPayChannelCode(payOrder.getChannelCode())); |
| 121 | 121 | if (updateCount == 0) { |
| 122 | - throw exception(PAY_DEMO_ORDER_UPDATE_PAID_STATUS_NOT_UNPAID); | |
| 122 | + throw exception(DEMO_ORDER_UPDATE_PAID_STATUS_NOT_UNPAID); | |
| 123 | 123 | } |
| 124 | 124 | } |
| 125 | 125 | |
| ... | ... | @@ -137,44 +137,44 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { |
| 137 | 137 | // 1.1 校验订单是否存在 |
| 138 | 138 | PayDemoOrderDO order = payDemoOrderMapper.selectById(id); |
| 139 | 139 | if (order == null) { |
| 140 | - throw exception(PAY_DEMO_ORDER_NOT_FOUND); | |
| 140 | + throw exception(DEMO_ORDER_NOT_FOUND); | |
| 141 | 141 | } |
| 142 | 142 | // 1.2 校验订单未支付 |
| 143 | 143 | if (order.getPayStatus()) { |
| 144 | 144 | log.error("[validateDemoOrderCanPaid][order({}) 不处于待支付状态,请进行处理!order 数据是:{}]", |
| 145 | 145 | id, toJsonString(order)); |
| 146 | - throw exception(PAY_DEMO_ORDER_UPDATE_PAID_STATUS_NOT_UNPAID); | |
| 146 | + throw exception(DEMO_ORDER_UPDATE_PAID_STATUS_NOT_UNPAID); | |
| 147 | 147 | } |
| 148 | 148 | // 1.3 校验支付订单匹配 |
| 149 | 149 | if (notEqual(order.getPayOrderId(), payOrderId)) { // 支付单号 |
| 150 | 150 | log.error("[validateDemoOrderCanPaid][order({}) 支付单不匹配({}),请进行处理!order 数据是:{}]", |
| 151 | 151 | id, payOrderId, toJsonString(order)); |
| 152 | - throw exception(PAY_DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR); | |
| 152 | + throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR); | |
| 153 | 153 | } |
| 154 | 154 | |
| 155 | 155 | // 2.1 校验支付单是否存在 |
| 156 | 156 | PayOrderRespDTO payOrder = payOrderApi.getOrder(payOrderId); |
| 157 | 157 | if (payOrder == null) { |
| 158 | 158 | log.error("[validateDemoOrderCanPaid][order({}) payOrder({}) 不存在,请进行处理!]", id, payOrderId); |
| 159 | - throw exception(PAY_ORDER_NOT_FOUND); | |
| 159 | + throw exception(ORDER_NOT_FOUND); | |
| 160 | 160 | } |
| 161 | 161 | // 2.2 校验支付单已支付 |
| 162 | 162 | if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) { |
| 163 | 163 | log.error("[validateDemoOrderCanPaid][order({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]", |
| 164 | 164 | id, payOrderId, toJsonString(payOrder)); |
| 165 | - throw exception(PAY_DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS); | |
| 165 | + throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS); | |
| 166 | 166 | } |
| 167 | 167 | // 2.3 校验支付金额一致 |
| 168 | 168 | if (notEqual(payOrder.getPrice(), order.getPrice())) { |
| 169 | 169 | log.error("[validateDemoOrderCanPaid][order({}) payOrder({}) 支付金额不匹配,请进行处理!order 数据是:{},payOrder 数据是:{}]", |
| 170 | 170 | id, payOrderId, toJsonString(order), toJsonString(payOrder)); |
| 171 | - throw exception(PAY_DEMO_ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH); | |
| 171 | + throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH); | |
| 172 | 172 | } |
| 173 | 173 | // 2.4 校验支付订单匹配(二次) |
| 174 | 174 | if (notEqual(payOrder.getMerchantOrderId(), id.toString())) { |
| 175 | 175 | log.error("[validateDemoOrderCanPaid][order({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]", |
| 176 | 176 | id, payOrderId, toJsonString(payOrder)); |
| 177 | - throw exception(PAY_DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR); | |
| 177 | + throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR); | |
| 178 | 178 | } |
| 179 | 179 | return payOrder; |
| 180 | 180 | } |
| ... | ... | @@ -203,15 +203,15 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { |
| 203 | 203 | // 校验订单是否存在 |
| 204 | 204 | PayDemoOrderDO order = payDemoOrderMapper.selectById(id); |
| 205 | 205 | if (order == null) { |
| 206 | - throw exception(PAY_DEMO_ORDER_NOT_FOUND); | |
| 206 | + throw exception(DEMO_ORDER_NOT_FOUND); | |
| 207 | 207 | } |
| 208 | 208 | // 校验订单是否支付 |
| 209 | 209 | if (!order.getPayStatus()) { |
| 210 | - throw exception(PAY_DEMO_ORDER_REFUND_FAIL_NOT_PAID); | |
| 210 | + throw exception(DEMO_ORDER_REFUND_FAIL_NOT_PAID); | |
| 211 | 211 | } |
| 212 | 212 | // 校验订单是否已退款 |
| 213 | 213 | if (order.getPayRefundId() != null) { |
| 214 | - throw exception(PAY_DEMO_ORDER_REFUND_FAIL_REFUNDED); | |
| 214 | + throw exception(DEMO_ORDER_REFUND_FAIL_REFUNDED); | |
| 215 | 215 | } |
| 216 | 216 | return order; |
| 217 | 217 | } |
| ... | ... | @@ -229,35 +229,35 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { |
| 229 | 229 | // 1.1 校验示例订单 |
| 230 | 230 | PayDemoOrderDO order = payDemoOrderMapper.selectById(id); |
| 231 | 231 | if (order == null) { |
| 232 | - throw exception(PAY_DEMO_ORDER_NOT_FOUND); | |
| 232 | + throw exception(DEMO_ORDER_NOT_FOUND); | |
| 233 | 233 | } |
| 234 | 234 | // 1.2 校验退款订单匹配 |
| 235 | 235 | if (Objects.equals(order.getPayOrderId(), payRefundId)) { |
| 236 | 236 | log.error("[validateDemoOrderCanRefunded][order({}) 退款单不匹配({}),请进行处理!order 数据是:{}]", |
| 237 | 237 | id, payRefundId, toJsonString(order)); |
| 238 | - throw exception(PAY_DEMO_ORDER_REFUND_FAIL_REFUND_ORDER_ID_ERROR); | |
| 238 | + throw exception(DEMO_ORDER_REFUND_FAIL_REFUND_ORDER_ID_ERROR); | |
| 239 | 239 | } |
| 240 | 240 | |
| 241 | 241 | // 2.1 校验退款订单 |
| 242 | 242 | PayRefundRespDTO payRefund = payRefundApi.getRefund(payRefundId); |
| 243 | 243 | if (payRefund == null) { |
| 244 | - throw exception(PAY_DEMO_ORDER_REFUND_FAIL_REFUND_NOT_FOUND); | |
| 244 | + throw exception(DEMO_ORDER_REFUND_FAIL_REFUND_NOT_FOUND); | |
| 245 | 245 | } |
| 246 | 246 | // 2.2 |
| 247 | 247 | if (!PayRefundStatusEnum.isSuccess(payRefund.getStatus())) { |
| 248 | - throw exception(PAY_DEMO_ORDER_REFUND_FAIL_REFUND_NOT_SUCCESS); | |
| 248 | + throw exception(DEMO_ORDER_REFUND_FAIL_REFUND_NOT_SUCCESS); | |
| 249 | 249 | } |
| 250 | 250 | // 2.3 校验退款金额一致 |
| 251 | 251 | if (notEqual(payRefund.getRefundPrice(), order.getPrice())) { |
| 252 | 252 | log.error("[validateDemoOrderCanRefunded][order({}) payRefund({}) 退款金额不匹配,请进行处理!order 数据是:{},payRefund 数据是:{}]", |
| 253 | 253 | id, payRefundId, toJsonString(order), toJsonString(payRefund)); |
| 254 | - throw exception(PAY_DEMO_ORDER_REFUND_FAIL_REFUND_PRICE_NOT_MATCH); | |
| 254 | + throw exception(DEMO_ORDER_REFUND_FAIL_REFUND_PRICE_NOT_MATCH); | |
| 255 | 255 | } |
| 256 | 256 | // 2.4 校验退款订单匹配(二次) |
| 257 | 257 | if (notEqual(payRefund.getMerchantOrderId(), id.toString())) { |
| 258 | 258 | log.error("[validateDemoOrderCanRefunded][order({}) 退款单不匹配({}),请进行处理!payRefund 数据是:{}]", |
| 259 | 259 | id, payRefundId, toJsonString(payRefund)); |
| 260 | - throw exception(PAY_DEMO_ORDER_REFUND_FAIL_REFUND_ORDER_ID_ERROR); | |
| 260 | + throw exception(DEMO_ORDER_REFUND_FAIL_REFUND_ORDER_ID_ERROR); | |
| 261 | 261 | } |
| 262 | 262 | return payRefund; |
| 263 | 263 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java
| ... | ... | @@ -49,41 +49,37 @@ public interface PayOrderService { |
| 49 | 49 | Long getOrderCountByAppId(Long appId); |
| 50 | 50 | |
| 51 | 51 | /** |
| 52 | - * 获得支付订单 | |
| 53 | - * 分页 | |
| 52 | + * 获得支付订单分页 | |
| 54 | 53 | * |
| 55 | 54 | * @param pageReqVO 分页查询 |
| 56 | - * @return 支付订单 | |
| 57 | - * 分页 | |
| 55 | + * @return 支付订单分页 | |
| 58 | 56 | */ |
| 59 | 57 | PageResult<PayOrderDO> getOrderPage(PayOrderPageReqVO pageReqVO); |
| 60 | 58 | |
| 61 | 59 | /** |
| 62 | - * 获得支付订单 | |
| 63 | - * 列表, 用于 Excel 导出 | |
| 60 | + * 获得支付订单列表, 用于 Excel 导出 | |
| 64 | 61 | * |
| 65 | 62 | * @param exportReqVO 查询条件 |
| 66 | - * @return 支付订单 | |
| 67 | - * 列表 | |
| 63 | + * @return 支付订单列表 | |
| 68 | 64 | */ |
| 69 | 65 | List<PayOrderDO> getOrderList(PayOrderExportReqVO exportReqVO); |
| 70 | 66 | |
| 71 | 67 | /** |
| 72 | - * 根据 ID 集合获取只包含商品名称的订单集合 | |
| 68 | + * 获得支付订单列表 | |
| 73 | 69 | * |
| 74 | - * @param idList 订单 ID 集合 | |
| 75 | - * @return 只包含商品名称的订单集合 | |
| 70 | + * @param ids 订单 ID 集合 | |
| 71 | + * @return 支付订单列表 | |
| 76 | 72 | */ |
| 77 | - List<PayOrderDO> getOrderSubjectList(Collection<Long> idList); | |
| 73 | + List<PayOrderDO> getOrderList(Collection<Long> ids); | |
| 78 | 74 | |
| 79 | 75 | /** |
| 80 | - * 根据订单 ID 集合获取订单商品名称Map集合 | |
| 76 | + * 获得支付订单 Map | |
| 81 | 77 | * |
| 82 | 78 | * @param ids 订单 ID 集合 |
| 83 | - * @return 订单商品 map 集合 | |
| 79 | + * @return 支付订单 Map 集合 | |
| 84 | 80 | */ |
| 85 | 81 | default Map<Long, PayOrderDO> getOrderSubjectMap(Collection<Long> ids) { |
| 86 | - List<PayOrderDO> list = getOrderSubjectList(ids); | |
| 82 | + List<PayOrderDO> list = getOrderList(ids); | |
| 87 | 83 | return CollectionUtils.convertMap(list, PayOrderDO::getId); |
| 88 | 84 | } |
| 89 | 85 | |
| ... | ... | @@ -122,4 +118,4 @@ public interface PayOrderService { |
| 122 | 118 | */ |
| 123 | 119 | void updateOrderRefundPrice(Long id, Integer incrRefundPrice); |
| 124 | 120 | |
| 125 | 121 | -} |
| 122 | +} | |
| 126 | 123 | \ No newline at end of file | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java
| ... | ... | @@ -102,10 +102,9 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 102 | 102 | return orderMapper.selectList(exportReqVO); |
| 103 | 103 | } |
| 104 | 104 | |
| 105 | - // TODO @艿艿:需要优化。不确定这个方法的作用 | |
| 106 | 105 | @Override |
| 107 | - public List<PayOrderDO> getOrderSubjectList(Collection<Long> idList) { | |
| 108 | - return orderMapper.findByIdListQueryOrderSubject(idList); | |
| 106 | + public List<PayOrderDO> getOrderList(Collection<Long> ids) { | |
| 107 | + return orderMapper.selectBatchIds(ids); | |
| 109 | 108 | } |
| 110 | 109 | |
| 111 | 110 | @Override |
| ... | ... | @@ -165,7 +164,7 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 165 | 164 | notifyPayOrder(channel, unifiedOrderResp); |
| 166 | 165 | // 如有渠道错误码,则抛出业务异常,提示用户 |
| 167 | 166 | if (StrUtil.isNotEmpty(unifiedOrderResp.getChannelErrorCode())) { |
| 168 | - throw exception(PAY_ORDER_SUBMIT_CHANNEL_ERROR, unifiedOrderResp.getChannelErrorCode(), | |
| 167 | + throw exception(ORDER_SUBMIT_CHANNEL_ERROR, unifiedOrderResp.getChannelErrorCode(), | |
| 169 | 168 | unifiedOrderResp.getChannelErrorMsg()); |
| 170 | 169 | } |
| 171 | 170 | // 此处需要读取最新的状态 |
| ... | ... | @@ -177,13 +176,13 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 177 | 176 | private PayOrderDO validateOrderCanSubmit(Long id) { |
| 178 | 177 | PayOrderDO order = orderMapper.selectById(id); |
| 179 | 178 | if (order == null) { // 是否存在 |
| 180 | - throw exception(PAY_ORDER_NOT_FOUND); | |
| 179 | + throw exception(ORDER_NOT_FOUND); | |
| 181 | 180 | } |
| 182 | 181 | if (!PayOrderStatusEnum.WAITING.getStatus().equals(order.getStatus())) { // 校验状态,必须是待支付 |
| 183 | - throw exception(PAY_ORDER_STATUS_IS_NOT_WAITING); | |
| 182 | + throw exception(ORDER_STATUS_IS_NOT_WAITING); | |
| 184 | 183 | } |
| 185 | 184 | if (LocalDateTimeUtils.beforeNow(order.getExpireTime())) { // 校验是否过期 |
| 186 | - throw exception(PAY_ORDER_IS_EXPIRED); | |
| 185 | + throw exception(ORDER_IS_EXPIRED); | |
| 187 | 186 | } |
| 188 | 187 | return order; |
| 189 | 188 | } |
| ... | ... | @@ -196,7 +195,7 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 196 | 195 | PayClient client = payClientFactory.getPayClient(channel.getId()); |
| 197 | 196 | if (client == null) { |
| 198 | 197 | log.error("[validatePayChannelCanSubmit][渠道编号({}) 找不到对应的支付客户端]", channel.getId()); |
| 199 | - throw exception(PAY_CHANNEL_CLIENT_NOT_FOUND); | |
| 198 | + throw exception(CHANNEL_NOT_FOUND); | |
| 200 | 199 | } |
| 201 | 200 | return channel; |
| 202 | 201 | } |
| ... | ... | @@ -238,33 +237,6 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 238 | 237 | TenantUtils.execute(channel.getTenantId(), () -> notifyPayOrder(channel, notify)); |
| 239 | 238 | } |
| 240 | 239 | |
| 241 | - @Override | |
| 242 | - public void updateOrderRefundPrice(Long id, Integer incrRefundPrice) { | |
| 243 | - PayOrderDO order = orderMapper.selectById(id); | |
| 244 | - if (order == null) { | |
| 245 | - throw exception(PAY_ORDER_NOT_FOUND); | |
| 246 | - } | |
| 247 | - if (!PayOrderStatusEnum.isSuccess(order.getStatus())) { | |
| 248 | - throw exception(PAY_REFUND_PRICE_EXCEED); | |
| 249 | - } | |
| 250 | - if (order.getRefundPrice() + incrRefundPrice > order.getPrice()) { | |
| 251 | - throw exception(PAY_REFUND_PRICE_EXCEED); | |
| 252 | - } | |
| 253 | - | |
| 254 | - // 更新订单 | |
| 255 | - PayOrderDO updateObj = new PayOrderDO() | |
| 256 | - .setRefundPrice(order.getRefundPrice() + incrRefundPrice) | |
| 257 | - .setRefundTimes(order.getRefundTimes() + 1); | |
| 258 | - if (Objects.equals(updateObj.getRefundPrice(), order.getPrice())) { | |
| 259 | - updateObj.setStatus(PayOrderStatusEnum.CLOSED.getStatus()) | |
| 260 | - .setRefundStatus(PayOrderRefundStatusEnum.ALL.getStatus()); | |
| 261 | - } else { | |
| 262 | - updateObj.setStatus(PayOrderStatusEnum.CLOSED.getStatus()) | |
| 263 | - .setRefundStatus(PayOrderRefundStatusEnum.PART.getStatus()); | |
| 264 | - } | |
| 265 | - orderMapper.updateByIdAndStatus(id, PayOrderStatusEnum.SUCCESS.getStatus(), updateObj); | |
| 266 | - } | |
| 267 | - | |
| 268 | 240 | private void notifyPayOrder(PayChannelDO channel, PayOrderRespDTO notify) { |
| 269 | 241 | // 情况一:支付成功的回调 |
| 270 | 242 | if (PayOrderStatusRespEnum.isSuccess(notify.getStatus())) { |
| ... | ... | @@ -301,21 +273,21 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 301 | 273 | // 1. 查询 PayOrderExtensionDO |
| 302 | 274 | PayOrderExtensionDO orderExtension = orderExtensionMapper.selectByNo(notify.getOutTradeNo()); |
| 303 | 275 | if (orderExtension == null) { |
| 304 | - throw exception(PAY_ORDER_EXTENSION_NOT_FOUND); | |
| 276 | + throw exception(ORDER_EXTENSION_NOT_FOUND); | |
| 305 | 277 | } |
| 306 | 278 | if (PayOrderStatusEnum.isSuccess(orderExtension.getStatus())) { // 如果已经是成功,直接返回,不用重复更新 |
| 307 | 279 | log.info("[updateOrderExtensionSuccess][支付拓展单({}) 已经是已支付,无需更新]", orderExtension.getId()); |
| 308 | 280 | return orderExtension; |
| 309 | 281 | } |
| 310 | 282 | if (ObjectUtil.notEqual(orderExtension.getStatus(), PayOrderStatusEnum.WAITING.getStatus())) { // 校验状态,必须是待支付 |
| 311 | - throw exception(PAY_ORDER_EXTENSION_STATUS_IS_NOT_WAITING); | |
| 283 | + throw exception(ORDER_EXTENSION_STATUS_IS_NOT_WAITING); | |
| 312 | 284 | } |
| 313 | 285 | |
| 314 | 286 | // 2. 更新 PayOrderExtensionDO |
| 315 | 287 | int updateCounts = orderExtensionMapper.updateByIdAndStatus(orderExtension.getId(), orderExtension.getStatus(), |
| 316 | 288 | PayOrderExtensionDO.builder().status(PayOrderStatusEnum.SUCCESS.getStatus()).channelNotifyData(toJsonString(notify)).build()); |
| 317 | 289 | if (updateCounts == 0) { // 校验状态,必须是待支付 |
| 318 | - throw exception(PAY_ORDER_EXTENSION_STATUS_IS_NOT_WAITING); | |
| 290 | + throw exception(ORDER_EXTENSION_STATUS_IS_NOT_WAITING); | |
| 319 | 291 | } |
| 320 | 292 | log.info("[updateOrderExtensionSuccess][支付拓展单({}) 更新为已支付]", orderExtension.getId()); |
| 321 | 293 | return orderExtension; |
| ... | ... | @@ -335,7 +307,7 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 335 | 307 | // 1. 判断 PayOrderDO 是否处于待支付 |
| 336 | 308 | PayOrderDO order = orderMapper.selectById(orderExtension.getOrderId()); |
| 337 | 309 | if (order == null) { |
| 338 | - throw exception(PAY_ORDER_NOT_FOUND); | |
| 310 | + throw exception(ORDER_NOT_FOUND); | |
| 339 | 311 | } |
| 340 | 312 | if (PayOrderStatusEnum.isSuccess(order.getStatus()) // 如果已经是成功,直接返回,不用重复更新 |
| 341 | 313 | && Objects.equals(order.getSuccessExtensionId(), orderExtension.getId())) { |
| ... | ... | @@ -343,7 +315,7 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 343 | 315 | return Pair.of(true, order); |
| 344 | 316 | } |
| 345 | 317 | if (!PayOrderStatusEnum.WAITING.getStatus().equals(order.getStatus())) { // 校验状态,必须是待支付 |
| 346 | - throw exception(PAY_ORDER_STATUS_IS_NOT_WAITING); | |
| 318 | + throw exception(ORDER_STATUS_IS_NOT_WAITING); | |
| 347 | 319 | } |
| 348 | 320 | |
| 349 | 321 | // 2. 更新 PayOrderDO |
| ... | ... | @@ -354,7 +326,7 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 354 | 326 | .channelOrderNo(notify.getChannelOrderNo()).channelUserId(notify.getChannelUserId()) |
| 355 | 327 | .notifyTime(LocalDateTime.now()).build()); |
| 356 | 328 | if (updateCounts == 0) { // 校验状态,必须是待支付 |
| 357 | - throw exception(PAY_ORDER_STATUS_IS_NOT_WAITING); | |
| 329 | + throw exception(ORDER_STATUS_IS_NOT_WAITING); | |
| 358 | 330 | } |
| 359 | 331 | log.info("[updateOrderExtensionSuccess][支付订单({}) 更新为已支付]", order.getId()); |
| 360 | 332 | return Pair.of(false, order); |
| ... | ... | @@ -368,7 +340,7 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 368 | 340 | // 1. 查询 PayOrderExtensionDO |
| 369 | 341 | PayOrderExtensionDO orderExtension = orderExtensionMapper.selectByNo(notify.getOutTradeNo()); |
| 370 | 342 | if (orderExtension == null) { |
| 371 | - throw exception(PAY_ORDER_EXTENSION_NOT_FOUND); | |
| 343 | + throw exception(ORDER_EXTENSION_NOT_FOUND); | |
| 372 | 344 | } |
| 373 | 345 | if (PayOrderStatusEnum.isClosed(orderExtension.getStatus())) { // 如果已经是关闭,直接返回,不用重复更新 |
| 374 | 346 | log.info("[updateOrderExtensionClosed][支付拓展单({}) 已经是支付关闭,无需更新]", orderExtension.getId()); |
| ... | ... | @@ -380,7 +352,7 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 380 | 352 | return; |
| 381 | 353 | } |
| 382 | 354 | if (ObjectUtil.notEqual(orderExtension.getStatus(), PayOrderStatusEnum.WAITING.getStatus())) { // 校验状态,必须是待支付 |
| 383 | - throw exception(PAY_ORDER_EXTENSION_STATUS_IS_NOT_WAITING); | |
| 355 | + throw exception(ORDER_EXTENSION_STATUS_IS_NOT_WAITING); | |
| 384 | 356 | } |
| 385 | 357 | |
| 386 | 358 | // 2. 更新 PayOrderExtensionDO |
| ... | ... | @@ -388,9 +360,36 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 388 | 360 | PayOrderExtensionDO.builder().status(PayOrderStatusEnum.CLOSED.getStatus()).channelNotifyData(toJsonString(notify)) |
| 389 | 361 | .channelErrorCode(notify.getChannelErrorCode()).channelErrorMsg(notify.getChannelErrorMsg()).build()); |
| 390 | 362 | if (updateCounts == 0) { // 校验状态,必须是待支付 |
| 391 | - throw exception(PAY_ORDER_EXTENSION_STATUS_IS_NOT_WAITING); | |
| 363 | + throw exception(ORDER_EXTENSION_STATUS_IS_NOT_WAITING); | |
| 392 | 364 | } |
| 393 | 365 | log.info("[updateOrderExtensionClosed][支付拓展单({}) 更新为支付关闭]", orderExtension.getId()); |
| 394 | 366 | } |
| 395 | 367 | |
| 368 | + @Override | |
| 369 | + public void updateOrderRefundPrice(Long id, Integer incrRefundPrice) { | |
| 370 | + PayOrderDO order = orderMapper.selectById(id); | |
| 371 | + if (order == null) { | |
| 372 | + throw exception(ORDER_NOT_FOUND); | |
| 373 | + } | |
| 374 | + if (!PayOrderStatusEnum.isSuccess(order.getStatus())) { | |
| 375 | + throw exception(REFUND_PRICE_EXCEED); | |
| 376 | + } | |
| 377 | + if (order.getRefundPrice() + incrRefundPrice > order.getPrice()) { | |
| 378 | + throw exception(REFUND_PRICE_EXCEED); | |
| 379 | + } | |
| 380 | + | |
| 381 | + // 更新订单 | |
| 382 | + PayOrderDO updateObj = new PayOrderDO() | |
| 383 | + .setRefundPrice(order.getRefundPrice() + incrRefundPrice) | |
| 384 | + .setRefundTimes(order.getRefundTimes() + 1); | |
| 385 | + if (Objects.equals(updateObj.getRefundPrice(), order.getPrice())) { | |
| 386 | + updateObj.setStatus(PayOrderStatusEnum.CLOSED.getStatus()) | |
| 387 | + .setRefundStatus(PayOrderRefundStatusEnum.ALL.getStatus()); | |
| 388 | + } else { | |
| 389 | + updateObj.setStatus(PayOrderStatusEnum.CLOSED.getStatus()) | |
| 390 | + .setRefundStatus(PayOrderRefundStatusEnum.PART.getStatus()); | |
| 391 | + } | |
| 392 | + orderMapper.updateByIdAndStatus(id, PayOrderStatusEnum.SUCCESS.getStatus(), updateObj); | |
| 393 | + } | |
| 394 | + | |
| 396 | 395 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java
| ... | ... | @@ -43,6 +43,7 @@ import java.util.List; |
| 43 | 43 | |
| 44 | 44 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 45 | 45 | import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; |
| 46 | +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_NOT_FOUND; | |
| 46 | 47 | |
| 47 | 48 | /** |
| 48 | 49 | * 退款订单 Service 实现类 |
| ... | ... | @@ -106,13 +107,13 @@ public class PayRefundServiceImpl implements PayRefundService { |
| 106 | 107 | PayClient client = payClientFactory.getPayClient(channel.getId()); |
| 107 | 108 | if (client == null) { |
| 108 | 109 | log.error("[refund][渠道编号({}) 找不到对应的支付客户端]", channel.getId()); |
| 109 | - throw exception(ErrorCodeConstants.PAY_CHANNEL_CLIENT_NOT_FOUND); | |
| 110 | + throw exception(CHANNEL_NOT_FOUND); | |
| 110 | 111 | } |
| 111 | 112 | // 1.4 校验退款订单是否已经存在 |
| 112 | 113 | PayRefundDO refund = refundMapper.selectByAppIdAndMerchantRefundId( |
| 113 | 114 | app.getId(), reqDTO.getMerchantRefundId()); |
| 114 | 115 | if (refund != null) { |
| 115 | - throw exception(ErrorCodeConstants.PAY_REFUND_EXISTS); | |
| 116 | + throw exception(ErrorCodeConstants.REFUND_EXISTS); | |
| 116 | 117 | } |
| 117 | 118 | |
| 118 | 119 | // 2.1 插入退款单 |
| ... | ... | @@ -153,25 +154,25 @@ public class PayRefundServiceImpl implements PayRefundService { |
| 153 | 154 | private PayOrderDO validatePayOrderCanRefund(PayRefundCreateReqDTO reqDTO) { |
| 154 | 155 | PayOrderDO order = orderService.getOrder(reqDTO.getAppId(), reqDTO.getMerchantOrderId()); |
| 155 | 156 | if (order == null) { |
| 156 | - throw exception(ErrorCodeConstants.PAY_ORDER_NOT_FOUND); | |
| 157 | + throw exception(ErrorCodeConstants.ORDER_NOT_FOUND); | |
| 157 | 158 | } |
| 158 | 159 | // 校验状态,必须是支付状态 |
| 159 | 160 | if (!PayOrderStatusEnum.SUCCESS.getStatus().equals(order.getStatus())) { |
| 160 | - throw exception(ErrorCodeConstants.PAY_ORDER_STATUS_IS_NOT_SUCCESS); | |
| 161 | + throw exception(ErrorCodeConstants.ORDER_STATUS_IS_NOT_SUCCESS); | |
| 161 | 162 | } |
| 162 | 163 | |
| 163 | 164 | // 是否已经全额退款 |
| 164 | 165 | if (PayOrderRefundStatusEnum.ALL.getStatus().equals(order.getRefundStatus())) { |
| 165 | - throw exception(ErrorCodeConstants.PAY_REFUND_ALL_REFUNDED); | |
| 166 | + throw exception(ErrorCodeConstants.REFUND_ALL_REFUNDED); | |
| 166 | 167 | } |
| 167 | 168 | // 校验金额 退款金额不能大于原定的金额 |
| 168 | 169 | if (reqDTO.getPrice() + order.getRefundPrice() > order.getPrice()){ |
| 169 | - throw exception(ErrorCodeConstants.PAY_REFUND_PRICE_EXCEED); | |
| 170 | + throw exception(ErrorCodeConstants.REFUND_PRICE_EXCEED); | |
| 170 | 171 | } |
| 171 | 172 | // 是否有退款中的订单 |
| 172 | 173 | if (refundMapper.selectCountByAppIdAndOrderId(reqDTO.getAppId(), order.getId(), |
| 173 | 174 | PayRefundStatusEnum.WAITING.getStatus()) > 0) { |
| 174 | - throw exception(ErrorCodeConstants.PAY_REFUND_HAS_REFUNDING); | |
| 175 | + throw exception(ErrorCodeConstants.REFUND_HAS_REFUNDING); | |
| 175 | 176 | } |
| 176 | 177 | return order; |
| 177 | 178 | } |
| ... | ... | @@ -230,13 +231,13 @@ public class PayRefundServiceImpl implements PayRefundService { |
| 230 | 231 | PayRefundDO refund = refundMapper.selectByAppIdAndNo( |
| 231 | 232 | channel.getAppId(), notify.getOutRefundNo()); |
| 232 | 233 | if (refund == null) { |
| 233 | - throw exception(ErrorCodeConstants.PAY_REFUND_NOT_FOUND); | |
| 234 | + throw exception(ErrorCodeConstants.REFUND_NOT_FOUND); | |
| 234 | 235 | } |
| 235 | 236 | if (PayRefundStatusEnum.isSuccess(refund.getStatus())) { // 如果已经是成功,直接返回,不用重复更新 |
| 236 | 237 | return; |
| 237 | 238 | } |
| 238 | 239 | if (!PayRefundStatusEnum.WAITING.getStatus().equals(refund.getStatus())) { |
| 239 | - throw exception(ErrorCodeConstants.PAY_REFUND_STATUS_IS_NOT_WAITING); | |
| 240 | + throw exception(ErrorCodeConstants.REFUND_STATUS_IS_NOT_WAITING); | |
| 240 | 241 | } |
| 241 | 242 | |
| 242 | 243 | // 1.2 更新 PayRefundDO |
| ... | ... | @@ -247,7 +248,7 @@ public class PayRefundServiceImpl implements PayRefundService { |
| 247 | 248 | .setChannelNotifyData(toJsonString(notify)); |
| 248 | 249 | int updateCounts = refundMapper.updateByIdAndStatus(refund.getId(), refund.getStatus(), updateRefundObj); |
| 249 | 250 | if (updateCounts == 0) { // 校验状态,必须是等待状态 |
| 250 | - throw exception(ErrorCodeConstants.PAY_REFUND_STATUS_IS_NOT_WAITING); | |
| 251 | + throw exception(ErrorCodeConstants.REFUND_STATUS_IS_NOT_WAITING); | |
| 251 | 252 | } |
| 252 | 253 | |
| 253 | 254 | // 2. 更新订单 | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/app/PayAppServiceTest.java
| ... | ... | @@ -90,7 +90,7 @@ public class PayAppServiceTest extends BaseDbUnitTest { |
| 90 | 90 | PayAppUpdateReqVO reqVO = randomPojo(PayAppUpdateReqVO.class, o -> |
| 91 | 91 | o.setStatus((RandomUtil.randomEle(CommonStatusEnum.values()).getStatus()))); |
| 92 | 92 | // 调用, 并断言异常 |
| 93 | - assertServiceException(() -> appService.updateApp(reqVO), PAY_APP_NOT_FOUND); | |
| 93 | + assertServiceException(() -> appService.updateApp(reqVO), APP_NOT_FOUND); | |
| 94 | 94 | } |
| 95 | 95 | |
| 96 | 96 | @Test |
| ... | ... | @@ -130,7 +130,7 @@ public class PayAppServiceTest extends BaseDbUnitTest { |
| 130 | 130 | Long id = randomLongId(); |
| 131 | 131 | |
| 132 | 132 | // 调用, 并断言异常 |
| 133 | - assertServiceException(() -> appService.deleteApp(id), PAY_APP_NOT_FOUND); | |
| 133 | + assertServiceException(() -> appService.deleteApp(id), APP_NOT_FOUND); | |
| 134 | 134 | } |
| 135 | 135 | |
| 136 | 136 | @Test |
| ... | ... | @@ -144,7 +144,7 @@ public class PayAppServiceTest extends BaseDbUnitTest { |
| 144 | 144 | when(orderService.getOrderCountByAppId(eq(id))).thenReturn(10L); |
| 145 | 145 | |
| 146 | 146 | // 调用, 并断言异常 |
| 147 | - assertServiceException(() -> appService.deleteApp(id), PAY_APP_EXIST_ORDER_CANT_DELETE); | |
| 147 | + assertServiceException(() -> appService.deleteApp(id), APP_EXIST_ORDER_CANT_DELETE); | |
| 148 | 148 | } |
| 149 | 149 | |
| 150 | 150 | @Test |
| ... | ... | @@ -158,7 +158,7 @@ public class PayAppServiceTest extends BaseDbUnitTest { |
| 158 | 158 | when(refundService.getRefundCountByAppId(eq(id))).thenReturn(10L); |
| 159 | 159 | |
| 160 | 160 | // 调用, 并断言异常 |
| 161 | - assertServiceException(() -> appService.deleteApp(id), PAY_APP_EXIST_REFUND_CANT_DELETE); | |
| 161 | + assertServiceException(() -> appService.deleteApp(id), APP_EXIST_REFUND_CANT_DELETE); | |
| 162 | 162 | } |
| 163 | 163 | |
| 164 | 164 | @Test |
| ... | ... | @@ -239,7 +239,7 @@ public class PayAppServiceTest extends BaseDbUnitTest { |
| 239 | 239 | |
| 240 | 240 | @Test |
| 241 | 241 | public void testValidPayApp_notFound() { |
| 242 | - assertServiceException(() -> appService.validPayApp(randomLongId()), PAY_APP_NOT_FOUND); | |
| 242 | + assertServiceException(() -> appService.validPayApp(randomLongId()), APP_NOT_FOUND); | |
| 243 | 243 | } |
| 244 | 244 | |
| 245 | 245 | @Test |
| ... | ... | @@ -252,7 +252,7 @@ public class PayAppServiceTest extends BaseDbUnitTest { |
| 252 | 252 | Long id = dbApp.getId(); |
| 253 | 253 | |
| 254 | 254 | // 调用,并断言异常 |
| 255 | - assertServiceException(() -> appService.validPayApp(id), PAY_APP_IS_DISABLE); | |
| 255 | + assertServiceException(() -> appService.validPayApp(id), APP_IS_DISABLE); | |
| 256 | 256 | } |
| 257 | 257 | |
| 258 | 258 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceTest.java
| ... | ... | @@ -26,8 +26,7 @@ import java.util.List; |
| 26 | 26 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; |
| 27 | 27 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; |
| 28 | 28 | import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; |
| 29 | -import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_EXIST_SAME_CHANNEL_ERROR; | |
| 30 | -import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_NOT_EXISTS; | |
| 29 | +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; | |
| 31 | 30 | import static org.junit.jupiter.api.Assertions.*; |
| 32 | 31 | |
| 33 | 32 | @Import({PayChannelServiceImpl.class}) |
| ... | ... | @@ -52,6 +51,40 @@ public class PayChannelServiceTest extends BaseDbUnitTest { |
| 52 | 51 | } |
| 53 | 52 | |
| 54 | 53 | @Test |
| 54 | + public void testInitLocalCache() { | |
| 55 | + // mock 数据 | |
| 56 | + PayChannelDO dbChannel = randomPojo(PayChannelDO.class, | |
| 57 | + o -> o.setConfig(randomWxPayClientConfig())); | |
| 58 | + channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据 | |
| 59 | + | |
| 60 | + // 调用 | |
| 61 | + channelService.initLocalCache(); | |
| 62 | + // 校验缓存 | |
| 63 | + assertEquals(1, channelService.getChannelCache().size()); | |
| 64 | + assertEquals(dbChannel, channelService.getChannelCache().get(0)); | |
| 65 | + } | |
| 66 | + | |
| 67 | + @Test | |
| 68 | + public void testRefreshLocalCache() { | |
| 69 | + // mock 数据 01 | |
| 70 | + PayChannelDO dbChannel = randomPojo(PayChannelDO.class, | |
| 71 | + o -> o.setConfig(randomWxPayClientConfig())); | |
| 72 | + channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据 | |
| 73 | + channelService.initLocalCache(); | |
| 74 | + // mock 数据 02 | |
| 75 | + PayChannelDO dbChannel02 = randomPojo(PayChannelDO.class, | |
| 76 | + o -> o.setConfig(randomWxPayClientConfig())); | |
| 77 | + channelMapper.insert(dbChannel02);// @Sql: 先插入出一条存在的数据 | |
| 78 | + | |
| 79 | + // 调用 | |
| 80 | + channelService.refreshLocalCache(); | |
| 81 | + // 校验缓存 | |
| 82 | + assertEquals(2, channelService.getChannelCache().size()); | |
| 83 | + assertEquals(dbChannel, channelService.getChannelCache().get(0)); | |
| 84 | + assertEquals(dbChannel02, channelService.getChannelCache().get(1)); | |
| 85 | + } | |
| 86 | + | |
| 87 | + @Test | |
| 55 | 88 | public void testCreateChannel_success() { |
| 56 | 89 | // 准备参数 |
| 57 | 90 | WxPayClientConfig config = randomWxPayClientConfig(); |
| ... | ... | @@ -125,7 +158,7 @@ public class PayChannelServiceTest extends BaseDbUnitTest { |
| 125 | 158 | }); |
| 126 | 159 | |
| 127 | 160 | // 调用, 并断言异常 |
| 128 | - assertServiceException(() -> channelService.updateChannel(reqVO), CHANNEL_NOT_EXISTS); | |
| 161 | + assertServiceException(() -> channelService.updateChannel(reqVO), CHANNEL_NOT_FOUND); | |
| 129 | 162 | } |
| 130 | 163 | |
| 131 | 164 | @Test |
| ... | ... | @@ -153,7 +186,7 @@ public class PayChannelServiceTest extends BaseDbUnitTest { |
| 153 | 186 | Long id = randomLongId(); |
| 154 | 187 | |
| 155 | 188 | // 调用, 并断言异常 |
| 156 | - assertServiceException(() -> channelService.deleteChannel(id), CHANNEL_NOT_EXISTS); | |
| 189 | + assertServiceException(() -> channelService.deleteChannel(id), CHANNEL_NOT_FOUND); | |
| 157 | 190 | } |
| 158 | 191 | |
| 159 | 192 | @Test |
| ... | ... | @@ -214,6 +247,101 @@ public class PayChannelServiceTest extends BaseDbUnitTest { |
| 214 | 247 | assertPojoEquals(channel, dbChannel); |
| 215 | 248 | } |
| 216 | 249 | |
| 250 | + @Test | |
| 251 | + public void testValidPayChannel_notExists() { | |
| 252 | + // 准备参数 | |
| 253 | + Long id = randomLongId(); | |
| 254 | + | |
| 255 | + // 调用, 并断言异常 | |
| 256 | + assertServiceException(() -> channelService.validPayChannel(id), CHANNEL_NOT_FOUND); | |
| 257 | + } | |
| 258 | + | |
| 259 | + @Test | |
| 260 | + public void testValidPayChannel_isDisable() { | |
| 261 | + // mock 数据 | |
| 262 | + PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { | |
| 263 | + o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); | |
| 264 | + o.setConfig(randomAlipayPayClientConfig()); | |
| 265 | + o.setStatus(CommonStatusEnum.DISABLE.getStatus()); | |
| 266 | + }); | |
| 267 | + channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据 | |
| 268 | + // 准备参数 | |
| 269 | + Long id = dbChannel.getId(); | |
| 270 | + | |
| 271 | + // 调用, 并断言异常 | |
| 272 | + assertServiceException(() -> channelService.validPayChannel(id), CHANNEL_IS_DISABLE); | |
| 273 | + } | |
| 274 | + | |
| 275 | + @Test | |
| 276 | + public void testValidPayChannel_success() { | |
| 277 | + // mock 数据 | |
| 278 | + PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { | |
| 279 | + o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); | |
| 280 | + o.setConfig(randomAlipayPayClientConfig()); | |
| 281 | + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); | |
| 282 | + }); | |
| 283 | + channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据 | |
| 284 | + // 准备参数 | |
| 285 | + Long id = dbChannel.getId(); | |
| 286 | + | |
| 287 | + // 调用 | |
| 288 | + PayChannelDO channel = channelService.validPayChannel(id); | |
| 289 | + // 断言异常 | |
| 290 | + assertPojoEquals(channel, dbChannel); | |
| 291 | + } | |
| 292 | + | |
| 293 | + @Test | |
| 294 | + public void testValidPayChannel_appIdAndCode() { | |
| 295 | + // mock 数据 | |
| 296 | + PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { | |
| 297 | + o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); | |
| 298 | + o.setConfig(randomAlipayPayClientConfig()); | |
| 299 | + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); | |
| 300 | + }); | |
| 301 | + channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据 | |
| 302 | + // 准备参数 | |
| 303 | + Long appId = dbChannel.getAppId(); | |
| 304 | + String code = dbChannel.getCode(); | |
| 305 | + | |
| 306 | + // 调用 | |
| 307 | + PayChannelDO channel = channelService.validPayChannel(appId, code); | |
| 308 | + // 断言异常 | |
| 309 | + assertPojoEquals(channel, dbChannel); | |
| 310 | + } | |
| 311 | + | |
| 312 | + @Test | |
| 313 | + public void testGetEnableChannelList() { | |
| 314 | + // 准备参数 | |
| 315 | + Long appId = randomLongId(); | |
| 316 | + // mock 数据 01(enable 不匹配) | |
| 317 | + PayChannelDO dbChannel01 = randomPojo(PayChannelDO.class, o -> { | |
| 318 | + o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); | |
| 319 | + o.setConfig(randomAlipayPayClientConfig()); | |
| 320 | + o.setStatus(CommonStatusEnum.DISABLE.getStatus()); | |
| 321 | + }); | |
| 322 | + channelMapper.insert(dbChannel01);// @Sql: 先插入出一条存在的数据 | |
| 323 | + // mock 数据 02(appId 不匹配) | |
| 324 | + PayChannelDO dbChannel02 = randomPojo(PayChannelDO.class, o -> { | |
| 325 | + o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); | |
| 326 | + o.setConfig(randomAlipayPayClientConfig()); | |
| 327 | + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); | |
| 328 | + }); | |
| 329 | + channelMapper.insert(dbChannel02);// @Sql: 先插入出一条存在的数据 | |
| 330 | + // mock 数据 03 | |
| 331 | + PayChannelDO dbChannel03 = randomPojo(PayChannelDO.class, o -> { | |
| 332 | + o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); | |
| 333 | + o.setConfig(randomAlipayPayClientConfig()); | |
| 334 | + o.setAppId(appId); | |
| 335 | + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); | |
| 336 | + }); | |
| 337 | + channelMapper.insert(dbChannel03);// @Sql: 先插入出一条存在的数据 | |
| 338 | + | |
| 339 | + // 调用 | |
| 340 | + List<PayChannelDO> channel = channelService.getEnableChannelList(appId); | |
| 341 | + // 断言异常 | |
| 342 | + assertPojoEquals(channel, dbChannel03); | |
| 343 | + } | |
| 344 | + | |
| 217 | 345 | public WxPayClientConfig randomWxPayClientConfig() { |
| 218 | 346 | return new WxPayClientConfig() |
| 219 | 347 | .setAppId(randomString()) | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java
| ... | ... | @@ -3,32 +3,53 @@ package cn.iocoder.yudao.module.pay.service.order; |
| 3 | 3 | import cn.hutool.core.date.DateUtil; |
| 4 | 4 | import cn.hutool.core.util.RandomUtil; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | +import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; | |
| 6 | 7 | import cn.iocoder.yudao.framework.pay.config.PayProperties; |
| 8 | +import cn.iocoder.yudao.framework.pay.core.client.PayClient; | |
| 7 | 9 | import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; |
| 10 | +import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; | |
| 8 | 11 | import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; |
| 9 | 12 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; |
| 13 | +import cn.iocoder.yudao.framework.test.core.util.AssertUtils; | |
| 14 | +import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; | |
| 10 | 15 | import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExportReqVO; |
| 11 | 16 | import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageReqVO; |
| 17 | +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitReqVO; | |
| 18 | +import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; | |
| 19 | +import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; | |
| 12 | 20 | import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; |
| 21 | +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderExtensionMapper; | |
| 13 | 22 | import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderMapper; |
| 14 | 23 | import cn.iocoder.yudao.module.pay.enums.order.PayOrderNotifyStatusEnum; |
| 15 | -import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; | |
| 16 | 24 | import cn.iocoder.yudao.module.pay.enums.order.PayOrderRefundStatusEnum; |
| 25 | +import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; | |
| 17 | 26 | import cn.iocoder.yudao.module.pay.service.app.PayAppService; |
| 18 | 27 | import cn.iocoder.yudao.module.pay.service.channel.PayChannelService; |
| 19 | 28 | import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService; |
| 20 | 29 | import org.junit.jupiter.api.Test; |
| 30 | +import org.mockito.Mockito; | |
| 21 | 31 | import org.springframework.boot.test.mock.mockito.MockBean; |
| 22 | 32 | import org.springframework.context.annotation.Import; |
| 23 | 33 | |
| 24 | 34 | import javax.annotation.Resource; |
| 35 | +import java.time.Duration; | |
| 25 | 36 | import java.time.LocalDateTime; |
| 26 | 37 | import java.util.List; |
| 27 | 38 | |
| 39 | +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; | |
| 28 | 40 | import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; |
| 41 | +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.equalsAny; | |
| 29 | 42 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; |
| 43 | +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; | |
| 30 | 44 | import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; |
| 31 | -import static org.junit.jupiter.api.Assertions.assertEquals; | |
| 45 | +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString; | |
| 46 | +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; | |
| 47 | +import static org.assertj.core.api.Assertions.assertThat; | |
| 48 | +import static org.junit.jupiter.api.Assertions.*; | |
| 49 | +import static org.mockito.ArgumentMatchers.any; | |
| 50 | +import static org.mockito.ArgumentMatchers.eq; | |
| 51 | +import static org.mockito.Mockito.mock; | |
| 52 | +import static org.mockito.Mockito.when; | |
| 32 | 53 | |
| 33 | 54 | /** |
| 34 | 55 | * {@link PayOrderServiceImpl} 的单元测试类 |
| ... | ... | @@ -43,6 +64,8 @@ public class PayOrderServiceTest extends BaseDbUnitTest { |
| 43 | 64 | |
| 44 | 65 | @Resource |
| 45 | 66 | private PayOrderMapper orderMapper; |
| 67 | + @Resource | |
| 68 | + private PayOrderExtensionMapper orderExtensionMapper; | |
| 46 | 69 | |
| 47 | 70 | @MockBean |
| 48 | 71 | private PayClientFactory payClientFactory; |
| ... | ... | @@ -55,42 +78,18 @@ public class PayOrderServiceTest extends BaseDbUnitTest { |
| 55 | 78 | @MockBean |
| 56 | 79 | private PayNotifyService notifyService; |
| 57 | 80 | |
| 58 | - public String generateNo() { | |
| 59 | - return DateUtil.format(LocalDateTime.now(), "yyyyMMddHHmmss") + RandomUtil.randomInt(100000, 999999); | |
| 60 | - } | |
| 61 | - | |
| 62 | 81 | @Test |
| 63 | 82 | public void testGetOrderPage() { |
| 64 | - | |
| 65 | - String merchantOrderId = generateNo(); | |
| 66 | - String channelOrderId = generateNo(); | |
| 67 | - | |
| 68 | 83 | // mock 数据 |
| 69 | 84 | PayOrderDO dbOrder = randomPojo(PayOrderDO.class, o -> { // 等会查询到 |
| 70 | 85 | o.setAppId(1L); |
| 71 | - o.setChannelId(1L); | |
| 86 | + o.setChannelId(10L); | |
| 72 | 87 | o.setChannelCode(PayChannelEnum.WX_PUB.getCode()); |
| 73 | - o.setMerchantOrderId(merchantOrderId); | |
| 74 | - o.setSubject("灿灿子的炸弹猫"); | |
| 75 | - o.setBody("斌斌子送给灿灿子的炸弹猫"); | |
| 76 | - o.setNotifyUrl("https://hc.com/lbh"); | |
| 88 | + o.setMerchantOrderId("110"); | |
| 77 | 89 | o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); |
| 78 | - o.setPrice(10000); | |
| 79 | - o.setChannelFeeRate(0.01); | |
| 80 | - o.setChannelFeePrice(1L); | |
| 81 | 90 | o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()); |
| 82 | - o.setUserIp("127.0.0.1"); | |
| 83 | - o.setCreateTime(LocalDateTime.of(2018, 1, 1, 10, 1, 0)); | |
| 84 | - o.setExpireTime(LocalDateTime.of(2018, 1, 1, 10, 30, 0)); | |
| 85 | - o.setSuccessTime(LocalDateTime.of(2018, 1, 1, 10, 10, 2)); | |
| 86 | - o.setNotifyTime(LocalDateTime.of(2018, 1, 1, 10, 10, 15)); | |
| 87 | - o.setSuccessExtensionId(1L); | |
| 91 | + o.setCreateTime(buildTime(2018, 1, 15)); | |
| 88 | 92 | o.setRefundStatus(PayOrderRefundStatusEnum.NO.getStatus()); |
| 89 | - o.setRefundTimes(0); | |
| 90 | - o.setRefundPrice(0); | |
| 91 | - o.setChannelUserId("1008611"); | |
| 92 | - o.setChannelOrderNo(channelOrderId); | |
| 93 | - o.setUpdateTime(LocalDateTime.of(2018, 1, 1, 10, 10, 15)); | |
| 94 | 93 | }); |
| 95 | 94 | orderMapper.insert(dbOrder); |
| 96 | 95 | // 测试 appId 不匹配 |
| ... | ... | @@ -100,7 +99,7 @@ public class PayOrderServiceTest extends BaseDbUnitTest { |
| 100 | 99 | // 测试 channelCode 不匹配 |
| 101 | 100 | orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode()))); |
| 102 | 101 | // 测试 merchantOrderId 不匹配 |
| 103 | - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setMerchantOrderId(generateNo()))); | |
| 102 | + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setMerchantOrderId(randomString()))); | |
| 104 | 103 | // 测试 notifyStatus 不匹配 |
| 105 | 104 | orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus()))); |
| 106 | 105 | // 测试 status 不匹配 |
| ... | ... | @@ -108,58 +107,38 @@ public class PayOrderServiceTest extends BaseDbUnitTest { |
| 108 | 107 | // 测试 refundStatus 不匹配 |
| 109 | 108 | orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setRefundStatus(PayOrderRefundStatusEnum.ALL.getStatus()))); |
| 110 | 109 | // 测试 createTime 不匹配 |
| 111 | - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setCreateTime(LocalDateTime.of(2019, 1, 1, 10, 10, | |
| 112 | - 1)))); | |
| 110 | + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setCreateTime(buildTime(2019, 1, 1)))); | |
| 113 | 111 | // 准备参数 |
| 114 | 112 | PayOrderPageReqVO reqVO = new PayOrderPageReqVO(); |
| 115 | 113 | reqVO.setAppId(1L); |
| 116 | - reqVO.setChannelId(1L); | |
| 114 | + reqVO.setChannelId(10L); | |
| 117 | 115 | reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode()); |
| 118 | - reqVO.setMerchantOrderId(merchantOrderId); | |
| 116 | + reqVO.setMerchantOrderId("110"); | |
| 119 | 117 | reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); |
| 120 | 118 | reqVO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()); |
| 121 | 119 | reqVO.setRefundStatus(PayOrderRefundStatusEnum.NO.getStatus()); |
| 122 | - reqVO.setCreateTime((new LocalDateTime[]{LocalDateTime.of(2018, 1, 1, 10, 1, 0), LocalDateTime.of(2018, 1, 1, 10, 1, 0)})); | |
| 120 | + reqVO.setCreateTime(buildBetweenTime(2018, 1, 10, 2018, 1, 30)); | |
| 121 | + | |
| 123 | 122 | // 调用 |
| 124 | 123 | PageResult<PayOrderDO> pageResult = orderService.getOrderPage(reqVO); |
| 125 | 124 | // 断言 |
| 126 | 125 | assertEquals(1, pageResult.getTotal()); |
| 127 | 126 | assertEquals(1, pageResult.getList().size()); |
| 128 | 127 | assertPojoEquals(dbOrder, pageResult.getList().get(0)); |
| 129 | - // assertEquals(0, dbOrder.getUpdateTime().compareTo(pageResult.getList().get(0).getUpdateTime())); | |
| 130 | 128 | } |
| 131 | 129 | |
| 132 | 130 | @Test |
| 133 | 131 | public void testGetOrderList() { |
| 134 | 132 | // mock 数据 |
| 135 | - String merchantOrderId = generateNo(); | |
| 136 | - String channelOrderId = generateNo(); | |
| 137 | 133 | PayOrderDO dbOrder = randomPojo(PayOrderDO.class, o -> { // 等会查询到 |
| 138 | 134 | o.setAppId(1L); |
| 139 | - o.setChannelId(1L); | |
| 135 | + o.setChannelId(10L); | |
| 140 | 136 | o.setChannelCode(PayChannelEnum.WX_PUB.getCode()); |
| 141 | - o.setMerchantOrderId(merchantOrderId); | |
| 142 | - o.setSubject("灿灿子的炸弹猫"); | |
| 143 | - o.setBody("斌斌子送给灿灿子的炸弹猫"); | |
| 144 | - o.setNotifyUrl("https://hc.com/lbh"); | |
| 137 | + o.setMerchantOrderId("110"); | |
| 145 | 138 | o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); |
| 146 | - o.setPrice(10000); | |
| 147 | - o.setChannelFeeRate(0.01); | |
| 148 | - o.setChannelFeePrice(1L); | |
| 149 | 139 | o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()); |
| 150 | - o.setUserIp("127.0.0.1"); | |
| 151 | - o.setCreateTime(LocalDateTime.of(2018, 1, 1, 10, 1, 0)); | |
| 152 | - o.setExpireTime(LocalDateTime.of(2018, 1, 1, 10, 30, 0)); | |
| 153 | - o.setSuccessTime(LocalDateTime.of(2018, 1, 1, 10, 10, 2)); | |
| 154 | - o.setNotifyTime(LocalDateTime.of(2018, 1, 1, 10, 10, 15)); | |
| 155 | - o.setSuccessExtensionId(1L); | |
| 140 | + o.setCreateTime(buildTime(2018, 1, 15)); | |
| 156 | 141 | o.setRefundStatus(PayOrderRefundStatusEnum.NO.getStatus()); |
| 157 | - o.setRefundTimes(0); | |
| 158 | - o.setRefundPrice(0); | |
| 159 | - o.setChannelUserId("1008611"); | |
| 160 | - o.setChannelOrderNo(channelOrderId); | |
| 161 | - o.setUpdateTime(LocalDateTime.of(2018, 1, 1, 10, 10, 15)); | |
| 162 | - | |
| 163 | 142 | }); |
| 164 | 143 | orderMapper.insert(dbOrder); |
| 165 | 144 | // 测试 appId 不匹配 |
| ... | ... | @@ -169,7 +148,7 @@ public class PayOrderServiceTest extends BaseDbUnitTest { |
| 169 | 148 | // 测试 channelCode 不匹配 |
| 170 | 149 | orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode()))); |
| 171 | 150 | // 测试 merchantOrderId 不匹配 |
| 172 | - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setMerchantOrderId(generateNo()))); | |
| 151 | + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setMerchantOrderId(randomString()))); | |
| 173 | 152 | // 测试 notifyStatus 不匹配 |
| 174 | 153 | orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus()))); |
| 175 | 154 | // 测试 status 不匹配 |
| ... | ... | @@ -177,18 +156,17 @@ public class PayOrderServiceTest extends BaseDbUnitTest { |
| 177 | 156 | // 测试 refundStatus 不匹配 |
| 178 | 157 | orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setRefundStatus(PayOrderRefundStatusEnum.ALL.getStatus()))); |
| 179 | 158 | // 测试 createTime 不匹配 |
| 180 | - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setCreateTime(LocalDateTime.of(2019, 1, 1, 10, 10, | |
| 181 | - 1)))); | |
| 159 | + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setCreateTime(buildTime(2019, 1, 1)))); | |
| 182 | 160 | // 准备参数 |
| 183 | 161 | PayOrderExportReqVO reqVO = new PayOrderExportReqVO(); |
| 184 | 162 | reqVO.setAppId(1L); |
| 185 | - reqVO.setChannelId(1L); | |
| 163 | + reqVO.setChannelId(10L); | |
| 186 | 164 | reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode()); |
| 187 | - reqVO.setMerchantOrderId(merchantOrderId); | |
| 165 | + reqVO.setMerchantOrderId("110"); | |
| 188 | 166 | reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); |
| 189 | 167 | reqVO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()); |
| 190 | 168 | reqVO.setRefundStatus(PayOrderRefundStatusEnum.NO.getStatus()); |
| 191 | - reqVO.setCreateTime((new LocalDateTime[]{LocalDateTime.of(2018, 1, 1, 10, 1, 0), LocalDateTime.of(2018, 1, 1, 10, 1, 0)})); | |
| 169 | + reqVO.setCreateTime(buildBetweenTime(2018, 1, 10, 2018, 1, 30)); | |
| 192 | 170 | |
| 193 | 171 | // 调用 |
| 194 | 172 | List<PayOrderDO> list = orderService.getOrderList(reqVO); |
| ... | ... | @@ -197,4 +175,154 @@ public class PayOrderServiceTest extends BaseDbUnitTest { |
| 197 | 175 | assertPojoEquals(dbOrder, list.get(0)); |
| 198 | 176 | } |
| 199 | 177 | |
| 178 | + @Test | |
| 179 | + public void testCreateOrder_success() { | |
| 180 | + // mock 参数 | |
| 181 | + PayOrderCreateReqDTO reqDTO = randomPojo(PayOrderCreateReqDTO.class, | |
| 182 | + o -> o.setAppId(1L).setMerchantOrderId("10") | |
| 183 | + .setSubject(randomString()).setBody(randomString())); | |
| 184 | + // mock 方法 | |
| 185 | + PayAppDO app = randomPojo(PayAppDO.class, o -> o.setId(1L).setOrderNotifyUrl("http://127.0.0.1")); | |
| 186 | + when(appService.validPayApp(eq(reqDTO.getAppId()))).thenReturn(app); | |
| 187 | + | |
| 188 | + // 调用 | |
| 189 | + Long orderId = orderService.createOrder(reqDTO); | |
| 190 | + // 断言 | |
| 191 | + PayOrderDO order = orderMapper.selectById(orderId); | |
| 192 | + assertPojoEquals(order, reqDTO); | |
| 193 | + assertEquals(order.getAppId(), 1L); | |
| 194 | + assertEquals(order.getNotifyUrl(), "http://127.0.0.1"); | |
| 195 | + assertEquals(order.getStatus(), PayOrderStatusEnum.WAITING.getStatus()); | |
| 196 | + assertEquals(order.getRefundStatus(), PayOrderRefundStatusEnum.NO.getStatus()); | |
| 197 | + assertEquals(order.getRefundTimes(), 0); | |
| 198 | + assertEquals(order.getRefundPrice(), 0); | |
| 199 | + } | |
| 200 | + | |
| 201 | + @Test | |
| 202 | + public void testCreateOrder_exists() { | |
| 203 | + // mock 参数 | |
| 204 | + PayOrderCreateReqDTO reqDTO = randomPojo(PayOrderCreateReqDTO.class, | |
| 205 | + o -> o.setAppId(1L).setMerchantOrderId("10")); | |
| 206 | + // mock 数据 | |
| 207 | + PayOrderDO dbOrder = randomPojo(PayOrderDO.class, o -> o.setAppId(1L).setMerchantOrderId("10")); | |
| 208 | + orderMapper.insert(dbOrder); | |
| 209 | + | |
| 210 | + // 调用 | |
| 211 | + Long orderId = orderService.createOrder(reqDTO); | |
| 212 | + // 断言 | |
| 213 | + PayOrderDO order = orderMapper.selectById(orderId); | |
| 214 | + assertPojoEquals(dbOrder, order); | |
| 215 | + } | |
| 216 | + | |
| 217 | + @Test | |
| 218 | + public void testSubmitOrder_notFound() { | |
| 219 | + // 准备参数 | |
| 220 | + PayOrderSubmitReqVO reqVO = randomPojo(PayOrderSubmitReqVO.class); | |
| 221 | + String userIp = randomString(); | |
| 222 | + | |
| 223 | + // 调用, 并断言异常 | |
| 224 | + assertServiceException(() -> orderService.submitOrder(reqVO, userIp), ORDER_NOT_FOUND); | |
| 225 | + } | |
| 226 | + | |
| 227 | + @Test | |
| 228 | + public void testSubmitOrder_notWaiting() { | |
| 229 | + // mock 数据(order) | |
| 230 | + PayOrderDO order = randomPojo(PayOrderDO.class, o -> o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus())); | |
| 231 | + orderMapper.insert(order); | |
| 232 | + // 准备参数 | |
| 233 | + PayOrderSubmitReqVO reqVO = randomPojo(PayOrderSubmitReqVO.class, o -> o.setId(order.getId())); | |
| 234 | + String userIp = randomString(); | |
| 235 | + | |
| 236 | + // 调用, 并断言异常 | |
| 237 | + assertServiceException(() -> orderService.submitOrder(reqVO, userIp), ORDER_STATUS_IS_NOT_WAITING); | |
| 238 | + } | |
| 239 | + | |
| 240 | + @Test | |
| 241 | + public void testSubmitOrder_expired() { | |
| 242 | + // mock 数据(order) | |
| 243 | + PayOrderDO order = randomPojo(PayOrderDO.class, o -> o.setStatus(PayOrderStatusEnum.WAITING.getStatus()) | |
| 244 | + .setExpireTime(addTime(Duration.ofDays(-1)))); | |
| 245 | + orderMapper.insert(order); | |
| 246 | + // 准备参数 | |
| 247 | + PayOrderSubmitReqVO reqVO = randomPojo(PayOrderSubmitReqVO.class, o -> o.setId(order.getId())); | |
| 248 | + String userIp = randomString(); | |
| 249 | + | |
| 250 | + // 调用, 并断言异常 | |
| 251 | + assertServiceException(() -> orderService.submitOrder(reqVO, userIp), ORDER_IS_EXPIRED); | |
| 252 | + } | |
| 253 | + | |
| 254 | + @Test | |
| 255 | + public void testSubmitOrder_channelNotFound() { | |
| 256 | + // mock 数据(order) | |
| 257 | + PayOrderDO order = randomPojo(PayOrderDO.class, o -> o.setStatus(PayOrderStatusEnum.WAITING.getStatus()) | |
| 258 | + .setAppId(1L)); | |
| 259 | + orderMapper.insert(order); | |
| 260 | + // 准备参数 | |
| 261 | + PayOrderSubmitReqVO reqVO = randomPojo(PayOrderSubmitReqVO.class, o -> o.setId(order.getId()) | |
| 262 | + .setChannelCode(PayChannelEnum.ALIPAY_APP.getCode())); | |
| 263 | + String userIp = randomString(); | |
| 264 | + // mock 方法(app) | |
| 265 | + PayAppDO app = randomPojo(PayAppDO.class, o -> o.setId(1L)); | |
| 266 | + when(appService.validPayApp(eq(1L))).thenReturn(app); | |
| 267 | + // mock 方法(channel) | |
| 268 | + PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setCode(PayChannelEnum.ALIPAY_APP.getCode())); | |
| 269 | + when(channelService.validPayChannel(eq(1L), eq(PayChannelEnum.ALIPAY_APP.getCode()))) | |
| 270 | + .thenReturn(channel); | |
| 271 | + | |
| 272 | + // 调用, 并断言异常 | |
| 273 | + assertServiceException(() -> orderService.submitOrder(reqVO, userIp), CHANNEL_NOT_FOUND); | |
| 274 | + } | |
| 275 | + | |
| 276 | + @Test // 调用 unifiedOrder 接口,返回存在渠道错误 | |
| 277 | + public void testSubmitOrder_channelError() { | |
| 278 | + // mock 数据(order) | |
| 279 | + PayOrderDO order = randomPojo(PayOrderDO.class, o -> o.setStatus(PayOrderStatusEnum.WAITING.getStatus()) | |
| 280 | + .setAppId(1L)); | |
| 281 | + orderMapper.insert(order); | |
| 282 | + // 准备参数 | |
| 283 | + PayOrderSubmitReqVO reqVO = randomPojo(PayOrderSubmitReqVO.class, o -> o.setId(order.getId()) | |
| 284 | + .setChannelCode(PayChannelEnum.ALIPAY_APP.getCode())); | |
| 285 | + String userIp = randomString(); | |
| 286 | + // mock 方法(app) | |
| 287 | + PayAppDO app = randomPojo(PayAppDO.class, o -> o.setId(1L)); | |
| 288 | + when(appService.validPayApp(eq(1L))).thenReturn(app); | |
| 289 | + // mock 方法(channel) | |
| 290 | + PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L) | |
| 291 | + .setCode(PayChannelEnum.ALIPAY_APP.getCode())); | |
| 292 | + when(channelService.validPayChannel(eq(1L), eq(PayChannelEnum.ALIPAY_APP.getCode()))) | |
| 293 | + .thenReturn(channel); | |
| 294 | + // mock 方法(client) | |
| 295 | + PayClient client = mock(PayClient.class); | |
| 296 | + when(payClientFactory.getPayClient(eq(10L))).thenReturn(client); | |
| 297 | + when(client.unifiedOrder(any(PayOrderUnifiedReqDTO.class))).thenThrow(new NullPointerException()); | |
| 298 | + | |
| 299 | + // 调用,并断言异常 | |
| 300 | + assertThrows(NullPointerException.class, () -> orderService.submitOrder(reqVO, userIp)); | |
| 301 | + // 断言,数据记录(PayOrderExtensionDO) | |
| 302 | + PayOrderExtensionDO orderExtension = orderExtensionMapper.selectOne(null); | |
| 303 | + assertNotNull(orderExtension); | |
| 304 | + assertThat(orderExtension).extracting("no", "orderId").isNotNull(); | |
| 305 | + assertThat(orderExtension) | |
| 306 | + .extracting("channelId", "channelCode","userIp" ,"status", "channelExtras", | |
| 307 | + "channelErrorCode", "channelErrorMsg", "channelNotifyData") | |
| 308 | + .containsExactly(10L, PayChannelEnum.ALIPAY_APP.getCode(), userIp, | |
| 309 | + PayOrderStatusEnum.WAITING.getStatus(), reqVO.getChannelExtras(), | |
| 310 | + null, null, null); | |
| 311 | + } | |
| 312 | + | |
| 313 | + @Test // 【成功】支付结果为等待中 | |
| 314 | + public void testSubmitOrder_waitingResult() { | |
| 315 | + | |
| 316 | + } | |
| 317 | + | |
| 318 | + @Test // 【成功】支付结果为已完成 | |
| 319 | + public void testSubmitOrder_successResult() { | |
| 320 | + | |
| 321 | + } | |
| 322 | + | |
| 323 | + @Test // 【成功】支付结果为已关闭 | |
| 324 | + public void testSubmitOrder_closedResult() { | |
| 325 | + | |
| 326 | + } | |
| 327 | + | |
| 200 | 328 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/test/resources/sql/create_tables.sql
| ... | ... | @@ -40,9 +40,9 @@ CREATE TABLE IF NOT EXISTS `pay_order` ( |
| 40 | 40 | `body` varchar(128) NOT NULL, |
| 41 | 41 | `notify_url` varchar(1024) NOT NULL, |
| 42 | 42 | `notify_status` tinyint(4) NOT NULL, |
| 43 | - `amount` bigint(20) NOT NULL, | |
| 43 | + `price` bigint(20) NOT NULL, | |
| 44 | 44 | `channel_fee_rate` double DEFAULT 0, |
| 45 | - `channel_fee_amount` bigint(20) DEFAULT 0, | |
| 45 | + `channel_fee_price` bigint(20) DEFAULT 0, | |
| 46 | 46 | `status` tinyint(4) NOT NULL, |
| 47 | 47 | `user_ip` varchar(50) NOT NULL, |
| 48 | 48 | `expire_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, |
| ... | ... | @@ -50,8 +50,8 @@ CREATE TABLE IF NOT EXISTS `pay_order` ( |
| 50 | 50 | `notify_time` datetime(0) DEFAULT CURRENT_TIMESTAMP, |
| 51 | 51 | `success_extension_id` bigint(20) DEFAULT NULL COMMENT '支付成功的订单拓展单编号', |
| 52 | 52 | `refund_status` tinyint(4) NOT NULL, |
| 53 | - `refund_times` tinyint(4) NOT NULL, | |
| 54 | - `refund_amount` bigint(20) NOT NULL, | |
| 53 | + `refund_times` int NOT NULL, | |
| 54 | + `refund_price` bigint(20) NOT NULL, | |
| 55 | 55 | `channel_user_id` varchar(255) DEFAULT NULL, |
| 56 | 56 | `channel_order_no` varchar(64) DEFAULT NULL, |
| 57 | 57 | `creator` varchar(64) DEFAULT '', |
| ... | ... | @@ -62,6 +62,26 @@ CREATE TABLE IF NOT EXISTS `pay_order` ( |
| 62 | 62 | PRIMARY KEY ("id") |
| 63 | 63 | ) COMMENT = '支付订单'; |
| 64 | 64 | |
| 65 | +CREATE TABLE IF NOT EXISTS `pay_order_extension` ( | |
| 66 | + "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY, | |
| 67 | + `no` varchar(64) NOT NULL, | |
| 68 | + `order_id` bigint(20) NOT NULL, | |
| 69 | + `channel_id` bigint(20) NOT NULL, | |
| 70 | + `channel_code` varchar(32) NOT NULL, | |
| 71 | + `user_ip` varchar(50) NULL DEFAULT NULL, | |
| 72 | + `status` tinyint(4) NOT NULL, | |
| 73 | + `channel_extras` varchar(1024) NULL DEFAULT NULL, | |
| 74 | + `channel_error_code` varchar(64) NULL, | |
| 75 | + `channel_error_msg` varchar(64) NULL, | |
| 76 | + `channel_notify_data` varchar(64) NULL, | |
| 77 | + `creator` varchar(64) NULL DEFAULT '', | |
| 78 | + `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 79 | + `updater` varchar(64) NULL DEFAULT '', | |
| 80 | + `update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, | |
| 81 | + `deleted` bit(1) NOT NULL DEFAULT FALSE, | |
| 82 | + PRIMARY KEY ("id") | |
| 83 | +) COMMENT = '支付订单拓展'; | |
| 84 | + | |
| 65 | 85 | CREATE TABLE IF NOT EXISTS `pay_refund` ( |
| 66 | 86 | "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY, |
| 67 | 87 | `app_id` bigint(20) NOT NULL, | ... | ... |