微信转账未完成
This commit is contained in:
parent
2c4d8298cf
commit
3b9548aa2d
|
@ -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<Boolean> 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<Boolean> 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
/**
|
||||
* 获得佣金提现
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -64,6 +64,10 @@
|
|||
<groupId>com.github.binarywang</groupId>
|
||||
<artifactId>weixin-java-pay</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.binarywang</groupId>
|
||||
<artifactId>wx-java-miniapp-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Test 测试相关 -->
|
||||
<dependency>
|
||||
|
@ -71,6 +75,7 @@
|
|||
<artifactId>yudao-spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -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<String, String> channelExtras;
|
||||
|
||||
/**
|
||||
* 转账结果的 notify 回调地址
|
||||
*/
|
||||
@NotEmpty(message = "转账结果的回调地址不能为空")
|
||||
@URL(message = "转账结果的 notify 回调地址必须是 URL 格式")
|
||||
private String notifyUrl;
|
||||
}
|
||||
|
|
|
@ -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<WxPayClientC
|
|||
}
|
||||
|
||||
@Override
|
||||
protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
|
||||
throw new UnsupportedOperationException("待实现");
|
||||
protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) throws WxPayException {
|
||||
TransferService transferService = client.getTransferService();
|
||||
List<TransferBatchesRequest.TransferDetail> 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
|
||||
|
|
|
@ -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<TransferDetail> 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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue