Commit c7f6f921598990cc0b3709e03e46628a9e8f7fbd
1 parent
1baa7f4a
钱包支付 Client 的实现
Showing
15 changed files
with
285 additions
and
6 deletions
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClientFactory.java
| 1 | 1 | package cn.iocoder.yudao.framework.pay.core.client; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.pay.core.client.impl.delegate.DelegatePayClient; | |
| 4 | + | |
| 3 | 5 | /** |
| 4 | 6 | * 支付客户端的工厂接口 |
| 5 | 7 | * |
| ... | ... | @@ -25,4 +27,6 @@ public interface PayClientFactory { |
| 25 | 27 | <Config extends PayClientConfig> void createOrUpdatePayClient(Long channelId, String channelCode, |
| 26 | 28 | Config config); |
| 27 | 29 | |
| 30 | + <Config extends PayClientConfig> void createOrUpdateDelegatePayClient(Long channelId, DelegatePayClient<Config> delegatePayClient); | |
| 31 | + | |
| 28 | 32 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/NonePayClientConfig.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.pay.core.client.impl; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; | |
| 4 | +import lombok.Data; | |
| 5 | + | |
| 6 | +import javax.validation.Validator; | |
| 7 | + | |
| 8 | +/** | |
| 9 | + * 无需任何配置 PayClientConfig 实现类 | |
| 10 | + * | |
| 11 | + * @author jason | |
| 12 | + */ | |
| 13 | +@Data | |
| 14 | +public class NonePayClientConfig implements PayClientConfig { | |
| 15 | + | |
| 16 | + /** | |
| 17 | + * 配置名称 | |
| 18 | + * <p> | |
| 19 | + * 如果不加任何属性,JsonUtils.parseObject2 解析会报错,所以暂时加个名称 | |
| 20 | + */ | |
| 21 | + private String name; | |
| 22 | + | |
| 23 | + public NonePayClientConfig(){ | |
| 24 | + this.name = "none-config"; | |
| 25 | + } | |
| 26 | + | |
| 27 | + @Override | |
| 28 | + public void validate(Validator validator) { | |
| 29 | + // 无任何配置不需要校验 | |
| 30 | + } | |
| 31 | +} | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java
| ... | ... | @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.pay.core.client.PayClient; |
| 5 | 5 | import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; |
| 6 | 6 | import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; |
| 7 | 7 | import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.*; |
| 8 | +import cn.iocoder.yudao.framework.pay.core.client.impl.delegate.DelegatePayClient; | |
| 8 | 9 | import cn.iocoder.yudao.framework.pay.core.client.impl.mock.MockPayClient; |
| 9 | 10 | import cn.iocoder.yudao.framework.pay.core.client.impl.mock.MockPayClientConfig; |
| 10 | 11 | import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.*; |
| ... | ... | @@ -51,6 +52,11 @@ public class PayClientFactoryImpl implements PayClientFactory { |
| 51 | 52 | } |
| 52 | 53 | } |
| 53 | 54 | |
| 55 | + @Override | |
| 56 | + public <Config extends PayClientConfig> void createOrUpdateDelegatePayClient(Long channelId, DelegatePayClient<Config> delegatePayClient) { | |
| 57 | + clients.put(channelId, delegatePayClient); | |
| 58 | + } | |
| 59 | + | |
| 54 | 60 | @SuppressWarnings("unchecked") |
| 55 | 61 | private <Config extends PayClientConfig> AbstractPayClient<Config> createPayClient( |
| 56 | 62 | Long channelId, String channelCode, Config config) { | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/delegate/DelegatePayClient.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.pay.core.client.impl.delegate; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; | |
| 4 | +import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; | |
| 5 | +import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; | |
| 6 | +import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; | |
| 7 | +import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; | |
| 8 | +import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; | |
| 9 | + | |
| 10 | +import java.util.Map; | |
| 11 | + | |
| 12 | +/** | |
| 13 | + * @author jason | |
| 14 | + */ | |
| 15 | +public abstract class DelegatePayClient<Config extends PayClientConfig> extends AbstractPayClient<PayClientConfig> { | |
| 16 | + | |
| 17 | + private final DelegatePayClient<Config> delegate; | |
| 18 | + | |
| 19 | + public DelegatePayClient(Long channelId, String channelCode, PayClientConfig config) { | |
| 20 | + super(channelId, channelCode, config); | |
| 21 | + delegate = this; | |
| 22 | + } | |
| 23 | + | |
| 24 | + @Override | |
| 25 | + protected void doInit() { | |
| 26 | + delegate.doInit(); | |
| 27 | + } | |
| 28 | + | |
| 29 | + @Override | |
| 30 | + protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) { | |
| 31 | + return delegate.doUnifiedOrder(reqDTO); | |
| 32 | + } | |
| 33 | + | |
| 34 | + @Override | |
| 35 | + protected PayOrderRespDTO doGetOrder(String outTradeNo) { | |
| 36 | + return delegate.doGetOrder(outTradeNo); | |
| 37 | + } | |
| 38 | + | |
| 39 | + @Override | |
| 40 | + protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) { | |
| 41 | + return delegate.doUnifiedRefund(reqDTO); | |
| 42 | + } | |
| 43 | + | |
| 44 | + @Override | |
| 45 | + protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) { | |
| 46 | + return delegate.doGetRefund(outTradeNo, outRefundNo); | |
| 47 | + } | |
| 48 | + | |
| 49 | + @Override | |
| 50 | + protected PayRefundRespDTO doParseRefundNotify(Map<String,String> params, String body) { | |
| 51 | + return delegate.doParseRefundNotify(params, body); | |
| 52 | + } | |
| 53 | + | |
| 54 | + @Override | |
| 55 | + protected PayOrderRespDTO doParseOrderNotify(Map<String,String> params, String body) { | |
| 56 | + return delegate.doParseOrderNotify(params, body); | |
| 57 | + } | |
| 58 | +} | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/channel/PayChannelEnum.java
| 1 | 1 | package cn.iocoder.yudao.framework.pay.core.enums.channel; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.util.ArrayUtil; |
| 4 | +import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig; | |
| 4 | 5 | import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; |
| 5 | 6 | import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig; |
| 6 | 7 | import cn.iocoder.yudao.framework.pay.core.client.impl.mock.MockPayClientConfig; |
| ... | ... | @@ -29,7 +30,9 @@ public enum PayChannelEnum { |
| 29 | 30 | ALIPAY_QR("alipay_qr", "支付宝扫码支付", AlipayPayClientConfig.class), |
| 30 | 31 | ALIPAY_BAR("alipay_bar", "支付宝条码支付", AlipayPayClientConfig.class), |
| 31 | 32 | |
| 32 | - MOCK("mock", "模拟支付", MockPayClientConfig.class); | |
| 33 | + MOCK("mock", "模拟支付", MockPayClientConfig.class), | |
| 34 | + | |
| 35 | + WALLET("wallet", "钱包支付", NonePayClientConfig.class); | |
| 33 | 36 | |
| 34 | 37 | /** |
| 35 | 38 | * 编码 | ... | ... |
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java
| ... | ... | @@ -43,6 +43,7 @@ public interface ErrorCodeConstants { |
| 43 | 43 | |
| 44 | 44 | // ========== 钱包模块(退款) 1007007000 ========== |
| 45 | 45 | ErrorCode WALLET_NOT_FOUND = new ErrorCode(1007007000, "用户钱包不存在"); |
| 46 | + ErrorCode WALLET_NOT_ENOUGH = new ErrorCode(1007007001, "钱包余额不足"); | |
| 46 | 47 | |
| 47 | 48 | // ========== 示例订单 1007900000 ========== |
| 48 | 49 | ErrorCode DEMO_ORDER_NOT_FOUND = new ErrorCode(1007900000, "示例订单不存在"); | ... | ... |
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/WalletBizTypeEnum.java
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.pay.framework.pay.wallet; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig; | |
| 4 | +import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; | |
| 5 | +import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; | |
| 6 | +import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; | |
| 7 | +import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; | |
| 8 | +import cn.iocoder.yudao.framework.pay.core.client.impl.delegate.DelegatePayClient; | |
| 9 | +import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; | |
| 10 | +import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService; | |
| 11 | +import lombok.extern.slf4j.Slf4j; | |
| 12 | + | |
| 13 | +import java.util.Map; | |
| 14 | + | |
| 15 | +/** | |
| 16 | + * 钱包支付的 PayClient 实现类 | |
| 17 | + * | |
| 18 | + * @author jason | |
| 19 | + */ | |
| 20 | +@Slf4j | |
| 21 | +public class WalletPayClient extends DelegatePayClient<NonePayClientConfig> { | |
| 22 | + | |
| 23 | + private PayWalletService payWalletService; | |
| 24 | + | |
| 25 | + public WalletPayClient(Long channelId, String channelCode, NonePayClientConfig config) { | |
| 26 | + super(channelId, channelCode, config); | |
| 27 | + } | |
| 28 | + | |
| 29 | + public WalletPayClient(Long channelId, String channelCode, NonePayClientConfig config, PayWalletService payWalletService) { | |
| 30 | + this(channelId, channelCode, config); | |
| 31 | + this.payWalletService = payWalletService; | |
| 32 | + } | |
| 33 | + | |
| 34 | + @Override | |
| 35 | + protected void doInit() { | |
| 36 | + // 钱包支付 无需初始化 | |
| 37 | + } | |
| 38 | + | |
| 39 | + @Override | |
| 40 | + protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) { | |
| 41 | + PayWalletTransactionDO payWalletTransaction = payWalletService.pay(reqDTO.getOutTradeNo(), reqDTO.getPrice()); | |
| 42 | + return PayOrderRespDTO.successOf(payWalletTransaction.getNo(), payWalletTransaction.getCreator(), | |
| 43 | + payWalletTransaction.getTransactionTime(), | |
| 44 | + reqDTO.getOutTradeNo(), ""); | |
| 45 | + } | |
| 46 | + | |
| 47 | + | |
| 48 | + @Override | |
| 49 | + protected PayOrderRespDTO doParseOrderNotify(Map<String, String> params, String body) { | |
| 50 | + throw new UnsupportedOperationException("钱包支付无支付回调"); | |
| 51 | + } | |
| 52 | + | |
| 53 | + @Override | |
| 54 | + protected PayOrderRespDTO doGetOrder(String outTradeNo) { | |
| 55 | + return null; | |
| 56 | + } | |
| 57 | + | |
| 58 | + @Override | |
| 59 | + protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) { | |
| 60 | + return null; | |
| 61 | + } | |
| 62 | + | |
| 63 | + @Override | |
| 64 | + protected PayRefundRespDTO doParseRefundNotify(Map<String, String> params, String body) { | |
| 65 | + throw new UnsupportedOperationException("钱包支付无退款回调"); | |
| 66 | + } | |
| 67 | + | |
| 68 | + @Override | |
| 69 | + protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) { | |
| 70 | + return null; | |
| 71 | + } | |
| 72 | +} | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceImpl.java
| ... | ... | @@ -6,6 +6,7 @@ import cn.hutool.core.util.ObjectUtil; |
| 6 | 6 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 7 | 7 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 8 | 8 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 9 | +import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig; | |
| 9 | 10 | import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; |
| 10 | 11 | import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; |
| 11 | 12 | import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; |
| ... | ... | @@ -15,6 +16,8 @@ import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateR |
| 15 | 16 | import cn.iocoder.yudao.module.pay.convert.channel.PayChannelConvert; |
| 16 | 17 | import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; |
| 17 | 18 | import cn.iocoder.yudao.module.pay.dal.mysql.channel.PayChannelMapper; |
| 19 | +import cn.iocoder.yudao.module.pay.framework.pay.wallet.WalletPayClient; | |
| 20 | +import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService; | |
| 18 | 21 | import lombok.Getter; |
| 19 | 22 | import lombok.Setter; |
| 20 | 23 | import lombok.extern.slf4j.Slf4j; |
| ... | ... | @@ -26,6 +29,7 @@ import javax.annotation.PostConstruct; |
| 26 | 29 | import javax.annotation.Resource; |
| 27 | 30 | import javax.validation.Validator; |
| 28 | 31 | import java.time.LocalDateTime; |
| 32 | +import java.util.ArrayList; | |
| 29 | 33 | import java.util.Collection; |
| 30 | 34 | import java.util.Collections; |
| 31 | 35 | import java.util.List; |
| ... | ... | @@ -56,6 +60,8 @@ public class PayChannelServiceImpl implements PayChannelService { |
| 56 | 60 | |
| 57 | 61 | @Resource |
| 58 | 62 | private Validator validator; |
| 63 | + @Resource | |
| 64 | + private PayWalletService payWalletService; | |
| 59 | 65 | |
| 60 | 66 | /** |
| 61 | 67 | * 初始化 {@link #payClientFactory} 缓存 |
| ... | ... | @@ -75,10 +81,24 @@ public class PayChannelServiceImpl implements PayChannelService { |
| 75 | 81 | log.error("[支付模块 yudao-module-pay - 表结构未导入][参考 https://doc.iocoder.cn/pay/build/ 开启]"); |
| 76 | 82 | } |
| 77 | 83 | log.info("[initLocalCache][缓存支付渠道,数量为:{}]", channels.size()); |
| 78 | - | |
| 84 | + List<PayChannelDO> walletChannels = new ArrayList<>(); | |
| 85 | + List<PayChannelDO> otherChannels = new ArrayList<>(); | |
| 86 | + channels.forEach(t -> { | |
| 87 | + if (PayChannelEnum.WALLET.getCode().equals(t.getCode())) { | |
| 88 | + walletChannels.add(t); | |
| 89 | + } else { | |
| 90 | + otherChannels.add(t); | |
| 91 | + } | |
| 92 | + }); | |
| 79 | 93 | // 第二步:构建缓存:创建或更新支付 Client |
| 80 | - channels.forEach(payChannel -> payClientFactory.createOrUpdatePayClient(payChannel.getId(), | |
| 94 | + otherChannels.forEach(payChannel -> payClientFactory.createOrUpdatePayClient(payChannel.getId(), | |
| 81 | 95 | payChannel.getCode(), payChannel.getConfig())); |
| 96 | + | |
| 97 | + walletChannels.forEach(payChannel -> { | |
| 98 | + WalletPayClient walletPayClient = new WalletPayClient(payChannel.getId(), payChannel.getCode(), | |
| 99 | + (NonePayClientConfig) payChannel.getConfig(), payWalletService); | |
| 100 | + payClientFactory.createOrUpdateDelegatePayClient(payChannel.getId(), walletPayClient); | |
| 101 | + }); | |
| 82 | 102 | this.channelCache = channels; |
| 83 | 103 | }); |
| 84 | 104 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java
| ... | ... | @@ -107,6 +107,14 @@ public interface PayOrderService { |
| 107 | 107 | PayOrderExtensionDO getOrderExtension(Long id); |
| 108 | 108 | |
| 109 | 109 | /** |
| 110 | + * 获得支付订单 | |
| 111 | + * | |
| 112 | + * @param no 支付订单 no | |
| 113 | + * @return 支付订单 | |
| 114 | + */ | |
| 115 | + PayOrderExtensionDO getOrderExtensionByNo(String no); | |
| 116 | + | |
| 117 | + /** | |
| 110 | 118 | * 同步订单的支付状态 |
| 111 | 119 | * |
| 112 | 120 | * @param minCreateTime 最小创建时间 | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java
| ... | ... | @@ -416,6 +416,11 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 416 | 416 | } |
| 417 | 417 | |
| 418 | 418 | @Override |
| 419 | + public PayOrderExtensionDO getOrderExtensionByNo(String no) { | |
| 420 | + return orderExtensionMapper.selectByNo(no); | |
| 421 | + } | |
| 422 | + | |
| 423 | + @Override | |
| 419 | 424 | public int syncOrder(LocalDateTime minCreateTime) { |
| 420 | 425 | // 1. 查询指定创建时间内的待支付订单 |
| 421 | 426 | List<PayOrderExtensionDO> orderExtensions = orderExtensionMapper.selectListByStatusAndCreateTimeGe( | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java
| 1 | 1 | package cn.iocoder.yudao.module.pay.service.wallet; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; |
| 4 | +import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; | |
| 4 | 5 | |
| 5 | 6 | /** |
| 6 | 7 | * 钱包 Service 接口 |
| ... | ... | @@ -15,4 +16,6 @@ public interface PayWalletService { |
| 15 | 16 | * @param userType 用户类型 |
| 16 | 17 | */ |
| 17 | 18 | PayWalletDO getPayWallet(Long userId, Integer userType); |
| 19 | + | |
| 20 | + PayWalletTransactionDO pay(String outTradeNo, Integer price); | |
| 18 | 21 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.pay.service.wallet; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; | |
| 3 | 4 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; |
| 5 | +import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; | |
| 4 | 6 | import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletMapper; |
| 7 | +import cn.iocoder.yudao.module.pay.dal.redis.no.PayNoRedisDAO; | |
| 8 | +import cn.iocoder.yudao.module.pay.service.order.PayOrderService; | |
| 9 | +import lombok.extern.slf4j.Slf4j; | |
| 10 | +import org.springframework.context.annotation.Lazy; | |
| 5 | 11 | import org.springframework.stereotype.Service; |
| 12 | +import org.springframework.transaction.annotation.Transactional; | |
| 6 | 13 | |
| 7 | 14 | import javax.annotation.Resource; |
| 8 | 15 | |
| 16 | +import java.time.LocalDateTime; | |
| 17 | + | |
| 18 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 19 | +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; | |
| 20 | +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserType; | |
| 21 | +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; | |
| 22 | +import static cn.iocoder.yudao.module.pay.enums.member.WalletBizTypeEnum.PAYMENT; | |
| 23 | + | |
| 9 | 24 | /** |
| 10 | 25 | * 钱包 Service 实现类 |
| 11 | 26 | * |
| 12 | 27 | * @author jason |
| 13 | 28 | */ |
| 14 | 29 | @Service |
| 30 | +@Slf4j | |
| 15 | 31 | public class PayWalletServiceImpl implements PayWalletService { |
| 16 | - | |
| 32 | + private static final String WALLET_CHANNEL_NO_PREFIX = "W"; | |
| 33 | + @Resource | |
| 34 | + @Lazy | |
| 35 | + private PayOrderService payOrderService; | |
| 17 | 36 | @Resource |
| 18 | 37 | private PayWalletMapper payWalletMapper; |
| 38 | + @Resource | |
| 39 | + private PayWalletTransactionService payWalletTransactionService; | |
| 40 | + @Resource | |
| 41 | + private PayNoRedisDAO noRedisDAO; | |
| 19 | 42 | |
| 20 | 43 | @Override |
| 21 | 44 | public PayWalletDO getPayWallet(Long userId, Integer userType) { |
| 22 | 45 | return payWalletMapper.selectByUserIdAndType(userId, userType); |
| 23 | 46 | } |
| 47 | + | |
| 48 | + @Override | |
| 49 | + @Transactional(rollbackFor = Exception.class) | |
| 50 | + public PayWalletTransactionDO pay(String outTradeNo, Integer price) { | |
| 51 | + // 判断支付交易拓展单是否存在 | |
| 52 | + PayOrderExtensionDO orderExtension = payOrderService.getOrderExtensionByNo(outTradeNo); | |
| 53 | + if (orderExtension == null) { | |
| 54 | + throw exception(ORDER_EXTENSION_NOT_FOUND); | |
| 55 | + } | |
| 56 | + Long userId = getLoginUserId(); | |
| 57 | + Integer userType = getLoginUserType(); | |
| 58 | + PayWalletDO payWallet = getPayWallet(userId, userType); | |
| 59 | + if (payWallet == null) { | |
| 60 | + log.error("[pay] 用户 {} 钱包不存在", userId); | |
| 61 | + throw exception(WALLET_NOT_FOUND); | |
| 62 | + } | |
| 63 | + // 判断余额是否足够 | |
| 64 | + int afterBalance = payWallet.getBalance() - price; | |
| 65 | + if(afterBalance < 0){ | |
| 66 | + throw exception(WALLET_NOT_ENOUGH); | |
| 67 | + } | |
| 68 | + payWallet.setBalance(afterBalance); | |
| 69 | + payWallet.setTotalExpense(payWallet.getTotalExpense() + price); | |
| 70 | + payWalletMapper.updateById(payWallet); | |
| 71 | + | |
| 72 | + // 生成钱包渠道流水号 | |
| 73 | + String walletNo = noRedisDAO.generate(WALLET_CHANNEL_NO_PREFIX); | |
| 74 | + PayWalletTransactionDO payWalletTransaction = new PayWalletTransactionDO().setWalletId(payWallet.getId()) | |
| 75 | + .setNo(walletNo).setAmount(price).setBalance(afterBalance).setTransactionTime(LocalDateTime.now()) | |
| 76 | + .setBizId(orderExtension.getOrderId()).setBizType(PAYMENT.getBizType()); | |
| 77 | + payWalletTransactionService.addPayWalletTransaction(payWalletTransaction); | |
| 78 | + | |
| 79 | + return payWalletTransaction; | |
| 80 | + } | |
| 24 | 81 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java
| ... | ... | @@ -20,4 +20,6 @@ public interface PayWalletTransactionService { |
| 20 | 20 | */ |
| 21 | 21 | PageResult<PayWalletTransactionDO> getWalletTransactionPage(Long userId, Integer userType, |
| 22 | 22 | AppPayWalletTransactionPageReqVO pageVO); |
| 23 | + | |
| 24 | + Long addPayWalletTransaction(PayWalletTransactionDO payWalletTransaction); | |
| 23 | 25 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionServiceImpl.java
| ... | ... | @@ -21,7 +21,7 @@ import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.WALLET_NOT_FO |
| 21 | 21 | */ |
| 22 | 22 | @Service |
| 23 | 23 | @Slf4j |
| 24 | -public class PayWalletTransactionServiceImpl implements PayWalletTransactionService{ | |
| 24 | +public class PayWalletTransactionServiceImpl implements PayWalletTransactionService { | |
| 25 | 25 | @Resource |
| 26 | 26 | private PayWalletService payWalletService; |
| 27 | 27 | @Resource |
| ... | ... | @@ -38,4 +38,12 @@ public class PayWalletTransactionServiceImpl implements PayWalletTransactionSer |
| 38 | 38 | return payWalletTransactionMapper.selectPageByWalletIdAndQueryType(payWallet.getId(), |
| 39 | 39 | WalletTransactionQueryTypeEnum.valueOf(pageVO.getType()), pageVO); |
| 40 | 40 | } |
| 41 | + | |
| 42 | + @Override | |
| 43 | + public Long addPayWalletTransaction(PayWalletTransactionDO payWalletTransaction) { | |
| 44 | + payWalletTransactionMapper.insert(payWalletTransaction); | |
| 45 | + return payWalletTransaction.getId(); | |
| 46 | + } | |
| 47 | + | |
| 48 | + | |
| 41 | 49 | } | ... | ... |