From 0e1b8126dd6cd28e1cd55224810fb60c7b8eb08e Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Thu, 14 Sep 2023 16:55:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=92=B1=E5=8C=85=E5=85=85?= =?UTF-8?q?=E5=80=BC=E3=80=82=E5=90=AF=E5=8A=A8=E6=8A=A5=E9=94=99=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/pay_wallet.sql | 3 +- .../api/combination/CombinationApiImpl.java | 2 + .../CombinationRecordServiceImpl.java | 1 + .../module/pay/enums/ErrorCodeConstants.java | 5 + .../AppPayWalletRechargeController.java | 55 +++++++ .../AppPayWalletTransactionController.java | 1 - .../AppPayWalletRechargeCreateReqVO.java | 22 +++ .../AppPayWalletRechargeCreateRespVO.java | 15 ++ .../wallet/PayWalletRechargeConvert.java | 27 ++++ .../pay/dal/mysql/wallet/PayWalletMapper.java | 13 ++ .../wallet/PayWalletRechargeService.java | 29 ++++ .../wallet/PayWalletRechargeServiceImpl.java | 135 ++++++++++++++++++ .../pay/service/wallet/PayWalletService.java | 14 +- .../service/wallet/PayWalletServiceImpl.java | 27 +++- 14 files changed, 335 insertions(+), 14 deletions(-) create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletRechargeController.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/recharge/AppPayWalletRechargeCreateReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/recharge/AppPayWalletRechargeCreateRespVO.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletRechargeConvert.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeService.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java diff --git a/sql/mysql/pay_wallet.sql b/sql/mysql/pay_wallet.sql index 9fab83c0e..e9cc6a288 100644 --- a/sql/mysql/pay_wallet.sql +++ b/sql/mysql/pay_wallet.sql @@ -57,12 +57,11 @@ CREATE TABLE `pay_wallet_recharge` `pay_order_id` bigint NULL COMMENT '支付订单编号', `pay_channel_code` varchar(16) NULL COMMENT '支付成功的支付渠道', `pay_time` datetime NULL COMMENT '订单支付时间', - `wallet_transaction_id` bigint NULL COMMENT '充值钱包流水', `pay_refund_id` bigint NULL COMMENT '支付退款单编号', `refund_price` int NOT NULL DEFAULT 0 COMMENT '退款金额,包含赠送金额', `refund_pay_price` int NOT NULL DEFAULT 0 COMMENT '退款支付金额', `refund_wallet_bonus` int NOT NULL DEFAULT 0 COMMENT '退款钱包赠送金额', - `refund_wallet_transaction_id` bigint NULL COMMENT '充值退款钱包流水', + `refund_time` datetime NULL COMMENT '退款时间', `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationApiImpl.java index 767b2e680..6c8ac989d 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationApiImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationApiImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.promotion.api.combination; import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationActivityUpdateStockReqDTO; import cn.iocoder.yudao.module.promotion.service.combination.CombinationActivityService; +import org.springframework.stereotype.Service; import javax.annotation.Resource; @@ -10,6 +11,7 @@ import javax.annotation.Resource; * * @author HUIHUI */ +@Service public class CombinationApiImpl implements CombinationApi { @Resource diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java index 556e47363..c82621805 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java @@ -38,6 +38,7 @@ import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; public class CombinationRecordServiceImpl implements CombinationRecordService { @Resource + @Lazy private CombinationActivityService combinationActivityService; @Resource private CombinationRecordMapper recordMapper; diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java index f3d6d8685..62adb63c5 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java @@ -46,6 +46,11 @@ public interface ErrorCodeConstants { ErrorCode WALLET_TRANSACTION_NOT_FOUND = new ErrorCode(1007007002, "未找到对应的钱包交易"); ErrorCode WALLET_REFUND_AMOUNT_ERROR = new ErrorCode(1007007003, "钱包退款金额不对"); ErrorCode WALLET_REFUND_EXIST = new ErrorCode(1007007004, "已经存在钱包退款"); + ErrorCode WALLET_RECHARGE_NOT_FOUND = new ErrorCode(1007007005, "钱包充值记录不存在"); + ErrorCode WALLET_RECHARGE_UPDATE_PAID_STATUS_NOT_UNPAID = new ErrorCode(1007007006, "钱包充值更新支付状态失败,钱包充值记录不是【未支付】状态"); + ErrorCode WALLET_RECHARGE_UPDATE_PAID_PAY_ORDER_ID_ERROR = new ErrorCode(1007007007, "钱包充值更新支付状态失败,支付单编号不匹配"); + ErrorCode WALLET_RECHARGE_UPDATE_PAID_PAY_ORDER_STATUS_NOT_SUCCESS = new ErrorCode(1007007008, "钱包充值更新支付状态失败,支付单状态不是【支付成功】状态"); + ErrorCode WALLET_RECHARGE_UPDATE_PAID_PAY_PRICE_NOT_MATCH = new ErrorCode(1007007009, "钱包充值更新支付状态失败,支付单金额不匹配"); // ========== 示例订单 1007900000 ========== ErrorCode DEMO_ORDER_NOT_FOUND = new ErrorCode(1007900000, "示例订单不存在"); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletRechargeController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletRechargeController.java new file mode 100644 index 000000000..0d8ae4913 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletRechargeController.java @@ -0,0 +1,55 @@ +package cn.iocoder.yudao.module.pay.controller.app.wallet; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO; +import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.recharge.AppPayWalletRechargeCreateReqVO; +import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.recharge.AppPayWalletRechargeCreateRespVO; +import cn.iocoder.yudao.module.pay.convert.wallet.PayWalletRechargeConvert; +import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletRechargeDO; +import cn.iocoder.yudao.module.pay.service.wallet.PayWalletRechargeService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.annotation.security.PermitAll; +import javax.validation.Valid; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserType; + +@Tag(name = "用户 APP - 钱包充值") +@RestController +@RequestMapping("/pay/wallet-recharge") +@Validated +@Slf4j +public class AppPayWalletRechargeController { + + @Resource + private PayWalletRechargeService payWalletRechargeService; + + @PostMapping("/create") + @Operation(summary = "创建钱包充值记录") + public CommonResult createWalletRecharge(@Valid @RequestBody AppPayWalletRechargeCreateReqVO reqVO) { + PayWalletRechargeDO walletRecharge = payWalletRechargeService.createWalletRecharge(getLoginUserId(), + getLoginUserType(), reqVO); + return success(PayWalletRechargeConvert.INSTANCE.convert(walletRecharge)); + } + + @PostMapping("/update-paid") + @Operation(summary = "更新钱包充值为已充值") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob + @PermitAll // 无需登录,安全由 内部校验实现 + @OperateLog(enable = false) // 禁用操作日志,因为没有操作人 + public CommonResult updateWalletRechargerPaid(@RequestBody PayOrderNotifyReqDTO notifyReqDTO) { + payWalletRechargeService.updateWalletRechargerPaid(Long.valueOf(notifyReqDTO.getMerchantOrderId()), + notifyReqDTO.getPayOrderId()); + return success(true); + } +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletTransactionController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletTransactionController.java index f9e908845..db0c7844d 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletTransactionController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletTransactionController.java @@ -18,7 +18,6 @@ import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import javax.validation.Valid; - import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/recharge/AppPayWalletRechargeCreateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/recharge/AppPayWalletRechargeCreateReqVO.java new file mode 100644 index 000000000..1478c4ceb --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/recharge/AppPayWalletRechargeCreateReqVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.pay.controller.app.wallet.vo.recharge; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.DecimalMin; +import javax.validation.constraints.NotNull; + +@Schema(description = "用户 APP - 创建钱包充值 Request VO") +@Data +public class AppPayWalletRechargeCreateReqVO { + + @Schema(description = "支付金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000") + @NotNull(message = "支付金额不能为空") + @DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零") + private Integer payPrice; + + @Schema(description = "钱包赠送金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000") + @NotNull(message = "钱包赠送金额不能为空") + @DecimalMin(value = "0", message = "钱包赠送金额必须大于等于零") + private Integer walletBonus; +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/recharge/AppPayWalletRechargeCreateRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/recharge/AppPayWalletRechargeCreateRespVO.java new file mode 100644 index 000000000..b1a80d2b3 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/recharge/AppPayWalletRechargeCreateRespVO.java @@ -0,0 +1,15 @@ +package cn.iocoder.yudao.module.pay.controller.app.wallet.vo.recharge; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "用户 APP - 创建钱包充值 Resp VO") +@Data +public class AppPayWalletRechargeCreateRespVO { + + @Schema(description = "钱包充值编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long id; + + @Schema(description = "支付订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") + private Long payOrderId; +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletRechargeConvert.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletRechargeConvert.java new file mode 100644 index 000000000..173cf75de --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletRechargeConvert.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.pay.convert.wallet; + +import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.recharge.AppPayWalletRechargeCreateReqVO; +import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.recharge.AppPayWalletRechargeCreateRespVO; +import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletRechargeDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author jason + */ +@Mapper +public interface PayWalletRechargeConvert { + + PayWalletRechargeConvert INSTANCE = Mappers.getMapper(PayWalletRechargeConvert.class); + + PayWalletRechargeDO convert(AppPayWalletRechargeCreateReqVO vo); + + default PayWalletRechargeDO convert(Long walletId, AppPayWalletRechargeCreateReqVO vo) { + PayWalletRechargeDO walletRecharge = convert(vo); + return walletRecharge.setWalletId(walletId) + .setPrice(walletRecharge.getPayPrice() + walletRecharge.getWalletBonus()); + } + + AppPayWalletRechargeCreateRespVO convert(PayWalletRechargeDO bean); + +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java index ef695c9fe..b93c240d2 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java @@ -42,6 +42,19 @@ public interface PayWalletMapper extends BaseMapperX { .ge(PayWalletDO::getBalance, price); // cas 逻辑 return update(null, lambdaUpdateWrapper); } + + /** + * 当充值的时候,更新钱包 + * @param price 钱包金额 + * @param id 钱包 id + */ + default int updateWhenRecharge(Integer price, Long id){ + LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() + .setSql(" balance = balance + " + price + + ", total_recharge = total_recharge + " + price) + .eq(PayWalletDO::getId, id); + return update(null, lambdaUpdateWrapper); + } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeService.java new file mode 100644 index 000000000..0752dbe99 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeService.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.pay.service.wallet; + +import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.recharge.AppPayWalletRechargeCreateReqVO; +import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletRechargeDO; + +/** + * 钱包充值 Service 接口 + * + * @author jason + */ +public interface PayWalletRechargeService { + + /** + * 创建钱包充值记录 + * @param userId 用户 id + * @param userType 用户类型 + * @param vo 钱包充值请求 vo + * @return 钱包充值记录 + */ + PayWalletRechargeDO createWalletRecharge(Long userId, Integer userType, AppPayWalletRechargeCreateReqVO vo); + + + /** + * 更新钱包充值成功 + * @param walletRechargeId 钱包充值 id + * @param payOrderId 支付订单 id + */ + void updateWalletRechargerPaid(Long walletRechargeId, Long payOrderId); +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java new file mode 100644 index 000000000..a68f034bc --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java @@ -0,0 +1,135 @@ +package cn.iocoder.yudao.module.pay.service.wallet; + +import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; +import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.recharge.AppPayWalletRechargeCreateReqVO; +import cn.iocoder.yudao.module.pay.convert.wallet.PayWalletRechargeConvert; +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletRechargeDO; +import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletRechargeMapper; +import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; +import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; +import cn.iocoder.yudao.module.pay.service.order.PayOrderService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.time.Duration; +import java.time.LocalDateTime; + +import static cn.hutool.core.util.ObjectUtil.notEqual; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.addTime; +import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; +import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; + +/** + * 钱包充值 Service 实现类 + * + * @author jason + */ +@Service +@Slf4j +public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { + /** + * TODO 放到 配置文件中 + */ + private static final Long WALLET_PAY_APP_ID = 8L; + + private static final String WALLET_RECHARGE_ORDER_SUBJECT = "钱包余额充值"; + + @Resource + private PayWalletRechargeMapper walletRechargeMapper; + @Resource + private PayWalletService payWalletService; + @Resource + private PayOrderService payOrderService; + + + @Override + @Transactional(rollbackFor = Exception.class) + public PayWalletRechargeDO createWalletRecharge(Long userId, Integer userType, AppPayWalletRechargeCreateReqVO vo) { + // 1. 获取钱包 + PayWalletDO wallet = payWalletService.getOrCreateWallet(userId, userType); + // 2. 新增钱包充值记录 + PayWalletRechargeDO walletRecharge = PayWalletRechargeConvert.INSTANCE.convert(wallet.getId(), vo); + walletRechargeMapper.insert(walletRecharge); + // 3.创建支付单 + Long payOrderId = payOrderService.createOrder(new PayOrderCreateReqDTO() + .setAppId(WALLET_PAY_APP_ID).setUserIp(getClientIP()) + .setMerchantOrderId(walletRecharge.getId().toString()) // 业务的订单编号 + .setSubject(WALLET_RECHARGE_ORDER_SUBJECT).setBody("").setPrice(walletRecharge.getPayPrice()) + .setExpireTime(addTime(Duration.ofHours(2L)))); + // 4.更新钱包充值记录中支付订单 + walletRechargeMapper.updateById(new PayWalletRechargeDO().setPayOrderId(payOrderId) + .setId(walletRecharge.getId())); + return walletRechargeMapper.selectById(walletRecharge.getId()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateWalletRechargerPaid(Long walletRechargeId, Long payOrderId) { + // 1. 获取钱包充值记录 + PayWalletRechargeDO walletRecharge = walletRechargeMapper.selectById(walletRechargeId); + if (walletRecharge == null) { + log.error("[updateWalletRechargerPaid],钱包充值记录不存在,钱包充值 Id:{} ", walletRechargeId); + throw exception(WALLET_RECHARGE_NOT_FOUND); + } + // 2. 校验钱包充值是否可以支付 + PayOrderDO payOrderDO = validateWalletRechargerCanPaid(walletRecharge, payOrderId); + // 3. 更新钱包充值的支付状态 + int updateCount = walletRechargeMapper.updateByIdAndPaid(walletRechargeId,false, new PayWalletRechargeDO().setId(walletRechargeId) + .setPayStatus(true).setPayTime(LocalDateTime.now()) + .setPayChannelCode(payOrderDO.getChannelCode())); + if (updateCount == 0) { + throw exception(WALLET_RECHARGE_UPDATE_PAID_STATUS_NOT_UNPAID); + } + // 4. 更新钱包余额 + payWalletService.addWalletBalance(walletRecharge.getWalletId(), String.valueOf(walletRechargeId), + PayWalletBizTypeEnum.RECHARGE, walletRecharge.getPrice()); + } + + private PayOrderDO validateWalletRechargerCanPaid(PayWalletRechargeDO walletRecharge, Long payOrderId) { + + // 1.1 校验充值记录的支付状态 + if (walletRecharge.getPayStatus()) { + log.error("[validateWalletRechargerCanPaid][钱包({}) 不处于未支付状态! 钱包数据是:{}]", + walletRecharge.getId(), toJsonString(walletRecharge)); + throw exception(WALLET_RECHARGE_UPDATE_PAID_STATUS_NOT_UNPAID); + } + // 1.2 校验支付订单匹配 + if (notEqual(walletRecharge.getPayOrderId(), payOrderId)) { // 支付单号 + log.error("[validateWalletRechargerCanPaid][钱包({}) 支付单不匹配({}),请进行处理! 钱包数据是:{}]", + walletRecharge.getId(), payOrderId, toJsonString(walletRecharge)); + throw exception(WALLET_RECHARGE_UPDATE_PAID_PAY_ORDER_ID_ERROR); + } + // 2.1 校验支付单是否存在 + PayOrderDO payOrder = payOrderService.getOrder(payOrderId); + if (payOrder == null) { + log.error("[validateWalletRechargerCanPaid][钱包({}) payOrder({}) 不存在,请进行处理!]", + walletRecharge.getId(), payOrderId); + throw exception(PAY_ORDER_NOT_FOUND); + } + // 2.2 校验支付单已支付 + if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) { + log.error("[validateWalletRechargerCanPaid][钱包({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]", + walletRecharge.getId(), payOrderId, toJsonString(payOrder)); + throw exception(WALLET_RECHARGE_UPDATE_PAID_PAY_ORDER_STATUS_NOT_SUCCESS); + } + // 2.3 校验支付金额一致 + if (notEqual(payOrder.getPrice(), walletRecharge.getPayPrice())) { + log.error("[validateDemoOrderCanPaid][钱包({}) payOrder({}) 支付金额不匹配,请进行处理!钱包 数据是:{},payOrder 数据是:{}]", + walletRecharge.getId(), payOrderId, toJsonString(walletRecharge), toJsonString(payOrder)); + throw exception(WALLET_RECHARGE_UPDATE_PAID_PAY_PRICE_NOT_MATCH); + } + // 2.4 校验支付订单的商户订单匹配 + if (notEqual(payOrder.getMerchantOrderId(), walletRecharge.getId().toString())) { + log.error("[validateDemoOrderCanPaid][钱包({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]", + walletRecharge.getId(), payOrderId, toJsonString(payOrder)); + throw exception(WALLET_RECHARGE_UPDATE_PAID_PAY_ORDER_ID_ERROR); + } + return payOrder; + } +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java index 28f9849b5..ed8dcee9f 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java @@ -21,6 +21,13 @@ public interface PayWalletService { */ PayWalletDO getOrCreateWallet(Long userId, Integer userType); + /** + * 获取钱包信息 + * + * @param walletId 钱包 id + */ + PayWalletDO getWallet(Long walletId); + /** * 钱包订单支付 * @@ -56,14 +63,13 @@ public interface PayWalletService { /** * 增加钱包余额 * - * @param userId 用户 id - * @param userType 用户类型 + * @param walletId 钱包 id * @param bizId 业务关联 id * @param bizType 业务关联分类 * @param price 增加金额 * @return 钱包流水 */ - PayWalletTransactionDO addWalletBalance(Long userId, Integer userType, - Long bizId, PayWalletBizTypeEnum bizType, Integer price); + PayWalletTransactionDO addWalletBalance(Long walletId, String bizId, + PayWalletBizTypeEnum bizType, Integer price); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java index 93c653154..8e24ed705 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java @@ -55,6 +55,11 @@ public class PayWalletServiceImpl implements PayWalletService { return wallet; } + @Override + public PayWalletDO getWallet(Long walletId) { + return walletMapper.selectById(walletId); + } + @Override @Transactional(rollbackFor = Exception.class) public PayWalletTransactionDO orderPay(Long userId, Integer userType, String outTradeNo, Integer price) { @@ -80,7 +85,7 @@ public class PayWalletServiceImpl implements PayWalletService { PayWalletDO wallet = walletMapper.selectById(walletId); Assert.notNull(wallet, "钱包 {} 不存在", walletId); // 2. 增加余额 - return addWalletBalance(wallet.getUserId(), wallet.getUserType(), payRefund.getId(), PAYMENT_REFUND, refundPrice); + return addWalletBalance(walletId, String.valueOf(payRefund.getId()), PAYMENT_REFUND, refundPrice); } /** @@ -139,25 +144,33 @@ public class PayWalletServiceImpl implements PayWalletService { } @Override - public PayWalletTransactionDO addWalletBalance(Long userId, Integer userType, - Long bizId, PayWalletBizTypeEnum bizType, Integer price) { + public PayWalletTransactionDO addWalletBalance(Long walletId, + String bizId, PayWalletBizTypeEnum bizType, Integer price) { // 1. 获取钱包 - PayWalletDO payWallet = getOrCreateWallet(userId, userType); + PayWalletDO payWallet = getWallet(walletId); + + if (payWallet == null) { + log.error("[addWalletBalance],用户钱包({})不存在.", walletId); + throw exception(WALLET_NOT_FOUND); + } + switch (bizType) { case PAYMENT_REFUND: { - // 更新退款 + // 退款更新 walletMapper.updateWhenConsumptionRefund(price, payWallet.getId()); break; } case RECHARGE: { - //TODO + // 充值更新 + walletMapper.updateWhenRecharge(price, payWallet.getId()); break; } + // TODO 其它类型 } // 2. 生成钱包流水 CreateWalletTransactionBO bo = new CreateWalletTransactionBO().setWalletId(payWallet.getId()) - .setPrice(price).setBalance(payWallet.getBalance()+price).setBizId(String.valueOf(bizId)) + .setPrice(price).setBalance(payWallet.getBalance()+price).setBizId(bizId) .setBizType(bizType.getType()).setTitle(bizType.getDescription()); return walletTransactionService.createWalletTransaction(bo); }