From 3b9548aa2dad920740b70d1e8e15404d98ad9a2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=97=B4=E8=B4=A7?= <252048765@qq.com> Date: Tue, 1 Oct 2024 12:16:10 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E8=BD=AC=E8=B4=A6?= =?UTF-8?q?=E6=9C=AA=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BrokerageWithdrawController.java | 5 +- .../brokerage/BrokerageWithdrawService.java | 2 +- .../BrokerageWithdrawServiceImpl.java | 46 ++++++- .../transfer/PayTransferServiceImpl.java | 4 +- .../yudao-spring-boot-starter-biz-pay/pom.xml | 5 + .../transfer/PayTransferUnifiedReqDTO.java | 9 ++ .../impl/weixin/AbstractWxPayClient.java | 29 ++++- .../bean/transfer/TransferBatchesRequest.java | 118 ++++++++++++++++++ 8 files changed, 207 insertions(+), 11 deletions(-) create mode 100644 yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBatchesRequest.java diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java index bb35c0d7f4..8e33e403d8 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java @@ -24,6 +24,7 @@ import java.util.Map; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; @Tag(name = "管理后台 - 佣金提现") @RestController @@ -41,7 +42,7 @@ public class BrokerageWithdrawController { @Operation(summary = "通过申请") @PreAuthorize("@ss.hasPermission('trade:brokerage-withdraw:audit')") public CommonResult approveBrokerageWithdraw(@RequestParam("id") Integer id) { - brokerageWithdrawService.auditBrokerageWithdraw(id, BrokerageWithdrawStatusEnum.AUDIT_SUCCESS, ""); + brokerageWithdrawService.auditBrokerageWithdraw(id, BrokerageWithdrawStatusEnum.AUDIT_SUCCESS, "", getClientIP()); return success(true); } @@ -49,7 +50,7 @@ public class BrokerageWithdrawController { @Operation(summary = "驳回申请") @PreAuthorize("@ss.hasPermission('trade:brokerage-withdraw:audit')") public CommonResult rejectBrokerageWithdraw(@Valid @RequestBody BrokerageWithdrawRejectReqVO reqVO) { - brokerageWithdrawService.auditBrokerageWithdraw(reqVO.getId(), BrokerageWithdrawStatusEnum.AUDIT_FAIL, reqVO.getAuditReason()); + brokerageWithdrawService.auditBrokerageWithdraw(reqVO.getId(), BrokerageWithdrawStatusEnum.AUDIT_FAIL, reqVO.getAuditReason(), getClientIP()); return success(true); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawService.java index 04ea9c49bc..865b4c97b1 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawService.java @@ -28,7 +28,7 @@ public interface BrokerageWithdrawService { * @param status 审核状态 * @param auditReason 驳回原因 */ - void auditBrokerageWithdraw(Integer id, BrokerageWithdrawStatusEnum status, String auditReason); + void auditBrokerageWithdraw(Integer id, BrokerageWithdrawStatusEnum status, String auditReason, String userIp); /** * 获得佣金提现 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java index 86814f8a55..0b6d88bfc0 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java @@ -4,20 +4,29 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; +import cn.iocoder.yudao.module.pay.api.transfer.PayTransferApi; +import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; +import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferTypeEnum; import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi; import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO; +import cn.iocoder.yudao.module.system.api.social.SocialUserApi; +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; +import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawPageReqVO; import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawCreateReqVO; import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageWithdrawConvert; import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO; import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO; import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageWithdrawMapper; +import cn.iocoder.yudao.module.trade.dal.redis.no.TradeNoRedisDAO; import cn.iocoder.yudao.module.trade.enums.MessageTemplateConstants; import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum; import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum; import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawTypeEnum; +import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageWithdrawSummaryRespBO; import cn.iocoder.yudao.module.trade.service.config.TradeConfigService; import org.springframework.stereotype.Service; @@ -27,12 +36,10 @@ import org.springframework.validation.annotation.Validated; import jakarta.annotation.Resource; import jakarta.validation.Validator; import java.time.LocalDateTime; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.trade.dal.redis.no.TradeNoRedisDAO.TRADE_ORDER_NO_PREFIX; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; /** @@ -46,6 +53,8 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { @Resource private BrokerageWithdrawMapper brokerageWithdrawMapper; + @Resource + private TradeNoRedisDAO tradeNoRedisDAO; @Resource private BrokerageRecordService brokerageRecordService; @@ -54,15 +63,23 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { @Resource private NotifyMessageSendApi notifyMessageSendApi; + @Resource + private PayTransferApi payTransferApi; + @Resource + private SocialUserApi socialUserApi; @Resource private Validator validator; + @Resource + private TradeOrderProperties tradeOrderProperties; + @Override @Transactional(rollbackFor = Exception.class) - public void auditBrokerageWithdraw(Integer id, BrokerageWithdrawStatusEnum status, String auditReason) { + public void auditBrokerageWithdraw(Integer id, BrokerageWithdrawStatusEnum status, String auditReason, String userIp) { // 1.1 校验存在 BrokerageWithdrawDO withdraw = validateBrokerageWithdrawExists(id); + // 1.2 校验状态为审核中 if (ObjectUtil.notEqual(BrokerageWithdrawStatusEnum.AUDITING.getStatus(), withdraw.getStatus())) { throw exception(BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING); @@ -81,6 +98,12 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { // 3.1 通过时佣金转余额 if (BrokerageWithdrawTypeEnum.WALLET.getType().equals(withdraw.getType())) { // todo 疯狂: + }else if (BrokerageWithdrawTypeEnum.WECHAT.getType().equals(withdraw.getType())){ + //获取openid + SocialUserRespDTO socialUser = socialUserApi.getSocialUserByUserId(UserTypeEnum.MEMBER.getValue(), withdraw.getUserId(), SocialTypeEnum.WECHAT_MINI_APP.getType()); + // 微信提现 + PayTransferCreateReqDTO payTransferCreateReqDTO = getPayTransferCreateReqDTO(userIp, withdraw, socialUser); + payTransferApi.createTransfer(payTransferCreateReqDTO); } // TODO 疯狂:调用转账接口 } else if (BrokerageWithdrawStatusEnum.AUDIT_FAIL.equals(status)) { @@ -102,6 +125,19 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { .setUserId(withdraw.getUserId()).setTemplateCode(templateCode).setTemplateParams(templateParams)); } + private PayTransferCreateReqDTO getPayTransferCreateReqDTO(String userIp, BrokerageWithdrawDO withdraw, SocialUserRespDTO socialUser) { + PayTransferCreateReqDTO payTransferCreateReqDTO = new PayTransferCreateReqDTO(); + payTransferCreateReqDTO.setAppKey(tradeOrderProperties.getPayAppKey()); + payTransferCreateReqDTO.setChannelCode("wx_lite"); + payTransferCreateReqDTO.setUserIp(userIp); + payTransferCreateReqDTO.setType(PayTransferTypeEnum.WX_BALANCE.getType()); + payTransferCreateReqDTO.setMerchantTransferId(withdraw.getId().toString()); + payTransferCreateReqDTO.setPrice(withdraw.getPrice()); + payTransferCreateReqDTO.setSubject("佣金提现"); + payTransferCreateReqDTO.setOpenid(socialUser.getOpenid()); + return payTransferCreateReqDTO; + } + private BrokerageWithdrawDO validateBrokerageWithdrawExists(Integer id) { BrokerageWithdrawDO withdraw = brokerageWithdrawMapper.selectById(id); if (withdraw == null) { diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java index 5ace5ab4be..04d86d1848 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java @@ -96,13 +96,15 @@ public class PayTransferServiceImpl implements PayTransferService { transfer = INSTANCE.convert(reqDTO) .setChannelId(channel.getId()) .setNo(no).setStatus(WAITING.getStatus()) - .setNotifyUrl(payApp.getTransferNotifyUrl()); + .setNotifyUrl(payApp.getTransferNotifyUrl()) + .setAppId(channel.getAppId()); transferMapper.insert(transfer); } try { // 3. 调用三方渠道发起转账 PayTransferUnifiedReqDTO transferUnifiedReq = INSTANCE.convert2(transfer) .setOutTransferNo(transfer.getNo()); + transferUnifiedReq.setNotifyUrl(payApp.getTransferNotifyUrl()); PayTransferRespDTO unifiedTransferResp = client.unifiedTransfer(transferUnifiedReq); // 4. 通知转账结果 getSelf().notifyTransfer(channel, unifiedTransferResp); diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/pom.xml b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/pom.xml index 93193d008e..c214af0f50 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/pom.xml +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/pom.xml @@ -64,6 +64,10 @@ com.github.binarywang weixin-java-pay + + com.github.binarywang + wx-java-miniapp-spring-boot-starter + @@ -71,6 +75,7 @@ yudao-spring-boot-starter-test test + diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java index 43afa86a30..61501cc58b 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java @@ -9,6 +9,8 @@ import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; +import org.hibernate.validator.constraints.URL; + import java.util.Map; import static cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum.*; @@ -75,4 +77,11 @@ public class PayTransferUnifiedReqDTO { * 支付渠道的额外参数 */ private Map channelExtras; + + /** + * 转账结果的 notify 回调地址 + */ + @NotEmpty(message = "转账结果的回调地址不能为空") + @URL(message = "转账结果的 notify 回调地址必须是 URL 格式") + private String notifyUrl; } diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java index 298e314d85..f5c753b8e3 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java @@ -17,20 +17,27 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifie import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum; import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum; +import com.binarywang.spring.starter.wxjava.miniapp.properties.WxMaProperties; import com.github.binarywang.wxpay.bean.notify.WxPayNotifyV3Result; import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult; import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyV3Result; import com.github.binarywang.wxpay.bean.request.*; import com.github.binarywang.wxpay.bean.result.*; +import com.github.binarywang.wxpay.bean.transfer.TransferBatchesRequest; +import com.github.binarywang.wxpay.bean.transfer.TransferBatchesResult; import com.github.binarywang.wxpay.config.WxPayConfig; import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.service.TransferService; import com.github.binarywang.wxpay.service.WxPayService; import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; +import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import java.time.LocalDateTime; import java.time.ZoneId; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.Objects; @@ -426,8 +433,26 @@ public abstract class AbstractWxPayClient extends AbstractPayClient transferDetailList = new ArrayList<>(); + transferDetailList.add(TransferBatchesRequest.TransferDetail.newBuilder() + .outDetailNo(reqDTO.getOutTransferNo()) + .transferAmount(reqDTO.getPrice()) + .transferRemark(reqDTO.getSubject()) + .openid(reqDTO.getOpenid()) + .build()); + TransferBatchesRequest transferBatches = TransferBatchesRequest.newBuilder() + .appid(this.config.getAppId()) + .outBatchNo(reqDTO.getOutTransferNo()) + .batchName(reqDTO.getSubject()) + .batchRemark(reqDTO.getSubject()) + .totalAmount(reqDTO.getPrice()) + .totalNum(1) + .transferDetailList(transferDetailList).build(); + transferBatches.setNotifyUrl(reqDTO.getNotifyUrl()); + TransferBatchesResult transferBatchesResult = transferService.transferBatches(transferBatches); + return PayTransferRespDTO.waitingOf(reqDTO.getOutTransferNo(), transferBatchesResult.getBatchId() ,transferBatchesResult); } @Override diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBatchesRequest.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBatchesRequest.java new file mode 100644 index 0000000000..72296daa83 --- /dev/null +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBatchesRequest.java @@ -0,0 +1,118 @@ +package com.github.binarywang.wxpay.bean.transfer; + +import com.github.binarywang.wxpay.v3.SpecEncrypt; +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + * 发起商家转账API参数 + * + * @author zhongjun + * created on 2022/6/17 + **/ +@Data +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor +public class TransferBatchesRequest implements Serializable { + private static final long serialVersionUID = -2175582517588397426L; + + /** + * 直连商户的appid + */ + @SerializedName("appid") + private String appid; + + /** + * 商家批次单号 + */ + @SerializedName("out_batch_no") + private String outBatchNo; + + /** + * 批次名称 + */ + @SerializedName("batch_name") + private String batchName; + + /** + * 批次备注 + */ + @SerializedName("batch_remark") + private String batchRemark; + + /** + * 转账总金额 + */ + @SerializedName("total_amount") + private Integer totalAmount; + + /** + * 转账总笔数 + */ + @SerializedName("total_num") + private Integer totalNum; + + /** + * 转账明细列表 + */ + @SpecEncrypt + @SerializedName("transfer_detail_list") + private List transferDetailList; + + /** + * 转账场景ID + */ + @SerializedName("transfer_scene_id") + private String transferSceneId; + + /** + * 通知地址 说明:异步接收微信支付结果通知的回调地址,通知url必须为公网可访问的url,必须为https,不能携带参数。 + */ + @SerializedName("notify_url") + private String notifyUrl; + + @Data + @Builder(builderMethodName = "newBuilder") + @AllArgsConstructor + @NoArgsConstructor + public static class TransferDetail { + + /** + * 商家明细单号 + */ + @SerializedName("out_detail_no") + private String outDetailNo; + + /** + * 转账金额 + */ + @SerializedName("transfer_amount") + private Integer transferAmount; + + /** + * 转账备注 + */ + @SerializedName("transfer_remark") + private String transferRemark; + + /** + * 用户在直连商户应用下的用户标示 + */ + @SerializedName("openid") + private String openid; + + /** + * 收款用户姓名 + */ + @SpecEncrypt + @SerializedName("user_name") + private String userName; + } +} From e025b52ff4b29a44aae486d812326b9163ebce93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=97=B4=E8=B4=A7?= <252048765@qq.com> Date: Tue, 1 Oct 2024 14:42:25 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E8=BD=AC=E8=B4=A6?= =?UTF-8?q?=E6=9C=AA=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/trade/enums/brokerage/BrokerageWithdrawTypeEnum.java | 1 + .../trade/service/brokerage/BrokerageWithdrawServiceImpl.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageWithdrawTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageWithdrawTypeEnum.java index 46edf010e9..67113b2ba6 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageWithdrawTypeEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageWithdrawTypeEnum.java @@ -19,6 +19,7 @@ public enum BrokerageWithdrawTypeEnum implements IntArrayValuable { BANK(2, "银行卡"), WECHAT(3, "微信"), ALIPAY(4, "支付宝"), + ALIPAY_SMALL(5, "微信零钱"), ; public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageWithdrawTypeEnum::getType).toArray(); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java index 0b6d88bfc0..7799b41fa6 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java @@ -98,7 +98,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { // 3.1 通过时佣金转余额 if (BrokerageWithdrawTypeEnum.WALLET.getType().equals(withdraw.getType())) { // todo 疯狂: - }else if (BrokerageWithdrawTypeEnum.WECHAT.getType().equals(withdraw.getType())){ + }else if (BrokerageWithdrawTypeEnum.ALIPAY_SMALL.getType().equals(withdraw.getType())){ //获取openid SocialUserRespDTO socialUser = socialUserApi.getSocialUserByUserId(UserTypeEnum.MEMBER.getValue(), withdraw.getUserId(), SocialTypeEnum.WECHAT_MINI_APP.getType()); // 微信提现 From ae1cf9e098d2a53d16970486897bac494744a560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=97=B4=E8=B4=A7?= <252048765@qq.com> Date: Fri, 4 Oct 2024 10:22:34 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E3=80=90=E5=8A=9F=E8=83=BD=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E3=80=91=E5=A2=9E=E5=8A=A0=E8=BD=AC=E8=B4=A6=E5=9B=9E?= =?UTF-8?q?=E8=B0=83=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../brokerage/BrokerageWithdrawController.java | 14 ++++++++++++++ .../pay/controller/admin/app/vo/PayAppBaseVO.java | 5 +++++ 2 files changed, 19 insertions(+) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java index 8e33e403d8..8c1b60f06b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.member.api.user.MemberUserApi; import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.pay.api.notify.dto.PayTransferNotifyReqDTO; import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawRejectReqVO; import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawPageReqVO; import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawRespVO; @@ -14,6 +15,8 @@ import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageWithdrawService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.security.PermitAll; +import lombok.extern.slf4j.Slf4j; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -30,6 +33,7 @@ import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getCli @RestController @RequestMapping("/trade/brokerage-withdraw") @Validated +@Slf4j public class BrokerageWithdrawController { @Resource @@ -76,4 +80,14 @@ public class BrokerageWithdrawController { return success(BrokerageWithdrawConvert.INSTANCE.convertPage(pageResult, userMap)); } + @PostMapping("/update-transfer") + @Operation(summary = "更新转账订单为转账成功") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob + @PermitAll // 无需登录,安全由 PayDemoOrderService 内部校验实现 + public CommonResult updateAfterRefund(@RequestBody PayTransferNotifyReqDTO notifyReqDTO) { + // 目前业务逻辑,不需要做任何事情 + // 当然,退款会有小概率会失败的情况,可以监控失败状态,进行告警 + log.info("[updateAfterRefund][notifyReqDTO({})]", notifyReqDTO); + return success(true); + } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppBaseVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppBaseVO.java index d6cabdc50d..08a7604d1b 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppBaseVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppBaseVO.java @@ -40,4 +40,9 @@ public class PayAppBaseVO { @URL(message = "退款结果的回调地址必须为 URL 格式") private String refundNotifyUrl; + @Schema(description = "转账结果的回调地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "http://127.0.0.1:48080/refund-callback") + @NotNull(message = "转账结果的回调地址不能为空") + @URL(message = "转账结果的回调地址必须为 URL 格式") + private String transferNotifyUrl; + } From 325d5e6b121cb95420bc96ccfd0b69050d7bf26a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=97=B4=E8=B4=A7?= <252048765@qq.com> Date: Sat, 5 Oct 2024 21:32:36 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E3=80=90=E5=8A=9F=E8=83=BD=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E3=80=91=E5=AE=8C=E6=88=90=E8=BD=AC=E8=B4=A6=E5=9B=9E?= =?UTF-8?q?=E8=B0=83=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../brokerage/BrokerageRecordController.java | 2 +- .../BrokerageWithdrawController.java | 5 +- .../vo/record/BrokerageRecordRespVO.java | 2 +- .../BrokerageWithdrawRejectReqVO.java | 2 +- .../vo/withdraw/BrokerageWithdrawRespVO.java | 2 +- .../brokerage/BrokerageWithdrawMapper.java | 2 +- .../brokerage/BrokerageRecordService.java | 2 +- .../brokerage/BrokerageRecordServiceImpl.java | 2 +- .../brokerage/BrokerageWithdrawService.java | 10 +- .../BrokerageWithdrawServiceImpl.java | 41 ++++-- .../pay/api/transfer/PayTransferApi.java | 7 + .../api/transfer/dto/PayTransferRespDTO.java | 32 +++++ .../pay/api/transfer/PayTransferApiImpl.java | 9 ++ .../admin/notify/PayNotifyController.java | 24 ++++ .../convert/transfer/PayTransferConvert.java | 5 +- .../dal/mysql/transfer/PayTransferMapper.java | 7 + .../framework/pay/config/PayProperties.java | 9 ++ .../framework/pay/core/WalletPayClient.java | 5 + .../pay/service/refund/PayRefundService.java | 1 - .../service/refund/PayRefundServiceImpl.java | 2 + .../service/transfer/PayTransferService.java | 9 ++ .../transfer/PayTransferServiceImpl.java | 32 +++-- .../framework/pay/core/client/PayClient.java | 11 ++ .../WxPayTransferPartnerNotifyV3Result.java | 128 ++++++++++++++++++ .../core/client/impl/AbstractPayClient.java | 16 +++ .../impl/alipay/AbstractAlipayPayClient.java | 5 + .../impl/alipay/AlipayAppPayClient.java | 2 + .../impl/alipay/AlipayBarPayClient.java | 2 + .../client/impl/alipay/AlipayPcPayClient.java | 2 + .../core/client/impl/mock/MockPayClient.java | 5 + .../impl/weixin/AbstractWxPayClient.java | 33 ++++- .../src/main/resources/application-dev.yaml | 3 +- .../src/main/resources/application-local.yaml | 1 + 33 files changed, 378 insertions(+), 42 deletions(-) create mode 100644 yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java create mode 100644 yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/WxPayTransferPartnerNotifyV3Result.java diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageRecordController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageRecordController.java index bcf46d1dfe..cbb8a6b22c 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageRecordController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageRecordController.java @@ -44,7 +44,7 @@ public class BrokerageRecordController { @Operation(summary = "获得佣金记录") @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('trade:brokerage-record:query')") - public CommonResult getBrokerageRecord(@RequestParam("id") Integer id) { + public CommonResult getBrokerageRecord(@RequestParam("id") Long id) { BrokerageRecordDO brokerageRecord = brokerageRecordService.getBrokerageRecord(id); return success(BrokerageRecordConvert.INSTANCE.convert(brokerageRecord)); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java index 8c1b60f06b..9b865ae953 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java @@ -45,7 +45,7 @@ public class BrokerageWithdrawController { @PutMapping("/approve") @Operation(summary = "通过申请") @PreAuthorize("@ss.hasPermission('trade:brokerage-withdraw:audit')") - public CommonResult approveBrokerageWithdraw(@RequestParam("id") Integer id) { + public CommonResult approveBrokerageWithdraw(@RequestParam("id") Long id) { brokerageWithdrawService.auditBrokerageWithdraw(id, BrokerageWithdrawStatusEnum.AUDIT_SUCCESS, "", getClientIP()); return success(true); } @@ -62,7 +62,7 @@ public class BrokerageWithdrawController { @Operation(summary = "获得佣金提现") @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('trade:brokerage-withdraw:query')") - public CommonResult getBrokerageWithdraw(@RequestParam("id") Integer id) { + public CommonResult getBrokerageWithdraw(@RequestParam("id") Long id) { BrokerageWithdrawDO brokerageWithdraw = brokerageWithdrawService.getBrokerageWithdraw(id); return success(BrokerageWithdrawConvert.INSTANCE.convert(brokerageWithdraw)); } @@ -87,6 +87,7 @@ public class BrokerageWithdrawController { // 目前业务逻辑,不需要做任何事情 // 当然,退款会有小概率会失败的情况,可以监控失败状态,进行告警 log.info("[updateAfterRefund][notifyReqDTO({})]", notifyReqDTO); + brokerageWithdrawService.updateTransfer(Long.parseLong(notifyReqDTO.getMerchantTransferId()), notifyReqDTO.getPayTransferId()); return success(true); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/record/BrokerageRecordRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/record/BrokerageRecordRespVO.java index 224ecf1e53..0012eb9ce7 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/record/BrokerageRecordRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/record/BrokerageRecordRespVO.java @@ -14,7 +14,7 @@ import java.time.LocalDateTime; public class BrokerageRecordRespVO extends BrokerageRecordBaseVO { @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "28896") - private Integer id; + private Long id; @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawRejectReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawRejectReqVO.java index 7de2b7d7f2..a0967f19b9 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawRejectReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawRejectReqVO.java @@ -14,7 +14,7 @@ public class BrokerageWithdrawRejectReqVO { @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "7161") @NotNull(message = "编号不能为空") - private Integer id; + private Long id; @Schema(description = "审核驳回原因", example = "不对") @NotEmpty(message = "审核驳回原因不能为空") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawRespVO.java index de74bb4f6c..0abd77e69a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawRespVO.java @@ -14,7 +14,7 @@ import java.time.LocalDateTime; public class BrokerageWithdrawRespVO extends BrokerageWithdrawBaseVO { @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "7161") - private Integer id; + private Long id; @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageWithdrawMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageWithdrawMapper.java index 9e2cf68ad1..dc2b009160 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageWithdrawMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageWithdrawMapper.java @@ -35,7 +35,7 @@ public interface BrokerageWithdrawMapper extends BaseMapperX() .eq(BrokerageWithdrawDO::getId, id) .eq(BrokerageWithdrawDO::getStatus, status)); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordService.java index 5869889f26..bc1f3aa6bd 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordService.java @@ -32,7 +32,7 @@ public interface BrokerageRecordService { * @param id 编号 * @return 佣金记录 */ - BrokerageRecordDO getBrokerageRecord(Integer id); + BrokerageRecordDO getBrokerageRecord(Long id); /** * 获得佣金记录分页 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordServiceImpl.java index 26e18c7bd7..6406f5d7ed 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordServiceImpl.java @@ -64,7 +64,7 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { private ProductSkuApi productSkuApi; @Override - public BrokerageRecordDO getBrokerageRecord(Integer id) { + public BrokerageRecordDO getBrokerageRecord(Long id) { return brokerageRecordMapper.selectById(id); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawService.java index 865b4c97b1..0fc2b401ff 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawService.java @@ -28,7 +28,7 @@ public interface BrokerageWithdrawService { * @param status 审核状态 * @param auditReason 驳回原因 */ - void auditBrokerageWithdraw(Integer id, BrokerageWithdrawStatusEnum status, String auditReason, String userIp); + void auditBrokerageWithdraw(Long id, BrokerageWithdrawStatusEnum status, String auditReason, String userIp); /** * 获得佣金提现 @@ -36,7 +36,7 @@ public interface BrokerageWithdrawService { * @param id 编号 * @return 佣金提现 */ - BrokerageWithdrawDO getBrokerageWithdraw(Integer id); + BrokerageWithdrawDO getBrokerageWithdraw(Long id); /** * 获得佣金提现分页 @@ -77,4 +77,10 @@ public interface BrokerageWithdrawService { return convertMap(getWithdrawSummaryListByUserId(userIds, status), BrokerageWithdrawSummaryRespBO::getUserId); } + /** + * + * @param merchantTransferId 提现编号 + * @param payTransferId 转账订单编号 + */ + void updateTransfer(Long merchantTransferId, Long payTransferId); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java index 7799b41fa6..ee82f4f31f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java @@ -9,6 +9,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; import cn.iocoder.yudao.module.pay.api.transfer.PayTransferApi; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; +import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO; +import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum; import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferTypeEnum; import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi; import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO; @@ -39,7 +41,6 @@ import java.time.LocalDateTime; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.trade.dal.redis.no.TradeNoRedisDAO.TRADE_ORDER_NO_PREFIX; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; /** @@ -76,7 +77,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { @Override @Transactional(rollbackFor = Exception.class) - public void auditBrokerageWithdraw(Integer id, BrokerageWithdrawStatusEnum status, String auditReason, String userIp) { + public void auditBrokerageWithdraw(Long id, BrokerageWithdrawStatusEnum status, String auditReason, String userIp) { // 1.1 校验存在 BrokerageWithdrawDO withdraw = validateBrokerageWithdrawExists(id); @@ -105,7 +106,6 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { PayTransferCreateReqDTO payTransferCreateReqDTO = getPayTransferCreateReqDTO(userIp, withdraw, socialUser); payTransferApi.createTransfer(payTransferCreateReqDTO); } - // TODO 疯狂:调用转账接口 } else if (BrokerageWithdrawStatusEnum.AUDIT_FAIL.equals(status)) { templateCode = MessageTemplateConstants.SMS_BROKERAGE_WITHDRAW_AUDIT_REJECT; // 3.2 驳回时需要退还用户佣金 @@ -116,13 +116,13 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { } // 4. 通知用户 - Map templateParams = MapUtil.builder() - .put("createTime", LocalDateTimeUtil.formatNormal(withdraw.getCreateTime())) - .put("price", MoneyUtils.fenToYuanStr(withdraw.getPrice())) - .put("reason", auditReason) - .build(); - notifyMessageSendApi.sendSingleMessageToMember(new NotifySendSingleToUserReqDTO() - .setUserId(withdraw.getUserId()).setTemplateCode(templateCode).setTemplateParams(templateParams)); +// Map templateParams = MapUtil.builder() +// .put("createTime", LocalDateTimeUtil.formatNormal(withdraw.getCreateTime())) +// .put("price", MoneyUtils.fenToYuanStr(withdraw.getPrice())) +// .put("reason", auditReason) +// .build(); +// notifyMessageSendApi.sendSingleMessageToMember(new NotifySendSingleToUserReqDTO() +// .setUserId(withdraw.getUserId()).setTemplateCode(templateCode).setTemplateParams(templateParams)); } private PayTransferCreateReqDTO getPayTransferCreateReqDTO(String userIp, BrokerageWithdrawDO withdraw, SocialUserRespDTO socialUser) { @@ -138,7 +138,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { return payTransferCreateReqDTO; } - private BrokerageWithdrawDO validateBrokerageWithdrawExists(Integer id) { + private BrokerageWithdrawDO validateBrokerageWithdrawExists(Long id) { BrokerageWithdrawDO withdraw = brokerageWithdrawMapper.selectById(id); if (withdraw == null) { throw exception(BROKERAGE_WITHDRAW_NOT_EXISTS); @@ -147,7 +147,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { } @Override - public BrokerageWithdrawDO getBrokerageWithdraw(Integer id) { + public BrokerageWithdrawDO getBrokerageWithdraw(Long id) { return brokerageWithdrawMapper.selectById(id); } @@ -186,6 +186,23 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { return brokerageWithdrawMapper.selectCountAndSumPriceByUserIdAndStatus(userIds, status.getStatus()); } + @Override + public void updateTransfer(Long id, Long payTransferId) { + BrokerageWithdrawDO withdraw = validateBrokerageWithdrawExists(id); + PayTransferRespDTO transfer = payTransferApi.getTransfer(payTransferId); + if(PayTransferStatusEnum.isSuccess(transfer.getStatus())){ + withdraw.setStatus(BrokerageWithdrawStatusEnum.WITHDRAW_SUCCESS.getStatus()); + }else if(PayTransferStatusEnum.isPendingStatus(transfer.getStatus())){ + withdraw.setStatus(BrokerageWithdrawStatusEnum.AUDIT_SUCCESS.getStatus()); + }else{ + withdraw.setStatus(BrokerageWithdrawStatusEnum.WITHDRAW_FAIL.getStatus()); + // 3.2 驳回时需要退还用户佣金 + brokerageRecordService.addBrokerage(withdraw.getUserId(), BrokerageRecordBizTypeEnum.WITHDRAW_REJECT, + String.valueOf(withdraw.getId()), withdraw.getPrice(), BrokerageRecordBizTypeEnum.WITHDRAW_REJECT.getTitle()); + } + brokerageWithdrawMapper.updateById(withdraw); + } + /** * 计算提现手续费 * diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApi.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApi.java index 7f000be74d..2139f08ef0 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApi.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApi.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.pay.api.transfer; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; +import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO; import jakarta.validation.Valid; /** @@ -19,4 +20,10 @@ public interface PayTransferApi { */ Long createTransfer(@Valid PayTransferCreateReqDTO reqDTO); + /** + * 获取转账单详细 + * @param id 转账单编号 + * @return 转账单详细 + */ + PayTransferRespDTO getTransfer(Long id); } diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java new file mode 100644 index 0000000000..4969da6bd8 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.pay.api.transfer.dto; + +import lombok.Data; + +@Data +public class PayTransferRespDTO { + + /** + * 编号 + */ + private Long id; + + /** + * 转账单号 + * + */ + private String no; + + /** + * 转账金额,单位:分 + */ + private Integer price; + + /** + * 转账状态 + * + * 枚举 {@link PayTransferStatusRespEnum} + */ + private Integer status; + + +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApiImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApiImpl.java index 5e6a3dcdb7..7c6cf5d758 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApiImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApiImpl.java @@ -1,6 +1,9 @@ package cn.iocoder.yudao.module.pay.api.transfer; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; +import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO; +import cn.iocoder.yudao.module.pay.convert.transfer.PayTransferConvert; +import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO; import cn.iocoder.yudao.module.pay.service.transfer.PayTransferService; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -24,4 +27,10 @@ public class PayTransferApiImpl implements PayTransferApi { return payTransferService.createTransfer(reqDTO); } + @Override + public PayTransferRespDTO getTransfer(Long id) { + PayTransferDO transfer = payTransferService.getTransfer(id); + return PayTransferConvert.INSTANCE.convert3(transfer); + } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java index 631cd7562b..0f707f0ee8 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.pay.core.client.PayClient; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO; import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskDetailRespVO; import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskPageReqVO; import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskRespVO; @@ -18,6 +19,7 @@ import cn.iocoder.yudao.module.pay.service.channel.PayChannelService; import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService; import cn.iocoder.yudao.module.pay.service.order.PayOrderService; import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; +import cn.iocoder.yudao.module.pay.service.transfer.PayTransferService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -49,6 +51,8 @@ public class PayNotifyController { @Resource private PayRefundService refundService; @Resource + private PayTransferService payTransferService; + @Resource private PayNotifyService notifyService; @Resource private PayAppService appService; @@ -95,6 +99,26 @@ public class PayNotifyController { return "success"; } + @PostMapping(value = "/transfer/{channelId}") + @Operation(summary = "支付渠道的统一【转账】回调") + @PermitAll + public String notifyTransfer(@PathVariable("channelId") Long channelId, + @RequestParam(required = false) Map params, + @RequestBody(required = false) String body) { + log.info("[notifyRefund][channelId({}) 回调数据({}/{})]", channelId, params, body); + // 1. 校验支付渠道是否存在 + PayClient payClient = channelService.getPayClient(channelId); + if (payClient == null) { + log.error("[notifyCallback][渠道编号({}) 找不到对应的支付客户端]", channelId); + throw exception(CHANNEL_NOT_FOUND); + } + + // 2. 解析通知数据 + PayTransferRespDTO notify = payClient.parseTransferNotify(params, body); + payTransferService.notifyTransfer(channelId, notify); + return "success"; + } + @GetMapping("/get-detail") @Operation(summary = "获得回调通知的明细") @Parameter(name = "id", description = "编号", required = true, example = "1024") diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/transfer/PayTransferConvert.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/transfer/PayTransferConvert.java index 4e79548d0d..73bb57a997 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/transfer/PayTransferConvert.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/transfer/PayTransferConvert.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.pay.convert.transfer; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; +import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO; import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer.PayDemoTransferCreateReqVO; import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferCreateReqVO; import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferPageItemRespVO; @@ -24,7 +25,9 @@ public interface PayTransferConvert { PayTransferCreateReqDTO convert(PayDemoTransferCreateReqVO vo); - PayTransferRespVO convert(PayTransferDO bean); + PayTransferRespVO convert(PayTransferDO bean); + + PayTransferRespDTO convert3(PayTransferDO bean); PageResult convertPage(PageResult pageResult); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java index af4f6debf7..a4845e0f82 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferPageReqVO; +import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.apache.ibatis.annotations.Mapper; @@ -44,6 +45,12 @@ public interface PayTransferMapper extends BaseMapperX { default List selectListByStatus(Integer status){ return selectList(PayTransferDO::getStatus, status); } + + default PayTransferDO selectByAppIdAndNo(Long appId, String no){ + return selectOne(new LambdaQueryWrapperX() + .eq(PayTransferDO::getAppId, appId) + .eq(PayTransferDO::getNo, no)); + } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/config/PayProperties.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/config/PayProperties.java index d124bbfc51..84905a5325 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/config/PayProperties.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/config/PayProperties.java @@ -39,6 +39,15 @@ public class PayProperties { @URL(message = "支付回调地址的格式必须是 URL") private String refundNotifyUrl; + /** + * 转账回调地址 + * + * 实际上,对应的 PayNotifyController 的 notifyTransfer 方法的 URL + * + * 回调顺序:支付渠道(支付宝支付、微信支付) => yudao-module-pay 的 transferNotifyUrl 地址 => 业务的 PayAppDO.transferNotifyUrl 地址 + */ + private String transferNotifyUrl; + /** * 支付订单 no 的前缀 */ diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/core/WalletPayClient.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/core/WalletPayClient.java index c7be35f1ab..63fc92ba3c 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/core/WalletPayClient.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/core/WalletPayClient.java @@ -177,6 +177,11 @@ public class WalletPayClient extends AbstractPayClient { throw new IllegalStateException(String.format("支付退款单[%s] 状态不正确", outRefundNo)); } + @Override + protected PayTransferRespDTO doParseTransferNotify(Map params, String body) throws Throwable { + throw new UnsupportedOperationException("未实现"); + } + @Override public PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) { throw new UnsupportedOperationException("待实现"); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java index 258cea9640..7515e7747e 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java @@ -78,5 +78,4 @@ public interface PayRefundService { * @return 同步到状态的退款数量,包括退款成功、退款失败 */ int syncRefund(); - } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java index 8df7f88615..b0c1c3d306 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java @@ -193,6 +193,8 @@ public class PayRefundServiceImpl implements PayRefundService { TenantUtils.execute(channel.getTenantId(), () -> getSelf().notifyRefund(channel, notify)); } + + /** * 通知并更新订单的退款结果 * diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java index d3bc982e44..8168050d12 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.pay.service.transfer; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferCreateReqVO; import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferPageReqVO; @@ -54,4 +55,12 @@ public interface PayTransferService { * @return 同步到状态的转账数量,包括转账成功、转账失败、转账中的 */ int syncTransfer(); + + /** + * 渠道的转账通知 + * + * @param channelId 渠道编号 + * @param notify 通知 + */ + void notifyTransfer(Long channelId, PayTransferRespDTO notify); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java index 04d86d1848..f6486b1886 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java @@ -21,6 +21,7 @@ import cn.iocoder.yudao.module.pay.dal.mysql.transfer.PayTransferMapper; import cn.iocoder.yudao.module.pay.dal.redis.no.PayNoRedisDAO; import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyTypeEnum; import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum; +import cn.iocoder.yudao.module.pay.framework.pay.config.PayProperties; import cn.iocoder.yudao.module.pay.service.app.PayAppService; import cn.iocoder.yudao.module.pay.service.channel.PayChannelService; import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService; @@ -28,6 +29,7 @@ import jakarta.annotation.Resource; import jakarta.validation.Validator; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import java.util.List; @@ -50,6 +52,9 @@ public class PayTransferServiceImpl implements PayTransferService { private static final String TRANSFER_NO_PREFIX = "T"; + @Resource + private PayProperties payProperties; + @Resource private PayTransferMapper transferMapper; @Resource @@ -104,7 +109,7 @@ public class PayTransferServiceImpl implements PayTransferService { // 3. 调用三方渠道发起转账 PayTransferUnifiedReqDTO transferUnifiedReq = INSTANCE.convert2(transfer) .setOutTransferNo(transfer.getNo()); - transferUnifiedReq.setNotifyUrl(payApp.getTransferNotifyUrl()); + transferUnifiedReq.setNotifyUrl(genChannelTransferNotifyUrl(channel)); PayTransferRespDTO unifiedTransferResp = client.unifiedTransfer(transferUnifiedReq); // 4. 通知转账结果 getSelf().notifyTransfer(channel, unifiedTransferResp); @@ -118,6 +123,16 @@ public class PayTransferServiceImpl implements PayTransferService { return transfer.getId(); } + /** + * 根据支付渠道的编码,生成支付渠道的回调地址 + * + * @param channel 支付渠道 + * @return 支付渠道的回调地址 配置地址 + "/" + channel id + */ + private String genChannelTransferNotifyUrl(PayChannelDO channel) { + return payProperties.getTransferNotifyUrl() + "/" + channel.getId(); + } + private PayTransferDO validateTransferCanCreate(PayTransferCreateReqDTO dto, Long appId) { PayTransferDO transfer = transferMapper.selectByAppIdAndMerchantTransferId(appId, dto.getMerchantTransferId()); if (transfer != null) { @@ -156,7 +171,8 @@ public class PayTransferServiceImpl implements PayTransferService { private void notifyTransferInProgress(PayChannelDO channel, PayTransferRespDTO notify) { // 1.校验 - PayTransferDO transfer = transferMapper.selectByNo(notify.getOutTransferNo()); + PayTransferDO transfer = transferMapper.selectByAppIdAndNo( + channel.getAppId(), notify.getOutTransferNo()); if (transfer == null) { throw exception(PAY_TRANSFER_NOT_FOUND); } @@ -174,16 +190,13 @@ public class PayTransferServiceImpl implements PayTransferService { throw exception(PAY_TRANSFER_STATUS_IS_NOT_WAITING); } log.info("[notifyTransferInProgress][transfer({}) 更新为转账进行中状态]", transfer.getId()); - - // 3. 插入转账通知记录 - notifyService.createPayNotifyTask(PayNotifyTypeEnum.TRANSFER.getType(), - transfer.getId()); } private void notifyTransferSuccess(PayChannelDO channel, PayTransferRespDTO notify) { // 1.校验 - PayTransferDO transfer = transferMapper.selectByNo(notify.getOutTransferNo()); + PayTransferDO transfer = transferMapper.selectByAppIdAndNo( + channel.getAppId(), notify.getOutTransferNo()); if (transfer == null) { throw exception(PAY_TRANSFER_NOT_FOUND); } @@ -212,7 +225,8 @@ public class PayTransferServiceImpl implements PayTransferService { private void notifyTransferClosed(PayChannelDO channel, PayTransferRespDTO notify) { // 1.校验 - PayTransferDO transfer = transferMapper.selectByNo(notify.getOutTransferNo()); + PayTransferDO transfer = transferMapper.selectByAppIdAndNo( + channel.getAppId(), notify.getOutTransferNo()); if (transfer == null) { throw exception(PAY_TRANSFER_NOT_FOUND); } @@ -285,7 +299,7 @@ public class PayTransferServiceImpl implements PayTransferService { } } - private void notifyTransfer(Long channelId, PayTransferRespDTO notify) { + public void notifyTransfer(Long channelId, PayTransferRespDTO notify) { // 校验渠道是否有效 PayChannelDO channel = channelService.validPayChannel(channelId); // 通知转账结果给对应的业务 diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java index 86e3566b2b..413f568834 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java @@ -79,6 +79,8 @@ public interface PayClient { */ PayRefundRespDTO getRefund(String outTradeNo, String outRefundNo); + // ============ 转账相关 ========== + /** * 调用渠道,进行转账 * @@ -95,4 +97,13 @@ public interface PayClient { * @return 转账信息 */ PayTransferRespDTO getTransfer(String outTradeNo, PayTransferTypeEnum type); + + /** + * 解析 transfer 回调数据 + * + * @param params HTTP 回调接口 content type 为 application/x-www-form-urlencoded 的所有参数 + * @param body HTTP 回调接口的 request body + * @return 转账信息 + */ + PayTransferRespDTO parseTransferNotify(Map params, String body); } diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/WxPayTransferPartnerNotifyV3Result.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/WxPayTransferPartnerNotifyV3Result.java new file mode 100644 index 0000000000..b0431a0d77 --- /dev/null +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/WxPayTransferPartnerNotifyV3Result.java @@ -0,0 +1,128 @@ +package cn.iocoder.yudao.framework.pay.core.client.dto.transfer; + +import com.github.binarywang.wxpay.bean.notify.OriginNotifyResponse; +import com.github.binarywang.wxpay.bean.notify.WxPayBaseNotifyV3Result; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +@NoArgsConstructor +public class WxPayTransferPartnerNotifyV3Result implements Serializable, WxPayBaseNotifyV3Result { + + private static final long serialVersionUID = -1L; + + /** + * 源数据 + */ + private OriginNotifyResponse rawData; + + /** + * 解密后的数据 + */ + private TransferNotifyResult result; + + @Override + public void setRawData(OriginNotifyResponse rawData) { + this.rawData = rawData; + } + + @Override + public void setResult(TransferNotifyResult data) { + this.result = data; + } + + public TransferNotifyResult getResult() { + return result; + } + + public OriginNotifyResponse getRawData() { + return rawData; + } + + @Data + @NoArgsConstructor + public static class TransferNotifyResult implements Serializable { + private static final long serialVersionUID = 1L; + + /*********************** 公共字段 ******************** + + /** + * 商家批次单号 + */ + @SerializedName(value = "out_batch_no") + protected String outBatchNo; + + /** + * 微信批次单号 + */ + @SerializedName(value = "batch_id") + protected String batchId; + + /** + * 批次状态 + */ + @SerializedName(value = "batch_status") + protected String batchStatus; + + /** + * 批次总笔数 + */ + @SerializedName(value = "total_num") + protected Integer totalNum; + + /** + * 批次总金额 + */ + @SerializedName(value = "total_amount") + protected Integer totalAmount; + + /** + * 批次更新时间 + */ + @SerializedName(value = "update_time") + private String updateTime; + + /*********************** FINISHED ******************** + + /** + * 转账成功金额 + */ + @SerializedName(value = "success_amount") + protected Integer successAmount; + + /** + * 转账成功笔数 + */ + @SerializedName(value = "success_num") + protected Integer successNum; + + /** + * 转账失败金额 + */ + @SerializedName(value = "fail_amount") + protected Integer failAmount; + + /** + * 转账失败笔数 + */ + @SerializedName(value = "fail_num") + protected Integer failNum; + + /*********************** CLOSED ******************** + + /** + * 商户号 + */ + @SerializedName(value = "mchid") + protected String mchId; + + /** + * 批次关闭原因 + */ + @SerializedName(value = "close_reason") + protected String closeReason; + + } +} diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java index 82d68b58f6..5c47504026 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java @@ -219,6 +219,22 @@ public abstract class AbstractPayClient implemen } } + @Override + public final PayTransferRespDTO parseTransferNotify(Map params, String body) { + try { + return doParseTransferNotify(params, body); + } catch (ServiceException ex) { // 业务异常,都是实现类已经翻译,所以直接抛出即可 + throw ex; + } catch (Throwable ex) { + log.error("[doParseTransferNotify][客户端({}) params({}) body({}) 解析失败]", + getId(), params, body, ex); + throw buildPayException(ex); + } + } + + protected abstract PayTransferRespDTO doParseTransferNotify(Map params, String body) + throws Throwable; + @Override public final PayTransferRespDTO getTransfer(String outTradeNo, PayTransferTypeEnum type) { try { diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java index 4dcf236755..471dc7d923 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java @@ -325,6 +325,11 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient params, String body) throws Throwable { + throw new UnsupportedOperationException("未实现"); + } + // ========== 各种工具方法 ========== protected String formatAmount(Integer amount) { diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayAppPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayAppPayClient.java index 4e5a37e9de..c990e7be6d 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayAppPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayAppPayClient.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO; import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum; import com.alipay.api.AlipayApiException; @@ -56,4 +57,5 @@ public class AlipayAppPayClient extends AbstractAlipayPayClient { return PayOrderRespDTO.waitingOf(displayMode, response.getBody(), reqDTO.getOutTradeNo(), response); } + } diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayBarPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayBarPayClient.java index 1f90d6b58e..8bd3413576 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayBarPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayBarPayClient.java @@ -5,6 +5,7 @@ import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO; import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum; import com.alipay.api.AlipayApiException; @@ -82,4 +83,5 @@ public class AlipayBarPayClient extends AbstractAlipayPayClient { return PayOrderRespDTO.waitingOf(displayMode, "", reqDTO.getOutTradeNo(), response); } + } diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClient.java index 6dbd19bef3..39cd78d540 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClient.java @@ -4,6 +4,7 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.http.Method; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO; import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum; import com.alipay.api.AlipayApiException; @@ -66,4 +67,5 @@ public class AlipayPcPayClient extends AbstractAlipayPayClient { return PayOrderRespDTO.waitingOf(displayMode, response.getBody(), reqDTO.getOutTradeNo(), response); } + } diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClient.java index 1ad1ad7134..34b1d5db6f 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClient.java @@ -57,6 +57,11 @@ public class MockPayClient extends AbstractPayClient { outRefundNo, MOCK_RESP_SUCCESS_DATA); } + @Override + protected PayTransferRespDTO doParseTransferNotify(Map params, String body) throws Throwable { + throw new UnsupportedOperationException("未实现"); + } + @Override protected PayRefundRespDTO doParseRefundNotify(Map params, String body) { throw new UnsupportedOperationException("模拟支付无退款回调"); diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java index f5c753b8e3..dc2bdfa0cf 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java @@ -14,14 +14,11 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.WxPayTransferPartnerNotifyV3Result; import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum; import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum; -import com.binarywang.spring.starter.wxjava.miniapp.properties.WxMaProperties; -import com.github.binarywang.wxpay.bean.notify.WxPayNotifyV3Result; -import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; -import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult; -import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyV3Result; +import com.github.binarywang.wxpay.bean.notify.*; import com.github.binarywang.wxpay.bean.request.*; import com.github.binarywang.wxpay.bean.result.*; import com.github.binarywang.wxpay.bean.transfer.TransferBatchesRequest; @@ -31,7 +28,6 @@ import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.service.TransferService; import com.github.binarywang.wxpay.service.WxPayService; import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; -import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import java.time.LocalDateTime; @@ -355,6 +351,29 @@ public abstract class AbstractWxPayClient extends AbstractPayClient params, String body) throws WxPayException { + switch (config.getApiVersion()) { + case API_VERSION_V3: + return parseTransferNotifyV3(body); + default: + throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion())); + } + } + + private PayTransferRespDTO parseTransferNotifyV3(String body) throws WxPayException { + WxPayTransferPartnerNotifyV3Result response = client.baseParseOrderNotifyV3Result(body, null, WxPayTransferPartnerNotifyV3Result.class, WxPayTransferPartnerNotifyV3Result.TransferNotifyResult.class); + WxPayTransferPartnerNotifyV3Result.TransferNotifyResult result = response.getResult(); + // 2. 构建结果 + if (Objects.equals("FINISHED", result.getBatchStatus())) { + if(result.getFailNum() <= 0){ + return PayTransferRespDTO.successOf(result.getBatchId(), parseDateV3(result.getUpdateTime()), + result.getOutBatchNo(), response); + } + } + return PayTransferRespDTO.closedOf(result.getBatchStatus(), result.getCloseReason(), result.getOutBatchNo(), response); + } + @Override protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) throws WxPayException { try { @@ -452,7 +471,7 @@ public abstract class AbstractWxPayClient extends AbstractPayClient Date: Mon, 7 Oct 2024 11:32:14 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E3=80=90=E5=8A=9F=E8=83=BD=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E3=80=91=E5=A2=9E=E5=8A=A0=E9=92=B1=E5=8C=85=E5=88=86?= =?UTF-8?q?=E4=BD=A3=E6=8F=90=E7=8E=B0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../job/order/TradeOrderAutoCommentJob.java | 2 +- .../BrokerageWithdrawServiceImpl.java | 19 ++++++++- .../module/pay/api/wallet/PayWalletApi.java | 25 +++++++++++ .../api/wallet/dto/PayWalletCreateReqDto.java | 42 +++++++++++++++++++ .../pay/api/wallet/dto/PayWalletRespDTO.java | 18 ++++++++ .../enums/wallet/PayWalletBizTypeEnum.java | 4 +- .../pay/api/wallet/PayWalletApiImpl.java | 34 +++++++++++++++ .../pay/convert/wallet/PayWalletConvert.java | 4 ++ .../service/wallet/PayWalletServiceImpl.java | 3 ++ 9 files changed, 148 insertions(+), 3 deletions(-) create mode 100644 yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApi.java create mode 100644 yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/dto/PayWalletCreateReqDto.java create mode 100644 yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/dto/PayWalletRespDTO.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApiImpl.java diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/job/order/TradeOrderAutoCommentJob.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/job/order/TradeOrderAutoCommentJob.java index c7b7d0b9f1..881637038c 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/job/order/TradeOrderAutoCommentJob.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/job/order/TradeOrderAutoCommentJob.java @@ -21,7 +21,7 @@ public class TradeOrderAutoCommentJob implements JobHandler { @Override @TenantJob public String execute(String param) { - int count = tradeOrderUpdateService.createOrderItemCommentBySystem(); + int count = tradeOrderUpdateService.createOrderItemCommentBySystem(); return String.format("评论订单 %s 个", count); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java index ee82f4f31f..e0bba181a1 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java @@ -10,8 +10,12 @@ import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; import cn.iocoder.yudao.module.pay.api.transfer.PayTransferApi; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO; +import cn.iocoder.yudao.module.pay.api.wallet.PayWalletApi; +import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletCreateReqDto; +import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletRespDTO; import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum; import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferTypeEnum; +import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi; import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO; import cn.iocoder.yudao.module.system.api.social.SocialUserApi; @@ -68,6 +72,8 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { private PayTransferApi payTransferApi; @Resource private SocialUserApi socialUserApi; + @Resource + private PayWalletApi payWalletApi; @Resource private Validator validator; @@ -98,7 +104,18 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { templateCode = MessageTemplateConstants.SMS_BROKERAGE_WITHDRAW_AUDIT_APPROVE; // 3.1 通过时佣金转余额 if (BrokerageWithdrawTypeEnum.WALLET.getType().equals(withdraw.getType())) { - // todo 疯狂: + PayWalletRespDTO wallet = payWalletApi.getWalletByUserId(withdraw.getUserId()); + payWalletApi.addWallet(new PayWalletCreateReqDto() + .setWalletId(wallet.getId()) + .setBizType(PayWalletBizTypeEnum.WITHDRAW) + .setBizId(withdraw.getId().toString()) + .setPrice(withdraw.getPrice()) + .setTitle("分佣提现")); + rows = brokerageWithdrawMapper.updateByIdAndStatus(id, BrokerageWithdrawStatusEnum.AUDIT_SUCCESS.getStatus(), + new BrokerageWithdrawDO().setStatus(BrokerageWithdrawStatusEnum.WITHDRAW_SUCCESS.getStatus()).setAuditReason(auditReason).setAuditTime(LocalDateTime.now())); + if (rows == 0) { + throw exception(BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING); + } }else if (BrokerageWithdrawTypeEnum.ALIPAY_SMALL.getType().equals(withdraw.getType())){ //获取openid SocialUserRespDTO socialUser = socialUserApi.getSocialUserByUserId(UserTypeEnum.MEMBER.getValue(), withdraw.getUserId(), SocialTypeEnum.WECHAT_MINI_APP.getType()); diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApi.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApi.java new file mode 100644 index 0000000000..24d8895138 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApi.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.pay.api.wallet; + +import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletCreateReqDto; +import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletRespDTO; + +/** + * 钱包 API 接口 + * + * @author liurulin + */ +public interface PayWalletApi { + + /** + * 添加钱包 + * @param reqDTO 创建请求 + */ + void addWallet(PayWalletCreateReqDto reqDTO); + + /** + * 根据用户id获取钱包信息 + * @param userId 用户id + * @return 钱包信息 + */ + PayWalletRespDTO getWalletByUserId(Long userId); +} diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/dto/PayWalletCreateReqDto.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/dto/PayWalletCreateReqDto.java new file mode 100644 index 0000000000..0a187c385c --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/dto/PayWalletCreateReqDto.java @@ -0,0 +1,42 @@ +package cn.iocoder.yudao.module.pay.api.wallet.dto; + +import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Data +public class PayWalletCreateReqDto { + + /** + * 钱包编号 + */ + @NotNull(message = "钱包编号不能为空") + private Long walletId; + + /** + * 关联业务分类 + */ + @NotNull(message = "关联业务分类不能为空") + private PayWalletBizTypeEnum bizType; + + /** + * 关联业务编号 + */ + @NotNull(message = "关联业务编号不能为空") + private String bizId; + + /** + * 流水说明 + */ + @NotNull(message = "流水说明不能为空") + private String title; + + /** + * 交易金额,单位分 + * + * 正值表示余额增加,负值表示余额减少 + */ + @NotNull(message = "交易金额不能为空") + private Integer price; + +} diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/dto/PayWalletRespDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/dto/PayWalletRespDTO.java new file mode 100644 index 0000000000..c8704a523b --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/dto/PayWalletRespDTO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.pay.api.wallet.dto; + +import lombok.Data; + +@Data +public class PayWalletRespDTO { + + /** + * 编号 + */ + private Long id; + + /** + * 余额,单位分 + */ + private Integer balance; + +} diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/wallet/PayWalletBizTypeEnum.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/wallet/PayWalletBizTypeEnum.java index ae99128b92..f06ea8d5ef 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/wallet/PayWalletBizTypeEnum.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/wallet/PayWalletBizTypeEnum.java @@ -19,7 +19,8 @@ public enum PayWalletBizTypeEnum implements IntArrayValuable { RECHARGE_REFUND(2, "充值退款"), PAYMENT(3, "支付"), PAYMENT_REFUND(4, "支付退款"), - UPDATE_BALANCE(5, "更新余额"); + UPDATE_BALANCE(5, "更新余额"), + WITHDRAW(6, "分佣提现"); /** * 业务分类 @@ -36,4 +37,5 @@ public enum PayWalletBizTypeEnum implements IntArrayValuable { public int[] array() { return ARRAYS; } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApiImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApiImpl.java new file mode 100644 index 0000000000..700f0be813 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApiImpl.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.pay.api.wallet; + +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletCreateReqDto; +import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletRespDTO; +import cn.iocoder.yudao.module.pay.convert.wallet.PayWalletConvert; +import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; +import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +/** + * 钱包 API 实现类 + * + * @author 芋道源码 + */ +@Service +public class PayWalletApiImpl implements PayWalletApi { + + @Resource + private PayWalletService payWalletService; + + @Override + public void addWallet(PayWalletCreateReqDto reqDTO) { + //添加钱包金额 + payWalletService.addWalletBalance(reqDTO.getWalletId(), reqDTO.getBizId(), reqDTO.getBizType(), reqDTO.getPrice()); + } + + @Override + public PayWalletRespDTO getWalletByUserId(Long userId) { + PayWalletDO orCreateWallet = payWalletService.getOrCreateWallet(userId, UserTypeEnum.MEMBER.getValue()); + return PayWalletConvert.INSTANCE.convert03(orCreateWallet); + } +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletConvert.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletConvert.java index 3617f23a04..c20908e018 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletConvert.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletConvert.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.pay.convert.wallet; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletCreateReqDto; +import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletRespDTO; import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletRespVO; import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.wallet.AppPayWalletRespVO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; @@ -18,4 +20,6 @@ public interface PayWalletConvert { PageResult convertPage(PageResult page); + PayWalletRespDTO convert03(PayWalletDO orCreateWallet); + } 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 cc9d570a27..8b9ca4b2c3 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 @@ -200,6 +200,9 @@ public class PayWalletServiceImpl implements PayWalletService { case UPDATE_BALANCE: // 更新余额 walletMapper.updateWhenRecharge(payWallet.getId(), price); break; + case WITHDRAW: + walletMapper.updateWhenRecharge(payWallet.getId(), price); + break; default: { // TODO 其它类型待实现 throw new UnsupportedOperationException("待实现");