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 | package cn.iocoder.yudao.framework.pay.core.client; | 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,4 +27,6 @@ public interface PayClientFactory { | ||
| 25 | <Config extends PayClientConfig> void createOrUpdatePayClient(Long channelId, String channelCode, | 27 | <Config extends PayClientConfig> void createOrUpdatePayClient(Long channelId, String channelCode, |
| 26 | Config config); | 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,6 +5,7 @@ import cn.iocoder.yudao.framework.pay.core.client.PayClient; | ||
| 5 | import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; | 5 | import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; |
| 6 | import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; | 6 | import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; |
| 7 | import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.*; | 7 | import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.*; |
| 8 | +import cn.iocoder.yudao.framework.pay.core.client.impl.delegate.DelegatePayClient; | ||
| 8 | import cn.iocoder.yudao.framework.pay.core.client.impl.mock.MockPayClient; | 9 | import cn.iocoder.yudao.framework.pay.core.client.impl.mock.MockPayClient; |
| 9 | import cn.iocoder.yudao.framework.pay.core.client.impl.mock.MockPayClientConfig; | 10 | import cn.iocoder.yudao.framework.pay.core.client.impl.mock.MockPayClientConfig; |
| 10 | import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.*; | 11 | import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.*; |
| @@ -51,6 +52,11 @@ public class PayClientFactoryImpl implements PayClientFactory { | @@ -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 | @SuppressWarnings("unchecked") | 60 | @SuppressWarnings("unchecked") |
| 55 | private <Config extends PayClientConfig> AbstractPayClient<Config> createPayClient( | 61 | private <Config extends PayClientConfig> AbstractPayClient<Config> createPayClient( |
| 56 | Long channelId, String channelCode, Config config) { | 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 | package cn.iocoder.yudao.framework.pay.core.enums.channel; | 1 | package cn.iocoder.yudao.framework.pay.core.enums.channel; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.util.ArrayUtil; | 3 | import cn.hutool.core.util.ArrayUtil; |
| 4 | +import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig; | ||
| 4 | import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; | 5 | import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; |
| 5 | import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig; | 6 | import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig; |
| 6 | import cn.iocoder.yudao.framework.pay.core.client.impl.mock.MockPayClientConfig; | 7 | import cn.iocoder.yudao.framework.pay.core.client.impl.mock.MockPayClientConfig; |
| @@ -29,7 +30,9 @@ public enum PayChannelEnum { | @@ -29,7 +30,9 @@ public enum PayChannelEnum { | ||
| 29 | ALIPAY_QR("alipay_qr", "支付宝扫码支付", AlipayPayClientConfig.class), | 30 | ALIPAY_QR("alipay_qr", "支付宝扫码支付", AlipayPayClientConfig.class), |
| 30 | ALIPAY_BAR("alipay_bar", "支付宝条码支付", AlipayPayClientConfig.class), | 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,6 +43,7 @@ public interface ErrorCodeConstants { | ||
| 43 | 43 | ||
| 44 | // ========== 钱包模块(退款) 1007007000 ========== | 44 | // ========== 钱包模块(退款) 1007007000 ========== |
| 45 | ErrorCode WALLET_NOT_FOUND = new ErrorCode(1007007000, "用户钱包不存在"); | 45 | ErrorCode WALLET_NOT_FOUND = new ErrorCode(1007007000, "用户钱包不存在"); |
| 46 | + ErrorCode WALLET_NOT_ENOUGH = new ErrorCode(1007007001, "钱包余额不足"); | ||
| 46 | 47 | ||
| 47 | // ========== 示例订单 1007900000 ========== | 48 | // ========== 示例订单 1007900000 ========== |
| 48 | ErrorCode DEMO_ORDER_NOT_FOUND = new ErrorCode(1007900000, "示例订单不存在"); | 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
| @@ -12,7 +12,8 @@ import lombok.Getter; | @@ -12,7 +12,8 @@ import lombok.Getter; | ||
| 12 | @Getter | 12 | @Getter |
| 13 | public enum WalletBizTypeEnum { | 13 | public enum WalletBizTypeEnum { |
| 14 | RECHARGE(1, "充值"), | 14 | RECHARGE(1, "充值"), |
| 15 | - RECHARGE_REFUND(2, "充值退款"); | 15 | + RECHARGE_REFUND(2, "充值退款"), |
| 16 | + PAYMENT(3, "支付"); | ||
| 16 | 17 | ||
| 17 | // TODO 后续增加 | 18 | // TODO 后续增加 |
| 18 | /** | 19 | /** |
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 +6,7 @@ import cn.hutool.core.util.ObjectUtil; | ||
| 6 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | 6 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 7 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | 7 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 8 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | 8 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 9 | +import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig; | ||
| 9 | import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; | 10 | import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; |
| 10 | import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; | 11 | import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; |
| 11 | import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; | 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,6 +16,8 @@ import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateR | ||
| 15 | import cn.iocoder.yudao.module.pay.convert.channel.PayChannelConvert; | 16 | import cn.iocoder.yudao.module.pay.convert.channel.PayChannelConvert; |
| 16 | import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; | 17 | import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; |
| 17 | import cn.iocoder.yudao.module.pay.dal.mysql.channel.PayChannelMapper; | 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 | import lombok.Getter; | 21 | import lombok.Getter; |
| 19 | import lombok.Setter; | 22 | import lombok.Setter; |
| 20 | import lombok.extern.slf4j.Slf4j; | 23 | import lombok.extern.slf4j.Slf4j; |
| @@ -26,6 +29,7 @@ import javax.annotation.PostConstruct; | @@ -26,6 +29,7 @@ import javax.annotation.PostConstruct; | ||
| 26 | import javax.annotation.Resource; | 29 | import javax.annotation.Resource; |
| 27 | import javax.validation.Validator; | 30 | import javax.validation.Validator; |
| 28 | import java.time.LocalDateTime; | 31 | import java.time.LocalDateTime; |
| 32 | +import java.util.ArrayList; | ||
| 29 | import java.util.Collection; | 33 | import java.util.Collection; |
| 30 | import java.util.Collections; | 34 | import java.util.Collections; |
| 31 | import java.util.List; | 35 | import java.util.List; |
| @@ -56,6 +60,8 @@ public class PayChannelServiceImpl implements PayChannelService { | @@ -56,6 +60,8 @@ public class PayChannelServiceImpl implements PayChannelService { | ||
| 56 | 60 | ||
| 57 | @Resource | 61 | @Resource |
| 58 | private Validator validator; | 62 | private Validator validator; |
| 63 | + @Resource | ||
| 64 | + private PayWalletService payWalletService; | ||
| 59 | 65 | ||
| 60 | /** | 66 | /** |
| 61 | * 初始化 {@link #payClientFactory} 缓存 | 67 | * 初始化 {@link #payClientFactory} 缓存 |
| @@ -75,10 +81,24 @@ public class PayChannelServiceImpl implements PayChannelService { | @@ -75,10 +81,24 @@ public class PayChannelServiceImpl implements PayChannelService { | ||
| 75 | log.error("[支付模块 yudao-module-pay - 表结构未导入][参考 https://doc.iocoder.cn/pay/build/ 开启]"); | 81 | log.error("[支付模块 yudao-module-pay - 表结构未导入][参考 https://doc.iocoder.cn/pay/build/ 开启]"); |
| 76 | } | 82 | } |
| 77 | log.info("[initLocalCache][缓存支付渠道,数量为:{}]", channels.size()); | 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 | // 第二步:构建缓存:创建或更新支付 Client | 93 | // 第二步:构建缓存:创建或更新支付 Client |
| 80 | - channels.forEach(payChannel -> payClientFactory.createOrUpdatePayClient(payChannel.getId(), | 94 | + otherChannels.forEach(payChannel -> payClientFactory.createOrUpdatePayClient(payChannel.getId(), |
| 81 | payChannel.getCode(), payChannel.getConfig())); | 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 | this.channelCache = channels; | 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,6 +107,14 @@ public interface PayOrderService { | ||
| 107 | PayOrderExtensionDO getOrderExtension(Long id); | 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 | * @param minCreateTime 最小创建时间 | 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,6 +416,11 @@ public class PayOrderServiceImpl implements PayOrderService { | ||
| 416 | } | 416 | } |
| 417 | 417 | ||
| 418 | @Override | 418 | @Override |
| 419 | + public PayOrderExtensionDO getOrderExtensionByNo(String no) { | ||
| 420 | + return orderExtensionMapper.selectByNo(no); | ||
| 421 | + } | ||
| 422 | + | ||
| 423 | + @Override | ||
| 419 | public int syncOrder(LocalDateTime minCreateTime) { | 424 | public int syncOrder(LocalDateTime minCreateTime) { |
| 420 | // 1. 查询指定创建时间内的待支付订单 | 425 | // 1. 查询指定创建时间内的待支付订单 |
| 421 | List<PayOrderExtensionDO> orderExtensions = orderExtensionMapper.selectListByStatusAndCreateTimeGe( | 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 | package cn.iocoder.yudao.module.pay.service.wallet; | 1 | package cn.iocoder.yudao.module.pay.service.wallet; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; | 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 | * 钱包 Service 接口 | 7 | * 钱包 Service 接口 |
| @@ -15,4 +16,6 @@ public interface PayWalletService { | @@ -15,4 +16,6 @@ public interface PayWalletService { | ||
| 15 | * @param userType 用户类型 | 16 | * @param userType 用户类型 |
| 16 | */ | 17 | */ |
| 17 | PayWalletDO getPayWallet(Long userId, Integer userType); | 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 | package cn.iocoder.yudao.module.pay.service.wallet; | 1 | package cn.iocoder.yudao.module.pay.service.wallet; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; | ||
| 3 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; | 4 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; |
| 5 | +import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; | ||
| 4 | import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletMapper; | 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 | import org.springframework.stereotype.Service; | 11 | import org.springframework.stereotype.Service; |
| 12 | +import org.springframework.transaction.annotation.Transactional; | ||
| 6 | 13 | ||
| 7 | import javax.annotation.Resource; | 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 | * 钱包 Service 实现类 | 25 | * 钱包 Service 实现类 |
| 11 | * | 26 | * |
| 12 | * @author jason | 27 | * @author jason |
| 13 | */ | 28 | */ |
| 14 | @Service | 29 | @Service |
| 30 | +@Slf4j | ||
| 15 | public class PayWalletServiceImpl implements PayWalletService { | 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 | @Resource | 36 | @Resource |
| 18 | private PayWalletMapper payWalletMapper; | 37 | private PayWalletMapper payWalletMapper; |
| 38 | + @Resource | ||
| 39 | + private PayWalletTransactionService payWalletTransactionService; | ||
| 40 | + @Resource | ||
| 41 | + private PayNoRedisDAO noRedisDAO; | ||
| 19 | 42 | ||
| 20 | @Override | 43 | @Override |
| 21 | public PayWalletDO getPayWallet(Long userId, Integer userType) { | 44 | public PayWalletDO getPayWallet(Long userId, Integer userType) { |
| 22 | return payWalletMapper.selectByUserIdAndType(userId, userType); | 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,4 +20,6 @@ public interface PayWalletTransactionService { | ||
| 20 | */ | 20 | */ |
| 21 | PageResult<PayWalletTransactionDO> getWalletTransactionPage(Long userId, Integer userType, | 21 | PageResult<PayWalletTransactionDO> getWalletTransactionPage(Long userId, Integer userType, |
| 22 | AppPayWalletTransactionPageReqVO pageVO); | 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,7 +21,7 @@ import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.WALLET_NOT_FO | ||
| 21 | */ | 21 | */ |
| 22 | @Service | 22 | @Service |
| 23 | @Slf4j | 23 | @Slf4j |
| 24 | -public class PayWalletTransactionServiceImpl implements PayWalletTransactionService{ | 24 | +public class PayWalletTransactionServiceImpl implements PayWalletTransactionService { |
| 25 | @Resource | 25 | @Resource |
| 26 | private PayWalletService payWalletService; | 26 | private PayWalletService payWalletService; |
| 27 | @Resource | 27 | @Resource |
| @@ -38,4 +38,12 @@ public class PayWalletTransactionServiceImpl implements PayWalletTransactionSer | @@ -38,4 +38,12 @@ public class PayWalletTransactionServiceImpl implements PayWalletTransactionSer | ||
| 38 | return payWalletTransactionMapper.selectPageByWalletIdAndQueryType(payWallet.getId(), | 38 | return payWalletTransactionMapper.selectPageByWalletIdAndQueryType(payWallet.getId(), |
| 39 | WalletTransactionQueryTypeEnum.valueOf(pageVO.getType()), pageVO); | 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 | } |