Compare commits
2 Commits
pay
...
70307e3833
| Author | SHA1 | Date | |
|---|---|---|---|
| 70307e3833 | |||
| 8bde6b15f6 |
@@ -6,6 +6,7 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* market服务 任务总调度
|
* market服务 任务总调度
|
||||||
|
*
|
||||||
* @author ww
|
* @author ww
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@@ -18,9 +19,9 @@ public class AAMarketTasks {
|
|||||||
|
|
||||||
|
|
||||||
// 分销延时发放
|
// 分销延时发放
|
||||||
@Scheduled(fixedRate = 30000)
|
@Scheduled(cron = "0 0 0/2 * * ? ")
|
||||||
public void distributionTask() {
|
public void distributionTask() {
|
||||||
distributionTask.deliver();
|
distributionTask.deliver(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -29,6 +30,7 @@ public class AAMarketTasks {
|
|||||||
public void birthdayGiftTask() {
|
public void birthdayGiftTask() {
|
||||||
birthdayGiftTask.deliver();
|
birthdayGiftTask.deliver();
|
||||||
}
|
}
|
||||||
|
|
||||||
//会员生日弹窗提醒重置 每年1月1日
|
//会员生日弹窗提醒重置 每年1月1日
|
||||||
@Scheduled(cron = "0 0 0 1 1 ?")
|
@Scheduled(cron = "0 0 0 1 1 ?")
|
||||||
public void birthdayGiftRemindTask() {
|
public void birthdayGiftRemindTask() {
|
||||||
@@ -39,6 +41,7 @@ public class AAMarketTasks {
|
|||||||
//优惠券 过期
|
//优惠券 过期
|
||||||
@Resource
|
@Resource
|
||||||
private CouponTask couponTask;
|
private CouponTask couponTask;
|
||||||
|
|
||||||
//每天每小时的30分 0秒 执行
|
//每天每小时的30分 0秒 执行
|
||||||
@Scheduled(cron = "0 30 * * * ? ")
|
@Scheduled(cron = "0 30 * * * ? ")
|
||||||
public void couponTask() {
|
public void couponTask() {
|
||||||
@@ -48,6 +51,7 @@ public class AAMarketTasks {
|
|||||||
//会员奖励发放
|
//会员奖励发放
|
||||||
@Resource
|
@Resource
|
||||||
private MemberTask memberTask;
|
private MemberTask memberTask;
|
||||||
|
|
||||||
//每天1点 0分 0秒 执行
|
//每天1点 0分 0秒 执行
|
||||||
@Scheduled(cron = "0 0 1 * * ? ")
|
@Scheduled(cron = "0 0 1 * * ? ")
|
||||||
public void memberTask() {
|
public void memberTask() {
|
||||||
@@ -57,6 +61,7 @@ public class AAMarketTasks {
|
|||||||
//满减活动/限时折扣 处理任务状态 定时任务
|
//满减活动/限时折扣 处理任务状态 定时任务
|
||||||
@Resource
|
@Resource
|
||||||
private ActivityStatusTask activityStatusTask;
|
private ActivityStatusTask activityStatusTask;
|
||||||
|
|
||||||
//每天0点 0分 1秒 执行
|
//每天0点 0分 1秒 执行
|
||||||
@Scheduled(cron = "1 0 0 * * ? ")
|
@Scheduled(cron = "1 0 0 * * ? ")
|
||||||
public void activityStatusTask() {
|
public void activityStatusTask() {
|
||||||
@@ -67,6 +72,7 @@ public class AAMarketTasks {
|
|||||||
//月累计 发送条数 累计金额
|
//月累计 发送条数 累计金额
|
||||||
@Resource
|
@Resource
|
||||||
private SmsShopMoneyTask smsShopMoneyTask;
|
private SmsShopMoneyTask smsShopMoneyTask;
|
||||||
|
|
||||||
//每月1号 0点 0分 1秒 执行
|
//每月1号 0点 0分 1秒 执行
|
||||||
@Scheduled(cron = "1 0 0 1 * ?")
|
@Scheduled(cron = "1 0 0 1 * ?")
|
||||||
public void smsShopMoneyTask() {
|
public void smsShopMoneyTask() {
|
||||||
|
|||||||
@@ -2,10 +2,13 @@ package com.czg.task;
|
|||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import com.czg.account.entity.ShopInfo;
|
||||||
import com.czg.account.entity.ShopUser;
|
import com.czg.account.entity.ShopUser;
|
||||||
import com.czg.account.service.ShopInfoService;
|
import com.czg.account.service.ShopInfoService;
|
||||||
import com.czg.account.service.ShopUserService;
|
import com.czg.account.service.ShopUserService;
|
||||||
import com.czg.constant.TableValueConstant;
|
import com.czg.constant.TableValueConstant;
|
||||||
|
import com.czg.constants.SystemConstants;
|
||||||
|
import com.czg.exception.CzgException;
|
||||||
import com.czg.market.entity.MkDistributionFlow;
|
import com.czg.market.entity.MkDistributionFlow;
|
||||||
import com.czg.market.service.MkDistributionFlowService;
|
import com.czg.market.service.MkDistributionFlowService;
|
||||||
import com.czg.market.service.MkDistributionUserService;
|
import com.czg.market.service.MkDistributionUserService;
|
||||||
@@ -18,6 +21,7 @@ import jakarta.annotation.Resource;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.dubbo.config.annotation.DubboReference;
|
import org.apache.dubbo.config.annotation.DubboReference;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@@ -40,8 +44,6 @@ public class DistributionTask {
|
|||||||
private OrderInfoService orderInfoService;
|
private OrderInfoService orderInfoService;
|
||||||
@DubboReference
|
@DubboReference
|
||||||
private ShopInfoService shopInfoService;
|
private ShopInfoService shopInfoService;
|
||||||
@DubboReference
|
|
||||||
private ShopUserService shopUserService;
|
|
||||||
|
|
||||||
List<String> list = List.of(OrderStatusEnums.REFUND.getCode(), OrderStatusEnums.PART_REFUND.getCode());
|
List<String> list = List.of(OrderStatusEnums.REFUND.getCode(), OrderStatusEnums.PART_REFUND.getCode());
|
||||||
|
|
||||||
@@ -51,44 +53,55 @@ public class DistributionTask {
|
|||||||
*/
|
*/
|
||||||
// @Scheduled(cron = "0 0 0 * * ?")
|
// @Scheduled(cron = "0 0 0 * * ?")
|
||||||
// @Scheduled(fixedRate = 30000)
|
// @Scheduled(fixedRate = 30000)
|
||||||
public void deliver() {
|
public void deliver(Long shopId) {
|
||||||
// 1. 订单完成支付时(判断是否分销)产生流水记录。
|
LocalDateTime now = LocalDateTime.now();
|
||||||
// 2. 判断入账时间。
|
List<ShopInfo> shopInfos = shopInfoService.list(QueryWrapper.create()
|
||||||
// 3. 如果是 0 天,再去判断商户余额是否足够。够则入账,不足则不管。
|
.eq(ShopInfo::getIsDeleted, SystemConstants.OneZero.ZERO)
|
||||||
// 4. 流水增加应该入账的时间(订单产生时带入)
|
.isNotNull(ShopInfo::getExpireTime)
|
||||||
// 5. 定时任务 应该是一天执行一次。查询待入账状态和应入账时间小于当前时间的记录,循环处理:并且判断商户余额是否足够,余额不足忽略处理;余额足够变为已入账并扣除商户余额。
|
.lt(ShopInfo::getExpireTime, now)
|
||||||
// 6. 订单产生退款时,去流水表查询该订单的流水记录,如果未入账改为已入账,并插入一条退款扣钱的流水。
|
.gt(ShopInfo::getAmount, BigDecimal.ZERO)
|
||||||
|
.eq(ShopInfo::getId, shopId)
|
||||||
// shopInfo 查余额>0
|
);
|
||||||
// 循环 shopId 查询 如果金额不足 终止
|
if (CollUtil.isEmpty(shopInfos)) {
|
||||||
//
|
log.info("分销延时分账 无符合条件的店铺,无需处理分账");
|
||||||
LocalDateTime localDateTime = DateUtil.date().toLocalDateTime();
|
return;
|
||||||
distributionFlowService.list(new QueryWrapper()
|
}
|
||||||
.eq(MkDistributionFlow::getStatus, TableValueConstant.DistributionFlow.Status.PENDING.getCode()).le(MkDistributionFlow::getDeliverTime, localDateTime)).forEach(item -> {
|
for (ShopInfo shopInfo : shopInfos) {
|
||||||
FunUtils.safeRunVoid(() -> {
|
boolean breakCurrentShopFlow = false;
|
||||||
log.info("开始处理延时分账, id: {}, orderNo: {}, 类型: {}", item.getId(), item.getOrderNo(), item.getType());
|
List<MkDistributionFlow> flowList = distributionFlowService.list(new QueryWrapper()
|
||||||
|
.eq(MkDistributionFlow::getShopId, shopInfo.getId())
|
||||||
OrderInfo orderInfo = orderInfoService.getOne(new QueryWrapper().eq(OrderInfo::getOrderNo, item.getOrderNo()));
|
.eq(MkDistributionFlow::getStatus, TableValueConstant.DistributionFlow.Status.PENDING.getCode())
|
||||||
if (orderInfo == null) {
|
.le(MkDistributionFlow::getDeliverTime, now)
|
||||||
item.setStatus(TableValueConstant.DistributionFlow.Status.FAIL.getCode());
|
.orderBy(MkDistributionFlow::getId, true)
|
||||||
distributionFlowService.updateById(item);
|
);
|
||||||
log.warn("订单不存在, 订单号: {}", item.getOrderNo());
|
for (MkDistributionFlow item : flowList) {
|
||||||
return;
|
if (breakCurrentShopFlow) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (list.contains(orderInfo.getStatus())) {
|
try {
|
||||||
log.warn("订单已退款, 订单号: {}", item.getOrderNo());
|
log.info("分销延时分账, id: {}, orderNo: {}, 类型: {}", item.getId(), item.getOrderNo(), item.getType());
|
||||||
distributionUserService.refund(orderInfo.getId(), orderInfo.getOrderNo());
|
OrderInfo orderInfo = orderInfoService.getOne(new QueryWrapper().eq(OrderInfo::getOrderNo, item.getOrderNo()));
|
||||||
} else {
|
if (orderInfo == null) {
|
||||||
item.setStatus(TableValueConstant.DistributionFlow.Status.SUCCESS.getCode());
|
item.setStatus(TableValueConstant.DistributionFlow.Status.FAIL.getCode());
|
||||||
ShopUser shopUser = shopUserService.getById(item.getDistributionUserId());
|
distributionFlowService.updateById(item);
|
||||||
distributionUserService.updateShopInfoAmount(orderInfo.getShopId(), item.getRewardAmount().negate(), orderInfo.getId(), TableValueConstant.DistributionAmountFlow.Type.SUB, "分销扣减");
|
log.warn("分销延时分账。订单不存在, 订单号: {}", item.getOrderNo());
|
||||||
distributionUserService.updateIncome(item.getRewardAmount().negate(), item.getRewardAmount(), BigDecimal.ZERO,
|
continue;
|
||||||
item.getDistributionUserId(), shopUser.getUserId(), item.getShopUserId(), item.getShopId(), item.getLevel());
|
}
|
||||||
distributionFlowService.updateById(item);
|
if (list.contains(orderInfo.getStatus())) {
|
||||||
|
log.warn("分销延时分账。订单已退款, 订单号: {}", item.getOrderNo());
|
||||||
|
distributionUserService.refund(orderInfo.getId(), orderInfo.getOrderNo());
|
||||||
|
} else {
|
||||||
|
item.setStatus(TableValueConstant.DistributionFlow.Status.SUCCESS.getCode());
|
||||||
|
distributionUserService.distributionUserAmount(item, orderInfo);
|
||||||
|
}
|
||||||
|
} catch (CzgException e) {
|
||||||
|
log.error("店铺{}:{}分销延时分账异常:{}", shopInfo.getId(), shopInfo.getShopName(), e.getMessage());
|
||||||
|
breakCurrentShopFlow = true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("店铺{}:{}分销延时分账异常", shopInfo.getId(), shopInfo.getShopName(), e);
|
||||||
|
breakCurrentShopFlow = true;
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
package com.czg.controller.pay;
|
package com.czg.controller;
|
||||||
|
|
||||||
import com.czg.annotation.Debounce;
|
import com.czg.annotation.Debounce;
|
||||||
import com.czg.order.dto.MkDistributionPayDTO;
|
import com.czg.order.dto.MkDistributionPayDTO;
|
||||||
import com.czg.resp.CzgResult;
|
import com.czg.resp.CzgResult;
|
||||||
|
import com.czg.sa.StpKit;
|
||||||
import com.czg.service.order.service.DistributionPayService;
|
import com.czg.service.order.service.DistributionPayService;
|
||||||
import com.czg.system.service.SysParamsService;
|
import com.czg.system.service.SysParamsService;
|
||||||
import com.czg.utils.AssertUtil;
|
import com.czg.utils.AssertUtil;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.czg.controller.pay;
|
package com.czg.controller;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.core.util.URLUtil;
|
import cn.hutool.core.util.URLUtil;
|
||||||
@@ -10,7 +10,7 @@ import com.czg.order.entity.OrderInfo;
|
|||||||
import com.czg.order.service.OrderInfoCustomService;
|
import com.czg.order.service.OrderInfoCustomService;
|
||||||
import com.czg.resp.CzgResult;
|
import com.czg.resp.CzgResult;
|
||||||
import com.czg.service.order.dto.OrderPayParamDTO;
|
import com.czg.service.order.dto.OrderPayParamDTO;
|
||||||
import com.czg.service.order.service.OrderPayService;
|
import com.czg.service.order.service.PayService;
|
||||||
import com.czg.system.service.SysParamsService;
|
import com.czg.system.service.SysParamsService;
|
||||||
import com.czg.utils.AssertUtil;
|
import com.czg.utils.AssertUtil;
|
||||||
import com.czg.utils.ServletUtil;
|
import com.czg.utils.ServletUtil;
|
||||||
@@ -35,7 +35,7 @@ import java.util.Map;
|
|||||||
@RequestMapping("/pay")
|
@RequestMapping("/pay")
|
||||||
public class OrderPayController {
|
public class OrderPayController {
|
||||||
@Resource
|
@Resource
|
||||||
private OrderPayService orderPayService;
|
private PayService payService;
|
||||||
@Resource
|
@Resource
|
||||||
private OrderInfoCustomService orderInfoCustomService;
|
private OrderInfoCustomService orderInfoCustomService;
|
||||||
@Resource
|
@Resource
|
||||||
@@ -47,14 +47,14 @@ public class OrderPayController {
|
|||||||
@Debounce(value = "#payParam.checkOrderPay.orderId")
|
@Debounce(value = "#payParam.checkOrderPay.orderId")
|
||||||
public CzgResult<Object> creditPayOrder(@RequestHeader Long shopId, @Validated @RequestBody OrderPayParamDTO payParam) {
|
public CzgResult<Object> creditPayOrder(@RequestHeader Long shopId, @Validated @RequestBody OrderPayParamDTO payParam) {
|
||||||
payParam.setShopId(shopId);
|
payParam.setShopId(shopId);
|
||||||
return orderPayService.creditPayOrder(payParam);
|
return payService.creditPayOrder(payParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/cashPay")
|
@PostMapping("/cashPay")
|
||||||
@Debounce(value = "#payParam.checkOrderPay.orderId")
|
@Debounce(value = "#payParam.checkOrderPay.orderId")
|
||||||
public CzgResult<Object> cashPayOrder(@RequestHeader Long shopId, @Validated @RequestBody OrderPayParamDTO payParam) {
|
public CzgResult<Object> cashPayOrder(@RequestHeader Long shopId, @Validated @RequestBody OrderPayParamDTO payParam) {
|
||||||
payParam.setShopId(shopId);
|
payParam.setShopId(shopId);
|
||||||
return orderPayService.cashPayOrder(payParam);
|
return payService.cashPayOrder(payParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,7 +66,7 @@ public class OrderPayController {
|
|||||||
@Debounce(value = "#payParam.checkOrderPay.orderId")
|
@Debounce(value = "#payParam.checkOrderPay.orderId")
|
||||||
public CzgResult<Map<String, Object>> rechargePayOrder(@RequestHeader Long shopId, HttpServletRequest request, @Validated @RequestBody OrderPayParamDTO payParam) {
|
public CzgResult<Map<String, Object>> rechargePayOrder(@RequestHeader Long shopId, HttpServletRequest request, @Validated @RequestBody OrderPayParamDTO payParam) {
|
||||||
payParam.setShopId(shopId);
|
payParam.setShopId(shopId);
|
||||||
return orderPayService.rechargePayOrder(ServletUtil.getClientIP(request), payParam);
|
return payService.rechargePayOrder(ServletUtil.getClientIP(request), payParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,7 +83,7 @@ public class OrderPayController {
|
|||||||
public CzgResult<Object> vipPayOrder(@RequestHeader Long shopId, @Validated @RequestBody OrderPayParamDTO payParam) {
|
public CzgResult<Object> vipPayOrder(@RequestHeader Long shopId, @Validated @RequestBody OrderPayParamDTO payParam) {
|
||||||
payParam.setShopId(shopId);
|
payParam.setShopId(shopId);
|
||||||
AssertUtil.isBlank(payParam.getPayType(), "支付类型不可为空");
|
AssertUtil.isBlank(payParam.getPayType(), "支付类型不可为空");
|
||||||
return orderPayService.vipPayOrder(payParam);
|
return payService.vipPayOrder(payParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -93,7 +93,7 @@ public class OrderPayController {
|
|||||||
@Debounce(value = "#payParam.checkOrderPay.orderId")
|
@Debounce(value = "#payParam.checkOrderPay.orderId")
|
||||||
public CzgResult<Map<String, Object>> h5PayOrder(@RequestHeader Long shopId, HttpServletRequest request, @Validated @RequestBody OrderPayParamDTO payParam) {
|
public CzgResult<Map<String, Object>> h5PayOrder(@RequestHeader Long shopId, HttpServletRequest request, @Validated @RequestBody OrderPayParamDTO payParam) {
|
||||||
payParam.setShopId(shopId);
|
payParam.setShopId(shopId);
|
||||||
return orderPayService.h5PayOrder(ServletUtil.getClientIP(request, ""), payParam);
|
return payService.h5PayOrder(ServletUtil.getClientIP(request, ""), payParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -106,7 +106,7 @@ public class OrderPayController {
|
|||||||
@Debounce(value = "#payParam.checkOrderPay.orderId")
|
@Debounce(value = "#payParam.checkOrderPay.orderId")
|
||||||
public CzgResult<Map<String, Object>> jsPayOrder(@RequestHeader Long shopId, HttpServletRequest request, @Validated @RequestBody OrderPayParamDTO payParam) {
|
public CzgResult<Map<String, Object>> jsPayOrder(@RequestHeader Long shopId, HttpServletRequest request, @Validated @RequestBody OrderPayParamDTO payParam) {
|
||||||
payParam.setShopId(shopId);
|
payParam.setShopId(shopId);
|
||||||
return orderPayService.jsPayOrder(ServletUtil.getClientIP(request), payParam);
|
return payService.jsPayOrder(ServletUtil.getClientIP(request), payParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -118,7 +118,7 @@ public class OrderPayController {
|
|||||||
@Debounce(value = "#payParam.checkOrderPay.orderId")
|
@Debounce(value = "#payParam.checkOrderPay.orderId")
|
||||||
public CzgResult<Map<String, Object>> ltPayOrder(@RequestHeader Long shopId, HttpServletRequest request, @Validated @RequestBody OrderPayParamDTO payParam) {
|
public CzgResult<Map<String, Object>> ltPayOrder(@RequestHeader Long shopId, HttpServletRequest request, @Validated @RequestBody OrderPayParamDTO payParam) {
|
||||||
payParam.setShopId(shopId);
|
payParam.setShopId(shopId);
|
||||||
return orderPayService.ltPayOrder(ServletUtil.getClientIP(request), payParam);
|
return payService.ltPayOrder(ServletUtil.getClientIP(request), payParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -128,7 +128,7 @@ public class OrderPayController {
|
|||||||
@Debounce(value = "#payParam.checkOrderPay.orderId")
|
@Debounce(value = "#payParam.checkOrderPay.orderId")
|
||||||
public CzgResult<Map<String, Object>> scanPayOrder(@RequestHeader Long shopId, HttpServletRequest request, @Validated @RequestBody OrderPayParamDTO payParam) {
|
public CzgResult<Map<String, Object>> scanPayOrder(@RequestHeader Long shopId, HttpServletRequest request, @Validated @RequestBody OrderPayParamDTO payParam) {
|
||||||
payParam.setShopId(shopId);
|
payParam.setShopId(shopId);
|
||||||
return orderPayService.scanPayOrder(ServletUtil.getClientIP(request), payParam);
|
return payService.scanPayOrder(ServletUtil.getClientIP(request), payParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -139,7 +139,7 @@ public class OrderPayController {
|
|||||||
@Debounce(value = "#payParam.checkOrderPay.orderId")
|
@Debounce(value = "#payParam.checkOrderPay.orderId")
|
||||||
public CzgResult<Map<String, Object>> microPayOrder(@RequestHeader Long shopId, @Validated @RequestBody OrderPayParamDTO payParam) {
|
public CzgResult<Map<String, Object>> microPayOrder(@RequestHeader Long shopId, @Validated @RequestBody OrderPayParamDTO payParam) {
|
||||||
payParam.setShopId(shopId);
|
payParam.setShopId(shopId);
|
||||||
return orderPayService.microPayOrder(payParam);
|
return payService.microPayOrder(payParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -174,7 +174,7 @@ public class OrderPayController {
|
|||||||
@PostMapping("/shopPayApi/js2Pay")
|
@PostMapping("/shopPayApi/js2Pay")
|
||||||
@Debounce(value = "#payParam.checkOrderPay.orderId")
|
@Debounce(value = "#payParam.checkOrderPay.orderId")
|
||||||
public CzgResult<Map<String, Object>> js2PayOrder(HttpServletRequest request, @RequestBody OrderPayParamDTO payParam) {
|
public CzgResult<Map<String, Object>> js2PayOrder(HttpServletRequest request, @RequestBody OrderPayParamDTO payParam) {
|
||||||
return orderPayService.js2PayOrder(ServletUtil.getClientIP(request), payParam);
|
return payService.js2PayOrder(ServletUtil.getClientIP(request), payParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.czg.controller.pay;
|
package com.czg.controller;
|
||||||
|
|
||||||
import com.czg.annotation.Debounce;
|
import com.czg.annotation.Debounce;
|
||||||
import com.czg.entity.resp.CzgBaseResp;
|
import com.czg.entity.resp.CzgBaseResp;
|
||||||
@@ -7,7 +7,6 @@ import com.czg.service.order.dto.VipMemberPayParamDTO;
|
|||||||
import com.czg.service.order.dto.VipPayParamDTO;
|
import com.czg.service.order.dto.VipPayParamDTO;
|
||||||
import com.czg.service.order.dto.VipRefundDTO;
|
import com.czg.service.order.dto.VipRefundDTO;
|
||||||
import com.czg.service.order.service.PayService;
|
import com.czg.service.order.service.PayService;
|
||||||
import com.czg.service.order.service.ShopUserPayService;
|
|
||||||
import com.czg.utils.AssertUtil;
|
import com.czg.utils.AssertUtil;
|
||||||
import com.czg.utils.ServletUtil;
|
import com.czg.utils.ServletUtil;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
@@ -29,8 +28,6 @@ import java.util.Map;
|
|||||||
public class VipPayController {
|
public class VipPayController {
|
||||||
@Resource
|
@Resource
|
||||||
private PayService payService;
|
private PayService payService;
|
||||||
@Resource
|
|
||||||
private ShopUserPayService shopUserPayService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 现金充值
|
* 现金充值
|
||||||
@@ -42,7 +39,7 @@ public class VipPayController {
|
|||||||
public CzgResult<Object> cashPayVip(@Validated @RequestBody VipPayParamDTO payParam) {
|
public CzgResult<Object> cashPayVip(@Validated @RequestBody VipPayParamDTO payParam) {
|
||||||
AssertUtil.isNull(payParam.getShopUserId(), "充值失败 未指定店铺用户Id");
|
AssertUtil.isNull(payParam.getShopUserId(), "充值失败 未指定店铺用户Id");
|
||||||
payParam.setPlatformType(ServletUtil.getHeaderIgnoreCase(ServletUtil.getRequest(), "platformType"));
|
payParam.setPlatformType(ServletUtil.getHeaderIgnoreCase(ServletUtil.getRequest(), "platformType"));
|
||||||
return shopUserPayService.cashPayVip(payParam);
|
return payService.cashPayVip(payParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,7 +52,7 @@ public class VipPayController {
|
|||||||
public CzgResult<Map<String, Object>> jsPayVip(HttpServletRequest request, @Validated @RequestBody VipPayParamDTO payParam) {
|
public CzgResult<Map<String, Object>> jsPayVip(HttpServletRequest request, @Validated @RequestBody VipPayParamDTO payParam) {
|
||||||
AssertUtil.isNull(payParam.getShopUserId(), "充值失败 未指定店铺用户Id");
|
AssertUtil.isNull(payParam.getShopUserId(), "充值失败 未指定店铺用户Id");
|
||||||
payParam.setPlatformType(ServletUtil.getHeaderIgnoreCase(ServletUtil.getRequest(), "platformType"));
|
payParam.setPlatformType(ServletUtil.getHeaderIgnoreCase(ServletUtil.getRequest(), "platformType"));
|
||||||
return shopUserPayService.jsPayVip(ServletUtil.getClientIP(request), payParam);
|
return payService.jsPayVip(ServletUtil.getClientIP(request), payParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -68,7 +65,7 @@ public class VipPayController {
|
|||||||
public CzgResult<Map<String, Object>> ltPayVip(HttpServletRequest request, @Validated @RequestBody VipPayParamDTO payParam) {
|
public CzgResult<Map<String, Object>> ltPayVip(HttpServletRequest request, @Validated @RequestBody VipPayParamDTO payParam) {
|
||||||
AssertUtil.isNull(payParam.getShopUserId(), "充值失败 未指定店铺用户Id");
|
AssertUtil.isNull(payParam.getShopUserId(), "充值失败 未指定店铺用户Id");
|
||||||
payParam.setPlatformType(ServletUtil.getHeaderIgnoreCase(ServletUtil.getRequest(), "platformType"));
|
payParam.setPlatformType(ServletUtil.getHeaderIgnoreCase(ServletUtil.getRequest(), "platformType"));
|
||||||
return shopUserPayService.ltPayVip(ServletUtil.getClientIP(request), payParam);
|
return payService.ltPayVip(ServletUtil.getClientIP(request), payParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,7 +81,7 @@ public class VipPayController {
|
|||||||
return CzgResult.failure("充值失败 未指定充值金额");
|
return CzgResult.failure("充值失败 未指定充值金额");
|
||||||
}
|
}
|
||||||
rechargeDTO.setPlatformType(ServletUtil.getHeaderIgnoreCase(ServletUtil.getRequest(), "platformType"));
|
rechargeDTO.setPlatformType(ServletUtil.getHeaderIgnoreCase(ServletUtil.getRequest(), "platformType"));
|
||||||
return shopUserPayService.recharge(ServletUtil.getClientIP(request), rechargeDTO, rechargeDTO.getShopUserId());
|
return payService.recharge(ServletUtil.getClientIP(request), rechargeDTO, rechargeDTO.getShopUserId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,7 +95,7 @@ public class VipPayController {
|
|||||||
public CzgResult<Map<String, Object>> ltPayMember(HttpServletRequest request, @Validated @RequestBody VipMemberPayParamDTO payParam) {
|
public CzgResult<Map<String, Object>> ltPayMember(HttpServletRequest request, @Validated @RequestBody VipMemberPayParamDTO payParam) {
|
||||||
AssertUtil.isNull(payParam.getShopUserId(), "购买失败 未指定店铺用户Id");
|
AssertUtil.isNull(payParam.getShopUserId(), "购买失败 未指定店铺用户Id");
|
||||||
payParam.setPlatformType(ServletUtil.getHeaderIgnoreCase(ServletUtil.getRequest(), "platformType"));
|
payParam.setPlatformType(ServletUtil.getHeaderIgnoreCase(ServletUtil.getRequest(), "platformType"));
|
||||||
return shopUserPayService.ltPayMember(ServletUtil.getClientIP(request), payParam);
|
return payService.ltPayMember(ServletUtil.getClientIP(request), payParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -111,7 +108,7 @@ public class VipPayController {
|
|||||||
public CzgResult<Map<String, Object>> scanPayVip(HttpServletRequest request, @Validated @RequestBody VipPayParamDTO payParam) {
|
public CzgResult<Map<String, Object>> scanPayVip(HttpServletRequest request, @Validated @RequestBody VipPayParamDTO payParam) {
|
||||||
AssertUtil.isNull(payParam.getShopUserId(), "充值失败 未指定店铺用户Id");
|
AssertUtil.isNull(payParam.getShopUserId(), "充值失败 未指定店铺用户Id");
|
||||||
payParam.setPlatformType(ServletUtil.getHeaderIgnoreCase(request, "platformType"));
|
payParam.setPlatformType(ServletUtil.getHeaderIgnoreCase(request, "platformType"));
|
||||||
return shopUserPayService.scanPayVip(ServletUtil.getClientIP(request), payParam);
|
return payService.scanPayVip(ServletUtil.getClientIP(request), payParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -124,7 +121,7 @@ public class VipPayController {
|
|||||||
public CzgResult<Map<String, Object>> microPayVip(@Validated @RequestBody VipPayParamDTO payParam) {
|
public CzgResult<Map<String, Object>> microPayVip(@Validated @RequestBody VipPayParamDTO payParam) {
|
||||||
AssertUtil.isNull(payParam.getShopUserId(), "充值失败 未指定店铺用户Id");
|
AssertUtil.isNull(payParam.getShopUserId(), "充值失败 未指定店铺用户Id");
|
||||||
payParam.setPlatformType(ServletUtil.getHeaderIgnoreCase(ServletUtil.getRequest(), "platformType"));
|
payParam.setPlatformType(ServletUtil.getHeaderIgnoreCase(ServletUtil.getRequest(), "platformType"));
|
||||||
return shopUserPayService.microPayVip(payParam);
|
return payService.microPayVip(payParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -135,7 +132,7 @@ public class VipPayController {
|
|||||||
@PostMapping("/refundVipBefore")
|
@PostMapping("/refundVipBefore")
|
||||||
@Debounce(value = "#payParam.flowId")
|
@Debounce(value = "#payParam.flowId")
|
||||||
public CzgResult<Map<String, BigDecimal>> refundVipBefore(@Validated @RequestBody VipRefundDTO payParam) {
|
public CzgResult<Map<String, BigDecimal>> refundVipBefore(@Validated @RequestBody VipRefundDTO payParam) {
|
||||||
return shopUserPayService.refundVipBefore(payParam);
|
return payService.refundVipBefore(payParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -158,7 +155,7 @@ public class VipPayController {
|
|||||||
return CzgResult.failure("退款金额过大");
|
return CzgResult.failure("退款金额过大");
|
||||||
}
|
}
|
||||||
payParam.setPlatformType(ServletUtil.getHeaderIgnoreCase(request, "platformType"));
|
payParam.setPlatformType(ServletUtil.getHeaderIgnoreCase(request, "platformType"));
|
||||||
return shopUserPayService.refundVip(payParam);
|
return payService.refundVip(payParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -9,7 +9,7 @@ import com.czg.order.vo.HistoryOrderVo;
|
|||||||
import com.czg.order.vo.OrderInfoVo;
|
import com.czg.order.vo.OrderInfoVo;
|
||||||
import com.czg.resp.CzgResult;
|
import com.czg.resp.CzgResult;
|
||||||
import com.czg.sa.StpKit;
|
import com.czg.sa.StpKit;
|
||||||
import com.czg.service.order.service.OrderPayService;
|
import com.czg.service.order.service.PayService;
|
||||||
import com.czg.utils.AssertUtil;
|
import com.czg.utils.AssertUtil;
|
||||||
import com.czg.utils.ServletUtil;
|
import com.czg.utils.ServletUtil;
|
||||||
import com.mybatisflex.core.paginate.Page;
|
import com.mybatisflex.core.paginate.Page;
|
||||||
@@ -31,7 +31,7 @@ public class AdminOrderController {
|
|||||||
@Resource
|
@Resource
|
||||||
private OrderInfoCustomService orderInfoService;
|
private OrderInfoCustomService orderInfoService;
|
||||||
@Resource
|
@Resource
|
||||||
private OrderPayService orderPayService;
|
private PayService payService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单列表
|
* 订单列表
|
||||||
@@ -94,7 +94,7 @@ public class AdminOrderController {
|
|||||||
@PostMapping("/refundOrder")
|
@PostMapping("/refundOrder")
|
||||||
@Debounce(value = "#refundDTO.orderId")
|
@Debounce(value = "#refundDTO.orderId")
|
||||||
public CzgResult<Object> refundOrder(@Validated @RequestBody OrderInfoRefundDTO refundDTO) {
|
public CzgResult<Object> refundOrder(@Validated @RequestBody OrderInfoRefundDTO refundDTO) {
|
||||||
return orderPayService.refundOrderBefore(refundDTO);
|
return payService.refundOrderBefore(refundDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,95 +0,0 @@
|
|||||||
package com.czg.controller.admin;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
|
||||||
import com.czg.EntryManager;
|
|
||||||
import com.czg.annotation.Debounce;
|
|
||||||
import com.czg.dto.req.AggregateMerchantDto;
|
|
||||||
import com.czg.dto.resp.BankBranchDto;
|
|
||||||
import com.czg.service.order.dto.AggregateMerchantVO;
|
|
||||||
import com.czg.service.order.service.ShopDirectMerchantService;
|
|
||||||
import com.czg.resp.CzgResult;
|
|
||||||
import com.czg.sa.StpKit;
|
|
||||||
import com.czg.task.EntryManagerTask;
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进件管理
|
|
||||||
*
|
|
||||||
* @author ww
|
|
||||||
*/
|
|
||||||
@AllArgsConstructor
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/admin/data/entryManager")
|
|
||||||
public class EntryManagerController {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private ShopDirectMerchantService shopDirectMerchantService;
|
|
||||||
@Resource
|
|
||||||
private EntryManagerTask entryManagerTask;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ocr识别填充
|
|
||||||
* 阿里 ocr识别图片
|
|
||||||
* 本接口支持:PNG、JPG、JPEG、BMP、GIF、TIFF、WebP、PDF。
|
|
||||||
* 图片长宽需要大于 15 像素,小于 8192 像素。
|
|
||||||
* 长宽比需要小于 50。长宽均大于 500px。
|
|
||||||
* 图片二进制文件不能超过 10MB。
|
|
||||||
* 图片过大会影响接口响应速度,建议使用小于 1.5M 图片进行识别,
|
|
||||||
*
|
|
||||||
* @param url 图片地址
|
|
||||||
* @param type IdCard 身份证
|
|
||||||
* BankCard 银行卡
|
|
||||||
* BusinessLicense 营业执照
|
|
||||||
*/
|
|
||||||
@GetMapping("getInfoByImg")
|
|
||||||
public CzgResult<JSONObject> getInfoByImg(String url, String type) throws Exception {
|
|
||||||
return CzgResult.success(shopDirectMerchantService.getInfoByImg(url, type));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询银行支行列表
|
|
||||||
*
|
|
||||||
* @param province 省份 陕西省 从 /system/admin/common/region获取
|
|
||||||
* @param city 城市 西安市 从 /system/admin/common/region获取
|
|
||||||
* @param instId 顶级机构ID CMB 从 /system/admin/common/bankInfo 获取
|
|
||||||
*/
|
|
||||||
@GetMapping("bankBranchList")
|
|
||||||
public CzgResult<List<BankBranchDto>> queryBankBranchList(String province, String city, String instId) {
|
|
||||||
return CzgResult.success(EntryManager.queryBankBranchList(province, city, instId));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取进件信息
|
|
||||||
*/
|
|
||||||
@GetMapping
|
|
||||||
public CzgResult<AggregateMerchantVO> getEntry(Long shopId) {
|
|
||||||
return CzgResult.success(shopDirectMerchantService.getEntry(shopId));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 主动查询进件信息状态
|
|
||||||
* 进件状态是INIT 待处理 AUDIT 审核中 SIGN 待签约
|
|
||||||
* 3分钟内只能查一次
|
|
||||||
*/
|
|
||||||
@GetMapping("queryEntry")
|
|
||||||
@Debounce(value = "#shopId", interval = 1000 * 60 * 3)
|
|
||||||
public CzgResult<Boolean> queryEntry(Long shopId) {
|
|
||||||
entryManagerTask.entryManager(shopId);
|
|
||||||
return CzgResult.success();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 申请进件
|
|
||||||
*/
|
|
||||||
@Debounce(value = "#reqDto.shopId")
|
|
||||||
@PostMapping
|
|
||||||
public CzgResult<Boolean> entryManager(@RequestBody AggregateMerchantDto reqDto) {
|
|
||||||
return CzgResult.success(shopDirectMerchantService.entryManager(reqDto));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
package com.czg.mq;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import com.czg.EntryManager;
|
|
||||||
import com.czg.PayCst;
|
|
||||||
import com.czg.config.RabbitConstants;
|
|
||||||
import com.czg.config.RedisCst;
|
|
||||||
import com.czg.dto.resp.EntryRespDto;
|
|
||||||
import com.czg.order.entity.ShopDirectMerchant;
|
|
||||||
import com.czg.service.RedisService;
|
|
||||||
import com.czg.service.order.dto.AggregateMerchantVO;
|
|
||||||
import com.czg.service.order.service.ShopDirectMerchantService;
|
|
||||||
import com.rabbitmq.client.Channel;
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.apache.logging.log4j.ThreadContext;
|
|
||||||
import org.springframework.amqp.core.Message;
|
|
||||||
import org.springframework.amqp.rabbit.annotation.*;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 打印mq消息处理器
|
|
||||||
*
|
|
||||||
* @author Administrator
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
@Slf4j
|
|
||||||
public class EntryManagerMqListener {
|
|
||||||
@Resource
|
|
||||||
private RedisService redisService;
|
|
||||||
@Resource
|
|
||||||
private ShopDirectMerchantService shopDirectMerchantService;
|
|
||||||
|
|
||||||
String key = RedisCst.SHOP_ENTRY;
|
|
||||||
|
|
||||||
@RabbitListener(
|
|
||||||
bindings = @QueueBinding(
|
|
||||||
value = @Queue(value = "${spring.profiles.active}-" + RabbitConstants.Queue.SHOP_ENTRY_MANAGER,
|
|
||||||
durable = "true", exclusive = "false", autoDelete = "false"),
|
|
||||||
exchange = @Exchange(value = "${spring.profiles.active}-" + RabbitConstants.Exchange.CASH_EXCHANGE),
|
|
||||||
key = "${spring.profiles.active}-" + RabbitConstants.Queue.SHOP_ENTRY_MANAGER
|
|
||||||
),
|
|
||||||
concurrency = "5"
|
|
||||||
)
|
|
||||||
@RabbitHandler
|
|
||||||
public void handle(Message message, Channel channel, String msg) throws IOException {
|
|
||||||
String messageId = message.getMessageProperties().getMessageId();
|
|
||||||
if (hasMessageId(messageId)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Long shopId = Long.valueOf(msg);
|
|
||||||
// 将唯一标识添加到日志上下文
|
|
||||||
ThreadContext.put("traceId", messageId);
|
|
||||||
// 安全转换shopId
|
|
||||||
if (shopId == null) {
|
|
||||||
channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
AggregateMerchantVO entry = shopDirectMerchantService.getEntry(Long.valueOf(msg));
|
|
||||||
if (entry != null) {
|
|
||||||
EntryManager.uploadParamImage(entry);
|
|
||||||
List<String> platform = new ArrayList<>();
|
|
||||||
if (PayCst.EntryStatus.WAIT.equals(entry.getAlipayStatus())) {
|
|
||||||
platform.add(PayCst.Platform.ALIPAY);
|
|
||||||
}
|
|
||||||
if (PayCst.EntryStatus.WAIT.equals(entry.getWechatStatus())) {
|
|
||||||
platform.add(PayCst.Platform.WECHAT);
|
|
||||||
}
|
|
||||||
EntryRespDto resp = EntryManager.entryMerchant(entry, platform.toArray(new String[0]));
|
|
||||||
ShopDirectMerchant merchant = new ShopDirectMerchant();
|
|
||||||
merchant.setShopId(entry.getShopId());
|
|
||||||
|
|
||||||
merchant.setWechatApplyId(resp.getWechatApplyId());
|
|
||||||
merchant.setWechatStatus(resp.getWechatStatus());
|
|
||||||
merchant.setWechatErrorMsg(resp.getWechatErrorMsg());
|
|
||||||
|
|
||||||
merchant.setAlipayOrderId(resp.getAlipayOrderId());
|
|
||||||
merchant.setAlipayStatus(resp.getAlipayStatus());
|
|
||||||
merchant.setAlipayErrorMsg(resp.getAlipayErrorMsg());
|
|
||||||
shopDirectMerchantService.updateById(merchant);
|
|
||||||
}
|
|
||||||
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("进件MQ对接业务异常shopId:{}", msg, e);
|
|
||||||
ShopDirectMerchant merchant = new ShopDirectMerchant();
|
|
||||||
merchant.setShopId(Long.valueOf(msg));
|
|
||||||
merchant.setWechatStatus(PayCst.EntryStatus.REJECTED);
|
|
||||||
merchant.setAlipayStatus(PayCst.EntryStatus.REJECTED);
|
|
||||||
merchant.setErrorMsg("系统错误,请联系管理员后重试。");
|
|
||||||
shopDirectMerchantService.updateById(merchant);
|
|
||||||
|
|
||||||
channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
|
|
||||||
} finally {
|
|
||||||
delMessageId(messageId);
|
|
||||||
// 清除日志上下文信息
|
|
||||||
ThreadContext.remove("messageId");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasMessageId(String messageId) {
|
|
||||||
if (!redisService.hasKey(key)) {
|
|
||||||
if (StrUtil.isNotBlank(messageId)) {
|
|
||||||
redisService.leftPush(key, messageId);
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
List<Object> list = redisService.lGet(key, 0, -1);
|
|
||||||
if (!list.contains(messageId)) {
|
|
||||||
redisService.leftPush(key, messageId);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void delMessageId(String messageId) {
|
|
||||||
redisService.lRemove(key, 0, messageId);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -48,6 +48,9 @@ public class OrderMqListener {
|
|||||||
orderInfoCustomService.updateOrderDetailStatus(Long.valueOf(finalInfo));
|
orderInfoCustomService.updateOrderDetailStatus(Long.valueOf(finalInfo));
|
||||||
|
|
||||||
});
|
});
|
||||||
|
info = info.replace("UP_ORDER_DETAIL:", "");
|
||||||
|
System.out.println(info);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.ORDER_STOCK_QUEUE})
|
@RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.ORDER_STOCK_QUEUE})
|
||||||
|
|||||||
@@ -6,12 +6,13 @@ import com.czg.config.RabbitConstants;
|
|||||||
import com.czg.config.RedisCst;
|
import com.czg.config.RedisCst;
|
||||||
import com.czg.order.entity.MqLog;
|
import com.czg.order.entity.MqLog;
|
||||||
import com.czg.order.service.MqLogService;
|
import com.czg.order.service.MqLogService;
|
||||||
import com.czg.service.RedisService;
|
|
||||||
import com.czg.service.order.print.PrinterHandler;
|
import com.czg.service.order.print.PrinterHandler;
|
||||||
|
import com.czg.service.order.utils.FunUtil;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
@@ -27,15 +28,19 @@ public class PrintMqListener {
|
|||||||
@Resource
|
@Resource
|
||||||
private MqLogService mqLogService;
|
private MqLogService mqLogService;
|
||||||
@Resource
|
@Resource
|
||||||
private RedisService redisService;
|
private FunUtil funUtil;
|
||||||
|
|
||||||
|
// 注入自定义线程池(建议单独配置,避免使用默认线程池)
|
||||||
|
@Resource
|
||||||
|
private ThreadPoolTaskExecutor asyncExecutor;
|
||||||
@Lazy
|
@Lazy
|
||||||
@Resource
|
@Resource
|
||||||
private PrinterHandler printerHandler;
|
private PrinterHandler printerHandler;
|
||||||
|
|
||||||
private <T> void invokeFun(String queue, String type, String plat, T data, Consumer<T> consumer) {
|
private <T> void invokeFun(String type, String plat, T data, Consumer<T> consumer) {
|
||||||
long startTime = DateUtil.date().getTime();
|
long startTime = DateUtil.date().getTime();
|
||||||
log.info("接收到{}打印消息:{}", type, data);
|
log.info("接收到{}打印消息:{}", type, data);
|
||||||
MqLog mqLog = new MqLog().setQueue(queue).setMsg(data.toString())
|
MqLog mqLog = new MqLog().setQueue(RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE).setMsg(data.toString())
|
||||||
.setType(type).setPlat(plat).setCreateTime(DateUtil.date().toLocalDateTime());
|
.setType(type).setPlat(plat).setCreateTime(DateUtil.date().toLocalDateTime());
|
||||||
try {
|
try {
|
||||||
consumer.accept(data);
|
consumer.accept(data);
|
||||||
@@ -51,18 +56,45 @@ public class PrintMqListener {
|
|||||||
@RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE})
|
@RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE})
|
||||||
public void orderPrint(String req) {
|
public void orderPrint(String req) {
|
||||||
// 执行核心打印逻辑
|
// 执行核心打印逻辑
|
||||||
invokeFun(RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE, "orderPrint", "java.order", req, (data) -> {
|
invokeFun("orderPrint", "java.order", req, (data) -> {
|
||||||
JSONObject jsonObject = JSONObject.parseObject(data);
|
JSONObject jsonObject = JSONObject.parseObject(data);
|
||||||
String orderId = jsonObject.getString("orderId");
|
String orderId = jsonObject.getString("orderId");
|
||||||
if (orderId == null) {
|
if (orderId == null) {
|
||||||
throw new RuntimeException("订单打印失败,未传递orderId");
|
throw new RuntimeException("订单打印失败,未传递orderId");
|
||||||
}
|
}
|
||||||
Boolean printOrder = jsonObject.getBoolean("printOrder");
|
Boolean printOrder = jsonObject.getBoolean("printOrder");
|
||||||
redisService.runFunAndCheckKey(() -> {
|
funUtil.runFunAndCheckKey(() -> {
|
||||||
printerHandler.handler(orderId, printOrder != null && !printOrder ? PrinterHandler.PrintTypeEnum.ONE : PrinterHandler.PrintTypeEnum.ONE_AND_ORDER);
|
printerHandler.handler(orderId, printOrder != null && !printOrder ? PrinterHandler.PrintTypeEnum.ONE : PrinterHandler.PrintTypeEnum.ONE_AND_ORDER);
|
||||||
return null;
|
return null;
|
||||||
}, RedisCst.getLockKey("orderPrint", orderId));
|
}, RedisCst.getLockKey("orderPrint", orderId));
|
||||||
});
|
});
|
||||||
|
// // 使用异步线程池执行延迟任务,不阻塞当前消费者线程
|
||||||
|
// CompletableFuture.runAsync(() -> {
|
||||||
|
// try {
|
||||||
|
// // 延迟3秒处理
|
||||||
|
// TimeUnit.SECONDS.sleep(3);
|
||||||
|
// // 执行核心打印逻辑
|
||||||
|
// invokeFun("orderPrint", "java.order", req, (data) -> {
|
||||||
|
// JSONObject jsonObject = JSONObject.parseObject(data);
|
||||||
|
// String orderId = jsonObject.getString("orderId");
|
||||||
|
// if (orderId == null) {
|
||||||
|
// throw new RuntimeException("订单打印失败,未传递orderId");
|
||||||
|
// }
|
||||||
|
// Boolean printOrder = jsonObject.getBoolean("printOrder");
|
||||||
|
// funUtil.runFunAndCheckKey(() -> {
|
||||||
|
// printerHandler.handler(orderId, printOrder != null && !printOrder ? PrinterHandler.PrintTypeEnum.ONE : PrinterHandler.PrintTypeEnum.ONE_AND_ORDER);
|
||||||
|
// return null;
|
||||||
|
// }, RedisCst.getLockKey("orderPrint", orderId));
|
||||||
|
// });
|
||||||
|
// } catch (InterruptedException e) {
|
||||||
|
// Thread.currentThread().interrupt();
|
||||||
|
// // 记录中断日志
|
||||||
|
// log.warn("打印任务被中断,req:{}", req, e);
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// // 记录业务异常日志
|
||||||
|
// log.error("打印任务处理失败,req:{}", req, e);
|
||||||
|
// }
|
||||||
|
// }, asyncExecutor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,16 +102,14 @@ public class PrintMqListener {
|
|||||||
*/
|
*/
|
||||||
@RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE})
|
@RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE})
|
||||||
public void handoverPrint(String id) {
|
public void handoverPrint(String id) {
|
||||||
invokeFun(RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE, "handoverPrint", "java.order", id, (data) ->
|
invokeFun("handoverPrint", "java.order", id, (data) -> printerHandler.handler(data, PrinterHandler.PrintTypeEnum.HANDOVER));
|
||||||
printerHandler.handler(data, PrinterHandler.PrintTypeEnum.HANDOVER));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 叫号打印
|
* 交班打印
|
||||||
*/
|
*/
|
||||||
@RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.CALL_TABLE_QUEUE})
|
@RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.CALL_TABLE_PRINT_QUEUE})
|
||||||
public void callTablePrint(String id) {
|
public void callTablePrint(String id) {
|
||||||
invokeFun(RabbitConstants.Queue.CALL_TABLE_QUEUE, "callTable", "java.order", id, (data) ->
|
invokeFun("handoverPrint", "java.order", id, (data) -> printerHandler.handler(data, PrinterHandler.PrintTypeEnum.CALL));
|
||||||
printerHandler.handler(data, PrinterHandler.PrintTypeEnum.CALL));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,87 +0,0 @@
|
|||||||
package com.czg.task;
|
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import com.czg.EntryManager;
|
|
||||||
import com.czg.PayCst;
|
|
||||||
import com.czg.account.entity.ShopInfo;
|
|
||||||
import com.czg.account.service.ShopInfoService;
|
|
||||||
import com.czg.dto.resp.QueryStatusResp;
|
|
||||||
import com.czg.order.entity.ShopDirectMerchant;
|
|
||||||
import com.czg.order.service.ShopOrderStatisticService;
|
|
||||||
import com.czg.order.service.ShopProdStatisticService;
|
|
||||||
import com.czg.order.service.ShopTableOrderStatisticService;
|
|
||||||
import com.czg.service.RedisService;
|
|
||||||
import com.czg.service.order.service.ShopDirectMerchantService;
|
|
||||||
import com.mybatisflex.core.query.QueryWrapper;
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.apache.dubbo.config.annotation.DubboReference;
|
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进件查询
|
|
||||||
*
|
|
||||||
* @author ww
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
@Slf4j
|
|
||||||
public class EntryManagerTask {
|
|
||||||
@Resource
|
|
||||||
private ShopDirectMerchantService shopDirectMerchantService;
|
|
||||||
@DubboReference
|
|
||||||
private ShopInfoService shopInfoService;
|
|
||||||
|
|
||||||
//每10分钟查一次
|
|
||||||
@Scheduled(cron = "0 0/10 * * * ? ")
|
|
||||||
public void run() {
|
|
||||||
log.info("进件查询,定时任务执行");
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
entryManager(null);
|
|
||||||
log.info("进件查询,定时任务执行完毕,耗时:{}ms", start - System.currentTimeMillis());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询状态为待处理、待签约、待审核的进件
|
|
||||||
*/
|
|
||||||
public void entryManager(Long shopId) {
|
|
||||||
List<ShopDirectMerchant> list = shopDirectMerchantService.list(QueryWrapper.create()
|
|
||||||
.eq(ShopDirectMerchant::getShopId, shopId)
|
|
||||||
.in(ShopDirectMerchant::getWechatStatus, PayCst.EntryStatus.NEED_QUERY_LIST)
|
|
||||||
.or(ShopDirectMerchant::getAlipayStatus).in(PayCst.EntryStatus.NEED_QUERY_LIST));
|
|
||||||
if (CollUtil.isEmpty(list)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (ShopDirectMerchant shopDirectMerchant : list) {
|
|
||||||
String wechatMerchantId = "";
|
|
||||||
String alipayMerchantId = "";
|
|
||||||
if (PayCst.EntryStatus.NEED_QUERY_LIST.contains(shopDirectMerchant.getWechatStatus()) && StrUtil.isNotBlank(shopDirectMerchant.getWechatApplyId())) {
|
|
||||||
QueryStatusResp wechatStatus = EntryManager.queryWechatEntryStatus(shopDirectMerchant.getWechatApplyId());
|
|
||||||
shopDirectMerchant.setWechatStatus(wechatStatus.getStatus());
|
|
||||||
shopDirectMerchant.setWechatErrorMsg(wechatStatus.getFailReason());
|
|
||||||
shopDirectMerchant.setWechatSignUrl(wechatStatus.getSignUrl());
|
|
||||||
if (PayCst.EntryStatus.FINISH.equals(wechatStatus.getStatus())) {
|
|
||||||
wechatMerchantId = wechatStatus.getThirdMerchantId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (PayCst.EntryStatus.NEED_QUERY_LIST.contains(shopDirectMerchant.getAlipayStatus()) && StrUtil.isNotBlank(shopDirectMerchant.getAlipayOrderId())) {
|
|
||||||
QueryStatusResp alipayStatus = EntryManager.queryAlipayEntryStatus(shopDirectMerchant.getAlipayOrderId());
|
|
||||||
shopDirectMerchant.setAlipayStatus(alipayStatus.getStatus());
|
|
||||||
shopDirectMerchant.setAlipayErrorMsg(alipayStatus.getFailReason());
|
|
||||||
shopDirectMerchant.setAlipaySignUrl(alipayStatus.getSignUrl());
|
|
||||||
if (PayCst.EntryStatus.FINISH.equals(alipayStatus.getStatus())) {
|
|
||||||
alipayMerchantId = alipayStatus.getThirdMerchantId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
shopDirectMerchantService.updateById(shopDirectMerchant);
|
|
||||||
if (StrUtil.isNotBlank(wechatMerchantId) || StrUtil.isNotBlank(alipayMerchantId)) {
|
|
||||||
shopInfoService.editEntry(shopDirectMerchant.getShopId(), wechatMerchantId, alipayMerchantId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -28,7 +28,6 @@ import java.util.List;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单过期处理
|
* 订单过期处理
|
||||||
* 退款失败 补偿
|
|
||||||
*
|
*
|
||||||
* @author ww
|
* @author ww
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
package com.czg.controller.admin;
|
|
||||||
|
|
||||||
import com.czg.BaseQueryParam;
|
|
||||||
import com.czg.resp.CzgResult;
|
|
||||||
import com.czg.system.entity.SysBankInfo;
|
|
||||||
import com.czg.system.entity.SysCategoryInfo;
|
|
||||||
import com.czg.system.entity.SysRegion;
|
|
||||||
import com.czg.system.service.SysBankInfoService;
|
|
||||||
import com.czg.system.service.SysCategoryInfoService;
|
|
||||||
import com.czg.system.service.SysRegionService;
|
|
||||||
import com.czg.system.vo.SysCategoryInfoVO;
|
|
||||||
import com.mybatisflex.core.paginate.Page;
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通用
|
|
||||||
*
|
|
||||||
* @author Administrator
|
|
||||||
*/
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/admin/common")
|
|
||||||
public class SysCommonController {
|
|
||||||
@Resource
|
|
||||||
private SysRegionService sysRegionService;
|
|
||||||
@Resource
|
|
||||||
private SysBankInfoService bankInfoService;
|
|
||||||
@Resource
|
|
||||||
private SysCategoryInfoService categoryInfoService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取所有地域
|
|
||||||
*/
|
|
||||||
@GetMapping("/region")
|
|
||||||
public CzgResult<List<SysRegion>> region() {
|
|
||||||
return CzgResult.success(sysRegionService.regionList());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取银行信息
|
|
||||||
*/
|
|
||||||
@GetMapping("/bankInfo")
|
|
||||||
public CzgResult<Page<SysBankInfo>> bankInfo(BaseQueryParam param, @RequestParam String bankName) {
|
|
||||||
return CzgResult.success(bankInfoService.bankInfoList(param, bankName));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 类目信息表
|
|
||||||
*/
|
|
||||||
@GetMapping("/category")
|
|
||||||
public CzgResult<List<SysCategoryInfoVO>> category() {
|
|
||||||
return CzgResult.success(categoryInfoService.categoryList());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -21,24 +21,12 @@ public class RabbitConfig {
|
|||||||
|
|
||||||
@Value("${spring.profiles.active}")
|
@Value("${spring.profiles.active}")
|
||||||
private String activeProfile;
|
private String activeProfile;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Primary
|
@Primary
|
||||||
public DirectExchange directExchange() {
|
public DirectExchange directExchange() {
|
||||||
return new DirectExchange(activeProfile + "-" + RabbitConstants.Exchange.CASH_EXCHANGE);
|
return new DirectExchange(activeProfile + "-" + RabbitConstants.Exchange.CASH_EXCHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------ 商家入驻
|
|
||||||
@Bean
|
|
||||||
public Queue entryManagerQueue() {
|
|
||||||
return new Queue(activeProfile + "-" + RabbitConstants.Queue.SHOP_ENTRY_MANAGER, true, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Binding entryManagerExchange(Queue entryManagerQueue, DirectExchange exchange) {
|
|
||||||
return BindingBuilder.bind(entryManagerQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.SHOP_ENTRY_MANAGER);
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------订单打印队列
|
//------------------------------------------------------订单打印队列
|
||||||
@Bean
|
@Bean
|
||||||
public Queue orderPrintQueue() {
|
public Queue orderPrintQueue() {
|
||||||
@@ -48,7 +36,6 @@ public class RabbitConfig {
|
|||||||
args.put("x-message-ttl", 180000);
|
args.put("x-message-ttl", 180000);
|
||||||
return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_PRINT_QUEUE, true, false, false, args);
|
return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_PRINT_QUEUE, true, false, false, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Binding bindingOrderPrintExchange(Queue orderPrintQueue, DirectExchange exchange) {
|
public Binding bindingOrderPrintExchange(Queue orderPrintQueue, DirectExchange exchange) {
|
||||||
return BindingBuilder.bind(orderPrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_PRINT_QUEUE);
|
return BindingBuilder.bind(orderPrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_PRINT_QUEUE);
|
||||||
@@ -64,7 +51,6 @@ public class RabbitConfig {
|
|||||||
// args.put("x-message-ttl", 180000);
|
// args.put("x-message-ttl", 180000);
|
||||||
return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE, true, false, false);
|
return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE, true, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Binding bindingOrderMachinePrintExchange(Queue orderMachinePrintQueue, DirectExchange exchange) {
|
public Binding bindingOrderMachinePrintExchange(Queue orderMachinePrintQueue, DirectExchange exchange) {
|
||||||
return BindingBuilder.bind(orderMachinePrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE);
|
return BindingBuilder.bind(orderMachinePrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE);
|
||||||
@@ -75,7 +61,6 @@ public class RabbitConfig {
|
|||||||
public Queue handoverPrintQueue() {
|
public Queue handoverPrintQueue() {
|
||||||
return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE, true, false, false);
|
return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE, true, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Binding bindingHandoverPrintExchange(Queue handoverPrintQueue, DirectExchange exchange) {
|
public Binding bindingHandoverPrintExchange(Queue handoverPrintQueue, DirectExchange exchange) {
|
||||||
return BindingBuilder.bind(handoverPrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE);
|
return BindingBuilder.bind(handoverPrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE);
|
||||||
@@ -84,12 +69,11 @@ public class RabbitConfig {
|
|||||||
//------------------------------------------------------叫号 打票
|
//------------------------------------------------------叫号 打票
|
||||||
@Bean
|
@Bean
|
||||||
public Queue callTablePrintQueue() {
|
public Queue callTablePrintQueue() {
|
||||||
return new Queue(activeProfile + "-" + RabbitConstants.Queue.CALL_TABLE_QUEUE, true, false, false);
|
return new Queue(activeProfile + "-" + RabbitConstants.Queue.CALL_TABLE_PRINT_QUEUE, true, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Binding bindingCallTablePrintExchange(Queue callTablePrintQueue, DirectExchange exchange) {
|
public Binding bindingCallTablePrintExchange(Queue callTablePrintQueue, DirectExchange exchange) {
|
||||||
return BindingBuilder.bind(callTablePrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.CALL_TABLE_QUEUE);
|
return BindingBuilder.bind(callTablePrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.CALL_TABLE_PRINT_QUEUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------订单取消
|
//------------------------------------------------------订单取消
|
||||||
@@ -97,10 +81,9 @@ public class RabbitConfig {
|
|||||||
public Queue orderCancelQueue() {
|
public Queue orderCancelQueue() {
|
||||||
return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_CANCEL_QUEUE, true);
|
return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_CANCEL_QUEUE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Binding bindingOrderCancelExchange(Queue orderCancelQueue, DirectExchange exchange) {
|
public Binding bindingOrderCancelExchange(Queue orderPrintQueue, DirectExchange exchange) {
|
||||||
return BindingBuilder.bind(orderCancelQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_CANCEL_QUEUE);
|
return BindingBuilder.bind(orderPrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_CANCEL_QUEUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------ 订单库存更新
|
//------------------------------------------------------ 订单库存更新
|
||||||
@@ -108,7 +91,6 @@ public class RabbitConfig {
|
|||||||
public Queue orderStockQueue() {
|
public Queue orderStockQueue() {
|
||||||
return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_STOCK_QUEUE, true);
|
return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_STOCK_QUEUE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Binding bindingOrderStockExchange(Queue orderStockQueue, DirectExchange exchange) {
|
public Binding bindingOrderStockExchange(Queue orderStockQueue, DirectExchange exchange) {
|
||||||
return BindingBuilder.bind(orderStockQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_STOCK_QUEUE);
|
return BindingBuilder.bind(orderStockQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_STOCK_QUEUE);
|
||||||
@@ -120,7 +102,6 @@ public class RabbitConfig {
|
|||||||
public Queue productInfoChangeQueue() {
|
public Queue productInfoChangeQueue() {
|
||||||
return new Queue(activeProfile + "-" + RabbitConstants.Queue.PRODUCT_INFO_CHANGE_QUEUE, true);
|
return new Queue(activeProfile + "-" + RabbitConstants.Queue.PRODUCT_INFO_CHANGE_QUEUE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Binding bindingProductInfoChange(Queue productInfoChangeQueue, DirectExchange exchange) {
|
public Binding bindingProductInfoChange(Queue productInfoChangeQueue, DirectExchange exchange) {
|
||||||
return BindingBuilder.bind(productInfoChangeQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.PRODUCT_INFO_CHANGE_QUEUE);
|
return BindingBuilder.bind(productInfoChangeQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.PRODUCT_INFO_CHANGE_QUEUE);
|
||||||
@@ -131,7 +112,6 @@ public class RabbitConfig {
|
|||||||
public Queue orderRefundQueue() {
|
public Queue orderRefundQueue() {
|
||||||
return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_REFUND_QUEUE, true);
|
return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_REFUND_QUEUE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Binding bindingOrderRefundExchange(Queue orderRefundQueue, DirectExchange exchange) {
|
public Binding bindingOrderRefundExchange(Queue orderRefundQueue, DirectExchange exchange) {
|
||||||
return BindingBuilder.bind(orderRefundQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_REFUND_QUEUE);
|
return BindingBuilder.bind(orderRefundQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_REFUND_QUEUE);
|
||||||
@@ -139,7 +119,6 @@ public class RabbitConfig {
|
|||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------ 申请短信模板队列
|
//------------------------------------------------------ 申请短信模板队列
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 1,2,applySmsTemp 模版审核
|
* 1,2,applySmsTemp 模版审核
|
||||||
* 1,2,sendMarkSms 发送营销短信
|
* 1,2,sendMarkSms 发送营销短信
|
||||||
@@ -150,18 +129,16 @@ public class RabbitConfig {
|
|||||||
public Queue applySmsTemplateQueue() {
|
public Queue applySmsTemplateQueue() {
|
||||||
return new Queue(activeProfile + "-" + RabbitConstants.Queue.APPLY_SMS_TEMPLATE_QUEUE, true);
|
return new Queue(activeProfile + "-" + RabbitConstants.Queue.APPLY_SMS_TEMPLATE_QUEUE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Binding bindingApplySmsTemplateExchange(Queue applySmsTemplateQueue, DirectExchange exchange) {
|
public Binding bindingApplySmsTemplateExchange(Queue applySmsTemplateQueue, DirectExchange exchange) {
|
||||||
return BindingBuilder.bind(applySmsTemplateQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.APPLY_SMS_TEMPLATE_QUEUE);
|
return BindingBuilder.bind(applySmsTemplateQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.APPLY_SMS_TEMPLATE_QUEUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------ 生日礼品短信队列
|
//------------------------------------------------------ 生日礼品短信队列
|
||||||
@Bean
|
@Bean
|
||||||
public Queue birthdayGiftSmsQueue() {
|
public Queue birthdayGiftSmsQueue() {
|
||||||
return new Queue(activeProfile + "-" + RabbitConstants.Queue.BIRTHDAY_GIFT_SMS_QUEUE, true);
|
return new Queue(activeProfile + "-" + RabbitConstants.Queue.BIRTHDAY_GIFT_SMS_QUEUE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Binding bindingBirthdayGiftSmsExchange(Queue birthdayGiftSmsQueue, DirectExchange exchange) {
|
public Binding bindingBirthdayGiftSmsExchange(Queue birthdayGiftSmsQueue, DirectExchange exchange) {
|
||||||
return BindingBuilder.bind(birthdayGiftSmsQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.BIRTHDAY_GIFT_SMS_QUEUE);
|
return BindingBuilder.bind(birthdayGiftSmsQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.BIRTHDAY_GIFT_SMS_QUEUE);
|
||||||
@@ -172,7 +149,6 @@ public class RabbitConfig {
|
|||||||
public Queue orderProductStatusQueue() {
|
public Queue orderProductStatusQueue() {
|
||||||
return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_PRODUCT_STATUS_QUEUE, true);
|
return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_PRODUCT_STATUS_QUEUE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Binding bindingOrderProductStatusExchange(Queue orderProductStatusQueue, DirectExchange exchange) {
|
public Binding bindingOrderProductStatusExchange(Queue orderProductStatusQueue, DirectExchange exchange) {
|
||||||
return BindingBuilder.bind(orderProductStatusQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_PRODUCT_STATUS_QUEUE);
|
return BindingBuilder.bind(orderProductStatusQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_PRODUCT_STATUS_QUEUE);
|
||||||
@@ -184,7 +160,6 @@ public class RabbitConfig {
|
|||||||
public Queue orderDetailStatusQueue() {
|
public Queue orderDetailStatusQueue() {
|
||||||
return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_DETAIL_STATUS_QUEUE, true);
|
return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_DETAIL_STATUS_QUEUE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Binding bindingOrderDetailStatusExchange(Queue orderDetailStatusQueue, DirectExchange exchange) {
|
public Binding bindingOrderDetailStatusExchange(Queue orderDetailStatusQueue, DirectExchange exchange) {
|
||||||
return BindingBuilder.bind(orderDetailStatusQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_DETAIL_STATUS_QUEUE);
|
return BindingBuilder.bind(orderDetailStatusQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_DETAIL_STATUS_QUEUE);
|
||||||
|
|||||||
@@ -10,14 +10,13 @@ public interface RabbitConstants {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Queue {
|
class Queue {
|
||||||
public static final String SHOP_ENTRY_MANAGER = "shop.entry.manager";
|
|
||||||
public static final String ORDER_STOCK_QUEUE = "order.stock.queue";
|
public static final String ORDER_STOCK_QUEUE = "order.stock.queue";
|
||||||
public static final String ORDER_REFUND_QUEUE = "order.refund.queue";
|
public static final String ORDER_REFUND_QUEUE = "order.refund.queue";
|
||||||
public static final String ORDER_CANCEL_QUEUE = "order.cancel.queue";
|
public static final String ORDER_CANCEL_QUEUE = "order.cancel.queue";
|
||||||
public static final String ORDER_PRINT_QUEUE = "order.print.queue";
|
public static final String ORDER_PRINT_QUEUE = "order.print.queue";
|
||||||
public static final String ORDER_MACHINE_PRINT_QUEUE = "order.machine.print.queue";
|
public static final String ORDER_MACHINE_PRINT_QUEUE = "order.machine.print.queue";
|
||||||
public static final String ORDER_HANDOVER_PRINT_QUEUE = "order.handover.print.queue";
|
public static final String ORDER_HANDOVER_PRINT_QUEUE = "order.handover.print.queue";
|
||||||
public static final String CALL_TABLE_QUEUE = "call.table.print.queue";
|
public static final String CALL_TABLE_PRINT_QUEUE = "call.table.print.queue";
|
||||||
public static final String PRODUCT_INFO_CHANGE_QUEUE = "product.info.change.queue";
|
public static final String PRODUCT_INFO_CHANGE_QUEUE = "product.info.change.queue";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -130,13 +130,6 @@ public class RabbitPublisher {
|
|||||||
sendMsg(RabbitConstants.Queue.ORDER_PRODUCT_STATUS_QUEUE, qrContent);
|
sendMsg(RabbitConstants.Queue.ORDER_PRODUCT_STATUS_QUEUE, qrContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单商品状态消息
|
|
||||||
*/
|
|
||||||
public void sendEntryManagerMsg(String shopId) {
|
|
||||||
sendMsg(RabbitConstants.Queue.SHOP_ENTRY_MANAGER, shopId);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单商品状态消息
|
* 订单商品状态消息
|
||||||
|
|||||||
@@ -33,8 +33,6 @@ public interface RedisCst {
|
|||||||
public static final String EXPIRED_WECHAT = "expired:wechat:";
|
public static final String EXPIRED_WECHAT = "expired:wechat:";
|
||||||
}
|
}
|
||||||
|
|
||||||
//商家进件
|
|
||||||
String SHOP_ENTRY = "shop:entry";
|
|
||||||
|
|
||||||
String SMS_CODE = "sms:code:";
|
String SMS_CODE = "sms:code:";
|
||||||
// 店铺会员动态支付码
|
// 店铺会员动态支付码
|
||||||
|
|||||||
@@ -142,14 +142,6 @@ public class ShopInfo implements Serializable {
|
|||||||
* -1 平台禁用 0-过期,1正式营业,
|
* -1 平台禁用 0-过期,1正式营业,
|
||||||
*/
|
*/
|
||||||
private Integer status;
|
private Integer status;
|
||||||
/**
|
|
||||||
* 微信商户id
|
|
||||||
*/
|
|
||||||
private String wechatMerchantId;
|
|
||||||
/**
|
|
||||||
* 支付宝商户id
|
|
||||||
*/
|
|
||||||
private String alipayMerchantId;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 到期时间
|
* 到期时间
|
||||||
|
|||||||
@@ -37,11 +37,6 @@ public interface ShopInfoService extends IService<ShopInfo> {
|
|||||||
|
|
||||||
Boolean edit(ShopInfoEditDTO shopInfoEditDTO);
|
Boolean edit(ShopInfoEditDTO shopInfoEditDTO);
|
||||||
|
|
||||||
/**
|
|
||||||
* 进件结果保存
|
|
||||||
*/
|
|
||||||
Boolean editEntry(Long shopId, String wechatMerchantId, String alipayMerchantId);
|
|
||||||
|
|
||||||
ShopDetailDTO detail(Long id) throws CzgException;
|
ShopDetailDTO detail(Long id) throws CzgException;
|
||||||
|
|
||||||
ShopInfoByCodeDTO getByCode(String tableCode, String lat, String lng, boolean checkState);
|
ShopInfoByCodeDTO getByCode(String tableCode, String lat, String lng, boolean checkState);
|
||||||
|
|||||||
@@ -7,10 +7,12 @@ import com.czg.exception.CzgException;
|
|||||||
import com.czg.market.dto.MkDistributionUserDTO;
|
import com.czg.market.dto.MkDistributionUserDTO;
|
||||||
import com.czg.market.dto.MkDistributionWithdrawFlowDTO;
|
import com.czg.market.dto.MkDistributionWithdrawFlowDTO;
|
||||||
import com.czg.market.entity.MkDistributionConfig;
|
import com.czg.market.entity.MkDistributionConfig;
|
||||||
|
import com.czg.market.entity.MkDistributionFlow;
|
||||||
import com.czg.market.entity.MkDistributionUser;
|
import com.czg.market.entity.MkDistributionUser;
|
||||||
import com.czg.market.vo.DistributionCenterShopVO;
|
import com.czg.market.vo.DistributionCenterShopVO;
|
||||||
import com.czg.market.vo.InviteUserVO;
|
import com.czg.market.vo.InviteUserVO;
|
||||||
import com.czg.order.dto.MkDistributionPayDTO;
|
import com.czg.order.dto.MkDistributionPayDTO;
|
||||||
|
import com.czg.order.entity.OrderInfo;
|
||||||
import com.mybatisflex.core.paginate.Page;
|
import com.mybatisflex.core.paginate.Page;
|
||||||
import com.mybatisflex.core.service.IService;
|
import com.mybatisflex.core.service.IService;
|
||||||
|
|
||||||
@@ -123,6 +125,8 @@ public interface MkDistributionUserService extends IService<MkDistributionUser>
|
|||||||
|
|
||||||
void refund(Long orderId, String orderNo);
|
void refund(Long orderId, String orderNo);
|
||||||
|
|
||||||
|
void distributionUserAmount(MkDistributionFlow item, OrderInfo orderInfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发放分销奖励
|
* 发放分销奖励
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package com.czg.order.dto;
|
|||||||
import com.czg.utils.AssertUtil;
|
import com.czg.utils.AssertUtil;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
@@ -14,7 +13,6 @@ import java.math.BigDecimal;
|
|||||||
* @author ww
|
* @author ww
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
|
||||||
public class LtPayOtherDTO {
|
public class LtPayOtherDTO {
|
||||||
/**
|
/**
|
||||||
* 积分商品id/团购商品id
|
* 积分商品id/团购商品id
|
||||||
|
|||||||
@@ -1,118 +0,0 @@
|
|||||||
package com.czg.order.entity;
|
|
||||||
|
|
||||||
import com.mybatisflex.annotation.Column;
|
|
||||||
import com.mybatisflex.annotation.Id;
|
|
||||||
import com.mybatisflex.annotation.Table;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
import java.io.Serial;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商户进件 实体类。
|
|
||||||
*
|
|
||||||
* @author ww
|
|
||||||
* @since 2026-01-07
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
@Table("tb_shop_direct_merchant")
|
|
||||||
public class ShopDirectMerchant implements Serializable {
|
|
||||||
|
|
||||||
@Serial
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 店铺id
|
|
||||||
*/
|
|
||||||
@Id
|
|
||||||
private Long shopId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 营业执照编号
|
|
||||||
*/
|
|
||||||
private String licenceNo;
|
|
||||||
/**
|
|
||||||
* 支付宝账号
|
|
||||||
*/
|
|
||||||
private String alipayAccount;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商户编号(在当前系统唯一)
|
|
||||||
*/
|
|
||||||
private String merchantCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商户基础信息
|
|
||||||
*/
|
|
||||||
private String merchantBaseInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 法人信息
|
|
||||||
*/
|
|
||||||
private String legalPersonInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 营业执照信息
|
|
||||||
*/
|
|
||||||
private String businessLicenceInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 门店信息
|
|
||||||
*/
|
|
||||||
private String storeInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结算信息
|
|
||||||
*/
|
|
||||||
private String settlementInfo;
|
|
||||||
|
|
||||||
@Column(onInsertValue = "now()")
|
|
||||||
private LocalDateTime createTime;
|
|
||||||
|
|
||||||
@Column(onInsertValue = "now()", onUpdateValue = "now()")
|
|
||||||
private LocalDateTime updateTime;
|
|
||||||
|
|
||||||
|
|
||||||
private String errorMsg;
|
|
||||||
|
|
||||||
private String wechatApplyId;
|
|
||||||
/**
|
|
||||||
* 微信状态
|
|
||||||
*/
|
|
||||||
private String wechatStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信进件错误信息
|
|
||||||
*/
|
|
||||||
private String wechatErrorMsg;
|
|
||||||
/**
|
|
||||||
* 微信进件签名地址
|
|
||||||
*/
|
|
||||||
private String wechatSignUrl;
|
|
||||||
|
|
||||||
private String alipayOrderId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付宝状态
|
|
||||||
*/
|
|
||||||
private String alipayStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付宝进件错误信息
|
|
||||||
*/
|
|
||||||
private String alipayErrorMsg;
|
|
||||||
/**
|
|
||||||
* 支付宝进件签名地址
|
|
||||||
*/
|
|
||||||
private String alipaySignUrl;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
package com.czg.system.entity;
|
|
||||||
|
|
||||||
import com.mybatisflex.annotation.Column;
|
|
||||||
import com.mybatisflex.annotation.Id;
|
|
||||||
import com.mybatisflex.annotation.KeyType;
|
|
||||||
import com.mybatisflex.annotation.Table;
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
import java.io.Serial;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 银行账户信息表 实体类。
|
|
||||||
*
|
|
||||||
* @author ww
|
|
||||||
* @since 2026-01-06
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
@Table("sys_bank_info")
|
|
||||||
public class SysBankInfo implements Serializable {
|
|
||||||
|
|
||||||
@Serial
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 主键ID
|
|
||||||
*/
|
|
||||||
@Id(keyType = KeyType.Auto)
|
|
||||||
private BigInteger id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 银行名称
|
|
||||||
*/
|
|
||||||
private String accountBank;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 银行数字编码
|
|
||||||
*/
|
|
||||||
private Integer accountBankCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 银行别名
|
|
||||||
*/
|
|
||||||
private String bankAlias;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 银行别名编码
|
|
||||||
*/
|
|
||||||
private String bankAliasCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 不知道干啥的
|
|
||||||
*/
|
|
||||||
private Boolean needBankBranch;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 银行英文编码
|
|
||||||
*/
|
|
||||||
private String bankCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
@Column(onInsertValue = "now()")
|
|
||||||
private LocalDateTime createTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新时间
|
|
||||||
*/
|
|
||||||
@Column(onInsertValue = "now()", onUpdateValue = "now()")
|
|
||||||
private LocalDateTime updateTime;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
package com.czg.system.entity;
|
|
||||||
|
|
||||||
import com.mybatisflex.annotation.Column;
|
|
||||||
import com.mybatisflex.annotation.Id;
|
|
||||||
import com.mybatisflex.annotation.KeyType;
|
|
||||||
import com.mybatisflex.annotation.Table;
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
import java.io.Serial;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 类目信息表 实体类。
|
|
||||||
*
|
|
||||||
* @author ww
|
|
||||||
* @since 2026-01-06
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
@Table("sys_category_info")
|
|
||||||
public class SysCategoryInfo implements Serializable {
|
|
||||||
|
|
||||||
@Serial
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 主键ID
|
|
||||||
*/
|
|
||||||
@Id(keyType = KeyType.Auto)
|
|
||||||
private BigInteger id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 一级类目code
|
|
||||||
*/
|
|
||||||
private String firstCategoryCode;
|
|
||||||
/**
|
|
||||||
* 一级类目
|
|
||||||
*/
|
|
||||||
private String firstCategory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 二级类目code
|
|
||||||
*/
|
|
||||||
private String secondCategoryCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 二级类目
|
|
||||||
*/
|
|
||||||
private String secondCategory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 适用商家说明
|
|
||||||
*/
|
|
||||||
private String applicableMerchant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 特殊资质(为空则无需提供)
|
|
||||||
*/
|
|
||||||
private String specialQualification;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
@Column(onInsertValue = "now()")
|
|
||||||
private LocalDateTime createTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新时间
|
|
||||||
*/
|
|
||||||
@Column(onInsertValue = "now()", onUpdateValue = "now()")
|
|
||||||
private LocalDateTime updateTime;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
package com.czg.system.entity;
|
|
||||||
|
|
||||||
import com.mybatisflex.annotation.Column;
|
|
||||||
import com.mybatisflex.annotation.Id;
|
|
||||||
import com.mybatisflex.annotation.Table;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
import java.io.Serial;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 行政区表 实体类。
|
|
||||||
*
|
|
||||||
* @author ww
|
|
||||||
* @since 2026-01-06
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
@Table("sys_region")
|
|
||||||
public class SysRegion implements Serializable {
|
|
||||||
|
|
||||||
@Serial
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 区域编码
|
|
||||||
*/
|
|
||||||
@Id
|
|
||||||
private String regionId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 上级区域编码
|
|
||||||
*/
|
|
||||||
private String parentRegionId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 区域级别:1=国家,2=省,3=市,4=县
|
|
||||||
*/
|
|
||||||
@Id
|
|
||||||
private Integer regionLevel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 区域中文全称
|
|
||||||
*/
|
|
||||||
private String regionName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 区域拼音
|
|
||||||
*/
|
|
||||||
private String regionPinyin;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 全级别名称(如“中国|北京|北京市|东城区)
|
|
||||||
*/
|
|
||||||
private String fullName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 子级区域
|
|
||||||
*/
|
|
||||||
@Column(ignore = true)
|
|
||||||
private List<SysRegion> children;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
package com.czg.system.service;
|
|
||||||
|
|
||||||
import com.czg.BaseQueryParam;
|
|
||||||
import com.mybatisflex.core.paginate.Page;
|
|
||||||
import com.mybatisflex.core.service.IService;
|
|
||||||
import com.czg.system.entity.SysBankInfo;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 银行账户信息表 服务层。
|
|
||||||
*
|
|
||||||
* @author ww
|
|
||||||
* @since 2026-01-06
|
|
||||||
*/
|
|
||||||
public interface SysBankInfoService extends IService<SysBankInfo> {
|
|
||||||
|
|
||||||
Page<SysBankInfo> bankInfoList(BaseQueryParam param, String bankName);
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package com.czg.system.service;
|
|
||||||
|
|
||||||
import com.czg.system.vo.SysCategoryInfoVO;
|
|
||||||
import com.mybatisflex.core.service.IService;
|
|
||||||
import com.czg.system.entity.SysCategoryInfo;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 类目信息表 服务层。
|
|
||||||
*
|
|
||||||
* @author ww
|
|
||||||
* @since 2026-01-06
|
|
||||||
*/
|
|
||||||
public interface SysCategoryInfoService extends IService<SysCategoryInfo> {
|
|
||||||
|
|
||||||
|
|
||||||
List<SysCategoryInfoVO> categoryList();
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package com.czg.system.service;
|
|
||||||
|
|
||||||
import com.mybatisflex.core.service.IService;
|
|
||||||
import com.czg.system.entity.SysRegion;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 行政区表 服务层。
|
|
||||||
*
|
|
||||||
* @author ww
|
|
||||||
* @since 2026-01-06
|
|
||||||
*/
|
|
||||||
public interface SysRegionService extends IService<SysRegion> {
|
|
||||||
|
|
||||||
List<SysRegion> regionList();
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
package com.czg.system.vo;
|
|
||||||
|
|
||||||
import com.czg.system.entity.SysCategoryInfo;
|
|
||||||
import com.mybatisflex.annotation.Column;
|
|
||||||
import com.mybatisflex.annotation.Id;
|
|
||||||
import com.mybatisflex.annotation.KeyType;
|
|
||||||
import com.mybatisflex.annotation.Table;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
import java.io.Serial;
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 类目信息表 实体类。
|
|
||||||
*
|
|
||||||
* @author ww
|
|
||||||
* @since 2026-01-06
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class SysCategoryInfoVO implements Serializable {
|
|
||||||
|
|
||||||
@Serial
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 一级类目
|
|
||||||
*/
|
|
||||||
private String firstCategory;
|
|
||||||
|
|
||||||
private List<SysCategoryInfo> child;
|
|
||||||
}
|
|
||||||
@@ -42,8 +42,6 @@
|
|||||||
<pinyin.version>2.5.1</pinyin.version>
|
<pinyin.version>2.5.1</pinyin.version>
|
||||||
<IJPay.version>2.9.10</IJPay.version>
|
<IJPay.version>2.9.10</IJPay.version>
|
||||||
<netty.version>4.1.128.Final</netty.version>
|
<netty.version>4.1.128.Final</netty.version>
|
||||||
<wechatpay.version>0.2.17</wechatpay.version>
|
|
||||||
<apipay-v3.version>3.1.65.ALL</apipay-v3.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
@@ -270,18 +268,6 @@
|
|||||||
<artifactId>netty-codec-mqtt</artifactId>
|
<artifactId>netty-codec-mqtt</artifactId>
|
||||||
<version>${netty.version}</version>
|
<version>${netty.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.github.wechatpay-apiv3</groupId>
|
|
||||||
<artifactId>wechatpay-java</artifactId>
|
|
||||||
<version>${wechatpay.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.alipay.sdk</groupId>
|
|
||||||
<artifactId>alipay-sdk-java-v3</artifactId>
|
|
||||||
<version>${apipay-v3.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
|
|||||||
@@ -1,461 +0,0 @@
|
|||||||
package com.czg;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import com.czg.dto.req.*;
|
|
||||||
import com.czg.dto.resp.BankBranchDto;
|
|
||||||
import com.czg.dto.resp.EntryRespDto;
|
|
||||||
import com.czg.dto.resp.EntryThirdRespDto;
|
|
||||||
import com.czg.dto.resp.QueryStatusResp;
|
|
||||||
import com.czg.exception.CzgException;
|
|
||||||
import com.czg.third.alipay.AlipayEntryManager;
|
|
||||||
import com.czg.third.alipay.AlipayIsvEntryManager;
|
|
||||||
import com.czg.third.wechat.WechatEntryManager;
|
|
||||||
import com.czg.utils.AssertUtil;
|
|
||||||
import com.czg.utils.AsyncTaskExecutor;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进件管理
|
|
||||||
*
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2026/1/6 13:56
|
|
||||||
*/
|
|
||||||
public class EntryManager {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询银行支行列表
|
|
||||||
*
|
|
||||||
* @param province 省份 陕西省
|
|
||||||
* @param city 城市 西安市
|
|
||||||
* @param instId 顶级机构ID CMB
|
|
||||||
*/
|
|
||||||
public static List<BankBranchDto> queryBankBranchList(String province, String city, String instId) {
|
|
||||||
return AlipayEntryManager.queryBankBranchList(null, instId, province, city);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询微信进件状态
|
|
||||||
*
|
|
||||||
* @param merchantCode 商户编号, 进件时返回的批次号 {@link EntryRespDto#wechatApplyId}
|
|
||||||
* @return 进件状态
|
|
||||||
*/
|
|
||||||
public static QueryStatusResp queryWechatEntryStatus(String merchantCode) {
|
|
||||||
return WechatEntryManager.queryMerchantEntryStatus(null, merchantCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询支付宝进件状态
|
|
||||||
*
|
|
||||||
* @param batchNo 商户编号, 进件时返回的批次号 {@link EntryRespDto#alipayOrderId}
|
|
||||||
* @return 进件状态
|
|
||||||
*/
|
|
||||||
public static QueryStatusResp queryAlipayEntryStatus(String batchNo) {
|
|
||||||
return AlipayIsvEntryManager.queryMerchantBatchStatus(null, batchNo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进件
|
|
||||||
* 请先执行:
|
|
||||||
* 1. {@link com.czg.EntryManager#verifyEntryParam(AggregateMerchantDto)} 验证进件参数
|
|
||||||
* 2. {@link com.czg.EntryManager#uploadParamImage(AggregateMerchantDto)} 上传图片至第三方
|
|
||||||
*
|
|
||||||
* @param reqDto 进件参数
|
|
||||||
* @param platform 平台 {@link com.czg.PayCst.Platform}
|
|
||||||
*/
|
|
||||||
public static EntryRespDto entryMerchant(AggregateMerchantDto reqDto, String... platform) {
|
|
||||||
List<Supplier<EntryThirdRespDto>> tasks = new ArrayList<>();
|
|
||||||
|
|
||||||
if (platform == null || platform.length == 0) {
|
|
||||||
platform = new String[]{PayCst.Platform.WECHAT, PayCst.Platform.ALIPAY};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ArrayUtil.contains(platform, PayCst.Platform.WECHAT)) {
|
|
||||||
tasks.add(() -> WechatEntryManager.entryMerchant(null, reqDto));
|
|
||||||
}
|
|
||||||
if (ArrayUtil.contains(platform, PayCst.Platform.ALIPAY)) {
|
|
||||||
tasks.add(() -> AlipayIsvEntryManager.entryMerchant(null, reqDto));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 执行所有任务
|
|
||||||
List<AsyncTaskExecutor.TaskResult<EntryThirdRespDto>> results = AsyncTaskExecutor.executeAll(tasks);
|
|
||||||
|
|
||||||
return getEntryRespDto(results);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static EntryRespDto getEntryRespDto(List<AsyncTaskExecutor.TaskResult<EntryThirdRespDto>> results) {
|
|
||||||
EntryRespDto entryRespDto = new EntryRespDto();
|
|
||||||
for (AsyncTaskExecutor.TaskResult<EntryThirdRespDto> result : results) {
|
|
||||||
// 合并两个进件结果
|
|
||||||
EntryThirdRespDto respDto = result.result();
|
|
||||||
if (PayCst.Platform.WECHAT.equals(respDto.getPlatform())) {
|
|
||||||
entryRespDto.setWechatApplyId(respDto.getEntryId());
|
|
||||||
entryRespDto.setWechatStatus(respDto.getStatus());
|
|
||||||
entryRespDto.setWechatErrorMsg(respDto.getErrorMsg());
|
|
||||||
} else if (PayCst.Platform.ALIPAY.equals(respDto.getPlatform())) {
|
|
||||||
entryRespDto.setAlipayOrderId(respDto.getEntryId());
|
|
||||||
entryRespDto.setAlipayStatus(respDto.getStatus());
|
|
||||||
entryRespDto.setAlipayErrorMsg(respDto.getErrorMsg());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return entryRespDto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 上传图片至第三方
|
|
||||||
* 请先执行 {@link com.czg.EntryManager#verifyEntryParam(AggregateMerchantDto)} 验证进件参数
|
|
||||||
*
|
|
||||||
* @param reqDto 进件参数
|
|
||||||
*/
|
|
||||||
public static void uploadParamImage(AggregateMerchantDto reqDto) {
|
|
||||||
List<Supplier<Void>> tasks = new ArrayList<>();
|
|
||||||
|
|
||||||
MerchantBaseInfoDto baseInfo = reqDto.getMerchantBaseInfo();
|
|
||||||
// 联系人身份证反面
|
|
||||||
tasks.add(() -> {
|
|
||||||
uploadImageToThird(baseInfo.getContactIdCardBackPic());
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
// 联系人身份证正面
|
|
||||||
tasks.add(() -> {
|
|
||||||
uploadImageToThird(baseInfo.getContactIdCardFrontPic());
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
LegalPersonInfoDto legalPersonInfo = reqDto.getLegalPersonInfo();
|
|
||||||
// 法人身份证反面
|
|
||||||
tasks.add(() -> {
|
|
||||||
uploadImageToThird(legalPersonInfo.getIdCardBackPic());
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
// 法人身份证正面
|
|
||||||
tasks.add(() -> {
|
|
||||||
uploadImageToThird(legalPersonInfo.getIdCardFrontPic());
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
// 法人手持身份证
|
|
||||||
tasks.add(() -> {
|
|
||||||
uploadImageToThird(legalPersonInfo.getIdCardHandPic());
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
BusinessLicenceInfoDto businessLicenceInfo = reqDto.getBusinessLicenceInfo();
|
|
||||||
// 营业执照
|
|
||||||
tasks.add(() -> {
|
|
||||||
uploadImageToThird(businessLicenceInfo.getLicensePic());
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
SettlementInfoDto settlementInfo = reqDto.getSettlementInfo();
|
|
||||||
// 银行卡背面
|
|
||||||
tasks.add(() -> {
|
|
||||||
uploadImageToThird(settlementInfo.getBankCardBackPic());
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
// 银行卡正面
|
|
||||||
tasks.add(() -> {
|
|
||||||
uploadImageToThird(settlementInfo.getBankCardFrontPic());
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
// 开户许可证
|
|
||||||
tasks.add(() -> {
|
|
||||||
uploadImageToThird(settlementInfo.getOpenAccountLicencePic());
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
// 非法人手持授权函
|
|
||||||
tasks.add(() -> {
|
|
||||||
uploadImageToThird(settlementInfo.getNoLegalHandSettleAuthPic());
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
// 非法人授权函
|
|
||||||
tasks.add(() -> {
|
|
||||||
uploadImageToThird(settlementInfo.getNoLegalSettleAuthPic());
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
// 非法人身份证反面
|
|
||||||
tasks.add(() -> {
|
|
||||||
uploadImageToThird(settlementInfo.getNoLegalIdCardBackPic());
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
// 非法人身份证正面
|
|
||||||
tasks.add(() -> {
|
|
||||||
uploadImageToThird(settlementInfo.getNoLegalIdCardFrontPic());
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
StoreInfoDto storeInfo = reqDto.getStoreInfo();
|
|
||||||
// 店内图片
|
|
||||||
tasks.add(() -> {
|
|
||||||
uploadImageToThird(storeInfo.getInsidePic());
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
// 门店门头图片
|
|
||||||
tasks.add(() -> {
|
|
||||||
uploadImageToThird(storeInfo.getDoorPic());
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
// 收银台图片
|
|
||||||
tasks.add(() -> {
|
|
||||||
uploadImageToThird(storeInfo.getCashierDeskPic());
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 执行所有任务
|
|
||||||
AsyncTaskExecutor.executeAll(tasks);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void uploadImageToThird(ImageDto dto) {
|
|
||||||
if (dto != null && StrUtil.isNotBlank(dto.getUrl())) {
|
|
||||||
if (StrUtil.isBlank(dto.getWechatId())) {
|
|
||||||
String image = WechatEntryManager.uploadImage(null, dto.getUrl());
|
|
||||||
dto.setWechatId(image);
|
|
||||||
}
|
|
||||||
if (StrUtil.isBlank(dto.getAlipayId())) {
|
|
||||||
String image = AlipayEntryManager.uploadImage(null, dto.getUrl());
|
|
||||||
dto.setAlipayId(image);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证进件参数
|
|
||||||
*
|
|
||||||
* @param reqDto 进件参数
|
|
||||||
*/
|
|
||||||
public static void verifyEntryParam(AggregateMerchantDto reqDto) {
|
|
||||||
AssertUtil.isBlank(reqDto.getMerchantCode(), "商户编号不能为空");
|
|
||||||
|
|
||||||
AssertUtil.isNull(reqDto.getMerchantBaseInfo(), "商户基础信息不能为空");
|
|
||||||
|
|
||||||
MerchantBaseInfoDto baseInfo = reqDto.getMerchantBaseInfo();
|
|
||||||
AssertUtil.isBlank(baseInfo.getUserType(), "商户类型不能为空");
|
|
||||||
AssertUtil.isBlank(baseInfo.getShortName(), "商户简称不能为空");
|
|
||||||
AssertUtil.isBlank(baseInfo.getMccCode(), "商户行业编码不能为空");
|
|
||||||
AssertUtil.isBlank(baseInfo.getAlipayAccount(), "支付宝账号不能为空");
|
|
||||||
AssertUtil.isBlank(baseInfo.getContactPersonType(), "联系人类型不能为空");
|
|
||||||
if (!PayCst.ContactPersonType.SUPER.equals(baseInfo.getContactPersonType()) && !PayCst.ContactPersonType.LEGAL.equals(baseInfo.getContactPersonType())) {
|
|
||||||
throw new CzgException("联系人类型错误");
|
|
||||||
}
|
|
||||||
if (PayCst.ContactPersonType.SUPER.equals(baseInfo.getContactPersonType())) {
|
|
||||||
AssertUtil.isBlank(baseInfo.getCertType(), "证件类型不能为空");
|
|
||||||
if (!"0".equals(baseInfo.getCertType())) {
|
|
||||||
throw new CzgException("证件类型错误");
|
|
||||||
}
|
|
||||||
AssertUtil.isBlank(baseInfo.getContactName(), "联系人姓名不能为空");
|
|
||||||
AssertUtil.isBlank(baseInfo.getContactPersonId(), "联系人身份证号不能为空");
|
|
||||||
AssertUtil.isBlank(baseInfo.getContactPhone(), "联系人电话不能为空");
|
|
||||||
AssertUtil.isBlank(baseInfo.getContactAddr(), "联系人地址不能为空");
|
|
||||||
AssertUtil.isBlank(baseInfo.getContactEmail(), "联系人邮箱不能为空");
|
|
||||||
AssertUtil.isBlank(baseInfo.getContactPersonIdStartDate(), "联系人身份证开始日期不能为空");
|
|
||||||
AssertUtil.isBlank(baseInfo.getContactPersonIdEndDate(), "联系人身份证到期日期不能为空");
|
|
||||||
AssertUtil.isNull(baseInfo.getContactIdCardBackPic(), "联系人身份证反面不能为空");
|
|
||||||
AssertUtil.isBlank(baseInfo.getContactIdCardBackPic().getUrl(), "联系人身份证反面不能为空");
|
|
||||||
AssertUtil.isNull(baseInfo.getContactIdCardFrontPic(), "联系人身份证正面不能为空");
|
|
||||||
AssertUtil.isBlank(baseInfo.getContactIdCardFrontPic().getUrl(), "联系人身份证正面不能为空");
|
|
||||||
}
|
|
||||||
AssertUtil.isBlank(baseInfo.getCompanyChildType(), "商户类型不能为空");
|
|
||||||
if ("0".equals(baseInfo.getUserType())) {
|
|
||||||
// 个体商户, 暂无其他校验
|
|
||||||
} else if ("1".equals(baseInfo.getUserType())) {
|
|
||||||
if (!"1".equals(baseInfo.getCompanyChildType()) && !"2".equals(baseInfo.getCompanyChildType()) && !"3".equals(baseInfo.getCompanyChildType())) {
|
|
||||||
throw new CzgException("商户类型错误");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new CzgException("商户类型错误");
|
|
||||||
}
|
|
||||||
|
|
||||||
AssertUtil.isNull(reqDto.getBusinessLicenceInfo(), "营业执照信息不能为空");
|
|
||||||
BusinessLicenceInfoDto businessLicenceInfo = reqDto.getBusinessLicenceInfo();
|
|
||||||
AssertUtil.isBlank(businessLicenceInfo.getLicenceNo(), "营业执照编号不能为空");
|
|
||||||
AssertUtil.isBlank(businessLicenceInfo.getLicenceName(), "营业执照名称不能为空");
|
|
||||||
AssertUtil.isBlank(businessLicenceInfo.getRegisteredAddress(), "营业执照注册地址不能为空");
|
|
||||||
AssertUtil.isBlank(businessLicenceInfo.getLicenceStartDate(), "营业执照开始日期不能为空");
|
|
||||||
AssertUtil.isBlank(businessLicenceInfo.getLicenceEndDate(), "营业执照到期日期不能为空");
|
|
||||||
AssertUtil.isNull(businessLicenceInfo.getLicensePic(), "营业执照名称不能为空");
|
|
||||||
AssertUtil.isBlank(businessLicenceInfo.getLicensePic().getUrl(), "营业执照名称不能为空");
|
|
||||||
|
|
||||||
|
|
||||||
AssertUtil.isNull(reqDto.getLegalPersonInfo(), "法人信息不能为空");
|
|
||||||
LegalPersonInfoDto legalPersonInfo = reqDto.getLegalPersonInfo();
|
|
||||||
AssertUtil.isBlank(legalPersonInfo.getLegalPersonName(), "法人姓名不能为空");
|
|
||||||
AssertUtil.isBlank(legalPersonInfo.getLegalPersonId(), "法人身份证号不能为空");
|
|
||||||
AssertUtil.isBlank(legalPersonInfo.getLegalIdPersonStartDate(), "法人身份证开始日期不能为空");
|
|
||||||
AssertUtil.isBlank(legalPersonInfo.getLegalPersonIdEndDate(), "法人身份证到期日期不能为空");
|
|
||||||
AssertUtil.isBlank(legalPersonInfo.getLegalPersonPhone(), "法人电话不能为空");
|
|
||||||
AssertUtil.isBlank(legalPersonInfo.getLegalPersonEmail(), "法人邮箱不能为空");
|
|
||||||
AssertUtil.isBlank(legalPersonInfo.getLegalGender(), "法人性别不能为空");
|
|
||||||
AssertUtil.isBlank(legalPersonInfo.getLegalAddress(), "法人地址不能为空");
|
|
||||||
AssertUtil.isNull(legalPersonInfo.getIdCardHandPic(), "法人身份证手持不能为空");
|
|
||||||
AssertUtil.isBlank(legalPersonInfo.getIdCardHandPic().getUrl(), "法人身份证手持不能为空");
|
|
||||||
AssertUtil.isNull(legalPersonInfo.getIdCardFrontPic(), "法人身份证正面不能为空");
|
|
||||||
AssertUtil.isBlank(legalPersonInfo.getIdCardFrontPic().getUrl(), "法人身份证正面不能为空");
|
|
||||||
AssertUtil.isNull(legalPersonInfo.getIdCardBackPic(), "法人身份证反面不能为空");
|
|
||||||
AssertUtil.isBlank(legalPersonInfo.getIdCardBackPic().getUrl(), "法人身份证反面不能为空");
|
|
||||||
|
|
||||||
AssertUtil.isNull(reqDto.getStoreInfo(), "门店信息不能为空");
|
|
||||||
StoreInfoDto storeInfo = reqDto.getStoreInfo();
|
|
||||||
AssertUtil.isBlank(storeInfo.getMercProvCode(), "门店省ID不能为空");
|
|
||||||
AssertUtil.isBlank(storeInfo.getMercCityCode(), "门店市ID不能为空");
|
|
||||||
AssertUtil.isBlank(storeInfo.getMercAreaCode(), "门店区ID不能为空");
|
|
||||||
AssertUtil.isBlank(storeInfo.getMercProv(), "门店省不能为空");
|
|
||||||
AssertUtil.isBlank(storeInfo.getMercCity(), "门店市不能为空");
|
|
||||||
AssertUtil.isBlank(storeInfo.getMercArea(), "门店区不能为空");
|
|
||||||
AssertUtil.isBlank(storeInfo.getBusinessAddress(), "门店营业地址不能为空");
|
|
||||||
AssertUtil.isNull(storeInfo.getInsidePic(), "门店营业地址不能为空");
|
|
||||||
AssertUtil.isBlank(storeInfo.getInsidePic().getUrl(), "门店营业地址不能为空");
|
|
||||||
AssertUtil.isNull(storeInfo.getDoorPic(), "门店门头照不能为空");
|
|
||||||
AssertUtil.isBlank(storeInfo.getDoorPic().getUrl(), "门店门头照不能为空");
|
|
||||||
AssertUtil.isNull(storeInfo.getCashierDeskPic(), "门店收银台照不能为空");
|
|
||||||
AssertUtil.isBlank(storeInfo.getCashierDeskPic().getUrl(), "门店收银台照不能为空");
|
|
||||||
|
|
||||||
|
|
||||||
AssertUtil.isNull(reqDto.getSettlementInfo(), "结算信息不能为空");
|
|
||||||
SettlementInfoDto settlementInfo = reqDto.getSettlementInfo();
|
|
||||||
AssertUtil.isBlank(settlementInfo.getSettlementCardNo(), "结算卡号不能为空");
|
|
||||||
AssertUtil.isBlank(settlementInfo.getSettlementName(), "结算账户户名不能为空");
|
|
||||||
AssertUtil.isBlank(settlementInfo.getBankName(), "结算银行名称不能为空");
|
|
||||||
AssertUtil.isBlank(settlementInfo.getBankInstId(), "结算银行缩写不能为空");
|
|
||||||
AssertUtil.isBlank(settlementInfo.getBankMobile(), "结算银行预留手机号不能为空");
|
|
||||||
AssertUtil.isBlank(settlementInfo.getSettlementCardType(), "结算卡类型不能为空");
|
|
||||||
AssertUtil.isBlank(settlementInfo.getOpenAccProvinceId(), "结算开户行省ID不能为空");
|
|
||||||
AssertUtil.isBlank(settlementInfo.getOpenAccCityId(), "结算开户行市ID不能为空");
|
|
||||||
AssertUtil.isBlank(settlementInfo.getOpenAccAreaId(), "结算开户行区ID不能为空");
|
|
||||||
AssertUtil.isBlank(settlementInfo.getOpenAccProvince(), "结算开户行省不能为空");
|
|
||||||
AssertUtil.isBlank(settlementInfo.getOpenAccCity(), "结算开户行市不能为空");
|
|
||||||
AssertUtil.isBlank(settlementInfo.getOpenAccArea(), "结算开户行区不能为空");
|
|
||||||
if ("11".equals(settlementInfo.getSettlementCardType())) {
|
|
||||||
// 11 对私借记卡(结算卡正面照、结算卡反面照图片必传)
|
|
||||||
AssertUtil.isNull(settlementInfo.getBankCardFrontPic(), "结算卡正面照不能为空");
|
|
||||||
AssertUtil.isBlank(settlementInfo.getBankCardFrontPic().getUrl(), "结算卡正面照不能为空");
|
|
||||||
AssertUtil.isNull(settlementInfo.getBankCardBackPic(), "结算卡反面照不能为空");
|
|
||||||
AssertUtil.isBlank(settlementInfo.getBankCardBackPic().getUrl(), "结算卡反面照不能为空");
|
|
||||||
AssertUtil.isBlank(settlementInfo.getSettlementType(), "结算类型不能为空");
|
|
||||||
if ("0".equals(settlementInfo.getSettlementType())) {
|
|
||||||
// 非法人结算
|
|
||||||
AssertUtil.isBlank(settlementInfo.getNoLegalName(), "非法人姓名不能为空");
|
|
||||||
AssertUtil.isBlank(settlementInfo.getNoLegalId(), "非法人身份证号不能为空");
|
|
||||||
AssertUtil.isNull(settlementInfo.getNoLegalIdCardFrontPic(), "非法人身份证正面不能为空");
|
|
||||||
AssertUtil.isBlank(settlementInfo.getNoLegalIdCardFrontPic().getUrl(), "非法人身份证正面不能为空");
|
|
||||||
AssertUtil.isNull(settlementInfo.getNoLegalIdCardBackPic(), "非法人身份证反面不能为空");
|
|
||||||
AssertUtil.isBlank(settlementInfo.getNoLegalIdCardBackPic().getUrl(), "非法人身份证反面不能为空");
|
|
||||||
AssertUtil.isNull(settlementInfo.getNoLegalSettleAuthPic(), "非法人结算授权书不能为空");
|
|
||||||
AssertUtil.isBlank(settlementInfo.getNoLegalSettleAuthPic().getUrl(), "非法人结算授权书不能为空");
|
|
||||||
} else if ("1".equals(settlementInfo.getSettlementType())) {
|
|
||||||
// 法人结算 暂无处理
|
|
||||||
} else {
|
|
||||||
throw new CzgException("结算类型错误");
|
|
||||||
}
|
|
||||||
} else if ("21".equals(settlementInfo.getSettlementCardType())) {
|
|
||||||
// 21 对公借记卡(只须结算卡正面照片)
|
|
||||||
AssertUtil.isNull(settlementInfo.getOpenAccountLicencePic(), "开户许可证不能为空");
|
|
||||||
AssertUtil.isBlank(settlementInfo.getOpenAccountLicencePic().getUrl(), "开户许可证不能为空");
|
|
||||||
} else {
|
|
||||||
throw new CzgException("结算卡类型错误");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
|
|
||||||
|
|
||||||
AggregateMerchantDto merchantDto = getTestMerchantEntryData();
|
|
||||||
|
|
||||||
// verifyEntryParam(merchantDto);
|
|
||||||
// uploadParamImage(merchantDto);
|
|
||||||
|
|
||||||
verifyEntryParam(merchantDto);
|
|
||||||
// uploadParamImage(merchantDto);
|
|
||||||
// System.out.println(merchantDto);
|
|
||||||
// entryMerchant(merchantDto, PayCst.Platform.WECHAT);
|
|
||||||
entryMerchant(merchantDto, PayCst.Platform.ALIPAY);
|
|
||||||
// entryMerchant(merchantDto, PayCst.Platform.WECHAT, PayCst.Platform.ALIPAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static AggregateMerchantDto getTestMerchantEntryData() {
|
|
||||||
AggregateMerchantDto merchantDto = new AggregateMerchantDto();
|
|
||||||
merchantDto.setMerchantCode("20220106000000000001");
|
|
||||||
|
|
||||||
MerchantBaseInfoDto baseInfoDto = new MerchantBaseInfoDto();
|
|
||||||
baseInfoDto.setUserType("1");
|
|
||||||
baseInfoDto.setCompanyChildType("1");
|
|
||||||
baseInfoDto.setShortName("测试商户");
|
|
||||||
baseInfoDto.setAlipayAccount("1157756119@qq.com");
|
|
||||||
baseInfoDto.setMccCode("A0001_B0001");
|
|
||||||
baseInfoDto.setContactPersonType(PayCst.ContactPersonType.SUPER);
|
|
||||||
baseInfoDto.setContactName("张三");
|
|
||||||
baseInfoDto.setContactPersonId("110101199001011234");
|
|
||||||
baseInfoDto.setContactPersonIdStartDate("2021-01-01");
|
|
||||||
baseInfoDto.setContactPersonIdEndDate("2025-01-01");
|
|
||||||
baseInfoDto.setContactPhone("13800000000");
|
|
||||||
baseInfoDto.setContactEmail("1157756119@qq.com");
|
|
||||||
baseInfoDto.setContactAddr("广东省深圳市南山区");
|
|
||||||
baseInfoDto.setContactIdCardFrontPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg"));
|
|
||||||
baseInfoDto.setContactIdCardBackPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg"));
|
|
||||||
merchantDto.setMerchantBaseInfo(baseInfoDto);
|
|
||||||
|
|
||||||
BusinessLicenceInfoDto businessLicenceInfoDto = new BusinessLicenceInfoDto();
|
|
||||||
businessLicenceInfoDto.setLicenceName("测试商户");
|
|
||||||
businessLicenceInfoDto.setLicenceNo("110101199001011234");
|
|
||||||
businessLicenceInfoDto.setLicenceStartDate("2021-01-01");
|
|
||||||
businessLicenceInfoDto.setLicenceEndDate("2052-01-01");
|
|
||||||
businessLicenceInfoDto.setRegisteredAddress("广东省深圳市南山区");
|
|
||||||
businessLicenceInfoDto.setLicensePic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg"));
|
|
||||||
merchantDto.setBusinessLicenceInfo(businessLicenceInfoDto);
|
|
||||||
|
|
||||||
LegalPersonInfoDto legalPersonInfoDto = new LegalPersonInfoDto();
|
|
||||||
legalPersonInfoDto.setLegalPersonName("张三");
|
|
||||||
legalPersonInfoDto.setLegalPersonId("110101199001011234");
|
|
||||||
legalPersonInfoDto.setLegalIdPersonStartDate("2021-01-01");
|
|
||||||
legalPersonInfoDto.setLegalPersonIdEndDate("2055-01-01");
|
|
||||||
legalPersonInfoDto.setLegalPersonPhone("13800000000");
|
|
||||||
legalPersonInfoDto.setLegalPersonEmail("1157756119@qq.com");
|
|
||||||
legalPersonInfoDto.setLegalGender("1");
|
|
||||||
legalPersonInfoDto.setLegalAddress("广东省深圳市南山区");
|
|
||||||
legalPersonInfoDto.setIdCardHandPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg"));
|
|
||||||
legalPersonInfoDto.setIdCardFrontPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg"));
|
|
||||||
legalPersonInfoDto.setIdCardBackPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg"));
|
|
||||||
merchantDto.setLegalPersonInfo(legalPersonInfoDto);
|
|
||||||
|
|
||||||
StoreInfoDto storeInfoDto = new StoreInfoDto();
|
|
||||||
storeInfoDto.setMercProvCode("440000");
|
|
||||||
storeInfoDto.setMercCityCode("440300");
|
|
||||||
storeInfoDto.setMercAreaCode("440303");
|
|
||||||
storeInfoDto.setMercProv("广东省");
|
|
||||||
storeInfoDto.setMercCity("深圳市");
|
|
||||||
storeInfoDto.setMercArea("南山区");
|
|
||||||
storeInfoDto.setBusinessAddress("广东省深圳市南山区");
|
|
||||||
storeInfoDto.setInsidePic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg"));
|
|
||||||
storeInfoDto.setDoorPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg"));
|
|
||||||
storeInfoDto.setCashierDeskPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg"));
|
|
||||||
merchantDto.setStoreInfo(storeInfoDto);
|
|
||||||
|
|
||||||
SettlementInfoDto settlementInfoDto = new SettlementInfoDto();
|
|
||||||
settlementInfoDto.setSettlementType("1");
|
|
||||||
settlementInfoDto.setSettlementCardType("21");
|
|
||||||
settlementInfoDto.setSettlementName("张三");
|
|
||||||
settlementInfoDto.setSettlementCardNo("110101199001011234");
|
|
||||||
settlementInfoDto.setBankMobile("13800000000");
|
|
||||||
settlementInfoDto.setOpenAccProvinceId("440000");
|
|
||||||
settlementInfoDto.setOpenAccCityId("440300");
|
|
||||||
settlementInfoDto.setOpenAccAreaId("440303");
|
|
||||||
settlementInfoDto.setOpenAccProvince("广东省");
|
|
||||||
settlementInfoDto.setOpenAccCity("深圳市");
|
|
||||||
settlementInfoDto.setOpenAccArea("南山区");
|
|
||||||
settlementInfoDto.setBankName("中国工商银行");
|
|
||||||
settlementInfoDto.setBankInstId("ICBC");
|
|
||||||
settlementInfoDto.setBankType("1");
|
|
||||||
settlementInfoDto.setBankBranchName("广东省深圳市南山区");
|
|
||||||
settlementInfoDto.setBankBranchCode("440300");
|
|
||||||
settlementInfoDto.setBankCardFrontPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg"));
|
|
||||||
settlementInfoDto.setBankCardBackPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg"));
|
|
||||||
settlementInfoDto.setOpenAccountLicencePic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg"));
|
|
||||||
merchantDto.setSettlementInfo(settlementInfoDto);
|
|
||||||
|
|
||||||
return merchantDto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
package com.czg;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
|
||||||
import com.aliyun.ocr_api20210707.models.RecognizeAllTextResponse;
|
|
||||||
import com.aliyun.tea.*;
|
|
||||||
import com.czg.exception.CzgException;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author ww
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class OcrUtils {
|
|
||||||
/**
|
|
||||||
* 阿里 ocr识别图片
|
|
||||||
* 本接口支持:PNG、JPG、JPEG、BMP、GIF、TIFF、WebP、PDF。
|
|
||||||
* 图片长宽需要大于 15 像素,小于 8192 像素。
|
|
||||||
* 长宽比需要小于 50。长宽均大于 500px。
|
|
||||||
* 图片二进制文件不能超过 10MB。
|
|
||||||
* 图片过大会影响接口响应速度,建议使用小于 1.5M 图片进行识别,
|
|
||||||
*
|
|
||||||
* @param url 图片地址
|
|
||||||
* @param type IdCard 身份证
|
|
||||||
* BankCard 银行卡
|
|
||||||
* BusinessLicense 营业执照
|
|
||||||
* 目前使用的角色为 czg-oss@1413456038175003.onaliyun.com
|
|
||||||
* 需要 AliyunOCRFullAccess 权限
|
|
||||||
* AliyunBSSContractFullAccess 权限
|
|
||||||
* 文档地址 <a href="https://help.aliyun.com/zh/ocr/developer-reference/api-ocr-api-2021-07-07-recognizealltext?spm=a2c4g.11186623.0.0.543669f32I79Gw#api-detail-35">
|
|
||||||
*/
|
|
||||||
public static JSONObject getInfoByImg(String accessKeyId, String accessKeySecret,
|
|
||||||
String url, String type) throws Exception {
|
|
||||||
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
|
|
||||||
// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
|
|
||||||
.setAccessKeyId(accessKeyId)
|
|
||||||
// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
|
|
||||||
.setAccessKeySecret(accessKeySecret);
|
|
||||||
config.endpoint = "ocr-api.cn-hangzhou.aliyuncs.com";
|
|
||||||
|
|
||||||
com.aliyun.ocr_api20210707.Client client = new com.aliyun.ocr_api20210707.Client(config);
|
|
||||||
com.aliyun.ocr_api20210707.models.RecognizeAllTextRequest recognizeAllTextRequest = new com.aliyun.ocr_api20210707.models.RecognizeAllTextRequest()
|
|
||||||
.setUrl(url).setType(type);
|
|
||||||
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
|
|
||||||
try {
|
|
||||||
RecognizeAllTextResponse resp = client.recognizeAllTextWithOptions(recognizeAllTextRequest, runtime);
|
|
||||||
return JSONObject.from(resp.body.data);
|
|
||||||
} catch (TeaException error) {
|
|
||||||
// // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
|
||||||
// // 错误 message
|
|
||||||
// System.out.println(error.getMessage());
|
|
||||||
// // 诊断地址
|
|
||||||
// System.out.println(error.getData().get("Recommend"));
|
|
||||||
// com.aliyun.teautil.Common.assertAsString(error.message);
|
|
||||||
log.error("识别失败, msg: {}", error.getMessage());
|
|
||||||
throw new CzgException(error.getMessage());
|
|
||||||
} catch (Exception error) {
|
|
||||||
// TeaException error = new TeaException(_error.getMessage(), _error);
|
|
||||||
// // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
|
||||||
// // 错误 message
|
|
||||||
// System.out.println(error.getMessage());
|
|
||||||
// // 诊断地址
|
|
||||||
// System.out.println(error.getData().get("Recommend"));
|
|
||||||
// com.aliyun.teautil.Common.assertAsString(error.message);
|
|
||||||
log.error("识别失败, msg: {}", error.getMessage());
|
|
||||||
throw new CzgException(error.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
package com.czg;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付相关常量
|
|
||||||
*
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2026/1/7 09:20
|
|
||||||
*/
|
|
||||||
public interface PayCst {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 长期有效时间
|
|
||||||
*/
|
|
||||||
String LONG_TERM_DATE = "2099-12-31";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 平台
|
|
||||||
*/
|
|
||||||
class Platform {
|
|
||||||
/**
|
|
||||||
* 微信
|
|
||||||
*/
|
|
||||||
public static final String WECHAT = "wechat";
|
|
||||||
/**
|
|
||||||
* 支付宝
|
|
||||||
*/
|
|
||||||
public static final String ALIPAY = "alipay";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进件状态
|
|
||||||
*/
|
|
||||||
class EntryStatus {
|
|
||||||
/**
|
|
||||||
* 待提交
|
|
||||||
*/
|
|
||||||
public static final String WAIT = "WAIT";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 待处理
|
|
||||||
*/
|
|
||||||
public static final String INIT = "INIT";
|
|
||||||
/**
|
|
||||||
* 审核中
|
|
||||||
*/
|
|
||||||
public static final String AUDIT = "AUDIT";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 待签约
|
|
||||||
*/
|
|
||||||
public static final String SIGN = "SIGN";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 已完成
|
|
||||||
*/
|
|
||||||
public static final String FINISH = "FINISH";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 失败
|
|
||||||
*/
|
|
||||||
public static final String REJECTED = "REJECTED";
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 需要查询的状态列表
|
|
||||||
* 待处理、待签约、待审核的进件
|
|
||||||
*/
|
|
||||||
public static final List<String> NEED_QUERY_LIST = List.of(INIT, AUDIT, SIGN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 联系人类型
|
|
||||||
*/
|
|
||||||
class ContactPersonType {
|
|
||||||
/**
|
|
||||||
* 法人
|
|
||||||
*/
|
|
||||||
public static final String LEGAL = "LEGAL";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 经办人
|
|
||||||
*/
|
|
||||||
public static final String SUPER = "SUPER";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
package com.czg.dto.req;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 统一进件
|
|
||||||
*
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2026/1/6 10:02
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class AggregateMerchantDto {
|
|
||||||
/**
|
|
||||||
* 商户Id
|
|
||||||
*/
|
|
||||||
private Long shopId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 自己生成 CZGyyyy-MM-dd HH:mm:ss.SSS
|
|
||||||
* 商户编号(在当前系统唯一)
|
|
||||||
*/
|
|
||||||
private String merchantCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 商户基础信息
|
|
||||||
*/
|
|
||||||
private MerchantBaseInfoDto merchantBaseInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 法人信息
|
|
||||||
*/
|
|
||||||
private LegalPersonInfoDto legalPersonInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 营业执照信息
|
|
||||||
*/
|
|
||||||
private BusinessLicenceInfoDto businessLicenceInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 门店信息
|
|
||||||
*/
|
|
||||||
private StoreInfoDto storeInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 结算信息
|
|
||||||
*/
|
|
||||||
private SettlementInfoDto settlementInfo;
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
package com.czg.dto.req;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 营业执照信息
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2026/1/6 10:17
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class BusinessLicenceInfoDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 营业执照全称--非小微必填
|
|
||||||
*/
|
|
||||||
private String licenceName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 营业执照号码--非小微必填
|
|
||||||
*/
|
|
||||||
private String licenceNo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 营业执照开始日期--非小微必填
|
|
||||||
*/
|
|
||||||
private String licenceStartDate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 营业执照结束日期--非小微必填
|
|
||||||
*/
|
|
||||||
private String licenceEndDate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 营业执照注册地址--非小微必填
|
|
||||||
*/
|
|
||||||
private String registeredAddress;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 营业执照
|
|
||||||
*/
|
|
||||||
private ImageDto licensePic;
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package com.czg.dto.req;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2026/1/6 16:53
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class ImageDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 图片 url
|
|
||||||
*/
|
|
||||||
private String url;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信 图片 mediaId
|
|
||||||
*/
|
|
||||||
private String wechatId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付宝 图片 mediaId
|
|
||||||
*/
|
|
||||||
private String alipayId;
|
|
||||||
|
|
||||||
public ImageDto() {}
|
|
||||||
|
|
||||||
public ImageDto(String url) {
|
|
||||||
this.url = url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
package com.czg.dto.req;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 法人信息
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2026/1/6 10:13
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class LegalPersonInfoDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 法人姓名
|
|
||||||
*/
|
|
||||||
private String legalPersonName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 法人身份证号
|
|
||||||
*/
|
|
||||||
private String legalPersonId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 法人身份证开始日期
|
|
||||||
*/
|
|
||||||
private String legalIdPersonStartDate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 法人身份证到期日期
|
|
||||||
*/
|
|
||||||
private String legalPersonIdEndDate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 法人电话
|
|
||||||
*/
|
|
||||||
private String legalPersonPhone;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 法人邮箱
|
|
||||||
*/
|
|
||||||
private String legalPersonEmail;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 法人性别(0男 1女)
|
|
||||||
*/
|
|
||||||
private String legalGender;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 法人地址
|
|
||||||
*/
|
|
||||||
private String legalAddress;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 身份证手持 图片
|
|
||||||
*/
|
|
||||||
private ImageDto idCardHandPic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 身份证正面
|
|
||||||
*/
|
|
||||||
private ImageDto idCardFrontPic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 身份证反面
|
|
||||||
*/
|
|
||||||
private ImageDto idCardBackPic;
|
|
||||||
}
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
package com.czg.dto.req;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商户基础信息
|
|
||||||
*
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2026/1/6 10:09
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class MerchantBaseInfoDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 商户类型
|
|
||||||
* 0: 个体商户;
|
|
||||||
* 1: 企业商户;
|
|
||||||
* 3: 小微商户 暂不支持
|
|
||||||
*/
|
|
||||||
private String userType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 商户简称--企业、个体必填
|
|
||||||
*/
|
|
||||||
private String shortName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 行业编码
|
|
||||||
* 一级类目code_二级类目code
|
|
||||||
* 【示例值】A0001_B0199
|
|
||||||
*/
|
|
||||||
private String mccCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 支付宝账号
|
|
||||||
*/
|
|
||||||
private String alipayAccount;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 联系人类型
|
|
||||||
* LEGAL: 经营者/法定代表人
|
|
||||||
* SUPER: 经办人
|
|
||||||
*/
|
|
||||||
private String contactPersonType = "LEGAL";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 联系人姓名
|
|
||||||
*/
|
|
||||||
private String contactName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 证件类型
|
|
||||||
* 目前只支持身份证 传值:0
|
|
||||||
*/
|
|
||||||
private String certType = "0";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 联系人身份证号
|
|
||||||
*/
|
|
||||||
private String contactPersonId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 联系人身份证开始日期
|
|
||||||
*/
|
|
||||||
private String contactPersonIdStartDate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 联系人身份证到期日期
|
|
||||||
*/
|
|
||||||
private String contactPersonIdEndDate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 联系人身份证背面
|
|
||||||
*/
|
|
||||||
private ImageDto contactIdCardBackPic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 联系人身份证正面
|
|
||||||
*/
|
|
||||||
private ImageDto contactIdCardFrontPic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 联系人电话
|
|
||||||
*/
|
|
||||||
private String contactPhone;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 联系人通讯地址
|
|
||||||
*/
|
|
||||||
private String contactAddr;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 联系人邮箱
|
|
||||||
*/
|
|
||||||
private String contactEmail;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 企业类型,1:普通企业,2:事业单位,3:政府机关,4:社会组织
|
|
||||||
*/
|
|
||||||
private String companyChildType = "1";
|
|
||||||
}
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
package com.czg.dto.req;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结算信息
|
|
||||||
*
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2026/1/6 10:22
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class SettlementInfoDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结算类型 0:非法人结算, 1:法人结算
|
|
||||||
*/
|
|
||||||
private String settlementType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 非法人姓名
|
|
||||||
*/
|
|
||||||
private String noLegalName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 非法人身份证号码
|
|
||||||
*/
|
|
||||||
private String noLegalId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结算卡类型 必填 11 对私借记卡(结算卡正面照、结算卡反面照图片必传) 21 对公借记卡(只须结算卡正面照片)
|
|
||||||
*/
|
|
||||||
private String settlementCardType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结算账户卡号
|
|
||||||
*/
|
|
||||||
private String settlementCardNo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结算账户户名
|
|
||||||
*/
|
|
||||||
private String settlementName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结算银行预留手机号
|
|
||||||
*/
|
|
||||||
private String bankMobile;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开户行省ID
|
|
||||||
*/
|
|
||||||
private String openAccProvinceId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开户行市ID
|
|
||||||
*/
|
|
||||||
private String openAccCityId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开户行区ID
|
|
||||||
*/
|
|
||||||
private String openAccAreaId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开户行省
|
|
||||||
*/
|
|
||||||
private String openAccProvince;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开户行市
|
|
||||||
*/
|
|
||||||
private String openAccCity;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开户行区
|
|
||||||
*/
|
|
||||||
private String openAccArea;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开户行行别名称
|
|
||||||
*/
|
|
||||||
private String bankName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开户行缩写
|
|
||||||
*/
|
|
||||||
private String bankInstId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开户行编号
|
|
||||||
*/
|
|
||||||
private String bankType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支行开户行行别名称
|
|
||||||
*/
|
|
||||||
private String bankBranchName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支行开户行编号
|
|
||||||
*/
|
|
||||||
private String bankBranchCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 银行卡正面
|
|
||||||
*/
|
|
||||||
private ImageDto bankCardFrontPic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 银行卡反面
|
|
||||||
*/
|
|
||||||
private ImageDto bankCardBackPic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开户许可证
|
|
||||||
*/
|
|
||||||
private ImageDto openAccountLicencePic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 非法人手持结算授权书
|
|
||||||
*/
|
|
||||||
private ImageDto noLegalHandSettleAuthPic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 非法人结算授权书
|
|
||||||
*/
|
|
||||||
private ImageDto noLegalSettleAuthPic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 非法人身份证正面
|
|
||||||
*/
|
|
||||||
private ImageDto noLegalIdCardFrontPic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 非法人身份证反面
|
|
||||||
*/
|
|
||||||
private ImageDto noLegalIdCardBackPic;
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
package com.czg.dto.req;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 门店信息
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2026/1/6 10:19
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class StoreInfoDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 商户归属省Code
|
|
||||||
*/
|
|
||||||
private String mercProvCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 商户归属市Code
|
|
||||||
*/
|
|
||||||
private String mercCityCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 商户归属区Code
|
|
||||||
*/
|
|
||||||
private String mercAreaCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商户归属省
|
|
||||||
*/
|
|
||||||
private String mercProv;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商户归属市
|
|
||||||
*/
|
|
||||||
private String mercCity;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商户归属区
|
|
||||||
*/
|
|
||||||
private String mercArea;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 营业地址
|
|
||||||
*/
|
|
||||||
private String businessAddress;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 经营场所内设照片
|
|
||||||
*/
|
|
||||||
private ImageDto insidePic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 门头照
|
|
||||||
*/
|
|
||||||
private ImageDto doorPic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 收银台照片
|
|
||||||
*/
|
|
||||||
private ImageDto cashierDeskPic;
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
package com.czg.dto.resp;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 银行支行信息
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2026/1/6 15:37
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class BankBranchDto {
|
|
||||||
/**
|
|
||||||
* 机构ID
|
|
||||||
*/
|
|
||||||
private String instId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 银行代码
|
|
||||||
*/
|
|
||||||
private String bankCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 城市
|
|
||||||
*/
|
|
||||||
private String city;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 银行简称
|
|
||||||
*/
|
|
||||||
private String simpleName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 省份
|
|
||||||
*/
|
|
||||||
@JSONField(name = "provice")
|
|
||||||
private String province;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IBPS代码
|
|
||||||
*/
|
|
||||||
private String ibpsCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 承担机构
|
|
||||||
*/
|
|
||||||
private String undertakeInst;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 分支机构名称
|
|
||||||
*/
|
|
||||||
private String branchName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 机构全称
|
|
||||||
*/
|
|
||||||
private String instName;
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package com.czg.dto.resp;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进件相应结果
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2026/1/6 18:15
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class EntryRespDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信申请 Id
|
|
||||||
*/
|
|
||||||
private String wechatApplyId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信状态
|
|
||||||
* {@link com.czg.PayCst.EntryStatus}
|
|
||||||
*/
|
|
||||||
private String wechatStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信进件错误信息
|
|
||||||
*/
|
|
||||||
private String wechatErrorMsg;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付宝订单 Id
|
|
||||||
*/
|
|
||||||
private String alipayOrderId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付宝状态
|
|
||||||
* {@link com.czg.PayCst.EntryStatus}
|
|
||||||
*/
|
|
||||||
private String alipayStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付宝进件错误信息
|
|
||||||
*/
|
|
||||||
private String alipayErrorMsg;
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package com.czg.dto.resp;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2026/1/7 09:07
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class EntryThirdRespDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 录入id
|
|
||||||
*/
|
|
||||||
private String entryId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 平台
|
|
||||||
*/
|
|
||||||
private String platform;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 状态
|
|
||||||
* {@link com.czg.PayCst.EntryStatus}
|
|
||||||
*/
|
|
||||||
private String status;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 错误信息
|
|
||||||
*/
|
|
||||||
private String errorMsg;
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
package com.czg.dto.resp;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询进件状态
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2026/1/7 17:12
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class QueryStatusResp {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 平台
|
|
||||||
* {@link com.czg.PayCst.Platform}
|
|
||||||
*/
|
|
||||||
private String platform;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商户编号
|
|
||||||
*/
|
|
||||||
private String merchantCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进件编号
|
|
||||||
*/
|
|
||||||
private String applyId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 三方商户id
|
|
||||||
*/
|
|
||||||
private String thirdMerchantId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进件状态
|
|
||||||
* {@link com.czg.PayCst.EntryStatus}
|
|
||||||
*/
|
|
||||||
private String status;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 签约地址
|
|
||||||
*/
|
|
||||||
private String signUrl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 失败原因
|
|
||||||
*/
|
|
||||||
private String failReason;
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
package com.czg.third.alipay;
|
|
||||||
|
|
||||||
import com.alipay.api.AlipayApiException;
|
|
||||||
import com.alipay.api.AlipayConfig;
|
|
||||||
import com.alipay.api.DefaultAlipayClient;
|
|
||||||
import com.alipay.v3.ApiClient;
|
|
||||||
import com.alipay.v3.Configuration;
|
|
||||||
import com.czg.third.alipay.dto.config.AlipayConfigDto;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2026/1/4 13:48
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class AlipayClient {
|
|
||||||
|
|
||||||
public static DefaultAlipayClient getDefaultClient(AlipayConfigDto configDto) {
|
|
||||||
try {
|
|
||||||
return new DefaultAlipayClient(getAlipayConfig(configDto));
|
|
||||||
} catch (AlipayApiException e) {
|
|
||||||
log.error("创建支付宝客户端失败", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setApiClient(AlipayConfigDto configDto) {
|
|
||||||
if (configDto == null) {
|
|
||||||
configDto = AlipayConfigDto.getDefaultConfig();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
ApiClient defaultClient = Configuration.getDefaultApiClient();
|
|
||||||
// 初始化alipay参数(全局设置一次)
|
|
||||||
com.alipay.v3.util.model.AlipayConfig alipayConfig = new com.alipay.v3.util.model.AlipayConfig();
|
|
||||||
alipayConfig.setServerUrl(configDto.getDomain());
|
|
||||||
alipayConfig.setAppId(configDto.getAppId());
|
|
||||||
alipayConfig.setAlipayPublicKey(configDto.getAlipayPublicKey());
|
|
||||||
alipayConfig.setPrivateKey(configDto.getPrivateKey());
|
|
||||||
defaultClient.setAlipayConfig(alipayConfig);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("创建支付宝客户端失败", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AlipayConfig getAlipayConfig(AlipayConfigDto configDto) {
|
|
||||||
if (configDto == null) {
|
|
||||||
configDto = AlipayConfigDto.getDefaultConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
AlipayConfig alipayConfig = new AlipayConfig();
|
|
||||||
alipayConfig.setServerUrl(configDto.getDomain());
|
|
||||||
alipayConfig.setAppId(configDto.getAppId());
|
|
||||||
alipayConfig.setPrivateKey(configDto.getPrivateKey());
|
|
||||||
alipayConfig.setFormat("json");
|
|
||||||
alipayConfig.setAlipayPublicKey(configDto.getAlipayPublicKey());
|
|
||||||
alipayConfig.setCharset("UTF-8");
|
|
||||||
alipayConfig.setSignType("RSA2");
|
|
||||||
|
|
||||||
return alipayConfig;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,385 +0,0 @@
|
|||||||
package com.czg.third.alipay;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import com.alibaba.fastjson2.JSONArray;
|
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
|
||||||
import com.alipay.api.AlipayApiException;
|
|
||||||
import com.alipay.api.DefaultAlipayClient;
|
|
||||||
import com.alipay.api.FileItem;
|
|
||||||
import com.alipay.api.domain.*;
|
|
||||||
import com.alipay.api.request.AlipayFinancialnetAuthPbcnameQueryRequest;
|
|
||||||
import com.alipay.api.request.AntMerchantExpandIndirectImageUploadRequest;
|
|
||||||
import com.alipay.api.request.AntMerchantExpandIndirectZftCreateRequest;
|
|
||||||
import com.alipay.api.request.AntMerchantExpandIndirectZftorderQueryRequest;
|
|
||||||
import com.alipay.api.response.AlipayFinancialnetAuthPbcnameQueryResponse;
|
|
||||||
import com.alipay.api.response.AntMerchantExpandIndirectImageUploadResponse;
|
|
||||||
import com.alipay.api.response.AntMerchantExpandIndirectZftCreateResponse;
|
|
||||||
import com.alipay.api.response.AntMerchantExpandIndirectZftorderQueryResponse;
|
|
||||||
import com.alipay.v3.ApiClient;
|
|
||||||
import com.alipay.v3.ApiException;
|
|
||||||
import com.alipay.v3.Configuration;
|
|
||||||
import com.alipay.v3.api.AlipayOpenAgentApi;
|
|
||||||
import com.alipay.v3.model.AlipayOpenAgentCreateDefaultResponse;
|
|
||||||
import com.alipay.v3.model.AlipayOpenAgentCreateModel;
|
|
||||||
import com.alipay.v3.model.AlipayOpenAgentCreateResponseModel;
|
|
||||||
import com.alipay.v3.model.ContactModel;
|
|
||||||
import com.alipay.v3.util.model.AlipayConfig;
|
|
||||||
import com.czg.PayCst;
|
|
||||||
import com.czg.dto.req.*;
|
|
||||||
import com.czg.dto.resp.BankBranchDto;
|
|
||||||
import com.czg.dto.resp.EntryThirdRespDto;
|
|
||||||
import com.czg.dto.resp.QueryStatusResp;
|
|
||||||
import com.czg.exception.CzgException;
|
|
||||||
import com.czg.third.alipay.dto.config.AlipayConfigDto;
|
|
||||||
import com.czg.third.wechat.dto.resp.WechatQueryStateResp;
|
|
||||||
import com.czg.utils.UploadFileUtil;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付宝进件管理
|
|
||||||
* <a href="https://opendocs.alipay.com/solution/9434dd99_ant.merchant.expand.indirect.zft.simplecreate?scene=bf5951260023430e944c2e9afdf7f9e2&pathHash=d3136936">...</a>
|
|
||||||
*
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/29 14:11
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class AlipayEntryManager {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询商户进件状态
|
|
||||||
*
|
|
||||||
* @param configDto 配置信息
|
|
||||||
* @param merchantCode 自系统的商户编号
|
|
||||||
* @return 进件状态
|
|
||||||
*/
|
|
||||||
public static QueryStatusResp queryMerchantEntryStatus(AlipayConfigDto configDto, String merchantCode) {
|
|
||||||
QueryStatusResp queryStatusResp = new QueryStatusResp();
|
|
||||||
queryStatusResp.setPlatform(PayCst.Platform.ALIPAY);
|
|
||||||
queryStatusResp.setMerchantCode(merchantCode);
|
|
||||||
|
|
||||||
AntMerchantExpandIndirectZftorderQueryRequest request = new AntMerchantExpandIndirectZftorderQueryRequest();
|
|
||||||
|
|
||||||
AntMerchantExpandIndirectZftorderQueryModel model = new AntMerchantExpandIndirectZftorderQueryModel();
|
|
||||||
model.setExternalId(merchantCode);
|
|
||||||
|
|
||||||
request.setBizModel(model);
|
|
||||||
|
|
||||||
try {
|
|
||||||
DefaultAlipayClient defaultAlipayClient = AlipayClient.getDefaultClient(configDto);
|
|
||||||
AntMerchantExpandIndirectZftorderQueryResponse response = defaultAlipayClient.execute(request);
|
|
||||||
log.info("支付宝查询进件状态结果:{}", response.getBody());
|
|
||||||
|
|
||||||
if (response.isSuccess()) {
|
|
||||||
List<ZftSubMerchantOrder> orders = response.getOrders();
|
|
||||||
if (orders != null && !orders.isEmpty()) {
|
|
||||||
ZftSubMerchantOrder first = orders.getFirst();
|
|
||||||
queryStatusResp.setApplyId(first.getExternalId());
|
|
||||||
|
|
||||||
if ("99".equals(first.getStatus())) {
|
|
||||||
// 已完成
|
|
||||||
queryStatusResp.setStatus(PayCst.EntryStatus.FINISH);
|
|
||||||
queryStatusResp.setThirdMerchantId(first.getSmid());
|
|
||||||
queryStatusResp.setFailReason("");
|
|
||||||
return queryStatusResp;
|
|
||||||
}
|
|
||||||
if ("-1".equals(first.getStatus())) {
|
|
||||||
// 拒绝
|
|
||||||
queryStatusResp.setStatus(PayCst.EntryStatus.REJECTED);
|
|
||||||
queryStatusResp.setFailReason(first.getReason());
|
|
||||||
return queryStatusResp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StrUtil.isNotBlank(first.getFkAudit())) {
|
|
||||||
if ("REJECT".equals(first.getFkAudit())) {
|
|
||||||
// 风控拒绝
|
|
||||||
queryStatusResp.setStatus(PayCst.EntryStatus.REJECTED);
|
|
||||||
queryStatusResp.setFailReason(first.getFkAuditMemo());
|
|
||||||
return queryStatusResp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ("CREATE".equals(first.getFkAudit())) {
|
|
||||||
queryStatusResp.setStatus(PayCst.EntryStatus.AUDIT);
|
|
||||||
queryStatusResp.setFailReason(first.getFkAuditMemo());
|
|
||||||
return queryStatusResp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StrUtil.isNotBlank(first.getKzAudit())) {
|
|
||||||
if ("REJECT".equals(first.getKzAudit())) {
|
|
||||||
// 风控拒绝
|
|
||||||
queryStatusResp.setStatus(PayCst.EntryStatus.REJECTED);
|
|
||||||
queryStatusResp.setFailReason(first.getKzAuditMemo());
|
|
||||||
return queryStatusResp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ("CREATE".equals(first.getKzAudit())) {
|
|
||||||
queryStatusResp.setStatus(PayCst.EntryStatus.AUDIT);
|
|
||||||
queryStatusResp.setFailReason(first.getKzAuditMemo());
|
|
||||||
return queryStatusResp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StrUtil.isNotBlank(first.getSubConfirm()) && "FAIL".equals(first.getSubConfirm())) {
|
|
||||||
// 签约失败
|
|
||||||
queryStatusResp.setStatus(PayCst.EntryStatus.REJECTED);
|
|
||||||
queryStatusResp.setFailReason("签约失败");
|
|
||||||
return queryStatusResp;
|
|
||||||
}
|
|
||||||
|
|
||||||
queryStatusResp.setStatus(PayCst.EntryStatus.SIGN);
|
|
||||||
queryStatusResp.setSignUrl(first.getSubSignQrCodeUrl());
|
|
||||||
return queryStatusResp;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
queryStatusResp.setStatus(PayCst.EntryStatus.REJECTED);
|
|
||||||
queryStatusResp.setFailReason(response.getSubMsg());
|
|
||||||
}
|
|
||||||
} catch (AlipayApiException e) {
|
|
||||||
log.error("支付宝查询进件状态报错:{}", e.getMessage(), e);
|
|
||||||
queryStatusResp.setStatus(PayCst.EntryStatus.INIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return queryStatusResp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进件商户
|
|
||||||
*
|
|
||||||
* @param configDto 配置信息
|
|
||||||
* @param reqDto 请求信息
|
|
||||||
*/
|
|
||||||
public static EntryThirdRespDto entryMerchant(AlipayConfigDto configDto, AggregateMerchantDto reqDto) {
|
|
||||||
AntMerchantExpandIndirectZftCreateModel entryReqDto = buildEntryParams(reqDto);
|
|
||||||
EntryThirdRespDto respDto = new EntryThirdRespDto()
|
|
||||||
.setPlatform(PayCst.Platform.ALIPAY);
|
|
||||||
|
|
||||||
try {
|
|
||||||
AntMerchantExpandIndirectZftCreateRequest request = new AntMerchantExpandIndirectZftCreateRequest();
|
|
||||||
DefaultAlipayClient defaultAlipayClient = AlipayClient.getDefaultClient(configDto);
|
|
||||||
request.setBizModel(entryReqDto);
|
|
||||||
AntMerchantExpandIndirectZftCreateResponse response = defaultAlipayClient.execute(request);
|
|
||||||
log.info("支付宝进件结果:{}", response.getBody());
|
|
||||||
if (response.isSuccess()) {
|
|
||||||
respDto.setStatus(PayCst.EntryStatus.INIT);
|
|
||||||
respDto.setEntryId(response.getOrderId());
|
|
||||||
respDto.setErrorMsg("");
|
|
||||||
} else {
|
|
||||||
respDto.setStatus(PayCst.EntryStatus.REJECTED);
|
|
||||||
respDto.setEntryId("");
|
|
||||||
respDto.setErrorMsg(response.getSubMsg());
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("支付宝进件报错:{}", e.getMessage(), e);
|
|
||||||
respDto.setStatus(PayCst.EntryStatus.REJECTED);
|
|
||||||
respDto.setEntryId("");
|
|
||||||
respDto.setErrorMsg(e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return respDto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 上传图片
|
|
||||||
*
|
|
||||||
* @param configDto 配置信息
|
|
||||||
* @param url 图片地址
|
|
||||||
* @return 图片ID
|
|
||||||
*/
|
|
||||||
public static String uploadImage(AlipayConfigDto configDto, String url) {
|
|
||||||
try {
|
|
||||||
byte[] bytes = UploadFileUtil.downloadImage(url);
|
|
||||||
|
|
||||||
Path tempFile = Files.createTempFile("image_", ".png");
|
|
||||||
|
|
||||||
// 写入数据
|
|
||||||
Files.write(tempFile, bytes);
|
|
||||||
|
|
||||||
File file = tempFile.toFile();
|
|
||||||
|
|
||||||
AntMerchantExpandIndirectImageUploadRequest request = new AntMerchantExpandIndirectImageUploadRequest();
|
|
||||||
request.setImageType(UploadFileUtil.extractImageExtension(url));
|
|
||||||
|
|
||||||
// 设置图片内容
|
|
||||||
FileItem imageContent = new FileItem(file);
|
|
||||||
request.setImageContent(imageContent);
|
|
||||||
|
|
||||||
DefaultAlipayClient defaultAlipayClient = AlipayClient.getDefaultClient(configDto);
|
|
||||||
AntMerchantExpandIndirectImageUploadResponse response = defaultAlipayClient.execute(request);
|
|
||||||
|
|
||||||
return response.getImageId();
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("支付宝上传图片报错,URL:{},错误信息:{}", "url", e.getMessage(), e);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询支行
|
|
||||||
*
|
|
||||||
* @param instId 顶级机构ID CMB
|
|
||||||
* @param province 省份 陕西省
|
|
||||||
* @param city 城市 西安市
|
|
||||||
*/
|
|
||||||
public static List<BankBranchDto> queryBankBranchList(AlipayConfigDto configDto, String instId, String province, String city) {
|
|
||||||
try {
|
|
||||||
AlipayFinancialnetAuthPbcnameQueryRequest request = new AlipayFinancialnetAuthPbcnameQueryRequest();
|
|
||||||
|
|
||||||
AlipayFinancialnetAuthPbcnameQueryModel model = new AlipayFinancialnetAuthPbcnameQueryModel();
|
|
||||||
model.setInstId(instId);
|
|
||||||
model.setProvice(province);
|
|
||||||
model.setCity(city);
|
|
||||||
|
|
||||||
request.setBizModel(model);
|
|
||||||
DefaultAlipayClient defaultAlipayClient = AlipayClient.getDefaultClient(configDto);
|
|
||||||
AlipayFinancialnetAuthPbcnameQueryResponse response = defaultAlipayClient.execute(request);
|
|
||||||
|
|
||||||
String data = response.getPbcQueryResult();
|
|
||||||
return JSONArray.parseArray(data, BankBranchDto.class);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("支付宝查询支行报错,错误信息:{}", e.getMessage(), e);
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建进件参数
|
|
||||||
*
|
|
||||||
* @param reqDto 请求参数
|
|
||||||
* @return 进件参数
|
|
||||||
*/
|
|
||||||
private static AntMerchantExpandIndirectZftCreateModel buildEntryParams(AggregateMerchantDto reqDto) {
|
|
||||||
AntMerchantExpandIndirectZftCreateModel entryParams = new AntMerchantExpandIndirectZftCreateModel();
|
|
||||||
|
|
||||||
MerchantBaseInfoDto baseInfo = reqDto.getMerchantBaseInfo();
|
|
||||||
LegalPersonInfoDto legalPersonInfo = reqDto.getLegalPersonInfo();
|
|
||||||
BusinessLicenceInfoDto businessLicenceInfo = reqDto.getBusinessLicenceInfo();
|
|
||||||
StoreInfoDto storeInfo = reqDto.getStoreInfo();
|
|
||||||
SettlementInfoDto settlementInfo = reqDto.getSettlementInfo();
|
|
||||||
|
|
||||||
entryParams.setExternalId(reqDto.getMerchantCode());
|
|
||||||
if ("0".equals(baseInfo.getUserType())) {
|
|
||||||
entryParams.setMerchantType("07");
|
|
||||||
} else if ("1".equals(baseInfo.getUserType())) {
|
|
||||||
switch (baseInfo.getCompanyChildType()) {
|
|
||||||
case "1" -> entryParams.setMerchantType("01");
|
|
||||||
case "2" -> entryParams.setMerchantType("02");
|
|
||||||
case "3" -> entryParams.setMerchantType("05");
|
|
||||||
case "4" -> entryParams.setMerchantType("04");
|
|
||||||
default -> throw new CzgException("主体类型错误");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new CzgException("用户类型错误");
|
|
||||||
}
|
|
||||||
entryParams.setName(businessLicenceInfo.getLicenceName());
|
|
||||||
entryParams.setAliasName(baseInfo.getShortName());
|
|
||||||
entryParams.setMcc(baseInfo.getMccCode());
|
|
||||||
entryParams.setService(List.of("当面付", "jsapi支付", "小程序支付"));
|
|
||||||
entryParams.setInDoorImages(List.of(storeInfo.getInsidePic().getAlipayId(), storeInfo.getCashierDeskPic().getAlipayId()));
|
|
||||||
entryParams.setOutDoorImages(List.of(storeInfo.getDoorPic().getAlipayId()));
|
|
||||||
|
|
||||||
// 证件类型(目前只支持个体和企业,所以都是营业执照)
|
|
||||||
entryParams.setCertType("201");
|
|
||||||
entryParams.setCertImage(businessLicenceInfo.getLicensePic().getAlipayId());
|
|
||||||
entryParams.setCertNo(businessLicenceInfo.getLicenceNo());
|
|
||||||
|
|
||||||
entryParams.setLegalName(legalPersonInfo.getLegalPersonName());
|
|
||||||
entryParams.setLegalCertNo(legalPersonInfo.getLegalPersonId());
|
|
||||||
entryParams.setLegalCertFrontImage(legalPersonInfo.getIdCardFrontPic().getAlipayId());
|
|
||||||
entryParams.setLegalCertBackImage(legalPersonInfo.getIdCardBackPic().getAlipayId());
|
|
||||||
|
|
||||||
entryParams.setServicePhone(PayCst.ContactPersonType.LEGAL.equals(baseInfo.getContactPersonType()) ? legalPersonInfo.getLegalPersonPhone() : baseInfo.getContactPhone());
|
|
||||||
|
|
||||||
com.alipay.api.domain.AddressInfo addressInfo = new com.alipay.api.domain.AddressInfo();
|
|
||||||
addressInfo.setCityCode(storeInfo.getMercCityCode());
|
|
||||||
addressInfo.setDistrictCode(storeInfo.getMercAreaCode());
|
|
||||||
addressInfo.setProvinceCode(storeInfo.getMercProvCode());
|
|
||||||
addressInfo.setAddress(storeInfo.getBusinessAddress());
|
|
||||||
entryParams.setBusinessAddress(addressInfo);
|
|
||||||
|
|
||||||
com.alipay.api.domain.SettleCardInfo settleCardInfo = new com.alipay.api.domain.SettleCardInfo();
|
|
||||||
settleCardInfo.setAccountHolderName(settlementInfo.getSettlementName());
|
|
||||||
settleCardInfo.setAccountNo(settlementInfo.getSettlementCardNo());
|
|
||||||
settleCardInfo.setAccountInstProvince(settlementInfo.getOpenAccProvince());
|
|
||||||
settleCardInfo.setAccountInstCity(settlementInfo.getOpenAccCity());
|
|
||||||
settlementInfo.setBankBranchName(settlementInfo.getBankBranchName());
|
|
||||||
settleCardInfo.setUsageType("21".equals(settlementInfo.getSettlementCardType()) ? "01" : "02");
|
|
||||||
settleCardInfo.setAccountType("DC");
|
|
||||||
settleCardInfo.setAccountInstName(settlementInfo.getBankName());
|
|
||||||
settleCardInfo.setAccountInstId(settlementInfo.getBankInstId());
|
|
||||||
settleCardInfo.setBankCode(settlementInfo.getBankBranchCode());
|
|
||||||
entryParams.setBizCards(List.of(settleCardInfo));
|
|
||||||
|
|
||||||
com.alipay.api.domain.ContactInfo contactInfo = new com.alipay.api.domain.ContactInfo();
|
|
||||||
if (PayCst.ContactPersonType.SUPER.equals(baseInfo.getContactPersonType())) {
|
|
||||||
contactInfo.setName(baseInfo.getContactName());
|
|
||||||
contactInfo.setMobile(baseInfo.getContactPhone());
|
|
||||||
contactInfo.setEmail(baseInfo.getContactEmail());
|
|
||||||
contactInfo.setIdCardNo(baseInfo.getContactPersonId());
|
|
||||||
} else if (PayCst.ContactPersonType.LEGAL.equals(baseInfo.getContactPersonType())) {
|
|
||||||
contactInfo.setName(legalPersonInfo.getLegalPersonName());
|
|
||||||
contactInfo.setMobile(legalPersonInfo.getLegalPersonPhone());
|
|
||||||
contactInfo.setEmail(legalPersonInfo.getLegalPersonEmail());
|
|
||||||
contactInfo.setIdCardNo(legalPersonInfo.getLegalPersonId());
|
|
||||||
} else {
|
|
||||||
throw new CzgException("联系人类型错误");
|
|
||||||
}
|
|
||||||
entryParams.setContactInfos(List.of(contactInfo));
|
|
||||||
|
|
||||||
entryParams.setLicenseAuthLetterImage(businessLicenceInfo.getLicensePic().getAlipayId());
|
|
||||||
|
|
||||||
// 小程序
|
|
||||||
SiteInfo miniAppInfo = new SiteInfo();
|
|
||||||
miniAppInfo.setSiteType("06");
|
|
||||||
miniAppInfo.setSiteUrl("https://sxczgkj.cn");
|
|
||||||
miniAppInfo.setSiteName("银收客");
|
|
||||||
miniAppInfo.setTinyAppId("2021004145625815");
|
|
||||||
entryParams.setSites(List.of(miniAppInfo));
|
|
||||||
|
|
||||||
return entryParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws ApiException {
|
|
||||||
|
|
||||||
// queryBankBranchList("CMB", "陕西省", "西安市");
|
|
||||||
// uploadImage(null, "https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg");
|
|
||||||
|
|
||||||
test();
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://opendocs.alipay.com/solution/0dec7x?pathHash=caec4753 直付通
|
|
||||||
public static void test() throws ApiException {
|
|
||||||
ApiClient defaultClient = Configuration.getDefaultApiClient();
|
|
||||||
// 初始化alipay参数(全局设置一次)
|
|
||||||
AlipayConfig alipayConfig = new AlipayConfig();
|
|
||||||
alipayConfig.setServerUrl("https://openapi.alipay.com");
|
|
||||||
alipayConfig.setAppId("2021006121646825");
|
|
||||||
alipayConfig.setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB");
|
|
||||||
alipayConfig.setPrivateKey("MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCz3FkdffxZibdwis9W7eOW1dEjGAbSvRDL2ikfeCIW5KZNoIjUqxI0mIoUlLRRKO71QLHZS1Vb2aJp8jeOAqIPa8e76HTneQEzk3FGA8gpraSGvbadHWzvxnmYKsts1TBiEZQL82ySJXhQTJvZ6jyDM7s6wHHUnrH+Qi29QpppQ1sxsoJeCtajUgRg3btD6XbBcyFAX3pzM56Kw9eaIjZoD8WToZOM/Y3sqNL2uo8lLqcIpTrI7Pq5ZOspmBQ+t8v3rS9IdDZZMvd0trzS67AXwHz8rKPBT/lL1A4iHnXCHUvktusX1fPs3/RGY/a7PIddaBLnfY0GcueE16K7QcrXAgMBAAECggEAbSdT2eckp75BWoaTcGEs1tRqeM7TDT/6moyKmnOQ1K3tE31SrSYpBUxxuC3LBNo/sw2RIZtrcTOyMnPyLTgB3DP/4lUf5X51MTTQ8LnI1ypvh+pIki9Sdm3QS33lOOZk149tdpdDk6ozyx/DEcvq74EMpoo2SuAIi5LkKVDrXuehvGA/WeXtpmuPgqRFdIA+JBlA3knHk5XEQY/k2Y31gq5oCwNL9iT9OAZqVkukE6EnvCXE9t2rAV4/snYilaf/UaO+ktgEwSbPBQ8YKlovDAarMBbGtgr6E174A9djlPyR+W/fgx8rlTwSWtieb9MkO8LN3KSxgVs0kY5U8OHg8QKBgQDljJq9kTFHare+W/fAXdUy3tJprfNQCAii6s+GuDfTQiviVQDtWmdtHAN+xU3to7MepvVhwHsqtQnZXKTtZuwwxn82FNl7A5RYD3GVFW+wG6AsGLIdESrWxySoL6Kx8QmNpMEVg8acT/ywzW/RnUXS5vU7GIi8GA0vtyBo24R9KQKBgQDIlf/R9+iNk9oXlbB/k4um9eVvBBS7l5cx4E5Id5Dpp4kGZfPZEa7oDsEUstZZM9mgQLJK/noNWbcf0+BohCR5ux7SC12qIoxwN3k4BzTDqrS8BzFuVVp5PELUsf/uCbRn05iMzpiDUhj3Vde04wvjHYIobfKlZO2HeSWXCpUH/wKBgQC8wSuU6ck90pEY5QMKmZ3wYK1g3PsQOirv3Gmde+nbu7PePsuuYQJfBAQTwCZeXJezgtKP+PjOm2Nn6vhrhpB9YxvD2s0ijET1TG23i5L1myHQYNZFdJJnXgXUjqcX7v5ODMYA7QTqEBPXRnbGRK7fx66rU3dMQ/LD46+wyaFeUQKBgA4QTk53dkuu6SSsLyLSwoDjTsHY5Gc+urAZjQORtoxbXcUgEtfOYJgOqMT9wP+iHgkZYCbX7tDO0IMfxOUvFqueTgvmFhwergAUM6CVCMMLTf689l9JBr3nVrw4+rvC3G5HLLP6rEDQ2cVFtIkPPj8fS4fwJYopKGpOOS9843QbAoGBAMoHH8LqoZ50FLsospx/hJe24Cd8wCgQTXSa/hMqNZ1999JDhftMt7R0ZdB1he2LReACe0K9ntBU4H4u225zZ3wZlyOfoyerAHuLK/ysNlgIIzblZlOxbBJ64Kul8leXzlYy3tOZuZ997KqBcWPCE3LUBBNvM6E3blJUnlmJAVoi");
|
|
||||||
defaultClient.setAlipayConfig(alipayConfig);
|
|
||||||
log.info("dd: {}", JSONObject.toJSONString(alipayConfig));
|
|
||||||
AlipayOpenAgentApi api = new AlipayOpenAgentApi();
|
|
||||||
AlipayOpenAgentCreateModel data = new AlipayOpenAgentCreateModel();
|
|
||||||
ContactModel contactInfo = new ContactModel();
|
|
||||||
contactInfo.setContactEmail("zhangsan@alipy.com");
|
|
||||||
contactInfo.setContactName("张三");
|
|
||||||
contactInfo.setContactMobile("18866668888");
|
|
||||||
data.setContactInfo(contactInfo);
|
|
||||||
// data.setOrderTicket("00ee2d475f374ad097ee0f1ac223fX00");
|
|
||||||
data.setAccount("1157756119@qq.com");
|
|
||||||
try {
|
|
||||||
AlipayOpenAgentCreateResponseModel response = api.create(data);
|
|
||||||
System.out.println(response);
|
|
||||||
} catch (ApiException e) {
|
|
||||||
AlipayOpenAgentCreateDefaultResponse errorObject = (AlipayOpenAgentCreateDefaultResponse) e.getErrorObject();
|
|
||||||
System.out.println("调用失败:" + errorObject);
|
|
||||||
System.out.println("调用失败:" + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,239 +0,0 @@
|
|||||||
package com.czg.third.alipay;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
|
||||||
import com.alipay.v3.ApiException;
|
|
||||||
import com.alipay.v3.api.*;
|
|
||||||
import com.alipay.v3.model.*;
|
|
||||||
import com.czg.PayCst;
|
|
||||||
import com.czg.dto.req.*;
|
|
||||||
import com.czg.dto.resp.EntryThirdRespDto;
|
|
||||||
import com.czg.dto.resp.QueryStatusResp;
|
|
||||||
import com.czg.exception.CzgException;
|
|
||||||
import com.czg.third.alipay.dto.config.AlipayConfigDto;
|
|
||||||
import com.czg.utils.UploadFileUtil;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付宝服务商进件管理
|
|
||||||
* <a href="https://opendocs.alipay.com/open-v3/b4c46445_alipay.open.agent.create?scene=common&pathHash=d7084b4b">...</a>
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2026/1/8 13:34
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class AlipayIsvEntryManager {
|
|
||||||
|
|
||||||
private static final String ERR_MESSAGE_KEY = "message";
|
|
||||||
|
|
||||||
public static QueryStatusResp queryMerchantBatchStatus(AlipayConfigDto configDto, String batchNo) {
|
|
||||||
QueryStatusResp respDto = new QueryStatusResp()
|
|
||||||
.setPlatform(PayCst.Platform.ALIPAY);
|
|
||||||
AlipayClient.setApiClient(configDto);
|
|
||||||
|
|
||||||
try {
|
|
||||||
AlipayOpenAgentOrderApi api = new AlipayOpenAgentOrderApi();
|
|
||||||
AlipayOpenAgentOrderQueryResponseModel response = api.query(batchNo);
|
|
||||||
|
|
||||||
log.info("支付宝查询进件状态: 响应={}", response);
|
|
||||||
respDto.setApplyId(batchNo);
|
|
||||||
|
|
||||||
switch (response.getOrderStatus()) {
|
|
||||||
case "MERCHANT_INFO_HOLD" -> {
|
|
||||||
respDto.setStatus(PayCst.EntryStatus.REJECTED);
|
|
||||||
respDto.setFailReason("三方异常,请重新提交");
|
|
||||||
return respDto;
|
|
||||||
}
|
|
||||||
case "MERCHANT_CONFIRM_TIME_OUT" -> {
|
|
||||||
respDto.setStatus(PayCst.EntryStatus.REJECTED);
|
|
||||||
respDto.setFailReason("商户确认超时,请重新提交");
|
|
||||||
return respDto;
|
|
||||||
}
|
|
||||||
case "MERCHANT_AUDITING" -> {
|
|
||||||
respDto.setStatus(PayCst.EntryStatus.AUDIT);
|
|
||||||
respDto.setFailReason("");
|
|
||||||
return respDto;
|
|
||||||
}
|
|
||||||
case "MERCHANT_CONFIRM" -> {
|
|
||||||
respDto.setStatus(PayCst.EntryStatus.SIGN);
|
|
||||||
respDto.setFailReason("");
|
|
||||||
respDto.setSignUrl(response.getConfirmUrl());
|
|
||||||
return respDto;
|
|
||||||
}
|
|
||||||
case "MERCHANT_APPLY_ORDER_CANCELED" -> {
|
|
||||||
respDto.setStatus(PayCst.EntryStatus.REJECTED);
|
|
||||||
respDto.setFailReason(response.getRejectReason());
|
|
||||||
return respDto;
|
|
||||||
}
|
|
||||||
case "MERCHANT_CONFIRM_SUCCESS" -> {
|
|
||||||
respDto.setStatus(PayCst.EntryStatus.FINISH);
|
|
||||||
respDto.setFailReason("");
|
|
||||||
respDto.setThirdMerchantId(response.getMerchantPid());
|
|
||||||
return respDto;
|
|
||||||
}
|
|
||||||
case null -> {
|
|
||||||
respDto.setStatus(PayCst.EntryStatus.REJECTED);
|
|
||||||
respDto.setFailReason("查询失败");
|
|
||||||
return respDto;
|
|
||||||
}
|
|
||||||
default -> {
|
|
||||||
return respDto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (ApiException e) {
|
|
||||||
String body = e.getResponseBody();
|
|
||||||
log.error("支付宝查询进件状态异常: {}", body);
|
|
||||||
JSONObject object = JSONObject.parseObject(body);
|
|
||||||
respDto.setStatus(PayCst.EntryStatus.REJECTED);
|
|
||||||
respDto.setFailReason(object.getString(ERR_MESSAGE_KEY));
|
|
||||||
return respDto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建商户
|
|
||||||
* @param configDto 配置信息
|
|
||||||
* @param reqDto 请求信息
|
|
||||||
*/
|
|
||||||
public static EntryThirdRespDto entryMerchant(AlipayConfigDto configDto, AggregateMerchantDto reqDto) {
|
|
||||||
AlipayClient.setApiClient(configDto);
|
|
||||||
EntryThirdRespDto respDto = new EntryThirdRespDto()
|
|
||||||
.setPlatform(PayCst.Platform.ALIPAY);
|
|
||||||
try {
|
|
||||||
String batchNo = createRequest(reqDto);
|
|
||||||
|
|
||||||
AlipayOpenAgentFacetofaceSignModel signModel = buildFaceToFaceModel(reqDto, batchNo);
|
|
||||||
File businessLicensePic = UploadFileUtil.getFileByUrl(reqDto.getBusinessLicenceInfo().getLicensePic().getUrl());
|
|
||||||
File shopScenePic = UploadFileUtil.getFileByUrl(reqDto.getStoreInfo().getInsidePic().getUrl());
|
|
||||||
File shopSignBoardPic = UploadFileUtil.getFileByUrl(reqDto.getStoreInfo().getDoorPic().getUrl());
|
|
||||||
|
|
||||||
// 构造请求参数以调用接口
|
|
||||||
AlipayOpenAgentFacetofaceApi api = new AlipayOpenAgentFacetofaceApi();
|
|
||||||
Object response = api.sign(null, businessLicensePic, signModel, shopScenePic, shopSignBoardPic, null);
|
|
||||||
log.info("支付宝开启代商户签约: 响应={}", JSONObject.toJSONString(response));
|
|
||||||
|
|
||||||
try {
|
|
||||||
String orderNo = confirmRequest(batchNo);
|
|
||||||
respDto.setEntryId(orderNo);
|
|
||||||
respDto.setStatus(PayCst.EntryStatus.INIT);
|
|
||||||
respDto.setErrorMsg("");
|
|
||||||
return respDto;
|
|
||||||
} catch (CzgException e) {
|
|
||||||
respDto.setStatus(PayCst.EntryStatus.REJECTED);
|
|
||||||
respDto.setErrorMsg(e.getMessage());
|
|
||||||
return respDto;
|
|
||||||
}
|
|
||||||
} catch (ApiException e) {
|
|
||||||
String body = e.getResponseBody();
|
|
||||||
log.error("支付宝开启代商户签约,创建应用事务异常: {}", body);
|
|
||||||
JSONObject object = JSONObject.parseObject(body);
|
|
||||||
respDto.setStatus(PayCst.EntryStatus.REJECTED);
|
|
||||||
respDto.setErrorMsg(object.getString(ERR_MESSAGE_KEY));
|
|
||||||
return respDto;
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error("上传图片出错", e);
|
|
||||||
respDto.setStatus(PayCst.EntryStatus.REJECTED);
|
|
||||||
respDto.setErrorMsg("上传图片出错");
|
|
||||||
return respDto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开启代商户签约、创建应用事务
|
|
||||||
* @param reqDto 请求信息
|
|
||||||
* @return 请求ID
|
|
||||||
*/
|
|
||||||
public static String createRequest(AggregateMerchantDto reqDto) {
|
|
||||||
AlipayOpenAgentApi api = new AlipayOpenAgentApi();
|
|
||||||
AlipayOpenAgentCreateModel openModel = new AlipayOpenAgentCreateModel();
|
|
||||||
|
|
||||||
MerchantBaseInfoDto info = reqDto.getMerchantBaseInfo();
|
|
||||||
LegalPersonInfoDto legalPersonInfo = reqDto.getLegalPersonInfo();
|
|
||||||
String contactPersonType = info.getContactPersonType();
|
|
||||||
boolean isSuper = PayCst.ContactPersonType.SUPER.equals(contactPersonType);
|
|
||||||
|
|
||||||
ContactModel contactModel = new ContactModel();
|
|
||||||
// 联系人名称
|
|
||||||
contactModel.setContactName(isSuper ? info.getContactName() : legalPersonInfo.getLegalPersonName());
|
|
||||||
// 联系人手机号码
|
|
||||||
contactModel.setContactMobile(isSuper ? info.getContactPhone() : legalPersonInfo.getLegalPersonPhone());
|
|
||||||
// 联系人邮箱
|
|
||||||
contactModel.setContactEmail(isSuper ? info.getContactEmail() : legalPersonInfo.getLegalPersonEmail());
|
|
||||||
openModel.setContactInfo(contactModel);
|
|
||||||
|
|
||||||
openModel.setAccount(reqDto.getMerchantBaseInfo().getAlipayAccount());
|
|
||||||
|
|
||||||
try {
|
|
||||||
AlipayOpenAgentCreateResponseModel responseModel = api.create(openModel);
|
|
||||||
log.info("支付宝开启代商户签约,开启事务: 结果={}, batchNo={}", responseModel.getBatchStatus(), responseModel.getBatchNo());
|
|
||||||
return responseModel.getBatchNo();
|
|
||||||
} catch (ApiException e) {
|
|
||||||
String body = e.getResponseBody();
|
|
||||||
log.error("支付宝开启代商户签约,开启事务异常: {}", body);
|
|
||||||
JSONObject object = JSONObject.parseObject(body);
|
|
||||||
throw new CzgException("支付宝开启代商户签约,开启事务异常: " + object.getString(ERR_MESSAGE_KEY));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String confirmRequest(String batchNo) {
|
|
||||||
AlipayClient.setApiClient(null);
|
|
||||||
// 构造请求参数以调用接口
|
|
||||||
AlipayOpenAgentCommonsignApi api = new AlipayOpenAgentCommonsignApi();
|
|
||||||
AlipayOpenAgentCommonsignConfirmModel data = new AlipayOpenAgentCommonsignConfirmModel();
|
|
||||||
|
|
||||||
// 设置ISV 代商户操作事务编号
|
|
||||||
data.setBatchNo(batchNo);
|
|
||||||
try {
|
|
||||||
AlipayOpenAgentCommonsignConfirmResponseModel response = api.confirm(data);
|
|
||||||
log.info("支付宝开启代商户签约,确认事务: 响应={}", response);
|
|
||||||
return response.getOrderNo();
|
|
||||||
} catch (ApiException e) {
|
|
||||||
String body = e.getResponseBody();
|
|
||||||
log.error("支付宝开启代商户签约,确认事务异常: {}", body);
|
|
||||||
JSONObject object = JSONObject.parseObject(body);
|
|
||||||
throw new CzgException(object.getString(ERR_MESSAGE_KEY));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建 当面付参数
|
|
||||||
*/
|
|
||||||
public static AlipayOpenAgentFacetofaceSignModel buildFaceToFaceModel(AggregateMerchantDto reqDto, String batchNo) {
|
|
||||||
AlipayOpenAgentFacetofaceSignModel signModel = new AlipayOpenAgentFacetofaceSignModel();
|
|
||||||
signModel.setBatchNo(batchNo);
|
|
||||||
|
|
||||||
MerchantBaseInfoDto baseInfo = reqDto.getMerchantBaseInfo();
|
|
||||||
LegalPersonInfoDto legalPersonInfo = reqDto.getLegalPersonInfo();
|
|
||||||
BusinessLicenceInfoDto licenceInfo = reqDto.getBusinessLicenceInfo();
|
|
||||||
StoreInfoDto storeInfo = reqDto.getStoreInfo();
|
|
||||||
|
|
||||||
signModel.setMccCode(baseInfo.getMccCode());
|
|
||||||
signModel.setRate("0.38");
|
|
||||||
signModel.setSignAndAuth(true);
|
|
||||||
|
|
||||||
signModel.setBusinessLicenseNo(licenceInfo.getLicenceNo());
|
|
||||||
signModel.setBusinessLicenseMobile(legalPersonInfo.getLegalPersonPhone());
|
|
||||||
signModel.setLongTerm(PayCst.LONG_TERM_DATE.equals(licenceInfo.getLicenceEndDate()));
|
|
||||||
signModel.setDateLimitation(licenceInfo.getLicenceStartDate());
|
|
||||||
|
|
||||||
signModel.setShopName(baseInfo.getShortName());
|
|
||||||
|
|
||||||
// 设置店铺地址
|
|
||||||
SignAddressInfo shopAddress = new SignAddressInfo();
|
|
||||||
shopAddress.setCountryCode("156");
|
|
||||||
shopAddress.setDistrictCode(storeInfo.getMercAreaCode());
|
|
||||||
shopAddress.setDetailAddress(storeInfo.getBusinessAddress());
|
|
||||||
shopAddress.setProvinceCode(storeInfo.getMercProvCode());
|
|
||||||
shopAddress.setCityCode(storeInfo.getMercCityCode());
|
|
||||||
signModel.setShopAddress(shopAddress);
|
|
||||||
|
|
||||||
return signModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
// confirmRequest("2026010815384505500018243");
|
|
||||||
queryMerchantBatchStatus(null, "2026010815384505500018243");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
package com.czg.third.alipay.dto.config;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2026/1/4 13:49
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class AlipayConfigDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付宝 AppId
|
|
||||||
*/
|
|
||||||
private String appId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商户私钥
|
|
||||||
*/
|
|
||||||
private String privateKey;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付宝公钥
|
|
||||||
*/
|
|
||||||
private String alipayPublicKey;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付宝支付域名
|
|
||||||
* <a href="https://openapi.alipay.com/gateway.do"></a>
|
|
||||||
*/
|
|
||||||
private String domain;
|
|
||||||
|
|
||||||
public static AlipayConfigDto getDefaultConfig() {
|
|
||||||
return new AlipayConfigDto()
|
|
||||||
.setAppId("2021006121646825")
|
|
||||||
.setPrivateKey("MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCz3FkdffxZibdwis9W7eOW1dEjGAbSvRDL2ikfeCIW5KZNoIjUqxI0mIoUlLRRKO71QLHZS1Vb2aJp8jeOAqIPa8e76HTneQEzk3FGA8gpraSGvbadHWzvxnmYKsts1TBiEZQL82ySJXhQTJvZ6jyDM7s6wHHUnrH+Qi29QpppQ1sxsoJeCtajUgRg3btD6XbBcyFAX3pzM56Kw9eaIjZoD8WToZOM/Y3sqNL2uo8lLqcIpTrI7Pq5ZOspmBQ+t8v3rS9IdDZZMvd0trzS67AXwHz8rKPBT/lL1A4iHnXCHUvktusX1fPs3/RGY/a7PIddaBLnfY0GcueE16K7QcrXAgMBAAECggEAbSdT2eckp75BWoaTcGEs1tRqeM7TDT/6moyKmnOQ1K3tE31SrSYpBUxxuC3LBNo/sw2RIZtrcTOyMnPyLTgB3DP/4lUf5X51MTTQ8LnI1ypvh+pIki9Sdm3QS33lOOZk149tdpdDk6ozyx/DEcvq74EMpoo2SuAIi5LkKVDrXuehvGA/WeXtpmuPgqRFdIA+JBlA3knHk5XEQY/k2Y31gq5oCwNL9iT9OAZqVkukE6EnvCXE9t2rAV4/snYilaf/UaO+ktgEwSbPBQ8YKlovDAarMBbGtgr6E174A9djlPyR+W/fgx8rlTwSWtieb9MkO8LN3KSxgVs0kY5U8OHg8QKBgQDljJq9kTFHare+W/fAXdUy3tJprfNQCAii6s+GuDfTQiviVQDtWmdtHAN+xU3to7MepvVhwHsqtQnZXKTtZuwwxn82FNl7A5RYD3GVFW+wG6AsGLIdESrWxySoL6Kx8QmNpMEVg8acT/ywzW/RnUXS5vU7GIi8GA0vtyBo24R9KQKBgQDIlf/R9+iNk9oXlbB/k4um9eVvBBS7l5cx4E5Id5Dpp4kGZfPZEa7oDsEUstZZM9mgQLJK/noNWbcf0+BohCR5ux7SC12qIoxwN3k4BzTDqrS8BzFuVVp5PELUsf/uCbRn05iMzpiDUhj3Vde04wvjHYIobfKlZO2HeSWXCpUH/wKBgQC8wSuU6ck90pEY5QMKmZ3wYK1g3PsQOirv3Gmde+nbu7PePsuuYQJfBAQTwCZeXJezgtKP+PjOm2Nn6vhrhpB9YxvD2s0ijET1TG23i5L1myHQYNZFdJJnXgXUjqcX7v5ODMYA7QTqEBPXRnbGRK7fx66rU3dMQ/LD46+wyaFeUQKBgA4QTk53dkuu6SSsLyLSwoDjTsHY5Gc+urAZjQORtoxbXcUgEtfOYJgOqMT9wP+iHgkZYCbX7tDO0IMfxOUvFqueTgvmFhwergAUM6CVCMMLTf689l9JBr3nVrw4+rvC3G5HLLP6rEDQ2cVFtIkPPj8fS4fwJYopKGpOOS9843QbAoGBAMoHH8LqoZ50FLsospx/hJe24Cd8wCgQTXSa/hMqNZ1999JDhftMt7R0ZdB1he2LReACe0K9ntBU4H4u225zZ3wZlyOfoyerAHuLK/ysNlgIIzblZlOxbBJ64Kul8leXzlYy3tOZuZ997KqBcWPCE3LUBBNvM6E3blJUnlmJAVoi")
|
|
||||||
.setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB")
|
|
||||||
.setDomain("https://openapi.alipay.com");
|
|
||||||
// return new AlipayConfigDto()
|
|
||||||
// .setAppId("2021004174605036")
|
|
||||||
// .setPrivateKey("MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQD48HaUoV7OH7os+9L01kHgxzwIhJick4OkFq4aHsntsXEJ J3gedhuEZtV8oHKZ30DPW12IJ4S8NXtpr8OWaqrAPFonf4wVaRY1d0yIAea57kfLEn9oOEEy4FzARgMNDkyxC+/3OUdGbLHpTjfVX3gusXsEhUDy1/WewihAkoNYF37+W3W/uVLzeWoPq0EcUbRv/G/t/p6gL69ltsMAiVFG4Q/Yk24YAN6lYgBPNLXUEwQ1Q+T+1omjfavHgvarKOp33z3JOUH+aGOmDsJ5Y9gyGtJzOCipAd8Zcv+T1ygsEzZYO1/gzcbPnfO1ShqStCHzssuw8FBVx2JdfQKXKMMNAgMBAAECggEAVTrO/pg5Q00titU1Jspsh67u6OOs9H605Ws2dI7yB8VmtAGlaJh7V1t14FN2qSP8poHbhhAxq9aLyGV7C3a9u09udnN+3J28EtYjh7VO732bavWMVXxdJjQWzWWrCb9JlpxFrlkYBA6W4w/6ob0sAqCVQ7jzwbEa0R4cde8ztOa5nysKSfr4YTSs0gqvoiC6fmg8eiRJraEQBoYz9VkKFtOhhh/4w5FhVcYQ2gQvZ3kK3QVuD1eJIQKlCtz8qaox9lXKDiZT4SCmnKshdUL0u5TYIcYeBjZmhJz0Q50KHcpZrCs5y7I0+vRBH3hU+TKSQt7ureymwhbwWMHScLV2gQKBgQD+58SHXhr5M8NGagAmTdsgmCnNv2kOYMd4STyPMY10SVwCv1Bk808ZuP+7e558J1b5/OuDLI5dLq6xrZ/1wLv1G++XqxI00hlFuWS5mUGJVcXotT1mw20rVeUILc7Qe3mLvbMGgfyKf4A7Qa5SSZ4bDeDTJYaFxyiQ281hMzDuPQKBgQD6AiL/Na2/uPH4CG6juwpjYvYVUcjK+7gbRwf3wWsWMpk90Z4ju2iUiP5c1J/oK9P+1T3PIr6M4Xjza8JJj+r9KC/PVB0gBv6vVM96cDpKUEy/UMpcn/T81vqj/Z+WEOODU8Ms6NiTTm+u9ldvpCjbu0u8M+9c0JeIyadJvSTFEQKBgQCsxmFyM3nq8YfpgU2qqNjfBeRH3faSVUy+nj1a/YZYjKS+A/i1BCnYUImeBVNN6chNV342ggvY4xxruDiU9Vcw8wd58O09Oi8BEIFSP6upL6cebUI6Fjo3xlegLJRiwV6INkNTJOYM5hD/mSxUACwXQFfkJipBINXBIgraWD1RLQKBgQCj49axWq0F6+WjZVOyPaD3uh37p9trRUxRhWTxw3fB23WdktaKMgbCqHOmwzP4bRLSEVQtf2dOz1gMqu14b8HqJvgAf/F/11YJ9hz09LEhmjZVjE68HZfqT7uK2W5OX8/lfXmK7TFcj6SjG5YB96lZMhTZ0WnufEd6QkdKDZYXIQKBgQD9GDTcIMbFwbEaKHnfZaTD3f876EGRgsgrCxwdEk7LBCRPwWo7yI929M4psIlpNwNeiyjBkBunWIVkpznp6qPtJqagIPUYesU4f5v6/okq5wcpaNKSkWbIvWVLaLGOiA1aeGJtbpMpyClbSr52puHpRRdvAiIEQ74yYh0JX8q96g==")
|
|
||||||
// .setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB")
|
|
||||||
// .setDomain("https://openapi.alipay.com/gateway.do");
|
|
||||||
// return new AlipayConfigDto()
|
|
||||||
// .setAppId("2021004145625815")
|
|
||||||
// .setPrivateKey("MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCAjDBuS8K/IJb9ui+KuNm/sTUdEiaji4BNpZ92avO1N5JpNlGmac6ec4p3tNFT950sBLcQkClcUpQxUHQzAT6DYNNXOKyvfI/EmcqwCw6PaMNLs/8cV//J2WWZBUhLaOsjKurpm9/3W5MnTh4BGxIfBoeBMA8f8K3BgKdmyKtvIEV2h2cyjsMskdn+g6oNZcmWcms0pvpPHyH46mRaGFhpp0v19wX3WsamGldh1L2VntmaDN3C2XbSrXv90XYp5bEUqwTbLwXpMAlzTibF56d/iqv9oYi8cpAKougUFLOymnbutLNs2tLrEDSFwHcmG2/wbZHybZyYcIgFgv4arf+tAgMBAAECggEAf7hKKlw1y6Z6vvAtalxNZUuRZSfyog3p1bwYWxTavZPQcZ7Zs0lvVDmiO1u5m/7q96BbryY9IhCeUv0H5uF2lhwu/3s9AEL3qTPQkeb6eXxyhhX6A9RfPdM1Qbtg4CQHdHKg4qjP9znSVHwmDZ0y/QaEvdPdQzPjv92u9c2tn4N4x6XyBYcU5gzxiJNnIugCmBgcJo/3H2fgV+XXEhORPvy5of9b4oATHEaLS/8dAS2wuOjhzaGS4MXp3VkXn3XaYjwSzaL03qYWA+xm+aO5sJv8bmqZW7sNVck5o3sPo7cQ4VkBFVzyrRdmJcxcSRJ9MsB9JsrhoKI8pgaXrVie4QKBgQDU2vai0lpBIK/0jzRpPNoqdT8lnafnnWni8nU4kfAh+gCLi+HBPhQRT0kv4unQc2q2/gALE7sgZVO00JGY5a3R0orsojPoUSZlpypGW7GGqKy576NHn0nw4o/PdfysT92VWgt1hlfTf6qfCDhfE9APU+RGvlSWXcT8nxVel3iUaQKBgQCamoJN6+4v+chJvL2nqV8NVVRLp0vDIHxs1QOtKwUodx8Qp1D6CJYtavCXn8aNUFVNQJPJ7TQPpJjXP2rI4SN01weDwx+I+wh8PBGHV6/234R+6TvFgY1PrYgCdfNP4i/E7B4uyEhAxdU73PB8qkqRAeJGok05p7oG71KCOBiYpQKBgEZfGflcuDAeAW5GRhqg3rP4zWa/R7qgZVh9tll8jjp9b96y4XFE99d9MgId8BVVgyt6sEL5Q/2C4ni+F9TH4n6jMADp42VkJuCmsqhOOlP9whU67+2G8Sgtj0QUivPg964f9ffl8XVgGOW5DwIIB9p5btggptCLscufQK5kP545AoGADBvf6tR4wl8w9b2HqTMV08iEIqzGvVC1Dh0c/Zop/EJgN4CzUfIMOSBwGaAVAApzs+pD6QPgGP2OTwWTioo/qa4R05sbxDHNN1XJFa2jhZV6HiqMWOrNs5jm1zJ/zRjtHuJTdtyO9CvKiLbESy9XScY4/8lEfSiK5HIoJzTXkFUCgYAkYkvkW6psJpWj05XWq44UN0n6QOU/Igl35Um/iuOMVhsTmIt09STQVTuzJzfH82+sCqoRsD1blE5unKNUC1DK77aNKTv3Z0dxN9R7FAyfZRiYQXTrbBPBqWjay6FCNxn8e8UsJN4Z6FIV2LGlQI114krSap1MALKLVvnld0NaUQ==")
|
|
||||||
// .setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB")
|
|
||||||
// .setDomain("https://openapi.alipay.com/gateway.do");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
package com.czg.third.wechat;
|
|
||||||
|
|
||||||
import com.czg.third.wechat.dto.config.WechatPayConfigDto;
|
|
||||||
import com.wechat.pay.java.core.Config;
|
|
||||||
import com.wechat.pay.java.core.RSAPublicKeyConfig;
|
|
||||||
import com.wechat.pay.java.service.file.FileUploadService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信支付 配置
|
|
||||||
*
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 09:33
|
|
||||||
*/
|
|
||||||
public class WechatConfig {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取微信支付配置
|
|
||||||
* @param dto 微信支付配置
|
|
||||||
* @return 微信支付配置
|
|
||||||
*/
|
|
||||||
public static Config getRsaConfig(WechatPayConfigDto dto) {
|
|
||||||
if (dto == null) {
|
|
||||||
dto = WechatPayConfigDto.getDefaultConfig();
|
|
||||||
}
|
|
||||||
return new RSAPublicKeyConfig.Builder()
|
|
||||||
.merchantId(dto.getMerchantId())
|
|
||||||
.privateKey(dto.getPrivateKey())
|
|
||||||
.publicKey(dto.getPublicKey())
|
|
||||||
.publicKeyId(dto.getPublicKeyId())
|
|
||||||
.merchantSerialNumber(dto.getSerialNumber())
|
|
||||||
.apiV3Key(dto.getApiV3Key())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static FileUploadService getFileUploadServiceByConfig(Config config) {
|
|
||||||
return new FileUploadService.Builder()
|
|
||||||
.config(config)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取文件上传服务
|
|
||||||
* @param dto 微信支付配置
|
|
||||||
* @return 文件上传服务
|
|
||||||
*/
|
|
||||||
public static FileUploadService getFileUploadService(WechatPayConfigDto dto) {
|
|
||||||
return getFileUploadServiceByConfig(getRsaConfig(dto));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
package com.czg.third.wechat;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import javax.crypto.BadPaddingException;
|
|
||||||
import javax.crypto.Cipher;
|
|
||||||
import javax.crypto.IllegalBlockSizeException;
|
|
||||||
import javax.crypto.NoSuchPaddingException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.security.InvalidKeyException;
|
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.PublicKey;
|
|
||||||
import java.security.cert.X509Certificate;
|
|
||||||
import java.util.Base64;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信支付加解密
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 10:58
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class WechatEncrypt {
|
|
||||||
|
|
||||||
public static String rsaEncryptOaep(String message, PublicKey publicKey) {
|
|
||||||
try {
|
|
||||||
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
|
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
|
||||||
byte[] data = message.getBytes(StandardCharsets.UTF_8);
|
|
||||||
byte[] cipherData = cipher.doFinal(data);
|
|
||||||
return Base64.getEncoder().encodeToString(cipherData);
|
|
||||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
|
|
||||||
log.error("当前Java环境不支持RSA v1.5/OAEP");
|
|
||||||
} catch (InvalidKeyException e) {
|
|
||||||
log.error("无效的证书");
|
|
||||||
} catch (IllegalBlockSizeException | BadPaddingException e) {
|
|
||||||
log.error("加密原串的长度不能超过214字节");
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getFileBytesSha256(byte[] input) throws NoSuchAlgorithmException {
|
|
||||||
return bytesToHex(calculateSha256(input));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 核心方法:计算字节数组的 SHA-256 哈希值
|
|
||||||
* @param input 待计算的字节数组
|
|
||||||
* @return SHA-256 哈希值(32 字节的字节数组)
|
|
||||||
*/
|
|
||||||
private static byte[] calculateSha256(byte[] input) throws NoSuchAlgorithmException {
|
|
||||||
// 获取 SHA-256 消息摘要实例(Java 21 完全兼容)
|
|
||||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
|
||||||
// 计算哈希值
|
|
||||||
return digest.digest(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 辅助方法:将字节数组转换为十六进制字符串(SHA-256 结果常用格式)
|
|
||||||
* @param bytes 待转换的字节数组
|
|
||||||
* @return 十六进制字符串(SHA-256 对应 64 位字符串)
|
|
||||||
*/
|
|
||||||
private static String bytesToHex(byte[] bytes) {
|
|
||||||
StringBuilder hexString = new StringBuilder();
|
|
||||||
// Java 21 可使用 var 简化声明
|
|
||||||
for (var b : bytes) {
|
|
||||||
// 将字节转换为两位十六进制数,不足补 0
|
|
||||||
String hex = Integer.toHexString(0xff & b);
|
|
||||||
if (hex.length() == 1) {
|
|
||||||
hexString.append('0');
|
|
||||||
}
|
|
||||||
hexString.append(hex);
|
|
||||||
}
|
|
||||||
return hexString.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,418 +0,0 @@
|
|||||||
package com.czg.third.wechat;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
|
||||||
import com.alibaba.fastjson2.JSONWriter;
|
|
||||||
import com.czg.PayCst;
|
|
||||||
import com.czg.dto.req.*;
|
|
||||||
import com.czg.dto.resp.EntryThirdRespDto;
|
|
||||||
import com.czg.dto.resp.QueryStatusResp;
|
|
||||||
import com.czg.exception.CzgException;
|
|
||||||
import com.czg.third.wechat.dto.config.WechatPayConfigDto;
|
|
||||||
import com.czg.third.wechat.dto.req.entry.*;
|
|
||||||
import com.czg.third.wechat.dto.req.entry.business.WechatEntryBusinessReqDto;
|
|
||||||
import com.czg.third.wechat.dto.req.entry.business.WechatEntryIdentityReqDto;
|
|
||||||
import com.czg.third.wechat.dto.req.entry.business.WechatEntryLicenseReqDto;
|
|
||||||
import com.czg.third.wechat.dto.req.entry.business.sales.WechatEntryMiniProgramReqDto;
|
|
||||||
import com.czg.third.wechat.dto.req.entry.business.sales.WechatEntrySalesInfoReqDto;
|
|
||||||
import com.czg.third.wechat.dto.req.entry.business.sales.WechatEntryStoreInfoReqDto;
|
|
||||||
import com.czg.third.wechat.dto.resp.WechatAuditDetail;
|
|
||||||
import com.czg.third.wechat.dto.resp.WechatQueryStateResp;
|
|
||||||
import com.czg.utils.UploadFileUtil;
|
|
||||||
import com.wechat.pay.java.core.Config;
|
|
||||||
import com.wechat.pay.java.core.cipher.PrivacyEncryptor;
|
|
||||||
import com.wechat.pay.java.service.file.FileUploadService;
|
|
||||||
import com.wechat.pay.java.service.file.model.FileUploadResponse;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信支付进件 管理
|
|
||||||
* 参考地址 <a href="https://pay.weixin.qq.com/doc/v3/partner/4012719997">...</a>
|
|
||||||
*
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 10:57
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class WechatEntryManager {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询商户进件状态
|
|
||||||
*
|
|
||||||
* @param configDto 配置信息
|
|
||||||
* @param applyId 自系统的商户编号
|
|
||||||
* @return 进件状态
|
|
||||||
*/
|
|
||||||
public static QueryStatusResp queryMerchantEntryStatus(WechatPayConfigDto configDto, String applyId) {
|
|
||||||
QueryStatusResp queryStatusResp = new QueryStatusResp();
|
|
||||||
queryStatusResp.setPlatform(PayCst.Platform.WECHAT);
|
|
||||||
queryStatusResp.setMerchantCode(applyId);
|
|
||||||
|
|
||||||
String resp = WechatReqUtils.getReq(configDto, "/v3/applyment4sub/applyment/applyment_id/" + applyId, Map.of());
|
|
||||||
JSONObject object = JSONObject.parseObject(resp);
|
|
||||||
JSONObject data = object.getJSONObject("data");
|
|
||||||
if (data == null) {
|
|
||||||
log.error("微信查询进件状态失败:{}", resp);
|
|
||||||
queryStatusResp.setFailReason(object.getString("message"));
|
|
||||||
queryStatusResp.setStatus(PayCst.EntryStatus.REJECTED);
|
|
||||||
return queryStatusResp;
|
|
||||||
}
|
|
||||||
log.info("微信查询进件状态:{}", resp);
|
|
||||||
WechatQueryStateResp stateResp = JSONObject.parseObject(data.toJSONString(), WechatQueryStateResp.class);
|
|
||||||
|
|
||||||
queryStatusResp.setApplyId(stateResp.getApplyId());
|
|
||||||
switch (stateResp.getApplyState()) {
|
|
||||||
case "APPLYMENT_STATE_EDITTING" -> {
|
|
||||||
queryStatusResp.setStatus(PayCst.EntryStatus.WAIT);
|
|
||||||
queryStatusResp.setFailReason("");
|
|
||||||
}
|
|
||||||
case "APPLYMENT_STATE_AUDITING" -> {
|
|
||||||
queryStatusResp.setStatus(PayCst.EntryStatus.AUDIT);
|
|
||||||
queryStatusResp.setFailReason("");
|
|
||||||
}
|
|
||||||
case "APPLYMENT_STATE_REJECTED" -> {
|
|
||||||
queryStatusResp.setStatus(PayCst.EntryStatus.REJECTED);
|
|
||||||
StringBuilder msg = new StringBuilder();
|
|
||||||
for (WechatAuditDetail auditDetail : stateResp.getAuditDetail()) {
|
|
||||||
msg.append(auditDetail.getRejectReason()).append(",");
|
|
||||||
}
|
|
||||||
queryStatusResp.setFailReason(msg.toString());
|
|
||||||
}
|
|
||||||
case "APPLYMENT_STATE_TO_BE_CONFIRMED", "APPLYMENT_STATE_TO_BE_SIGNED" -> {
|
|
||||||
queryStatusResp.setStatus(PayCst.EntryStatus.SIGN);
|
|
||||||
queryStatusResp.setFailReason("");
|
|
||||||
queryStatusResp.setSignUrl(stateResp.getSignUrl());
|
|
||||||
}
|
|
||||||
case "APPLYMENT_STATE_SIGNING", "APPLYMENT_STATE_FINISHED" -> {
|
|
||||||
queryStatusResp.setStatus(PayCst.EntryStatus.FINISH);
|
|
||||||
queryStatusResp.setFailReason("");
|
|
||||||
queryStatusResp.setThirdMerchantId(stateResp.getSubMchId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return queryStatusResp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进件商户
|
|
||||||
*
|
|
||||||
* @param configDto 配置信息
|
|
||||||
* @param reqDto 请求信息
|
|
||||||
*/
|
|
||||||
public static EntryThirdRespDto entryMerchant(WechatPayConfigDto configDto, AggregateMerchantDto reqDto) {
|
|
||||||
WechatEntryReqDto entryReqDto = buildEntryParams(configDto, reqDto);
|
|
||||||
EntryThirdRespDto respDto = new EntryThirdRespDto()
|
|
||||||
.setPlatform(PayCst.Platform.WECHAT);
|
|
||||||
|
|
||||||
log.info("微信进件参数:{}", JSONObject.toJSONString(entryReqDto));
|
|
||||||
try {
|
|
||||||
String params = JSONObject.toJSONString(entryReqDto, JSONWriter.Feature.IgnoreEmpty);
|
|
||||||
String respBody = WechatReqUtils.postReq(configDto, "/v3/applyment4sub/applyment/", params);
|
|
||||||
JSONObject object = JSONObject.parseObject(respBody);
|
|
||||||
JSONObject data = object.getJSONObject("data");
|
|
||||||
log.info("微信进件结果:{}", respBody);
|
|
||||||
if (data != null) {
|
|
||||||
respDto.setStatus(PayCst.EntryStatus.INIT);
|
|
||||||
respDto.setEntryId(data.getString("applyment_id"));
|
|
||||||
respDto.setErrorMsg("");
|
|
||||||
} else {
|
|
||||||
respDto.setStatus(PayCst.EntryStatus.REJECTED);
|
|
||||||
respDto.setEntryId("");
|
|
||||||
respDto.setErrorMsg(object.getString("message"));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("微信进件报错:{}", e.getMessage(), e);
|
|
||||||
respDto.setStatus(PayCst.EntryStatus.REJECTED);
|
|
||||||
respDto.setEntryId("");
|
|
||||||
respDto.setErrorMsg(e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return respDto;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static JSONObject queryBankList(WechatPayConfigDto configDto, Integer offset, Integer limit) {
|
|
||||||
String resp = WechatReqUtils.getReq(configDto, "/v3/capital/capitallhh/banks/corporate-banking", Map.of("offset", offset, "limit", limit));
|
|
||||||
log.info("微信查询银行列表:{}", resp);
|
|
||||||
return JSONObject.parseObject(resp);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static JSONObject queryBankBranchList(WechatPayConfigDto configDto, String bankAliceCode, String cityCode, Integer offset, Integer limit) {
|
|
||||||
String resp = WechatReqUtils.getReq(configDto, "/v3/capital/capitallhh/banks/" + bankAliceCode + "/branches", Map.of("city_code", cityCode, "offset", offset, "limit", limit));
|
|
||||||
log.info("微信查询银行支行列表:{}", resp);
|
|
||||||
return JSONObject.parseObject(resp);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static JSONObject queryProvinceList(WechatPayConfigDto configDto) {
|
|
||||||
String resp = WechatReqUtils.getReq(configDto, "/v3/capital/capitallhh/areas/provinces", Map.of());
|
|
||||||
log.info("微信查询省份列表:{}", resp);
|
|
||||||
return JSONObject.parseObject(resp);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static JSONObject queryCityList(WechatPayConfigDto configDto, String provinceCode) {
|
|
||||||
String resp = WechatReqUtils.getReq(configDto, "/v3/capital/capitallhh/areas/provinces/" + provinceCode + "/cities", Map.of());
|
|
||||||
log.info("微信查询城市列表:{}", resp);
|
|
||||||
return JSONObject.parseObject(resp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 上传图片
|
|
||||||
*
|
|
||||||
* @param url 图片URL
|
|
||||||
* @return 图片ID
|
|
||||||
*/
|
|
||||||
public static String uploadImage(WechatPayConfigDto configDto, String url) {
|
|
||||||
if (configDto == null) {
|
|
||||||
configDto = WechatPayConfigDto.getDefaultConfig();
|
|
||||||
}
|
|
||||||
// 校验入参
|
|
||||||
if (url == null || url.trim().isEmpty()) {
|
|
||||||
log.error("上传图片失败:URL参数为空");
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
FileUploadService service = WechatConfig.getFileUploadService(configDto);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 获取图片字节数组
|
|
||||||
byte[] bytes = UploadFileUtil.downloadImage(url);
|
|
||||||
if (bytes.length == 0) {
|
|
||||||
log.error("下载的图片内容为空,URL:{}", url);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 计算SHA256
|
|
||||||
String sha256Hex = WechatEncrypt.getFileBytesSha256(bytes);
|
|
||||||
|
|
||||||
// 3. 构造元数据(从URL提取文件名,或自定义)
|
|
||||||
JSONObject meta = new JSONObject();
|
|
||||||
meta.put("sha256", sha256Hex);
|
|
||||||
// 从URL提取文件名,若提取失败则使用默认名
|
|
||||||
String fileName = UploadFileUtil.extractFileNameFromUrl(url);
|
|
||||||
meta.put("filename", fileName);
|
|
||||||
|
|
||||||
// 4. 上传图片到微信接口
|
|
||||||
FileUploadResponse uploadResponse = service.uploadImage(
|
|
||||||
configDto.getDomain() + "/v3/merchant/media/upload",
|
|
||||||
meta.toJSONString(),
|
|
||||||
fileName,
|
|
||||||
bytes
|
|
||||||
);
|
|
||||||
|
|
||||||
return uploadResponse.getMediaId();
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("微信上传图片报错,URL:{},错误信息:{}", url, e.getMessage(), e);
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建进件参数
|
|
||||||
*
|
|
||||||
* @param reqDto 请求参数
|
|
||||||
* @return 进件参数
|
|
||||||
*/
|
|
||||||
private static WechatEntryReqDto buildEntryParams(WechatPayConfigDto configDto, AggregateMerchantDto reqDto) {
|
|
||||||
WechatEntryReqDto entryParams = new WechatEntryReqDto();
|
|
||||||
|
|
||||||
Config config = WechatConfig.getRsaConfig(configDto);
|
|
||||||
PrivacyEncryptor encryptor = config.createEncryptor();
|
|
||||||
|
|
||||||
entryParams.setBusinessCode(reqDto.getMerchantCode());
|
|
||||||
|
|
||||||
MerchantBaseInfoDto baseInfo = reqDto.getMerchantBaseInfo();
|
|
||||||
LegalPersonInfoDto legalPersonInfo = reqDto.getLegalPersonInfo();
|
|
||||||
BusinessLicenceInfoDto businessLicenceInfo = reqDto.getBusinessLicenceInfo();
|
|
||||||
StoreInfoDto storeInfo = reqDto.getStoreInfo();
|
|
||||||
SettlementInfoDto settlementInfo = reqDto.getSettlementInfo();
|
|
||||||
|
|
||||||
WechatEntryContactReqDto contactInfo = new WechatEntryContactReqDto();
|
|
||||||
contactInfo.setContactType(baseInfo.getContactPersonType());
|
|
||||||
// 默认都使用身份证 暂不支持其他证件
|
|
||||||
contactInfo.setContactIdDocCopy("IDENTIFICATION_TYPE_IDCARD");
|
|
||||||
if (PayCst.ContactPersonType.SUPER.equals(baseInfo.getContactPersonType())) {
|
|
||||||
contactInfo.setContactName(encryptor.encrypt(baseInfo.getContactName()));
|
|
||||||
contactInfo.setContactIdNumber(encryptor.encrypt(baseInfo.getContactPersonId()));
|
|
||||||
contactInfo.setContactIdDocCopy(baseInfo.getContactIdCardFrontPic().getWechatId());
|
|
||||||
contactInfo.setContactIdDocCopyBack(baseInfo.getContactIdCardBackPic().getWechatId());
|
|
||||||
contactInfo.setContactPeriodBegin(baseInfo.getContactPersonIdStartDate());
|
|
||||||
contactInfo.setContactPeriodEnd(baseInfo.getContactPersonIdEndDate());
|
|
||||||
contactInfo.setMobilePhone(encryptor.encrypt(baseInfo.getContactPhone()));
|
|
||||||
contactInfo.setContactEmail(encryptor.encrypt(baseInfo.getContactEmail()));
|
|
||||||
} else if (PayCst.ContactPersonType.LEGAL.equals(baseInfo.getContactPersonType())) {
|
|
||||||
contactInfo.setContactName(encryptor.encrypt(legalPersonInfo.getLegalPersonName()));
|
|
||||||
contactInfo.setContactIdNumber(encryptor.encrypt(legalPersonInfo.getLegalPersonId()));
|
|
||||||
contactInfo.setContactIdDocCopy(legalPersonInfo.getIdCardFrontPic().getWechatId());
|
|
||||||
contactInfo.setContactIdDocCopyBack(legalPersonInfo.getIdCardBackPic().getWechatId());
|
|
||||||
contactInfo.setContactPeriodBegin(legalPersonInfo.getLegalIdPersonStartDate());
|
|
||||||
contactInfo.setContactPeriodEnd(legalPersonInfo.getLegalPersonIdEndDate());
|
|
||||||
contactInfo.setMobilePhone(encryptor.encrypt(legalPersonInfo.getLegalPersonPhone()));
|
|
||||||
contactInfo.setContactEmail(encryptor.encrypt(legalPersonInfo.getLegalPersonEmail()));
|
|
||||||
} else {
|
|
||||||
throw new CzgException("联系人类型错误");
|
|
||||||
}
|
|
||||||
entryParams.setContactInfo(contactInfo);
|
|
||||||
|
|
||||||
WechatEntrySubjectReqDto subjectInfo = new WechatEntrySubjectReqDto();
|
|
||||||
if ("0".equals(baseInfo.getUserType())) {
|
|
||||||
subjectInfo.setSubjectType("SUBJECT_TYPE_INDIVIDUAL");
|
|
||||||
} else if ("1".equals(baseInfo.getUserType())) {
|
|
||||||
switch (baseInfo.getCompanyChildType()) {
|
|
||||||
case "1" -> subjectInfo.setSubjectType("SUBJECT_TYPE_ENTERPRISE");
|
|
||||||
case "2" -> subjectInfo.setSubjectType("SUBJECT_TYPE_INSTITUTIONS");
|
|
||||||
case "3" -> subjectInfo.setSubjectType("SUBJECT_TYPE_GOVERNMENT");
|
|
||||||
case "4" -> subjectInfo.setSubjectType("SUBJECT_TYPE_OTHERS");
|
|
||||||
default -> throw new CzgException("主体类型错误");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new CzgException("用户类型错误");
|
|
||||||
}
|
|
||||||
subjectInfo.setFinanceInstitution(false);
|
|
||||||
|
|
||||||
WechatEntryLicenseReqDto licenseReqDto = new WechatEntryLicenseReqDto();
|
|
||||||
licenseReqDto.setLicenseCopy(businessLicenceInfo.getLicensePic().getWechatId());
|
|
||||||
licenseReqDto.setLicenseNumber(businessLicenceInfo.getLicenceNo());
|
|
||||||
licenseReqDto.setMerchantName(businessLicenceInfo.getLicenceName());
|
|
||||||
licenseReqDto.setLegalPerson(legalPersonInfo.getLegalPersonName());
|
|
||||||
licenseReqDto.setLicenseAddress(businessLicenceInfo.getRegisteredAddress());
|
|
||||||
licenseReqDto.setPeriodBegin(businessLicenceInfo.getLicenceStartDate());
|
|
||||||
licenseReqDto.setPeriodEnd(businessLicenceInfo.getLicenceEndDate());
|
|
||||||
subjectInfo.setBusinessLicenseInfo(licenseReqDto);
|
|
||||||
WechatEntryIdentityReqDto identityInfo = new WechatEntryIdentityReqDto();
|
|
||||||
identityInfo.setIdHolderType(PayCst.ContactPersonType.LEGAL);
|
|
||||||
subjectInfo.setIdentityInfo(identityInfo);
|
|
||||||
entryParams.setSubjectInfo(subjectInfo);
|
|
||||||
|
|
||||||
WechatEntryBusinessReqDto businessReqInfo = new WechatEntryBusinessReqDto();
|
|
||||||
businessReqInfo.setMerchantShortname(baseInfo.getShortName());
|
|
||||||
businessReqInfo.setServicePhone(PayCst.ContactPersonType.LEGAL.equals(baseInfo.getContactPersonType()) ? legalPersonInfo.getLegalPersonPhone() : baseInfo.getContactPhone());
|
|
||||||
WechatEntrySalesInfoReqDto salesInfo = new WechatEntrySalesInfoReqDto();
|
|
||||||
salesInfo.setSalesScenesType(List.of("SALES_SCENES_STORE", "SALES_SCENES_MINI_PROGRAM"));
|
|
||||||
WechatEntryStoreInfoReqDto bizStoreInfo = new WechatEntryStoreInfoReqDto();
|
|
||||||
bizStoreInfo.setBizStoreName(baseInfo.getShortName());
|
|
||||||
bizStoreInfo.setBizAddressCode(storeInfo.getMercAreaCode());
|
|
||||||
bizStoreInfo.setBizStoreAddress(storeInfo.getBusinessAddress());
|
|
||||||
bizStoreInfo.setStoreEntrancePic(List.of(storeInfo.getDoorPic().getWechatId()));
|
|
||||||
bizStoreInfo.setIndoorPic(List.of(storeInfo.getInsidePic().getWechatId(), storeInfo.getCashierDeskPic().getWechatId()));
|
|
||||||
salesInfo.setBizStoreInfo(bizStoreInfo);
|
|
||||||
WechatEntryMiniProgramReqDto miniProgramInfo = new WechatEntryMiniProgramReqDto();
|
|
||||||
miniProgramInfo.setMiniProgramAppid("wxd88fffa983758a30");
|
|
||||||
salesInfo.setMiniProgramInfo(miniProgramInfo);
|
|
||||||
businessReqInfo.setSalesInfo(salesInfo);
|
|
||||||
entryParams.setBusinessInfo(businessReqInfo);
|
|
||||||
|
|
||||||
WechatEntrySettleReqDto settlementReqInfo = new WechatEntrySettleReqDto();
|
|
||||||
settlementReqInfo.setSettlementId("0".equals(baseInfo.getUserType()) ? "719" : "716");
|
|
||||||
settlementReqInfo.setQualificationType("餐饮");
|
|
||||||
settlementReqInfo.setActivitiesId("20191030111cff5b5e");
|
|
||||||
settlementReqInfo.setActivitiesRate("0.38");
|
|
||||||
entryParams.setSettlementInfo(settlementReqInfo);
|
|
||||||
|
|
||||||
WechatEntryBankAccountReqDto bankAccountReqInfo = new WechatEntryBankAccountReqDto();
|
|
||||||
bankAccountReqInfo.setBankAccountType("21".equals(settlementInfo.getSettlementCardType()) ? "BANK_ACCOUNT_TYPE_CORPORATE" : "BANK_ACCOUNT_TYPE_PERSONAL");
|
|
||||||
bankAccountReqInfo.setAccountName(encryptor.encrypt(settlementInfo.getSettlementName()));
|
|
||||||
bankAccountReqInfo.setAccountBank(settlementInfo.getBankName());
|
|
||||||
bankAccountReqInfo.setBankBranchId(settlementInfo.getBankBranchCode());
|
|
||||||
bankAccountReqInfo.setBankName(settlementInfo.getBankBranchName());
|
|
||||||
bankAccountReqInfo.setAccountNumber(encryptor.encrypt(settlementInfo.getSettlementCardNo()));
|
|
||||||
entryParams.setBankAccountInfo(bankAccountReqInfo);
|
|
||||||
|
|
||||||
return entryParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
|
||||||
|
|
||||||
|
|
||||||
queryMerchantEntryStatus(null, "20220106000000000001");
|
|
||||||
|
|
||||||
// int offset = 0;
|
|
||||||
// Integer limit = 100;
|
|
||||||
// JSONObject resp = queryBankList(null, offset, limit);
|
|
||||||
|
|
||||||
// queryBankBranchList(dto, "1000009561", "110000", offset, limit);
|
|
||||||
// queryBankBranchList(dto, "1000009561", "29", offset, limit);
|
|
||||||
|
|
||||||
// queryProvinceList(dto);
|
|
||||||
// queryCityList(dto, "28");
|
|
||||||
|
|
||||||
|
|
||||||
// String string = uploadImage(dto, "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png");
|
|
||||||
// log.info("图片上传成功:{}", string);
|
|
||||||
|
|
||||||
// Config config = WechatConfig.getRsaConfig(dto);
|
|
||||||
// PrivacyEncryptor encryptor = config.createEncryptor();
|
|
||||||
//
|
|
||||||
// WechatEntryReqDto reqDto = new WechatEntryReqDto()
|
|
||||||
// .setBusinessCode("MER_20231025110010000010000000000001");
|
|
||||||
//
|
|
||||||
// WechatEntryContactReqDto contactInfo = new WechatEntryContactReqDto()
|
|
||||||
// .setContactType("LEGAL")
|
|
||||||
// .setContactName(encryptor.encrypt("张三"))
|
|
||||||
// .setContactIdType("IDCARD")
|
|
||||||
// .setContactIdNumber(encryptor.encrypt("110101199001011234"))
|
|
||||||
// .setContactIdDocCopy("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png")
|
|
||||||
// .setContactIdDocCopyBack("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png")
|
|
||||||
// .setContactPeriodBegin("2023-10-25")
|
|
||||||
// .setContactPeriodEnd("2024-10-25")
|
|
||||||
// .setMobilePhone(encryptor.encrypt("13888888888"))
|
|
||||||
// .setContactEmail(encryptor.encrypt("123456@qq.com"));
|
|
||||||
//
|
|
||||||
// reqDto.setContactInfo(contactInfo);
|
|
||||||
//
|
|
||||||
// WechatEntrySubjectReqDto subjectInfo = new WechatEntrySubjectReqDto()
|
|
||||||
// .setSubjectType("SUBJECT_TYPE_INDIVIDUAL");
|
|
||||||
//
|
|
||||||
// WechatEntryLicenseReqDto licenseInfo = new WechatEntryLicenseReqDto()
|
|
||||||
// .setLicenseCopy("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png")
|
|
||||||
// .setLicenseNumber("110101199001011234")
|
|
||||||
// .setMerchantName("张三商行")
|
|
||||||
// .setLegalPerson(encryptor.encrypt("张三"))
|
|
||||||
// .setLicenseAddress("北京")
|
|
||||||
// .setPeriodBegin("2023-10-25")
|
|
||||||
// .setPeriodEnd("2024-10-25");
|
|
||||||
// subjectInfo.setBusinessLicenseInfo(licenseInfo);
|
|
||||||
//
|
|
||||||
// WechatEntryIdentityReqDto identityInfo = new WechatEntryIdentityReqDto()
|
|
||||||
// .setIdHolderType("LEGAL");
|
|
||||||
// subjectInfo.setIdentityInfo(identityInfo);
|
|
||||||
//
|
|
||||||
// reqDto.setSubjectInfo(subjectInfo);
|
|
||||||
//
|
|
||||||
// WechatEntryBusinessReqDto businessInfo = new WechatEntryBusinessReqDto()
|
|
||||||
// .setMerchantShortname("张三商行")
|
|
||||||
// .setServicePhone("13888888888");
|
|
||||||
// WechatEntrySalesInfoReqDto salesInfo = new WechatEntrySalesInfoReqDto()
|
|
||||||
// .setSalesScenesType(List.of("SALES_SCENES_STORE"));
|
|
||||||
// WechatEntryStoreInfoReqDto storeInfo = new WechatEntryStoreInfoReqDto()
|
|
||||||
// .setBizStoreName("张三商行")
|
|
||||||
// .setBizAddressCode("110101")
|
|
||||||
// .setBizStoreAddress("北京")
|
|
||||||
// .setStoreEntrancePic(List.of("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"))
|
|
||||||
// .setIndoorPic(List.of("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"));
|
|
||||||
// salesInfo.setBizStoreInfo(storeInfo);
|
|
||||||
// businessInfo.setSalesInfo(salesInfo);
|
|
||||||
//
|
|
||||||
// reqDto.setBusinessInfo(businessInfo);
|
|
||||||
//
|
|
||||||
// WechatEntrySettleReqDto settleInfo = new WechatEntrySettleReqDto()
|
|
||||||
// .setSettlementId("719")
|
|
||||||
// .setQualificationType("IDCARD")
|
|
||||||
// .setQualifications(List.of("110101199001011234"))
|
|
||||||
// .setActivitiesId("20191030111cff5b5e");
|
|
||||||
//
|
|
||||||
// reqDto.setSettlementInfo(settleInfo);
|
|
||||||
//
|
|
||||||
// WechatEntryBankAccountReqDto bankAccountInfo = new WechatEntryBankAccountReqDto()
|
|
||||||
// .setBankAccountType("BANK_ACCOUNT_TYPE_CORPORATE")
|
|
||||||
// .setAccountBank("ICBC")
|
|
||||||
// .setBankName("中国工商银行")
|
|
||||||
// .setAccountName(encryptor.encrypt("张三"))
|
|
||||||
// .setAccountNumber(encryptor.encrypt("110101199001011234"));
|
|
||||||
//
|
|
||||||
// reqDto.setBankAccountInfo(bankAccountInfo);
|
|
||||||
|
|
||||||
// entryMerchant(dto, reqDto);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package com.czg.third.wechat;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 09:15
|
|
||||||
*/
|
|
||||||
public class WechatPayManager {
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
package com.czg.third.wechat;
|
|
||||||
|
|
||||||
import cn.hutool.http.HttpRequest;
|
|
||||||
import cn.hutool.http.HttpResponse;
|
|
||||||
import cn.hutool.http.HttpUtil;
|
|
||||||
import com.czg.exception.CzgException;
|
|
||||||
import com.czg.third.wechat.dto.config.WechatPayConfigDto;
|
|
||||||
import com.wechat.pay.java.core.Config;
|
|
||||||
import com.wechat.pay.java.core.cipher.Signer;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信请求工具类
|
|
||||||
*
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/29 10:02
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class WechatReqUtils {
|
|
||||||
|
|
||||||
public static String postReq(WechatPayConfigDto configDto, String url, String body) {
|
|
||||||
return req(configDto, url, "POST", body);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getReq(WechatPayConfigDto configDto, String url, Map<String, Object> params) {
|
|
||||||
url = Arrays.stream(params.entrySet().toArray(new Map.Entry[0]))
|
|
||||||
.map(entry -> entry.getKey() + "=" + URLEncoder.encode(entry.getValue().toString(), StandardCharsets.UTF_8))
|
|
||||||
.collect(Collectors.joining("&", url + "?", ""));
|
|
||||||
|
|
||||||
// 如果最后没有参数,则去掉多余的 "?"
|
|
||||||
url = url.endsWith("?") ? url.substring(0, url.length() - 1) : url;
|
|
||||||
|
|
||||||
return req(configDto, url, "GET", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String req(WechatPayConfigDto configDto, String url, String method, String body) {
|
|
||||||
if (configDto == null) {
|
|
||||||
configDto = WechatPayConfigDto.getDefaultConfig();
|
|
||||||
}
|
|
||||||
long timestamp = getTimestamp();
|
|
||||||
String nonce = getNonceStr();
|
|
||||||
String signature = encryptReqParam(configDto, method, url, body, timestamp, nonce);
|
|
||||||
String authorization = String.format("WECHATPAY2-SHA256-RSA2048 mchid=\"%s\",nonce_str=\"%s\",signature=\"%s\",timestamp=\"%d\",serial_no=\"%s\"",
|
|
||||||
configDto.getMerchantId(), nonce, signature, timestamp, configDto.getSerialNumber());
|
|
||||||
|
|
||||||
HttpRequest request = switch (method) {
|
|
||||||
case "POST" -> HttpUtil.createPost(configDto.getDomain() + url)
|
|
||||||
.header("Authorization", authorization)
|
|
||||||
.header("Content-Type", "application/json")
|
|
||||||
.header("Wechatpay-Serial", configDto.getPublicKeyId())
|
|
||||||
.body(body);
|
|
||||||
|
|
||||||
case "GET" -> HttpUtil.createGet(configDto.getDomain() + url)
|
|
||||||
.header("Authorization", authorization)
|
|
||||||
.header("Content-Type", "application/json")
|
|
||||||
.header("Wechatpay-Serial", configDto.getPublicKeyId());
|
|
||||||
default -> throw new CzgException("不支持的请求方法");
|
|
||||||
};
|
|
||||||
HttpResponse response = request.execute();
|
|
||||||
String s = response.body();
|
|
||||||
log.info("微信支付请求:url = {}, method: {}, body: {}, resp: {}", url, method, body, s);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 加密请求参数
|
|
||||||
*
|
|
||||||
* @param configDto 配置
|
|
||||||
* @param method 请求方法
|
|
||||||
* @param url 请求地址
|
|
||||||
* @param body 请求报文主体
|
|
||||||
* @return 加密后的报文
|
|
||||||
* <p>
|
|
||||||
* 签名方法
|
|
||||||
* HTTP请求方法\n
|
|
||||||
* URL\n
|
|
||||||
* 请求时间戳\n
|
|
||||||
* 请求随机串\n
|
|
||||||
* 请求报文主体\n
|
|
||||||
*/
|
|
||||||
public static String encryptReqParam(WechatPayConfigDto configDto, String method, String url, String body, long timestamp, String nonce) {
|
|
||||||
String encryptStr = String.format("%s\n%s\n%d\n%s\n%s\n",
|
|
||||||
method, url, timestamp, nonce, body);
|
|
||||||
|
|
||||||
Config config = WechatConfig.getRsaConfig(configDto);
|
|
||||||
Signer signer = config.createSigner();
|
|
||||||
String signature = signer.sign(encryptStr).getSign();
|
|
||||||
log.info("微信签名 encryptStr = {},\nsignature:{}", encryptStr, signature);
|
|
||||||
return signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取随机串
|
|
||||||
*/
|
|
||||||
private static String getNonceStr() {
|
|
||||||
return UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取时间戳
|
|
||||||
*/
|
|
||||||
private static long getTimestamp() {
|
|
||||||
return System.currentTimeMillis() / 1000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.config;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 09:21
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatPayConfigDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商户号
|
|
||||||
*/
|
|
||||||
private String merchantId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Api V3密钥
|
|
||||||
*/
|
|
||||||
private String apiV3Key;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商户证书序列号
|
|
||||||
*/
|
|
||||||
private String serialNumber;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商户私钥
|
|
||||||
*/
|
|
||||||
private String privateKey;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商户公钥
|
|
||||||
*/
|
|
||||||
private String publicKey;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商户公钥 ID
|
|
||||||
*/
|
|
||||||
private String publicKeyId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信支付域名
|
|
||||||
* <a href="https://api.mch.weixin.qq.com"></a>
|
|
||||||
*/
|
|
||||||
private String domain;
|
|
||||||
|
|
||||||
public static WechatPayConfigDto getDefaultConfig() {
|
|
||||||
return new WechatPayConfigDto()
|
|
||||||
.setMerchantId("1643779408")
|
|
||||||
.setApiV3Key("a92baac5eb7a36ed8ec198113e769a03")
|
|
||||||
.setSerialNumber("4DE9BAC2EA584C3F274F694C9753CA814C4E9BF4")
|
|
||||||
.setPublicKey("""
|
|
||||||
-----BEGIN PUBLIC KEY-----
|
|
||||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtbeWXEEjBaYtw2OyM+SC
|
|
||||||
aCEMbryRXi4duKxx3vYG4rUVix+d5/Jz7Khev4Upml9zC+Xxvv/G9bHWAUyolzqD
|
|
||||||
wefahGurIxr43r4GJVnQ4i5G6BbBVw5d4Vuz0y/9Zd14zmc/EmBpT0Ml26H7tOZl
|
|
||||||
n1LSbQ4xNFkrRKrNEcExBLxkCd+K5K2TREZznywIi0izbHImvuzM8IneuR51FiqK
|
|
||||||
pdFnAjTwb126EIj6ECkL6KLCl8RWqpfiX8SFiolSQLs1/w79O0sIUk96X2zWpnoW
|
|
||||||
rTDFatPif/VEKl3y2dTlxxDxoZtVi48yTDW00OMzVl5D67oX3FVK0KsjHJSCfGlZ
|
|
||||||
6wIDAQAB
|
|
||||||
-----END PUBLIC KEY-----""")
|
|
||||||
.setPrivateKey("""
|
|
||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDqnAZhTxT572fo
|
|
||||||
6wvSr8Rt0vRXg+EFKC6UvUiNE24oocQU5fjedX9KL/+fmoqay/xqIxvxvCNFTs4J
|
|
||||||
zlMqavSl6bMWCpjvf/Ry82JmN1v2kJEO4lgP8BsEiqlUpObCH8BMAVUOn1j+9q4Q
|
|
||||||
uZJJcbtRvec2fNweDM8EJp4B7RlUdDbHm86lfcDVp8iini7VjDp6D7aHT+C8A8OT
|
|
||||||
ugxQIquDec778wVd9r2Sv3+t6rAzFs+n+Zu++2xtFEPhO5N0wjrLHaukl+9crU+1
|
|
||||||
lktjDzcPd07SwGZ+A+3BTmW3UCramI3506e/3MWBECB7ge+gM4URAV0nJJCLH/Im
|
|
||||||
WgEvPMr5AgMBAAECggEBAKv+wraoMWqiVv1tA/froAgbtcJLDranJK8qrXuvmPz0
|
|
||||||
yzm+91qvrSgIVFEADUk67swo/R2Vng37nhWWS2Y3jy/rSr2H+2Lp3Z5ATA0/3I3A
|
|
||||||
onfU/FaC4mvL9CP32KzMdj/CYkccDzSsSCQ+x75MQNXGcTGDDCSDo2kZnpEu73j3
|
|
||||||
aqvO1jbqTGWigRfjOIaIhStjQIT8nEm/3mJ4f5dM9M6FMz33mhax8EahSgvdahYB
|
|
||||||
t45iaGOWw81OJhmry47EvpwjXBl7jtO2HX3LiLbq5Ebcwu1zqDz5NM7ttnnGAqWC
|
|
||||||
6y7JN5Vt4wPYrCydiUDe7dj0looffr2yw6MkNfYjLGECgYEA+FAvbEInQEi9YguS
|
|
||||||
CQtLHngqvYeai66tvyykog9o38KHnPGx2Myf+rn/Hcp7KNRfjd5G34CCNg7KLnrx
|
|
||||||
YIYh6+2bY3jirzdYUxuNKGbvM4gky/6M/P9zHF/uALKOE02yArdqemf4UxUvrYCc
|
|
||||||
JdXsAMqvbpdvW1aGgNRB32YCkG0CgYEA8d89vawsCjNCEUh0VWTMoBLFoex3qBMZ
|
|
||||||
rfzYQeBo6bDCRlAlUVzl+ouBUxSYxP/U8rzeNaRzGUwRLmlGMjyIr58FBlHsg2cR
|
|
||||||
DlsX3HVCUjpS6sgPXOqakdiLfhMcHZAspislSyVfeS3TbUWiA45+5PuNUq+EZYwl
|
|
||||||
ESsB1+yfRT0CgYEA0Ct49ksnWM8iZbXJgeeD3FFlk2rBd2TDqEem5W4Bv8T3p+0/
|
|
||||||
6b7yR2HyrGj5gys3yFmWFP1JLESN3xWWkhMhEQcrg+LuN3Iwi8vHNR3GXu892f7W
|
|
||||||
96q4OAt8Hf2S+j/igkB99YyANDbIt63gOh/zMF67X/14j5wkOpC3gK+maqkCgYEA
|
|
||||||
s7nIrPoUt3ejLiiCmTmPe5q3VDzcJP4cZNau8zSHgK6hjZHcSPsYwPWMoWl6o1fe
|
|
||||||
qoiBLacHB9MoKS58xLOKdcVZ/Ho/ntylJd+2eVCAeY1xM5h5IfgJ5znbXVFh4O3S
|
|
||||||
357L1Wzt5qOQqW/GlZH65LevKbPWU4axvHISqpnfN5kCgYEAqiqLuAPu84VSsqsE
|
|
||||||
GFh25t+1f0JY1sNfilE3/t9AdQeeCFv/5z9KB1kMt3a5ZFeVonsFIvCyaOJjhSkj
|
|
||||||
4HCB94vWS7NuN5G9r874lMaPbZYQGwrcVaf265tN7cYYr3gUx1qB6+u+fh/kcft1
|
|
||||||
BBmTzhb0zp5k8ngwAkA1g/LK204=
|
|
||||||
-----END PRIVATE KEY-----""")
|
|
||||||
.setPublicKeyId("PUB_KEY_ID_0116437794082025111000382377001000")
|
|
||||||
.setDomain("https://api.mch.weixin.qq.com");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.req.entry;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信进件-补充信息
|
|
||||||
*
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 13:43
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatEntryAdditionReqDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 法定代表人开户承诺函
|
|
||||||
* 模板下载地址 <a href="https://kf.qq.com/faq/191018yUFjEj191018Vfmaei.html">...</a>
|
|
||||||
* 通过图片上传完成后 MediaID
|
|
||||||
*/
|
|
||||||
@JSONField(name = "legal_person_commitment")
|
|
||||||
private String legalPersonCommitment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 法定代表人开户意愿视频
|
|
||||||
* 通过视频上传完成后 MediaID
|
|
||||||
*/
|
|
||||||
@JSONField(name = "legal_person_video")
|
|
||||||
private String legalPersonVideo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 补充材料
|
|
||||||
* 最多可上传5张照片
|
|
||||||
* 通过图片上传完成后 MediaID
|
|
||||||
*/
|
|
||||||
@JSONField(name = "business_addition_pics")
|
|
||||||
private List<String> businessAdditionPics;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 补充说明 512字以内
|
|
||||||
*/
|
|
||||||
@JSONField(name = "business_addition_msg")
|
|
||||||
private String businessAdditionMsg;
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.req.entry;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信进件-银行账号
|
|
||||||
*
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 13:42
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatEntryBankAccountReqDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 账户类型
|
|
||||||
* 1、若主体为企业/政府机关/事业单位/社会组织,可填写:对公银行账户;
|
|
||||||
* 2、若主体为个体户,可选择填写:对公银行账户或经营者个人银行卡
|
|
||||||
* 可选取值 BANK_ACCOUNT_TYPE_CORPORATE: 对公银行账户 BANK_ACCOUNT_TYPE_PERSONAL: 经营者个人银行卡
|
|
||||||
*/
|
|
||||||
@JSONField(name = "bank_account_type")
|
|
||||||
private String bankAccountType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 开户名称
|
|
||||||
* 1、选择“经营者个人银行卡”时,开户名称必须与“经营者证件姓名”一致;
|
|
||||||
* 2、选择“对公银行账户”时,开户名称必须与营业执照上的“商户名称”一致;
|
|
||||||
* 3、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。
|
|
||||||
* <a href="https://pay.weixin.qq.com/doc/v3/partner/4013059044">...</a>
|
|
||||||
*/
|
|
||||||
@JSONField(name = "account_name")
|
|
||||||
private String accountName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 开户银行
|
|
||||||
* 对私银行调用:查询支持个人业务的银行列表API
|
|
||||||
* 对公银行调用:查询支持对公业务的银行列表API
|
|
||||||
*/
|
|
||||||
@JSONField(name = "account_bank")
|
|
||||||
private String accountBank;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 开户银行银行号
|
|
||||||
* 1、根据开户银行查询接口中的“是否需要填写支行”判断是否需要填写。如为其他银行,开户银行全称(含支行)和开户银行联行号二选一;
|
|
||||||
* 2、详细需调用查询支行列表API查看查询结果。 <a href="https://pay.weixin.qq.com/doc/v3/partner/4012697673">...</a>
|
|
||||||
*/
|
|
||||||
@JSONField(name = "bank_branch_id")
|
|
||||||
private String bankBranchId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 开户银行全称(含支行)
|
|
||||||
* 1、根据开户银行查询接口中的“是否需要填写支行”判断是否需要填写。如为其他银行,开户银行全称(含支行)和开户银行联行号二选一;
|
|
||||||
* 2、详细需调用查询支行列表API查看查询结果。 <a href="https://pay.weixin.qq.com/doc/v3/partner/4012697673">...</a>
|
|
||||||
*/
|
|
||||||
@JSONField(name = "bank_name")
|
|
||||||
private String bankName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 开户银行账号
|
|
||||||
* 1、选择“经营者个人银行卡”时,开户账号为经营者个人银行卡号;
|
|
||||||
* 2、选择“对公银行账户”时,开户账号为对公银行账号;
|
|
||||||
* 3、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。
|
|
||||||
* <a href="https://pay.weixin.qq.com/doc/v3/partner/4013059044">...</a>
|
|
||||||
*/
|
|
||||||
@JSONField(name = "account_number")
|
|
||||||
private String accountNumber;
|
|
||||||
}
|
|
||||||
@@ -1,139 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.req.entry;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进件 联系人信息
|
|
||||||
*
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 13:38
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatEntryContactReqDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 超级管理员类型
|
|
||||||
* 主体为“个体工商户/企业/政府机关/事业单位/社会组织”,可选择:LEGAL:经营者/法定代表人,SUPER:经办人 。(经办人:经商户授权办理微信支付业务的人员)。
|
|
||||||
* 可选取值
|
|
||||||
* LEGAL: 经营者/法定代表人
|
|
||||||
* SUPER: 经办人
|
|
||||||
*/
|
|
||||||
@JSONField(name = "contact_type")
|
|
||||||
private String contactType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 超级管理员姓名
|
|
||||||
* 1、长度为2-100个字符;
|
|
||||||
* 2、前后不能有空格、制表符、换行符;
|
|
||||||
* 3、不能仅含数字、特殊字符;
|
|
||||||
* 4、仅能填写数字、英文字母、汉字及特殊字符。
|
|
||||||
* 该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "contact_name")
|
|
||||||
private String contactName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 超级管理员证件类型 当超级管理员类型是经办人时,请上传超级管理员证件类型。
|
|
||||||
* 可选取值
|
|
||||||
* IDENTIFICATION_TYPE_IDCARD: 中国大陆居民-身份证
|
|
||||||
* IDENTIFICATION_TYPE_OVERSEA_PASSPORT: 其他国家或地区居民-护照
|
|
||||||
* IDENTIFICATION_TYPE_HONGKONG_PASSPORT: 中国香港居民-来往内地通行证
|
|
||||||
* IDENTIFICATION_TYPE_MACAO_PASSPORT: 中国澳门居民-来往内地通行证
|
|
||||||
* IDENTIFICATION_TYPE_TAIWAN_PASSPORT: 中国台湾居民-来往大陆通行证
|
|
||||||
* IDENTIFICATION_TYPE_FOREIGN_RESIDENT: 外国人居留证
|
|
||||||
* IDENTIFICATION_TYPE_HONGKONG_MACAO_RESIDENT: 港澳居民居住证
|
|
||||||
* IDENTIFICATION_TYPE_TAIWAN_RESIDENT: 台湾居民居住证
|
|
||||||
*/
|
|
||||||
@JSONField(name = "contact_id_type")
|
|
||||||
private String contactIdType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 超级管理员身份证件号码
|
|
||||||
* 1、当超级管理员类型是经办人时,请上传超级管理员证件号码;
|
|
||||||
* 2、可传身份证、来往内地通行证、来往大陆通行证、护照等证件号码,号码规范如下:
|
|
||||||
* 身份证(限中国大陆居民):17位数字+1位数字|X;
|
|
||||||
* 护照(限境外人士):4-15位 数字|字母|连字符;
|
|
||||||
* 中国香港居民--来往内地通行证:H/h开头+8或10位数字/字母;
|
|
||||||
* 中国澳门居民--来往内地通行证:M/m开头+8或10位数字/字母;
|
|
||||||
* 中国台湾居民--来往大陆通行证:8位数字或10位数字;
|
|
||||||
* 外国人居留证:15位 数字|字母;
|
|
||||||
* 台湾居民居住证/港澳居民居住证:17位数字+1位数字|X;
|
|
||||||
* 3、超级管理员签约时,校验微信号绑定的银行卡实名信息,是否与该证件号码一致;
|
|
||||||
* 4、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "contact_id_number")
|
|
||||||
private String contactIdNumber;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 超级管理员证件正面照片
|
|
||||||
* 1、当超级管理员类型是经办人时,请上传超级管理员证件的正面照片;
|
|
||||||
* 2、若证件类型为身份证,请上传人像面照片;
|
|
||||||
* 3、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS;
|
|
||||||
* 4、请上传彩色照片或彩色扫描件或复印件(需加盖公章鲜章),可添加“微信支付”相关水印(如微信支付认证),见【指引文档】;
|
|
||||||
* 5、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "contact_id_doc_copy")
|
|
||||||
private String contactIdDocCopy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 超级管理员证件反面照片
|
|
||||||
* 1、当超级管理员类型是经办人时,请上传超级管理员证件的反面照片;
|
|
||||||
* 2、若证件类型为护照,无需上传反面照片;
|
|
||||||
* 3、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS;
|
|
||||||
* 4、请上传彩色照片或彩色扫描件,复印件需加盖公章鲜章,可添加“微信支付”相关水印(如微信支付认证),见【指引文档】;
|
|
||||||
* 5、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "contact_id_doc_copy_back")
|
|
||||||
private String contactIdDocCopyBack;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 超级管理员证件有效期开始时间
|
|
||||||
* 1、当超级管理员类型是经办人时,请上传证件有效期开始时间;
|
|
||||||
* 2、请按照示例值填写,日期格式应满足合法的YYYY-MM-DD格式;
|
|
||||||
* 3、开始时间不能小于1900-01-01,开始时间不能大于等于当前日期。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "contact_period_begin")
|
|
||||||
private String contactPeriodBegin;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 超级管理员证件有效期截止时间
|
|
||||||
* 1、当超级管理员类型是经办人时,请上传证件有效期结束时间;
|
|
||||||
* 2、请按照示例值填写,日期格式应满足合法的YYYY-MM-DD格式,若证件有效期为长期,请填写:长期;
|
|
||||||
* 3、结束时间大于开始时间。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "contact_period_end")
|
|
||||||
private String contactPeriodEnd;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 联系手机
|
|
||||||
* 1、前后不能有空格、制表符、换行符;
|
|
||||||
* 2、需满足以下任一条件:
|
|
||||||
* 11位数字的手机号码;
|
|
||||||
* 5-20位数字、连字符“-”、加号“+”;
|
|
||||||
* 3、用于接收微信支付的重要管理信息及日常操作验证码;
|
|
||||||
* 4、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "mobile_phone")
|
|
||||||
private String mobilePhone;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 联系邮箱
|
|
||||||
* 1、用于接收微信支付的开户邮件及日常业务通知;
|
|
||||||
* 2、需要带@,遵循邮箱格式校验 ,该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "contact_email")
|
|
||||||
private String contactEmail;
|
|
||||||
}
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.req.entry;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import com.czg.third.wechat.dto.req.entry.business.WechatEntryBusinessReqDto;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信进件请求参数
|
|
||||||
* 参考地址 <a href="https://pay.weixin.qq.com/doc/v3/partner/4012719997">...</a>
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 13:36
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatEntryReqDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 业务申请编号
|
|
||||||
*/
|
|
||||||
@JSONField(name = "business_code")
|
|
||||||
private String businessCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 超级管理员信息
|
|
||||||
*/
|
|
||||||
@JSONField(name = "contact_info")
|
|
||||||
private WechatEntryContactReqDto contactInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 主体资料
|
|
||||||
*/
|
|
||||||
@JSONField(name = "subject_info")
|
|
||||||
private WechatEntrySubjectReqDto subjectInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 经营资料
|
|
||||||
* 商家的经营业务信息、售卖商品/提供服务场景信息
|
|
||||||
*/
|
|
||||||
@JSONField(name = "business_info")
|
|
||||||
private WechatEntryBusinessReqDto businessInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 结算规则
|
|
||||||
* 请填写商家的结算费率规则、特殊资质等信息
|
|
||||||
*/
|
|
||||||
@JSONField(name = "settlement_info")
|
|
||||||
private WechatEntrySettleReqDto settlementInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 结算银行账户
|
|
||||||
*/
|
|
||||||
@JSONField(name = "bank_account_info")
|
|
||||||
private WechatEntryBankAccountReqDto bankAccountInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 补充材料
|
|
||||||
* 根据实际审核情况,会额外要求商家提供指定的补充资料
|
|
||||||
*/
|
|
||||||
@JSONField(name = "addition_info")
|
|
||||||
private WechatEntryAdditionReqDto additionInfo;
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.req.entry;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进件 结算信息
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 13:38
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatEntrySettleReqDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 入驻结算规则ID
|
|
||||||
* 请选择结算规则ID,详细参见费率结算规则对照表
|
|
||||||
* <a href="https://kf.qq.com/faq/220228IJb2UV220228uEjU3Q.html">...</a>
|
|
||||||
*/
|
|
||||||
@JSONField(name = "settlement_id")
|
|
||||||
private String settlementId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 所属行业
|
|
||||||
* <a href="https://kf.qq.com/faq/220228IJb2UV220228uEjU3Q.html">...</a>
|
|
||||||
*/
|
|
||||||
@JSONField(name = "qualification_type")
|
|
||||||
private String qualificationType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 特殊资质图片
|
|
||||||
* 1、仅当商户选择了必需提交特殊资质的行业时,需要提供该项资料;若商户选择了无需特殊资质的行业,或未选择行业时,无需提交该项资料,详情查看《费率结算规则对照表》;
|
|
||||||
* 2、最多可上传5张照片,请填写通过图片上传API预先上传图片生成好的MediaID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "qualifications")
|
|
||||||
private List<String> qualifications;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 优惠费率活动ID
|
|
||||||
* 如果商户有意向报名优惠费率活动,该字段【必填】。详细参见《优惠费率活动对照表》
|
|
||||||
* <a href="https://pay.weixin.qq.com/doc/v3/partner/4012082816">...</a>
|
|
||||||
*/
|
|
||||||
@JSONField(name = "activities_id")
|
|
||||||
private String activitiesId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 优惠费率活动值
|
|
||||||
* 根据优惠费率活动规则,由合作伙伴自定义填写,支持两个小数点,需在优惠费率活动ID指定费率范围内
|
|
||||||
* (1)2023年7月17日-9月17日,各合作伙伴平台可选择只传入“活动费率值”,或分别传入“信用卡优惠活动费率值” 与 “非信用卡优惠活动费率值”,只传入“活动费率值”的情况下,平台将协助将申请单中的 “优惠活动费率值” 回填入新增的 “信用卡优惠活动费率值” 与 “非信用卡优惠活动费率值”中 ;
|
|
||||||
* (2)2023年9月18日起,平台将不再提供如上兼容能力,届时仅能分别传入“信用卡优惠活动费率值” 与 “非信用卡优惠活动费率值”,否则接口将会报错。为避免影响正常进件,请在兼容期间完成相关调整。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "activities_rate")
|
|
||||||
private String activitiesRate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 优惠费率活动补充材料
|
|
||||||
* 1、根据所选优惠费率活动,提供相关材料,详细参见《优惠费率活动对照表》;<a href="https://pay.weixin.qq.com/doc/v3/partner/4012082816">...</a>
|
|
||||||
* 2、最多可上传5张照片,请填写通过图片上传API预先上传图片生成好的MediaID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "activities_additions")
|
|
||||||
private List<String> activitiesAdditions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 非信用卡活动费率值
|
|
||||||
* 用户支付方式为借记卡时收取的手续费费率:
|
|
||||||
* 1、若填写了优惠费率活动ID,则该字段【必填】;
|
|
||||||
* 2、仅能填入2位以内小数,且在优惠费率活动ID指定费率范围内。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "debit_activities_rate")
|
|
||||||
private String debitActivitiesRate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 信用卡活动费率值
|
|
||||||
* 用户支付方式为信用卡时收取的手续费费率:
|
|
||||||
* 1、若填写了优惠费率活动ID,则该字段【必填】;
|
|
||||||
* 2、仅能填入2位以内小数,且在优惠费率活动ID指定费率范围内。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "credit_activities_rate")
|
|
||||||
private String creditActivitiesRate;
|
|
||||||
}
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.req.entry;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import com.czg.third.wechat.dto.req.entry.business.*;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进件 主体资料
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 13:40
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatEntrySubjectReqDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 主体类型 主体类型需与营业执照/登记证书上一致,可参考选择主体指引。<a href="https://kf.qq.com/faq/180910IBZVnQ180910naQ77b.html">...</a>
|
|
||||||
* 可选取值
|
|
||||||
* SUBJECT_TYPE_INDIVIDUAL: (个体户)营业执照上的主体类型一般为个体户、个体工商户、个体经营
|
|
||||||
* SUBJECT_TYPE_ENTERPRISE: (企业)营业执照上的主体类型一般为有限公司、有限责任公司
|
|
||||||
* SUBJECT_TYPE_GOVERNMENT: (政府机关)包括各级、各类政府机关,如机关党委、税务、民政、人社、工商、商务、市监等
|
|
||||||
* SUBJECT_TYPE_INSTITUTIONS: (事业单位)包括国内各类事业单位,如:医疗、教育、学校等单位
|
|
||||||
* SUBJECT_TYPE_OTHERS:(社会组织) 包括社会团体、民办非企业、基金会、基层群众性自治组织、农村集体经济组织等组织
|
|
||||||
*/
|
|
||||||
@JSONField(name = "subject_type")
|
|
||||||
private String subjectType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 是否是金融机构
|
|
||||||
* 【是否是金融机构】 【选填】,请根据申请主体的实际情况填写,可参考选择金融机构指引:
|
|
||||||
* 1、若商户主体是金融机构,则填写:true;
|
|
||||||
* 2、若商户主体不是金融机构,则填写:false。
|
|
||||||
* 若未传入将默认填写:false。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "finance_institution")
|
|
||||||
private Boolean financeInstitution;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 营业执照 当前不允许小微注册,所以【必填】
|
|
||||||
* 1、主体为个体户/企业,【必填】;
|
|
||||||
* 2、请上传“营业执照”,需年检章齐全,当年注册除外;
|
|
||||||
*/
|
|
||||||
@JSONField(name = "business_license_info")
|
|
||||||
private WechatEntryLicenseReqDto businessLicenseInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 登记证书 主体为政府机关/事业单位/其他组织时,【必填】。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "certificate_info")
|
|
||||||
private WechatEntryCertificateReqDto certificateInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 单位证明函照片
|
|
||||||
* 1、主体类型为政府机关、事业单位选传:
|
|
||||||
* (1)若上传,则审核通过后即可签约,无需汇款验证;
|
|
||||||
* (2)若未上传,则审核通过后,需汇款验证。
|
|
||||||
* 2、主体为个体户、企业、其他组织等,不需要上传本字段;
|
|
||||||
* 3、请参照示例图打印单位证明函,全部信息需打印,不支持手写商户信息,并加盖公章; <a href="https://kf.qq.com/faq/200114u2y2yQ200114uEz26z.html">...</a>
|
|
||||||
* 4、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "certificate_letter_copy")
|
|
||||||
private String certificateLetterCopy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 金融机构许可证信息 当主体是金融机构时,【必填】。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "finance_institution_info")
|
|
||||||
private WechatEntryFinanceInstitutionReqDto financeInstitutionInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 经营者/法定代表人身份证件
|
|
||||||
* 1、个体户:请上传经营者的身份证件;
|
|
||||||
* 2、企业/社会组织:请上传法定代表人的身份证件;
|
|
||||||
* 3、政府机关/事业单位:请上传法定代表人/经办人的身份证件。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "identity_info")
|
|
||||||
private WechatEntryIdentityReqDto identityInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 最终受益人信息列表(UBO)
|
|
||||||
* 1、主体类型个体户/社会组织/政府机关/事业单位时,无需填写
|
|
||||||
* 2、主体类型为企业时,按照下述要求填写
|
|
||||||
* 1)若经营者/法定代表人不是最终受益所有人,则需提填写受益所有人信息,最多上传4个。
|
|
||||||
* 2)若经营者/法定代表人是最终受益所有人之一,可在此填写其他受益所有人信息,最多上传3个。
|
|
||||||
* 根据国家相关法律法规,需要提供公司受益所有人信息,受益所有人需符合至少以下条件之一:
|
|
||||||
* ▪️直接或者间接拥有超过25%公司股权或者表决权的自然人。
|
|
||||||
* ▪️通过人事、财务等其他方式对公司进行控制的自然人。
|
|
||||||
* ▪️公司的高级管理人员,包括公司的经理、副经理、财务负责人、上市公司董事会秘书和公司章程规定的其他人员。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "ubo_info_list")
|
|
||||||
private List<WechatEntryUboInfoReqDto> uboInfoList;
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.req.entry.business;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import com.czg.third.wechat.dto.req.entry.business.sales.WechatEntrySalesInfoReqDto;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信进件 商户信息 经营资料
|
|
||||||
*
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 13:41
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatEntryBusinessReqDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 商户简称 在支付完成页向买家展示,需与微信经营类目相关
|
|
||||||
* 1、请输入1-64个字符;
|
|
||||||
* 2、前后不能有空格、制表符、换行符;
|
|
||||||
* 3、不能仅含特殊字符;
|
|
||||||
* 4、仅能填写数字、英文字母、汉字及特殊字符;
|
|
||||||
* 5、仅支持utf-8格式;
|
|
||||||
* 6、简称要求
|
|
||||||
* (1)不支持单纯以人名来命名,若为个体户经营,可用“个体户+经营者名称”或“经营者名称+业务”命名,如“个体户张三”或“张三餐饮店”;
|
|
||||||
* (2)不支持无实际意义的文案,如“XX特约商户”、“800”、“XX客服电话XXX”。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "merchant_shortname")
|
|
||||||
private String merchantShortname;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 客服电话 将在交易记录中向买家展示,请确保电话畅通以便平台回拨确认
|
|
||||||
* 1、前后不能有空格、制表符、换行符;
|
|
||||||
* 2、需满足以下任一条件;
|
|
||||||
* 11位数字的手机号码;
|
|
||||||
* 5-20位数字、连字符“-”、加号“+”。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "service_phone")
|
|
||||||
private String servicePhone;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 经营场景
|
|
||||||
*/
|
|
||||||
@JSONField(name = "sales_info")
|
|
||||||
private WechatEntrySalesInfoReqDto salesInfo;
|
|
||||||
}
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.req.entry.business;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 登记证书
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 15:07
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatEntryCertificateReqDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 登记证书照片
|
|
||||||
* 1、照片应正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS;
|
|
||||||
* 2、上传彩色照片、彩色扫描件,复印件需加盖公章鲜章;
|
|
||||||
* 3、水印仅限于微信支付业务相关;
|
|
||||||
* 4、指引与示例可参考【指引文档】;
|
|
||||||
* 5、请填写通过图片上传API预先上传图片生成好的MediaID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "cert_copy")
|
|
||||||
private String certCopy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 登记证书类型
|
|
||||||
* 1、主体为“政府机关/事业单位/社会组织”时,请上传登记证书类型;
|
|
||||||
* 2、主体为“个体工商户/企业”时,不填;
|
|
||||||
* 当主体为事业单位时,选择此枚举值:
|
|
||||||
* CERTIFICATE_TYPE_2388:事业单位法人证书
|
|
||||||
* 当主体为政府机关,选择此枚举值:
|
|
||||||
* CERTIFICATE_TYPE_2389:统一社会信用代码证书
|
|
||||||
* 当主体为社会组织,选择以下枚举值之一:
|
|
||||||
* CERTIFICATE_TYPE_2389:统一社会信用代码证书
|
|
||||||
* CERTIFICATE_TYPE_2394:社会团体法人登记证书
|
|
||||||
* CERTIFICATE_TYPE_2395:民办非企业单位登记证书
|
|
||||||
* CERTIFICATE_TYPE_2396:基金会法人登记证书
|
|
||||||
* CERTIFICATE_TYPE_2520:执业许可证/执业证
|
|
||||||
* CERTIFICATE_TYPE_2521:基层群众性自治组织特别法人统一社会信用代码证
|
|
||||||
* CERTIFICATE_TYPE_2522:农村集体经济组织登记证
|
|
||||||
* CERTIFICATE_TYPE_2399:宗教活动场所登记证
|
|
||||||
* CERTIFICATE_TYPE_2400:政府部门下发的其他有效证明文件
|
|
||||||
*/
|
|
||||||
@JSONField(name = "cert_type")
|
|
||||||
private String certType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 证书号 请输入与所选证书类型相匹配且符合国家标准规范的证书号,其中除政府证明文件外,需满足18位阿拉伯数字或大写英文字母(不得包含英文字母I/O/Z/S/V)
|
|
||||||
*/
|
|
||||||
@JSONField(name = "cert_number")
|
|
||||||
private String certNumber;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 商户名称 请填写登记证书上的商户名称
|
|
||||||
* 1、长度为2-128个字符;
|
|
||||||
* 2、前后不能有空格、制表符、换行符;
|
|
||||||
* 3、不能仅含数字、特殊字符;
|
|
||||||
* 4、仅能填写数字、英文字母、汉字及特殊字符;
|
|
||||||
* 5、仅支持utf-8格式。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "merchant_name")
|
|
||||||
private String merchantName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 注册地址 请填写登记证书的注册地址
|
|
||||||
* 1、长度为4-128个字符;
|
|
||||||
* 2、前后不能有空格、制表符、换行符;
|
|
||||||
* 3、不能仅含数字、特殊字符;
|
|
||||||
* 4、仅能填写数字、英文字母、汉字及特殊字符;
|
|
||||||
* 5、仅支持utf-8格式。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "company_address")
|
|
||||||
private String companyAddress;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 法定代表人 请填写登记证书上的法定代表人姓名
|
|
||||||
* 1、长度为2-100个字符;
|
|
||||||
* 2、前后不能有空格、制表符、换行符;
|
|
||||||
* 3、不能仅含特殊字符;
|
|
||||||
* 4、仅能填写数字、英文字母、汉字及特殊字符。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "legal_person")
|
|
||||||
private String legalPerson;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 有效期限开始日期 建议填写营业执照的有效期限开始时间,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。
|
|
||||||
* 1、日期格式应满足合法的YYYY-MM-DD格式;
|
|
||||||
* 2、开始时间不能小于1900-01-01;
|
|
||||||
* 3、开始时间不能大于等于当前日期。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "period_begin")
|
|
||||||
private String periodBegin;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 营业期限结束日期 建议填写营业执照的有效期限结束时间,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。
|
|
||||||
* 1、日期格式应满足合法的YYYY-MM-DD格式或长期;
|
|
||||||
* 2、结束时间需大于开始时间。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "period_end")
|
|
||||||
private String periodEnd;
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.req.entry.business;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 金融机构许可证信息
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 15:21
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatEntryFinanceInstitutionReqDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 金融机构类型 金融机构类型需与营业执照/登记证书上一致,可参考选择金融机构指引。
|
|
||||||
* BANK_AGENT:银行业, 适用于商业银行、政策性银行、农村合作银行、村镇银行、开发性金融机构等
|
|
||||||
* PAYMENT_AGENT:支付机构, 适用于非银行类支付机构
|
|
||||||
* INSURANCE:保险业, 适用于保险、保险中介、保险代理、保险经纪等保险类业务
|
|
||||||
* TRADE_AND_SETTLE:交易及结算类金融机构, 适用于交易所、登记结算类机构、银行卡清算机构、资金清算中心等
|
|
||||||
* OTHER:其他金融机构, 适用于财务公司、信托公司、金融资产管理公司、金融租赁公司、汽车金融公司、贷款公司、货币经纪公司、消费金融公司、证券业、金融控股公司、股票、期货、货币兑换、小额贷款公司、金融资产管理、担保公司、商业保理公司、典当行、融资租赁公司、财经咨询等其他金融业务
|
|
||||||
*/
|
|
||||||
@JSONField(name = "finance_type")
|
|
||||||
private String financeType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 必填
|
|
||||||
* 金融机构许可证图片
|
|
||||||
* 1、照片应正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS;
|
|
||||||
* 2、上传彩色照片、彩色扫描件,复印件需加盖公章鲜章;
|
|
||||||
* 3、水印仅限于微信支付业务相关;
|
|
||||||
* 4、根据所属金融机构类型的许可证要求提供,详情查看金融机构指引; <a href="https://kf.qq.com/faq/220215IrMRZ3220215n6buiU.html">...</a>
|
|
||||||
* 5、请提供为“申请商家主体”所属的许可证,可授权使用总公司/分公司的特殊资质;
|
|
||||||
* 6、最多可上传5张照片,请填写通过图片上传API预先上传图片生成好的MediaID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "finance_license_pics")
|
|
||||||
private List<String> financeLicensePics;
|
|
||||||
}
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.req.entry.business;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import com.czg.third.wechat.dto.req.entry.id.WechatEntryIdCardReqDto;
|
|
||||||
import com.czg.third.wechat.dto.req.entry.id.WechatEntryIdDocInfoReqDto;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 经营者/法定代表人身份证件
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 15:24
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatEntryIdentityReqDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 证件持有人类型
|
|
||||||
* 1、主体类型为政府机关/事业单位时选传:
|
|
||||||
* (1)若上传的是法定代表人证件,则不需要上传该字段。
|
|
||||||
* (2)若因政策保密等原因,无法提供法定代表人证件时,可上传经办人。 (经办人:经商户授权办理微信支付业务的人员,授权范围包括但不限于签约,入驻过程需完成账户验证)。
|
|
||||||
* 2、主体类型为小微/个人卖家/企业/个体户/社会组织时,默认为经营者/法定代表人,不需要上传该字段。
|
|
||||||
* LEGAL: 经营者/法定代表人
|
|
||||||
* SUPER: 经办人
|
|
||||||
*/
|
|
||||||
@JSONField(name = "id_holder_type")
|
|
||||||
private String idHolderType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 证件类型
|
|
||||||
* 1、当证件持有人类型为法定代表人时,填写。其他情况,无需上传;
|
|
||||||
* 2、个体户/企业/事业单位/社会组织:可选择任一证件类型,政府机关仅支持中国大陆居民-身份证类型。
|
|
||||||
* 可选取值
|
|
||||||
* IDENTIFICATION_TYPE_IDCARD: 中国大陆居民-身份证
|
|
||||||
* IDENTIFICATION_TYPE_OVERSEA_PASSPORT: 其他国家或地区居民-护照
|
|
||||||
* IDENTIFICATION_TYPE_HONGKONG_PASSPORT: 中国香港居民-来往内地通行证
|
|
||||||
* IDENTIFICATION_TYPE_MACAO_PASSPORT: 中国澳门居民-来往内地通行证
|
|
||||||
* IDENTIFICATION_TYPE_TAIWAN_PASSPORT: 中国台湾居民-来往大陆通行证
|
|
||||||
* IDENTIFICATION_TYPE_FOREIGN_RESIDENT: 外国人居留证
|
|
||||||
* IDENTIFICATION_TYPE_HONGKONG_MACAO_RESIDENT: 港澳居民居住证
|
|
||||||
* IDENTIFICATION_TYPE_TAIWAN_RESIDENT: 台湾居民居住证
|
|
||||||
*/
|
|
||||||
@JSONField(name = "id_doc_type")
|
|
||||||
private String idDocType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 法定代表人说明函
|
|
||||||
* 1、当证件持有人类型为经办人时,必须上传。其他情况,无需上传;
|
|
||||||
* 2、若因特殊情况,无法提供法定代表人证件时,请参照示例图打印法定代表人说明函,全部信息需打印,不支持手写商户信息,并加盖公章; <a href="https://kf.qq.com/faq/220127aUzAju220127UfiuQr.html">...</a>
|
|
||||||
* 3、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "authorize_letter_copy")
|
|
||||||
private String authorizeLetterCopy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 身份证信息 当证件持有人类型为经营者/法定代表人且证件类型为“身份证”时填写。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "id_card_info")
|
|
||||||
private WechatEntryIdCardReqDto idCardInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 其他类型证件信息 当证件持有人类型为经营者/法定代表人且证件类型不为“身份证”时填写。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "id_doc_info")
|
|
||||||
private WechatEntryIdDocInfoReqDto idDocInfo;
|
|
||||||
}
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.req.entry.business;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 营业执照信息
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 14:59
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatEntryLicenseReqDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 营业执照照片
|
|
||||||
* 1、照片应正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS;
|
|
||||||
* 2、上传彩色照片、彩色扫描件,复印件需加盖公章鲜章;
|
|
||||||
* 3、水印仅限于微信支付业务相关;
|
|
||||||
* 4、指引与示例可参考【指引文档】;
|
|
||||||
* 5、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "license_copy")
|
|
||||||
private String licenseCopy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 注册号/统一社会信用代码
|
|
||||||
*/
|
|
||||||
@JSONField(name = "license_number")
|
|
||||||
private String licenseNumber;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 商户名称
|
|
||||||
* 1、长度为2-128个字符;
|
|
||||||
* 2、前后不能有空格、制表符、换行符;
|
|
||||||
* 3、不能仅含数字、特殊字符;
|
|
||||||
* 4、仅能填写数字、英文字母、汉字及特殊字符;
|
|
||||||
* 5、仅支持utf-8格式;
|
|
||||||
* 6、个体户证件为以下情况时,按照个体户XXX命名(XXX是营业执照经营人姓名):营业执照登记名称为空、仅含数字、仅含特殊字符、“无”、“无字号”;
|
|
||||||
* 7、个体户不能使用“企业”“公司”或“农民专业合作社”结尾。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "merchant_name")
|
|
||||||
private String merchantName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 个体户经营者/法定代表人姓名 请填写营业执照的经营者/法定代表人姓名
|
|
||||||
* 1、长度为2-100个字符;
|
|
||||||
* 2、前后不能有空格、制表符、换行符;
|
|
||||||
* 3、不能仅含特殊字符;
|
|
||||||
* 4、仅能填写数字、英文字母、汉字及特殊字符。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "legal_person")
|
|
||||||
private String legalPerson;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 注册地址 建议填写营业执照的注册地址,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。
|
|
||||||
* 1、长度为4-128个字符;
|
|
||||||
* 2、前后不能有空格、制表符、换行符;
|
|
||||||
* 3、不能仅含数字、特殊字符;
|
|
||||||
* 4、仅能填写数字、英文字母、汉字及特殊字符;
|
|
||||||
* 5、仅支持utf-8格式。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "license_address")
|
|
||||||
private String licenseAddress;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 有效期限开始日期 建议填写营业执照的有效期限开始时间,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。
|
|
||||||
* 1、日期格式应满足合法的YYYY-MM-DD格式;
|
|
||||||
* 2、开始时间不能小于1900-01-01;
|
|
||||||
* 3、开始时间不能大于等于当前日期。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "period_begin")
|
|
||||||
private String periodBegin;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 营业期限结束日期 建议填写营业执照的有效期限结束时间,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。
|
|
||||||
* 1、日期格式应满足合法的YYYY-MM-DD格式或长期;
|
|
||||||
* 2、结束时间需大于开始时间。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "period_end")
|
|
||||||
private String periodEnd;
|
|
||||||
}
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.req.entry.business;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 最终受益人信息
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 15:50
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatEntryUboInfoReqDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 证件类型 请填写受益人的证件类型。枚举值:
|
|
||||||
* 可选取值
|
|
||||||
* IDENTIFICATION_TYPE_IDCARD: 中国大陆居民-身份证
|
|
||||||
* IDENTIFICATION_TYPE_OVERSEA_PASSPORT: 其他国家或地区居民-护照
|
|
||||||
* IDENTIFICATION_TYPE_HONGKONG_PASSPORT: 中国香港居民-来往内地通行证
|
|
||||||
* IDENTIFICATION_TYPE_MACAO_PASSPORT: 中国澳门居民-来往内地通行证
|
|
||||||
* IDENTIFICATION_TYPE_TAIWAN_PASSPORT: 中国台湾居民-来往大陆通行证
|
|
||||||
* IDENTIFICATION_TYPE_FOREIGN_RESIDENT: 外国人居留证
|
|
||||||
* IDENTIFICATION_TYPE_HONGKONG_MACAO_RESIDENT: 港澳居民居住证
|
|
||||||
* IDENTIFICATION_TYPE_TAIWAN_RESIDENT: 台湾居民居住证
|
|
||||||
*/
|
|
||||||
@JSONField(name = "ubo_id_doc_type")
|
|
||||||
private String uboIdDocType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 必填
|
|
||||||
* 证件正面照片
|
|
||||||
* 1、请上传受益人证件的正面照片;
|
|
||||||
* 2、若证件类型为身份证,请上传人像面照片;
|
|
||||||
* 3、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS;
|
|
||||||
* 4、请上传彩色照片or彩色扫描件,复印件需加盖公章鲜章,可添加“微信支付”相关水印(如微信支付认证),见【指引文档】;
|
|
||||||
* 5、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "ubo_id_doc_copy")
|
|
||||||
private String uboIdDocCopy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 证件反面照片
|
|
||||||
* 1、请上传受益人证件的反面照片;
|
|
||||||
* 2、若证件类型为身份证,请上传国徽面照片;
|
|
||||||
* 3、若证件类型为护照,无需上传反面照片;
|
|
||||||
* 4、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS;
|
|
||||||
* 5、请上传彩色照片or彩色扫描件,复印件需加盖公章鲜章,可添加“微信支付”相关水印(如微信支付认证),见【指引文档】;
|
|
||||||
* 6、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "ubo_id_doc_copy_back")
|
|
||||||
private String uboIdDocCopyBack;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 必填
|
|
||||||
* 证件姓名
|
|
||||||
* 1、长度为2-100个字符;
|
|
||||||
* 2、前后不能有空格、制表符、换行符;
|
|
||||||
* 3、不能仅含数字、特殊字符;
|
|
||||||
* 4、仅能填写数字、英文字母、汉字及特殊字符;
|
|
||||||
* 5、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "ubo_id_doc_name")
|
|
||||||
private String uboIdDocName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 必填
|
|
||||||
* 证件号码
|
|
||||||
* 1、证件号码为证件正反面中一致的号码;
|
|
||||||
* 2、证件号码为18位或15位,或港澳居民来往内地通行证为9位;
|
|
||||||
* 3、证件号码为英文字母X或x,或港澳居民来往内地通行证为英文字母X或x;
|
|
||||||
* 4、证件号码为英文字母x或X,或港澳居民来往内地通行证为英文字母x或X;
|
|
||||||
* 5、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥
|
|
||||||
*/
|
|
||||||
@JSONField(name = "ubo_id_doc_number")
|
|
||||||
private String uboIdDocNumber;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 必填
|
|
||||||
* 证件居住地址
|
|
||||||
* 1、请按照身份证住址填写,如广东省深圳市南山区xx路xx号xx室;
|
|
||||||
* 2、长度为4-128个字符;
|
|
||||||
* 3、前后不能有空格、制表符、换行符;
|
|
||||||
* 4、不能仅含数字、特殊字符;
|
|
||||||
* 5、仅能填写数字、英文字母、汉字及特殊字符;
|
|
||||||
* 6、仅支持utf-8格式;
|
|
||||||
* 7、 该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "ubo_id_doc_address")
|
|
||||||
private String uboIdDocAddress;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 必填
|
|
||||||
* 证件有效期开始时间
|
|
||||||
* 1、日期格式应满足合法的YYYY-MM-DD格式;
|
|
||||||
* 2、开始时间不能小于1900-01-01;
|
|
||||||
* 3、开始时间不能大于等于当前日期。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "ubo_period_begin")
|
|
||||||
private String uboPeriodBegin;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 必填
|
|
||||||
* 证件有效期结束时间
|
|
||||||
* 1、日期格式应满足合法的YYYY-MM-DD格式或长期;
|
|
||||||
* 2、结束时间需大于开始时间。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "ubo_period_end")
|
|
||||||
private String uboPeriodEnd;
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.req.entry.business.sales;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进件-经营资料-经营场景-App场景
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 14:26
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatEntryAppInfoReqDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* App截图
|
|
||||||
* 1、请提供APP首页截图、尾页截图、应用内截图、支付页截图各1张;
|
|
||||||
* 2、请填写通过图片上传API预先上传图片生成好的MediaID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "app_pics")
|
|
||||||
private List<String> appPics;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 商家应用AppID
|
|
||||||
* 1、服务商应用AppID与商家应用AppID,二选一【必填】;
|
|
||||||
* 2、可填写与商家主体一致且已认证的应用AppID,需是已认证的App;
|
|
||||||
* 3、审核通过后,系统将发起特约商家商户号与该AppID的绑定(即配置为sub_appid),服务商随后可在发起支付时选择传入该AppID,以完成支付,并获取sub_openid用于数据统计,营销等业务场景。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "app_sub_appid")
|
|
||||||
private String appSubAppid;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 服务商应用AppID
|
|
||||||
* 1、服务商应用AppID与商家应用AppID,二选一【必填】;
|
|
||||||
* 2、可填写当前服务商商户号已绑定的应用AppID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "app_appid")
|
|
||||||
private String appAppid;
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.req.entry.business.sales;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进件-经营资料-经营场景-小程序场景
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 14:23
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatEntryMiniProgramReqDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 服务商小程序AppID
|
|
||||||
* 1、服务商小程序AppID与商家小程序AppID,二选一必填;
|
|
||||||
* 2、可填写当前服务商商户号已绑定的小程序AppID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "mini_program_appid")
|
|
||||||
private String miniProgramAppid;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 商家小程序AppID
|
|
||||||
* 1、服务商小程序AppID与商家小程序AppID,二选一必填;
|
|
||||||
* 2、请填写已认证的小程序AppID;
|
|
||||||
* 3、完成进件后,系统发起特约商户号与该AppID的绑定(即配置为sub_appid可在发起支付时传入)
|
|
||||||
* (1)若AppID主体与商家主体/服务商主体一致,则直接完成绑定;
|
|
||||||
* (2)若AppID主体与商家主体/服务商主体不一致,则商户签约时显示《联合营运承诺函》,并且AppID的管理员需登录公众平台确认绑定意愿。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "mini_program_sub_appid")
|
|
||||||
private String miniProgramSubAppid;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 小程序截图
|
|
||||||
* 1、请提供展示商品/服务的页面截图/设计稿(最多5张),若小程序未建设完善或未上线 请务必提供;
|
|
||||||
* 2、请填写通过图片上传API预先上传图片生成好的MediaID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "mini_program_pics")
|
|
||||||
private List<String> miniProgramPics;
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.req.entry.business.sales;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进件-经营资料-经营场景-服务号或公众号景
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 14:20
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatEntryMpInfoReqDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 服务号或公众号页面截图
|
|
||||||
* 1、请提供展示商品/服务的页面截图/设计稿(最多5张),若服务号或公众号未建设完善或未上线请务必提供;
|
|
||||||
* 2、请填写通过图片上传API预先上传图片生成好的MediaID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "mp_pics")
|
|
||||||
private List<String> mpPics;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 商家服务号或公众号AppID
|
|
||||||
* 1、服务商服务号或公众号AppID、商家服务号或公众号AppID,二选一【必填】;
|
|
||||||
* 2、可填写与商家主体一致且已认证的服务号或公众号AppID,需是已认证的服务号、政府或媒体类型的公众号;
|
|
||||||
* 3、审核通过后,系统将发起特约商家商户号与该AppID的绑定(即配置为sub_appid),服务商随后可在发起支付时选择传入该appid,以完成支付,并获取sub_openid用于数据统计,营销等业务场景。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "mp_sub_appid")
|
|
||||||
private String mpSubAppid;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 服务商服务号或公众号AppID
|
|
||||||
* 1、服务商服务号或公众号AppID、商家服务号或公众号AppID,二选一【必填】;
|
|
||||||
* 2、可填写当前服务商商户号已绑定的服务号或公众号AppID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "mp_appid")
|
|
||||||
private String mpAppid;
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.req.entry.business.sales;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进件-经营场景
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 14:07
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatEntrySalesInfoReqDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 经营场景类型
|
|
||||||
* 1、请勾选实际售卖商品/提供服务场景(至少一项),以便为你开通需要的支付权限;
|
|
||||||
* 2、建议只勾选目前必须的场景,以便尽快通过入驻审核,其他支付权限可在入驻后再根据实际需要发起申请
|
|
||||||
* 可选取值
|
|
||||||
* SALES_SCENES_STORE: 线下场所
|
|
||||||
* SALES_SCENES_MP: 服务号与公众号
|
|
||||||
* SALES_SCENES_MINI_PROGRAM: 小程序
|
|
||||||
* SALES_SCENES_WEB: 互联网网站
|
|
||||||
* SALES_SCENES_APP: App
|
|
||||||
* SALES_SCENES_WEWORK: 企业微信
|
|
||||||
*/
|
|
||||||
@JSONField(name = "sales_scenes_type")
|
|
||||||
private List<String> salesScenesType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 线下场所场景
|
|
||||||
* 1、审核通过后,服务商可帮商户发起付款码支付、JSAPI支付;
|
|
||||||
* 2、当"经营场景类型"选择"SALES_SCENES_STORE",该场景资料【必填】。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "biz_store_info")
|
|
||||||
private WechatEntryStoreInfoReqDto bizStoreInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 服务号或公众号场景
|
|
||||||
* 1、审核通过后,服务商可帮商家发起JSAPI支付;
|
|
||||||
* 2、当"经营场景类型"选择"SALES_SCENES_MP",该场景资料【必填】。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "mp_info")
|
|
||||||
private WechatEntryMpInfoReqDto mpInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 小程序场景
|
|
||||||
* 1、审核通过后,服务商可帮商家发起JSAPI支付;
|
|
||||||
* 2、当"经营场景类型"选择"SALES_SCENES_MINI_PROGRAM",该场景资料必填。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "mini_program_info")
|
|
||||||
private WechatEntryMiniProgramReqDto miniProgramInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* App场景
|
|
||||||
* 1、审核通过后,服务商可帮商家发起App支付;
|
|
||||||
* 2、当"经营场景类型"选择"SALES_SCENES_APP",该场景资料必填。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "app_info")
|
|
||||||
private WechatEntryAppInfoReqDto appInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 互联网网站场景
|
|
||||||
* 1、审核通过后,服务商可帮商家发起JSAPI支付;
|
|
||||||
* 2、当"经营场景类型"选择"SALES_SCENES_WEB",该场景资料必填。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "web_info")
|
|
||||||
private WechatEntryWebInfoReqDto webInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 企业微信场景
|
|
||||||
* 1、审核通过后,服务商可帮商家发起JSAPI支付;
|
|
||||||
* 2、当"经营场景类型"选择"SALES_SCENES_WEWORK",该场景资料必填。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "wework_info")
|
|
||||||
private WechatEntryWeworkInfoReqDto weworkInfo;
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.req.entry.business.sales;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进件-经营资料-经营场景-线下场所场景
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 14:10
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatEntryStoreInfoReqDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 线下场所名称 请填写门店名称
|
|
||||||
* 1、长度为1-50个字符;
|
|
||||||
* 2、前后不能有空格、制表符、换行符;
|
|
||||||
* 3、不能仅含数字、特殊字符;
|
|
||||||
* 4、仅能填写数字、英文字母、汉字及特殊字符;
|
|
||||||
* 5、仅支持utf-8格式。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "biz_store_name")
|
|
||||||
private String bizStoreName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 线下场所省市编码
|
|
||||||
* 1、只能由数字组成;
|
|
||||||
* 2、详细参见微信支付提供的省市对照表。 <a href="https://pay.weixin.qq.com/doc/v3/partner/4012082815">...</a>
|
|
||||||
*/
|
|
||||||
@JSONField(name = "biz_address_code")
|
|
||||||
private String bizAddressCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 线下场所地址 请填写详细的经营场所信息,如有多个场所,选择一个主要场所填写即可。
|
|
||||||
* 1、长度为4-512个字符;
|
|
||||||
* 2、前后不能有空格、制表符、换行符;
|
|
||||||
* 3、不能仅含数字、特殊字符;
|
|
||||||
* 4、仅能填写数字、英文字母、汉字及特殊字符;
|
|
||||||
* 5、仅支持utf-8格式
|
|
||||||
*/
|
|
||||||
@JSONField(name = "biz_store_address")
|
|
||||||
private String bizStoreAddress;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 线下场所门头照片
|
|
||||||
* 1、请上传门头正面照片(要求门店招牌、门框完整、清晰、可辨识);若为停车场等无固定门头照片的经营场所,可上传岗亭/出入闸口。具体参考【指引文档】;
|
|
||||||
* 2、请填写通过图片上传API预先上传图片生成好的MediaID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "store_entrance_pic")
|
|
||||||
private List<String> storeEntrancePic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 线下场所内部照片
|
|
||||||
* 1、请上传门店内部环境照片(可辨识经营内容)。若为停车场等无固定门头的经营场所,可上传停车场内部照片。具体参考【指引文档】;
|
|
||||||
* 2、请填写通过图片上传API预先上传图片生成好的MediaID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "indoor_pic")
|
|
||||||
private List<String> indoorPic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 线下场所对应的商家AppID
|
|
||||||
* 1、可填写与商家主体一致且已认证的服务号或公众号、小程序、APP的AppID,其中服务号或公众号AppID需是已认证的服务号、政府或媒体类型的公众号;
|
|
||||||
* 2、审核通过后,系统将额外为商家开通付款码支付、JSAPI支付的自有交易权限,并完成商家商户号与该AppID的绑定。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "biz_sub_appid")
|
|
||||||
private String bizSubAppid;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.req.entry.business.sales;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进件-经营资料-经营场景-互联网网站场景
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 14:29
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatEntryWebInfoReqDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 互联网网站域名
|
|
||||||
* 1、如为PC端商城、智能终端等场景,可上传官网链接;
|
|
||||||
* 2、网站域名需ICP备案,若备案主体与申请主体不同,请上传加盖公章的网站授权函。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "domain")
|
|
||||||
private String domain;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 网站授权函
|
|
||||||
* 1、若备案主体与申请主体不同,请务必上传加盖公章的网站授权函.doc; <a href="https://gtimg.wechatpay.cn/resource/xres/mmpaydoc/static/attachment/bb55b16e3825a5952a531d55fba0f382/%E7%BD%91%E7%AB%99%E6%8E%88%E6%9D%83%E5%87%BD.doc">...</a>
|
|
||||||
* 2、请填写通过图片上传API预先上传图片生成好的MediaID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "web_authorisation")
|
|
||||||
private String webAuthorisation;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 互联网网站对应的商家AppID
|
|
||||||
* 1、可填写已认证的服务号或公众号、小程序、APP的AppID,其中服务号或公众号AppID需是已认证的服务号、政府或媒体类型的公众号;
|
|
||||||
* 2、完成进件后,系统发起特约商户号与该AppID的绑定(即配置为sub_appid,可在发起支付时传入)
|
|
||||||
* (1)若APPID主体与商家主体一致,则直接完成绑定;
|
|
||||||
* (2)若APPID主体与商家主体不一致,则商户签约时显示《联合营运承诺函》,并且 AppID的管理员需登录公众平台确认绑定意愿;( 暂不支持绑定异主体的应用APPID)。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "web_appid")
|
|
||||||
private String webAppid;
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.req.entry.business.sales;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进件-经营资料-经营场景-企业微信场景
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 14:32
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatEntryWeworkInfoReqDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 商家企业微信CorpID
|
|
||||||
* 1、可填写与商家主体一致且已认证的企业微信CorpID;
|
|
||||||
* 2、审核通过后,系统将为商家开通企业微信专区的自有交易权限,并完成商家商户号与该AppID的绑定,商家可自行发起交易。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "sub_corp_id")
|
|
||||||
private String subCorpId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 必填
|
|
||||||
* 企业微信页面截图
|
|
||||||
* 1、最多可上传5张照片;
|
|
||||||
* 2、请填写通过图片上传API预先上传图片生成好的MediaID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "wework_pics")
|
|
||||||
private String[] weworkPics;
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.req.entry.id;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 身份证信息
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 15:29
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatEntryIdCardReqDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 身份证人像面照片
|
|
||||||
* 1、请上传个体户经营者/法定代表人的身份证人像面照片;
|
|
||||||
* 2、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS;
|
|
||||||
* 3、请上传彩色照片or彩色扫描件,复印件需加盖公章鲜章,可添加“微信支付”相关水印(如微信支付认证),见【指引文档】;
|
|
||||||
* 4、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "id_card_copy")
|
|
||||||
private String idCardCopy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 身份证国徽面照片
|
|
||||||
* 、请上传个体户经营者/法定代表人的身份证国徽面照片;
|
|
||||||
* 2、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS;
|
|
||||||
* 3、请上传彩色照片or彩色扫描件,复印件需加盖公章鲜章,可添加“微信支付”相关水印(如微信支付认证),见【指引文档】;
|
|
||||||
* 4、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "id_card_national")
|
|
||||||
private String idCardNational;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 身份证姓名
|
|
||||||
* 1、请填写个体户经营者/法定代表人对应身份证的姓名;
|
|
||||||
* 2、长度为2-100个字符;
|
|
||||||
* 3、前后不能有空格、制表符、换行符;
|
|
||||||
* 4、不能仅含数字、特殊字符;
|
|
||||||
* 5、仅能填写数字、英文字母、汉字及特殊字符;
|
|
||||||
* 6、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。
|
|
||||||
* <a href="https://pay.weixin.qq.com/doc/v3/partner/4013059044">加密</a>
|
|
||||||
*/
|
|
||||||
@JSONField(name = "id_card_name")
|
|
||||||
private String idCardName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 必填
|
|
||||||
* 身份证号码
|
|
||||||
* 1、请填写个体户经营者/法定代表人对应身份证的号码;
|
|
||||||
* 2、17位数字+1位数字|X ,该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。
|
|
||||||
* <a href="https://pay.weixin.qq.com/doc/v3/partner/4013059044">加密</a>
|
|
||||||
*/
|
|
||||||
@JSONField(name = "id_card_number")
|
|
||||||
private String idCardNumber;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 身份证居住地址
|
|
||||||
* 1、主体类型为企业时,需要填写。其他主体类型,无需上传;
|
|
||||||
* 2、请按照身份证住址填写,如广东省深圳市南山区xx路xx号xx室;
|
|
||||||
* 3、长度为4-128个字符;
|
|
||||||
* 4、前后不能有空格、制表符、换行符;
|
|
||||||
* 5、不能仅含数字、特殊字符;
|
|
||||||
* 6、仅能填写数字、英文字母、汉字及特殊字符;
|
|
||||||
* 7、仅支持utf-8格式;
|
|
||||||
* 8、 该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。
|
|
||||||
* <a href="https://pay.weixin.qq.com/doc/v3/partner/4013059044">加密</a>
|
|
||||||
*/
|
|
||||||
@JSONField(name = "id_card_address")
|
|
||||||
private String idCardAddress;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 必填
|
|
||||||
* 身份证有效期开始时间
|
|
||||||
* 1、请填写身份证有效期开始时间,格式为yyyy-MM-dd;
|
|
||||||
* 2、开始时间不能小于1900-01-01;
|
|
||||||
* 3、开始时间不能大于等于当前日期。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "card_period_begin")
|
|
||||||
private String cardPeriodBegin;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 必填
|
|
||||||
* 身份证有效期截止时间
|
|
||||||
* 1、日期格式应满足合法的YYYY-MM-DD格式或长期;
|
|
||||||
* 2、结束时间需大于开始时间。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "card_period_end")
|
|
||||||
private String cardPeriodEnd;
|
|
||||||
}
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.req.entry.id;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 其他类型证件信息
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2025/12/26 15:42
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatEntryIdDocInfoReqDto {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 证件正面照片
|
|
||||||
* 1、证件类型不为“身份证”时,上传证件正面照片;
|
|
||||||
* 2、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS;
|
|
||||||
* 3、请上传彩色照片or彩色扫描件,复印件需加盖公章鲜章,可添加“微信支付”相关水印(如微信支付认证),见【指引文档】;
|
|
||||||
* 4、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "id_doc_copy")
|
|
||||||
private String idDocCopy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 证件反面照片
|
|
||||||
* 1、若证件类型为往来通行证、外国人居留证、港澳居民居住证、台湾居民居住证时,上传证件反面照片;
|
|
||||||
* 2、若证件类型为护照,无需上传反面照片;
|
|
||||||
* 3、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS;
|
|
||||||
* 4、请上传彩色照片or彩色扫描件,复印件需加盖公章鲜章,可添加“微信支付”相关水印(如微信支付认证),见【指引文档】;
|
|
||||||
* 5、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "id_doc_copy_back")
|
|
||||||
private String idDocCopyBack;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 证件姓名
|
|
||||||
* 1、请填写经营者/法定代表人的证件姓名;
|
|
||||||
* 2、长度为2-100个字符;
|
|
||||||
* 3、前后不能有空格、制表符、换行符;
|
|
||||||
* 4、不能仅含数字、特殊字符;
|
|
||||||
* 5、仅能填写数字、英文字母、汉字及特殊字符;
|
|
||||||
* 6、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "id_doc_name")
|
|
||||||
private String idDocName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【必填】
|
|
||||||
* 证件号码
|
|
||||||
* 1、请填写经营者/法定代表人的证件号码:
|
|
||||||
* 护照(限境外人士):4-15位 数字|字母|连字符;
|
|
||||||
* 中国香港居民--来往内地通行证:H/h开头+8或10位数字/字母;
|
|
||||||
* 中国澳门居民--来往内地通行证:M/m开头+8或10位数字/字母;
|
|
||||||
* 中国台湾居民--来往大陆通行证:8位数字或10位数字;
|
|
||||||
* 外国人居留证:15位 数字|字母;
|
|
||||||
* 台湾居民居住证/港澳居民居住证:17位数字+1位数字|X;
|
|
||||||
* 2、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "id_doc_number")
|
|
||||||
private String idDocNumber;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【选填】
|
|
||||||
* 证件居住地址
|
|
||||||
* 1、主体类型为企业时,需要填写。其他主体类型,无需上传;
|
|
||||||
* 2、请按照身份证住址填写,如广东省深圳市南山区xx路xx号xx室;
|
|
||||||
* 3、长度为4-128个字符;
|
|
||||||
* 4、前后不能有空格、制表符、换行符;
|
|
||||||
* 5、不能仅含数字、特殊字符;
|
|
||||||
* 6、仅能填写数字、英文字母、汉字及特殊字符;
|
|
||||||
* 7、仅支持utf-8格式;
|
|
||||||
* 8、 该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "id_doc_address")
|
|
||||||
private String idDocAddress;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 必填
|
|
||||||
* 证件有效期开始时间
|
|
||||||
* 1、日期格式应满足合法的YYYY-MM-DD格式;
|
|
||||||
* 2、开始时间不能小于1900-01-01;
|
|
||||||
* 3、开始时间不能大于等于当前日期。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "doc_period_begin")
|
|
||||||
private String docPeriodBegin;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 必填
|
|
||||||
* 证件有效期结束时间
|
|
||||||
* 1、日期格式应满足合法的YYYY-MM-DD格式或长期;
|
|
||||||
* 2、结束时间需大于开始时间。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "doc_period_end")
|
|
||||||
private String docPeriodEnd;
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.resp;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2026/1/7 15:46
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class WechatAuditDetail {
|
|
||||||
/**
|
|
||||||
* 字段名
|
|
||||||
*/
|
|
||||||
@JSONField(name = "field")
|
|
||||||
public String field;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字段名称
|
|
||||||
*/
|
|
||||||
@JSONField(name = "field_name")
|
|
||||||
public String fieldName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 驳回原因
|
|
||||||
*/
|
|
||||||
@JSONField(name = "reject_reason")
|
|
||||||
public String rejectReason;
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
package com.czg.third.wechat.dto.resp;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信进件状态查询返回参数
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2026/1/7 15:42
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Accessors(chain = true)
|
|
||||||
public class WechatQueryStateResp {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 业务申请编号
|
|
||||||
*/
|
|
||||||
@JSONField(name = "business_code")
|
|
||||||
public String businessCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信支付申请单号
|
|
||||||
*/
|
|
||||||
@JSONField(name = "applyment_id")
|
|
||||||
public String applyId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 特约商户号
|
|
||||||
* 当申请单状态为APPLYMENT_STATE_TO_BE_SIGNED、APPLYMENT_STATE_SIGNING、APPLYMENT_STATE_FINISHED时才返回。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "sub_mchid")
|
|
||||||
public String subMchId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 超级管理员签约链接
|
|
||||||
* 1、超级管理员用微信扫码,关注“微信支付商家助手”公众号后,公众号将自动发送签约消息;超管需点击消息,根据指引完成核对联系信息、账户验证、签约等操作;
|
|
||||||
* 2、超管完成核对联系信息,后续申请单进度可通过公众号自动通知超级管理员。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "sign_url")
|
|
||||||
public String signUrl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 申请单状态
|
|
||||||
* APPLYMENT_STATE_EDITTING:(编辑中)提交申请发生错误导致,请尝试重新提交。
|
|
||||||
* APPLYMENT_STATE_AUDITING:(审核中)申请单正在审核中,超级管理员用微信打开“签约链接”,完成绑定微信号后,申请单进度将通过微信公众号通知超级管理员,引导完成后续步骤。
|
|
||||||
* APPLYMENT_STATE_REJECTED:(已驳回)请按照驳回原因修改申请资料,超级管理员用微信打开“签约链接”,完成绑定微信号,后续申请单进度将通过微信公众号通知超级管理员。
|
|
||||||
* APPLYMENT_STATE_TO_BE_CONFIRMED:(待账户验证)请超级管理员使用微信打开返回的“签约链接”,根据页面指引完成账户验证。
|
|
||||||
* APPLYMENT_STATE_TO_BE_SIGNED:(待签约)请超级管理员使用微信打开返回的“签约链接”,根据页面指引完成签约。
|
|
||||||
* APPLYMENT_STATE_SIGNING:(开通权限中)系统开通相关权限中,请耐心等待。
|
|
||||||
* APPLYMENT_STATE_FINISHED:(已完成)商户入驻申请已完成。
|
|
||||||
* APPLYMENT_STATE_CANCELED:(已作废)申请单已被撤销。
|
|
||||||
*/
|
|
||||||
@JSONField(name = "applyment_state")
|
|
||||||
public String applyState;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 申请状态描述
|
|
||||||
*/
|
|
||||||
@JSONField(name = "applyment_state_msg")
|
|
||||||
public String applyStateMsg;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 驳回原因详情
|
|
||||||
*/
|
|
||||||
@JSONField(name = "audit_detail")
|
|
||||||
public List<WechatAuditDetail> auditDetail;
|
|
||||||
}
|
|
||||||
@@ -1,157 +0,0 @@
|
|||||||
package com.czg.utils;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Java 21 异步多任务执行工具类
|
|
||||||
* 功能:异步执行多个任务,等待所有任务完成后统一返回结果(包含成功/失败信息)
|
|
||||||
* 特性:基于虚拟线程、支持泛型、完善的异常处理、可自定义线程池
|
|
||||||
*
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2026/1/6 18:21
|
|
||||||
*/
|
|
||||||
public class AsyncTaskExecutor {
|
|
||||||
|
|
||||||
// 默认线程池:Java 21 虚拟线程池(轻量级、高并发)
|
|
||||||
private static final ExecutorService DEFAULT_EXECUTOR = Executors.newVirtualThreadPerTaskExecutor();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行多个异步任务,等待所有任务完成后统一返回结果
|
|
||||||
*
|
|
||||||
* @param tasks 任务列表(每个任务是一个 Supplier 函数式接口,封装具体业务逻辑)
|
|
||||||
* @param <T> 任务返回值类型
|
|
||||||
* @return 所有任务的执行结果(包含成功/失败信息)
|
|
||||||
*/
|
|
||||||
public static <T> List<TaskResult<T>> executeAll(List<Supplier<T>> tasks) {
|
|
||||||
return executeAll(tasks, DEFAULT_EXECUTOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行多个异步任务(自定义线程池),等待所有任务完成后统一返回结果
|
|
||||||
*
|
|
||||||
* @param tasks 任务列表
|
|
||||||
* @param executor 自定义线程池(如需要使用传统线程池可传入)
|
|
||||||
* @param <T> 任务返回值类型
|
|
||||||
* @return 所有任务的执行结果
|
|
||||||
*/
|
|
||||||
public static <T> List<TaskResult<T>> executeAll(List<Supplier<T>> tasks, ExecutorService executor) {
|
|
||||||
// 校验入参
|
|
||||||
if (tasks == null || tasks.isEmpty()) {
|
|
||||||
return List.of();
|
|
||||||
}
|
|
||||||
if (executor == null) {
|
|
||||||
throw new IllegalArgumentException("线程池不能为null");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. 提交所有异步任务,获取CompletableFuture列表
|
|
||||||
List<CompletableFuture<TaskResult<T>>> futureList = tasks.stream()
|
|
||||||
.map(task -> CompletableFuture.supplyAsync(
|
|
||||||
() -> executeSingleTask(task),
|
|
||||||
executor
|
|
||||||
))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
// 2. 等待所有任务完成(无超时)
|
|
||||||
CompletableFuture<Void> allFutures = CompletableFuture.allOf(
|
|
||||||
futureList.toArray(new CompletableFuture[0])
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 阻塞等待所有任务完成(可根据业务需求添加超时,如 allFutures.get(10, TimeUnit.SECONDS))
|
|
||||||
allFutures.get();
|
|
||||||
} catch (Exception e) {
|
|
||||||
// 全局等待异常(如超时、中断),标记所有未完成的任务为失败
|
|
||||||
handleGlobalException(futureList, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 收集所有任务结果
|
|
||||||
return futureList.stream()
|
|
||||||
// 显式指定泛型类型,让编译器明确知道map的返回类型是TaskResult<T>
|
|
||||||
.<TaskResult<T>>map(future -> {
|
|
||||||
try {
|
|
||||||
// 这里强制指定泛型,避免类型推断模糊
|
|
||||||
return future.get();
|
|
||||||
} catch (Exception e) {
|
|
||||||
// 理论上不会走到这里,因为singleTask已捕获异常,allOf已等待完成
|
|
||||||
return new TaskResult<>(null, false, "结果收集异常:" + e.getMessage());
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行单个任务,捕获任务执行过程中的异常
|
|
||||||
*/
|
|
||||||
private static <T> TaskResult<T> executeSingleTask(Supplier<T> task) {
|
|
||||||
try {
|
|
||||||
T result = task.get();
|
|
||||||
return new TaskResult<>(result, true, null);
|
|
||||||
} catch (Exception e) {
|
|
||||||
// 捕获单个任务的所有异常,封装为失败结果
|
|
||||||
return new TaskResult<>(null, false, "任务执行失败:" + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理全局等待过程中的异常(如超时、中断),标记未完成任务为失败
|
|
||||||
*/
|
|
||||||
private static <T> void handleGlobalException(List<CompletableFuture<TaskResult<T>>> futureList, Exception e) {
|
|
||||||
String errorMsg = "全局等待异常:" + e.getMessage();
|
|
||||||
futureList.forEach(future -> {
|
|
||||||
if (!future.isDone()) {
|
|
||||||
// 取消未完成的任务,并标记为失败
|
|
||||||
future.complete(new TaskResult<>(null, false, errorMsg));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// 恢复线程中断状态(如果是中断异常)
|
|
||||||
if (e instanceof InterruptedException) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 任务结果封装类
|
|
||||||
* 包含:返回值、是否成功、失败信息
|
|
||||||
*
|
|
||||||
* @param <T> 结果类型
|
|
||||||
* @param result Getter 方法 任务返回值(成功时非null)
|
|
||||||
* @param success 是否执行成功
|
|
||||||
* @param errorMsg 失败信息(失败时非null)
|
|
||||||
*/
|
|
||||||
public record TaskResult<T>(T result, boolean success, String errorMsg) {
|
|
||||||
|
|
||||||
// 重写toString,方便打印结果
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
if (success) {
|
|
||||||
return "TaskResult{success=true, result=" + result + "}";
|
|
||||||
} else {
|
|
||||||
return "TaskResult{success=false, errorMsg='" + errorMsg + "'}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 关闭默认线程池(可选,如应用退出时调用)
|
|
||||||
*/
|
|
||||||
public static void shutdownDefaultExecutor() {
|
|
||||||
DEFAULT_EXECUTOR.shutdown();
|
|
||||||
try {
|
|
||||||
if (!DEFAULT_EXECUTOR.awaitTermination(5, TimeUnit.SECONDS)) {
|
|
||||||
DEFAULT_EXECUTOR.shutdownNow();
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
DEFAULT_EXECUTOR.shutdownNow();
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
package com.czg.utils;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.http.HttpClient;
|
|
||||||
import java.net.http.HttpRequest;
|
|
||||||
import java.net.http.HttpResponse;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author yjjie
|
|
||||||
* @date 2026/1/4 13:58
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class UploadFileUtil {
|
|
||||||
|
|
||||||
// 匹配常见的图片扩展名
|
|
||||||
private static final Pattern PATTERN = Pattern.compile("\\.(jpg|jpeg|png|gif|bmp|webp|svg|ico)(?:[\\?#]|$)", Pattern.CASE_INSENSITIVE);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 使用正则表达式提取图片后缀
|
|
||||||
*/
|
|
||||||
public static String extractImageExtension(String imageUrl) {
|
|
||||||
java.util.regex.Matcher matcher = PATTERN.matcher(imageUrl);
|
|
||||||
|
|
||||||
if (matcher.find()) {
|
|
||||||
String extension = matcher.group(1).toLowerCase();
|
|
||||||
// 处理jpeg的情况
|
|
||||||
return "jpeg".equals(extension) ? "jpg" : extension;
|
|
||||||
}
|
|
||||||
// 默认后缀
|
|
||||||
return "png";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据图片URL获取图片文件
|
|
||||||
*
|
|
||||||
* @param url 图片URL
|
|
||||||
* @return 图片文件
|
|
||||||
*/
|
|
||||||
public static File getFileByUrl(String url) throws IOException {
|
|
||||||
byte[] bytes = downloadImage(url);
|
|
||||||
|
|
||||||
Path tempFile = Files.createTempFile("image_", "." + extractImageExtension(url));
|
|
||||||
Files.write(tempFile, bytes);
|
|
||||||
|
|
||||||
return tempFile.toFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 下载图片
|
|
||||||
* @param url 图片地址
|
|
||||||
* @return 图片字节数组
|
|
||||||
*/
|
|
||||||
public static byte[] downloadImage(String url) {
|
|
||||||
HttpClient client = HttpClient.newHttpClient();
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
|
||||||
.uri(URI.create(url))
|
|
||||||
.GET()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
try {
|
|
||||||
HttpResponse<byte[]> response = client.send(request, HttpResponse.BodyHandlers.ofByteArray());
|
|
||||||
|
|
||||||
if (response.statusCode() != 200) {
|
|
||||||
throw new RuntimeException("Failed to download image, status code: " + response.statusCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.body();
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Failed to download image: {}", e.getMessage());
|
|
||||||
return new byte[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 从URL中提取文件名
|
|
||||||
*
|
|
||||||
* @param url 图片URL
|
|
||||||
* @return 提取的文件名,失败则返回默认名
|
|
||||||
*/
|
|
||||||
public static String extractFileNameFromUrl(String url) {
|
|
||||||
try {
|
|
||||||
if (url.contains("/")) {
|
|
||||||
String fileName = url.substring(url.lastIndexOf("/") + 1);
|
|
||||||
// 如果文件名包含参数,截取?之前的部分
|
|
||||||
if (fileName.contains("?")) {
|
|
||||||
fileName = fileName.substring(0, fileName.indexOf("?"));
|
|
||||||
}
|
|
||||||
// 如果提取的文件名有效,直接返回
|
|
||||||
if (fileName.contains(".")) {
|
|
||||||
return fileName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn("提取文件名失败,使用默认文件名", e);
|
|
||||||
}
|
|
||||||
// 默认文件名
|
|
||||||
return "upload_" + System.currentTimeMillis() + ".png";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -13,13 +13,11 @@ import com.czg.entity.CzgBaseRespParams;
|
|||||||
import com.czg.entity.req.*;
|
import com.czg.entity.req.*;
|
||||||
import com.czg.entity.resp.*;
|
import com.czg.entity.resp.*;
|
||||||
import com.czg.enums.CzgPayEnum;
|
import com.czg.enums.CzgPayEnum;
|
||||||
import com.czg.resp.CzgRespCode;
|
|
||||||
import com.czg.resp.CzgResult;
|
import com.czg.resp.CzgResult;
|
||||||
import com.czg.utils.AssertUtil;
|
import com.czg.utils.AssertUtil;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -37,10 +35,9 @@ public class CzgPayUtils {
|
|||||||
* @param domain 域名
|
* @param domain 域名
|
||||||
* @param appId 应用id tb_shop_merchant 表中的 app_id
|
* @param appId 应用id tb_shop_merchant 表中的 app_id
|
||||||
* @param appSecret 应用密钥 tb_shop_merchant 表中的 app_secret
|
* @param appSecret 应用密钥 tb_shop_merchant 表中的 app_secret
|
||||||
* CzgResult<CzgH5PayResp>
|
|
||||||
*/
|
*/
|
||||||
public static CzgResult<Map<String, Object>> h5Pay(@NonNull String domain, @NonNull String appId, @NonNull String appSecret, CzgH5PayReq bizData) {
|
public static CzgResult<CzgH5PayResp> h5Pay(@NonNull String domain, @NonNull String appId, @NonNull String appSecret, CzgH5PayReq bizData) {
|
||||||
return execPayResult(sendCzg(domain.concat(CzgPayEnum.H5PAY.getUri()), CzgBaseReqParams.getInstance(appId, appSecret, bizData), CzgH5PayResp.class));
|
return sendCzg(domain.concat(CzgPayEnum.H5PAY.getUri()), CzgBaseReqParams.getInstance(appId, appSecret, bizData), CzgH5PayResp.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -49,10 +46,9 @@ public class CzgPayUtils {
|
|||||||
* @param domain 域名
|
* @param domain 域名
|
||||||
* @param appId 应用id tb_shop_merchant 表中的 app_id
|
* @param appId 应用id tb_shop_merchant 表中的 app_id
|
||||||
* @param appSecret 应用密钥 tb_shop_merchant 表中的 app_secret
|
* @param appSecret 应用密钥 tb_shop_merchant 表中的 app_secret
|
||||||
* CzgResult<CzgJsPayResp>
|
|
||||||
*/
|
*/
|
||||||
public static CzgResult<Map<String, Object>> jsPay(@NonNull String domain, @NonNull String appId, @NonNull String appSecret, CzgJsPayReq bizData) {
|
public static CzgResult<CzgJsPayResp> jsPay(@NonNull String domain, @NonNull String appId, @NonNull String appSecret, CzgJsPayReq bizData) {
|
||||||
return execPayResult(sendCzg(domain.concat(CzgPayEnum.JSPAY.getUri()), CzgBaseReqParams.getInstance(appId, appSecret, bizData), CzgJsPayResp.class));
|
return sendCzg(domain.concat(CzgPayEnum.JSPAY.getUri()), CzgBaseReqParams.getInstance(appId, appSecret, bizData), CzgJsPayResp.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,10 +57,9 @@ public class CzgPayUtils {
|
|||||||
* @param domain 域名
|
* @param domain 域名
|
||||||
* @param appId 应用id tb_shop_merchant 表中的 app_id
|
* @param appId 应用id tb_shop_merchant 表中的 app_id
|
||||||
* @param appSecret 应用密钥 tb_shop_merchant 表中的 app_secret
|
* @param appSecret 应用密钥 tb_shop_merchant 表中的 app_secret
|
||||||
* CzgResult<CzgLtPayResp>
|
|
||||||
*/
|
*/
|
||||||
public static CzgResult<Map<String, Object>> ltPay(@NonNull String domain, @NonNull String appId, @NonNull String appSecret, CzgLtPayReq bizData) {
|
public static CzgResult<CzgLtPayResp> ltPay(@NonNull String domain, @NonNull String appId, @NonNull String appSecret, CzgLtPayReq bizData) {
|
||||||
return execPayResult(sendCzg(domain.concat(CzgPayEnum.LTPAY.getUri()), CzgBaseReqParams.getInstance(appId, appSecret, bizData), CzgLtPayResp.class));
|
return sendCzg(domain.concat(CzgPayEnum.LTPAY.getUri()), CzgBaseReqParams.getInstance(appId, appSecret, bizData), CzgLtPayResp.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -73,10 +68,9 @@ public class CzgPayUtils {
|
|||||||
* @param domain 域名
|
* @param domain 域名
|
||||||
* @param appId 应用id tb_shop_merchant 表中的 app_id
|
* @param appId 应用id tb_shop_merchant 表中的 app_id
|
||||||
* @param appSecret 应用密钥 tb_shop_merchant 表中的 app_secret
|
* @param appSecret 应用密钥 tb_shop_merchant 表中的 app_secret
|
||||||
* CzgResult<CzgScanPayResp>
|
|
||||||
*/
|
*/
|
||||||
public static CzgResult<Map<String, Object>> scanPay(@NonNull String domain, @NonNull String appId, @NonNull String appSecret, CzgScanPayReq bizData) {
|
public static CzgResult<CzgScanPayResp> scanPay(@NonNull String domain, @NonNull String appId, @NonNull String appSecret, CzgScanPayReq bizData) {
|
||||||
return execPayResult(sendCzg(domain.concat(CzgPayEnum.SCANPAY.getUri()), CzgBaseReqParams.getInstance(appId, appSecret, bizData), CzgScanPayResp.class));
|
return sendCzg(domain.concat(CzgPayEnum.SCANPAY.getUri()), CzgBaseReqParams.getInstance(appId, appSecret, bizData), CzgScanPayResp.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -85,10 +79,9 @@ public class CzgPayUtils {
|
|||||||
* @param domain 域名
|
* @param domain 域名
|
||||||
* @param appId 应用id tb_shop_merchant 表中的 app_id
|
* @param appId 应用id tb_shop_merchant 表中的 app_id
|
||||||
* @param appSecret 应用密钥 tb_shop_merchant 表中的 app_secret
|
* @param appSecret 应用密钥 tb_shop_merchant 表中的 app_secret
|
||||||
* CzgResult<CzgMicroPayResp>
|
|
||||||
*/
|
*/
|
||||||
public static CzgResult<Map<String, Object>> microPay(@NonNull String domain, @NonNull String appId, @NonNull String appSecret, CzgMicroPayReq bizData) {
|
public static CzgResult<CzgMicroPayResp> microPay(@NonNull String domain, @NonNull String appId, @NonNull String appSecret, CzgMicroPayReq bizData) {
|
||||||
return execPayResult(sendCzg(domain.concat(CzgPayEnum.MICROPAY.getUri()), CzgBaseReqParams.getInstance(appId, appSecret, bizData), CzgMicroPayResp.class));
|
return sendCzg(domain.concat(CzgPayEnum.MICROPAY.getUri()), CzgBaseReqParams.getInstance(appId, appSecret, bizData), CzgMicroPayResp.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -236,41 +229,51 @@ public class CzgPayUtils {
|
|||||||
}
|
}
|
||||||
return sortParam;
|
return sortParam;
|
||||||
}
|
}
|
||||||
private static CzgResult<Map<String, Object>> execPayResult(CzgResult<? extends CzgBaseResp> res) {
|
|
||||||
CzgResult<Map<String, Object>> result = CzgResult.success();
|
|
||||||
if (res.getCode() != 200 || res.getData() == null) {
|
|
||||||
result.setCode(500);
|
|
||||||
result.setMsg(res.getMsg());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
CzgBaseResp data = res.getData();
|
|
||||||
|
|
||||||
Map<String, Object> map = new HashMap<>();
|
// public static void main(String[] args) {
|
||||||
switch (data) {
|
//// String appId = "66691a6afdf641f0bf1dc701";
|
||||||
case CzgMicroPayResp ignored -> {
|
// String appId = "66e3dd399a7621f45a6293c1";
|
||||||
if ("TRADE_SUCCESS".equals(data.getState())) {
|
//// String appSecret = "jikd52TefZcSPI5hRWrfPSpQcXZrbqshbnLmqH6UattqspIDEzjbGvZmfwTW58RMf1XuPhN4zE1GbIjKy3b1oabgOx5n79faT93Si6i7g2IPSQJAln2NNsCSNynHIJ8";
|
||||||
return result;
|
// String appSecret = "2p7TCixkN3FuhTqJyr23GNAfrqAqUt84T1IOSunCEEqFBP9gVkSO8CqrfNwNAJqLYuWmQou7lbwdW0Lb4zJVkBEdV7CPq3VhnbGDRIpQXpBNPOjJbor1IFGuLLOA7oll";
|
||||||
} else if ("TRADE_AWAIT".equals(data.getState())) {
|
// CzgJsPayReq bizData = new CzgJsPayReq("20250428150248328893", 100L,
|
||||||
result.setCode(CzgRespCode.WAIT_PAY.getCode());
|
// "订单支付", "or1l867cx6JFbLgmppwtG46AUhwg","1.80.211.145", "http://store.sxczgkj.com/h5/#/pages/user-order/user-order", "", "");
|
||||||
result.setMsg("等待用户付款");
|
// bizData.setCurrency("cny");
|
||||||
} else {
|
// bizData.setPayType("WECHAT");
|
||||||
result.setCode(CzgRespCode.FAILURE.getCode());
|
// bizData.setSubAppid("wxd88fffa983758a30");
|
||||||
}
|
//
|
||||||
}
|
// bizData.setSubject("订单支付");
|
||||||
case CzgH5PayResp h5PayResp ->
|
//// bizData.setStoreId("S2409148611");
|
||||||
map = JSONObject.parseObject(JSONObject.toJSONString(h5PayResp.getPayInfo()));
|
// bizData.setStoreId("S2406120331");
|
||||||
case CzgJsPayResp jsPayResp ->
|
//
|
||||||
map = JSONObject.parseObject(JSONObject.toJSONString(jsPayResp.getPayInfo()));
|
// CzgBaseReqParams params = CzgBaseReqParams.getInstance(appId, appSecret, bizData);
|
||||||
case CzgLtPayResp ltPayResp ->
|
// params.setVersion("1.0");
|
||||||
map = JSONObject.parseObject(JSONObject.toJSONString(ltPayResp.getPayInfo()));
|
// params.setReqId("57143686759273485473");
|
||||||
case CzgScanPayResp scanPayResp ->
|
// params.setReqTime("20250428150248");
|
||||||
map = JSONObject.parseObject(JSONObject.toJSONString(scanPayResp.getPayInfo()));
|
// params.setSignType("MD5");
|
||||||
default -> throw new IllegalStateException("Unexpected value: " + data);
|
// CzgResult<CzgH5PayResp> czgH5PayRespCzgResult = sendCzg("https://paymentapi.sxczgkj.cn/api/open/payment/jspay", params, CzgH5PayResp.class);
|
||||||
}
|
// System.out.println(czgH5PayRespCzgResult);
|
||||||
|
// }
|
||||||
|
|
||||||
result.setData(map);
|
|
||||||
|
|
||||||
return result;
|
// public static void main(String[] args) {
|
||||||
}
|
// CzgResult<Object> result = CzgResult.success();
|
||||||
|
// CzgBaseRespParams respParams = new CzgBaseRespParams();
|
||||||
|
// respParams.setCode("000000");
|
||||||
|
// respParams.setMsg("成功");
|
||||||
|
// respParams.setSign("6c0f1e11b0d3a16298c2dfeee8c1491a");
|
||||||
|
// respParams.setBizData("{\"amount\":500,\"currency\":\"cny\",\"ifCode\":\"lklspay\",\"mchOrderNo\":\"WX1889977729515615615\",\"mercNo\":\"B240612563201\",\"note\":\"成功\",\"payOrderId\":\"202502151890598483156443138V6W\",\"payType\":\"WECHAT\",\"settlementType\":\"D1\",\"state\":\"TRADE_SUCCESS\",\"storeId\":\"S2406125309\",\"subject\":\"超掌柜\",\"tradeFee\":2}");
|
||||||
|
// respParams.setTimestamp("20250215110620");
|
||||||
|
// log.info("超掌柜交易请求响应,{}", respParams);
|
||||||
|
//
|
||||||
|
// result.setCode("000000".equals(respParams.getCode()) ? 200 : Integer.parseInt(respParams.getCode()));
|
||||||
|
// result.setMsg(respParams.getMsg());
|
||||||
|
// if ("000000".equals(respParams.getCode()) && StrUtil.isNotBlank(respParams.getSign())) {
|
||||||
|
// if (validateSign(respParams.getSign(), JSONObject.toJSONString(respParams))) {
|
||||||
|
// log.info("验签失败");
|
||||||
|
// }
|
||||||
|
// result.setData(JSONObject.parseObject(respParams.getBizData(), CzgMicroPayResp.class));
|
||||||
|
// }
|
||||||
|
// System.out.println(JSONObject.toJSONString(result));
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
<description>第三方内容</description>
|
<description>第三方内容</description>
|
||||||
<modules>
|
<modules>
|
||||||
<module>czg-pay</module>
|
<module>czg-pay</module>
|
||||||
<module>aggregation-pay</module>
|
|
||||||
</modules>
|
</modules>
|
||||||
<artifactId>cash-sdk</artifactId>
|
<artifactId>cash-sdk</artifactId>
|
||||||
|
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ public class ShopInfoServiceImpl extends ServiceImpl<ShopInfoMapper, ShopInfo> i
|
|||||||
if (shopInfo == null) {
|
if (shopInfo == null) {
|
||||||
throw new CzgException("店铺不存在");
|
throw new CzgException("店铺不存在");
|
||||||
}
|
}
|
||||||
if (shopInfo.getExpireTime() != null && (DateUtil.date().toLocalDateTime().isAfter(shopInfo.getExpireTime()))) {
|
if (shopInfo.getExpireTime() != null && (LocalDateTime.now().isAfter(shopInfo.getExpireTime()))) {
|
||||||
throw new CzgException("店铺已过期,请联系商家");
|
throw new CzgException("店铺已过期,请联系商家");
|
||||||
}
|
}
|
||||||
if (SystemConstants.OneZero.ZERO == shopInfo.getOnSale() || shopInfo.getStatus() != SystemConstants.OneZero.ONE) {
|
if (SystemConstants.OneZero.ZERO == shopInfo.getOnSale() || shopInfo.getStatus() != SystemConstants.OneZero.ONE) {
|
||||||
@@ -324,15 +324,6 @@ public class ShopInfoServiceImpl extends ServiceImpl<ShopInfoMapper, ShopInfo> i
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@CacheEvict(key = "#shopId")
|
|
||||||
public Boolean editEntry(Long shopId, String wechatMerchantId, String alipayMerchantId) {
|
|
||||||
ShopInfo shopInfo = new ShopInfo();
|
|
||||||
shopInfo.setWechatMerchantId(wechatMerchantId);
|
|
||||||
shopInfo.setAlipayMerchantId(alipayMerchantId);
|
|
||||||
return update(shopInfo, new QueryWrapper().eq(ShopInfo::getId, shopId));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ShopDetailDTO detail(Long id) throws CzgException {
|
public ShopDetailDTO detail(Long id) throws CzgException {
|
||||||
ShopInfo shopInfo = queryChain().eq(ShopInfo::getId, id == null ? StpKit.USER.getShopId() : id).one();
|
ShopInfo shopInfo = queryChain().eq(ShopInfo::getId, id == null ? StpKit.USER.getShopId() : id).one();
|
||||||
|
|||||||
@@ -85,8 +85,6 @@ public class MkDistributionUserServiceImpl extends ServiceImpl<MkDistributionUse
|
|||||||
private ShopUserService shopUserService;
|
private ShopUserService shopUserService;
|
||||||
@DubboReference
|
@DubboReference
|
||||||
private UserInfoService userInfoService;
|
private UserInfoService userInfoService;
|
||||||
@DubboReference
|
|
||||||
private OrderPaymentService orderPaymentService;
|
|
||||||
@Resource
|
@Resource
|
||||||
private OrderInfoService orderInfoService;
|
private OrderInfoService orderInfoService;
|
||||||
@DubboReference
|
@DubboReference
|
||||||
@@ -706,6 +704,16 @@ public class MkDistributionUserServiceImpl extends ServiceImpl<MkDistributionUse
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public void distributionUserAmount(MkDistributionFlow item, OrderInfo orderInfo) {
|
||||||
|
ShopUser shopUser = shopUserService.getById(item.getDistributionUserId());
|
||||||
|
updateShopInfoAmount(orderInfo.getShopId(), item.getRewardAmount().negate(), orderInfo.getId(), TableValueConstant.DistributionAmountFlow.Type.SUB, "分销扣减");
|
||||||
|
updateIncome(item.getRewardAmount().negate(), item.getRewardAmount(), BigDecimal.ZERO,
|
||||||
|
item.getDistributionUserId(), shopUser.getUserId(), item.getShopUserId(), item.getShopId(), item.getLevel());
|
||||||
|
distributionFlowService.updateById(item);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void distribute(Long sourceId, String orderNo, BigDecimal amount, Long sourceUserId, Long shopId, String type) {
|
public void distribute(Long sourceId, String orderNo, BigDecimal amount, Long sourceUserId, Long shopId, String type) {
|
||||||
MkDistributionDeliver deliver = new MkDistributionDeliver().setSourceId(sourceId).setOrderNo(orderNo).setShopId(shopId).setType(type).setStatus("success");
|
MkDistributionDeliver deliver = new MkDistributionDeliver().setSourceId(sourceId).setOrderNo(orderNo).setShopId(shopId).setType(type).setStatus("success");
|
||||||
|
|||||||
@@ -175,9 +175,9 @@ public class MkShopRechargeServiceImpl extends ServiceImpl<MkShopRechargeMapper,
|
|||||||
|
|
||||||
// 标准充值
|
// 标准充值
|
||||||
if (rechargeDetailId != null) {
|
if (rechargeDetailId != null) {
|
||||||
|
MkShopRechargeDetail rechargeDetail = shopRechargeDetailService.getById(rechargeDetailId);
|
||||||
|
shopUserMoneyEditDTO.setMoney(rechargeDetail.getAmount());
|
||||||
FunUtils.asyncSafeRunVoid(() -> {
|
FunUtils.asyncSafeRunVoid(() -> {
|
||||||
MkShopRechargeDetail rechargeDetail = shopRechargeDetailService.getById(rechargeDetailId);
|
|
||||||
shopUserMoneyEditDTO.setMoney(rechargeDetail.getAmount());
|
|
||||||
// 赠送金额
|
// 赠送金额
|
||||||
ShopUserMoneyEditDTO shopUserMoneyEditRewardDTO = new ShopUserMoneyEditDTO()
|
ShopUserMoneyEditDTO shopUserMoneyEditRewardDTO = new ShopUserMoneyEditDTO()
|
||||||
.setId(shopUserId)
|
.setId(shopUserId)
|
||||||
|
|||||||
@@ -361,6 +361,7 @@ public class TbMemberConfigServiceImpl extends ServiceImpl<TbMemberConfigMapper,
|
|||||||
memberExpFlowService.save(expFlow);
|
memberExpFlowService.save(expFlow);
|
||||||
|
|
||||||
upShopUser.setExperience(shopUser.getExperience() + exp);
|
upShopUser.setExperience(shopUser.getExperience() + exp);
|
||||||
|
shopUser.setExperience(upShopUser.getExperience());
|
||||||
// 修改会员等级
|
// 修改会员等级
|
||||||
MemberLevelConfig nextConfig = levelConfigService.getOne(new QueryWrapper().eq(MemberLevelConfig::getShopId, shopUser.getMainShopId())
|
MemberLevelConfig nextConfig = levelConfigService.getOne(new QueryWrapper().eq(MemberLevelConfig::getShopId, shopUser.getMainShopId())
|
||||||
.gt(MemberLevelConfig::getExperienceValue, levelVO.getExperienceValue()).orderBy(MemberLevelConfig::getExperienceValue, true).limit(1));
|
.gt(MemberLevelConfig::getExperienceValue, levelVO.getExperienceValue()).orderBy(MemberLevelConfig::getExperienceValue, true).limit(1));
|
||||||
|
|||||||
@@ -20,12 +20,7 @@
|
|||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.czg</groupId>
|
<groupId>com.czg</groupId>
|
||||||
<artifactId>czg-pay</artifactId>
|
<artifactId>pay-service</artifactId>
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.czg</groupId>
|
|
||||||
<artifactId>aggregation-pay</artifactId>
|
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
package com.czg.service.order.dto;
|
|
||||||
|
|
||||||
import com.czg.dto.req.*;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author ww
|
|
||||||
*/
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Data
|
|
||||||
public class AggregateMerchantVO extends AggregateMerchantDto{
|
|
||||||
|
|
||||||
private LocalDateTime createTime;
|
|
||||||
|
|
||||||
private LocalDateTime updateTime;
|
|
||||||
|
|
||||||
private String errorMsg;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link com.czg.PayCst.EntryStatus}
|
|
||||||
* 微信状态
|
|
||||||
* WAIT 待提交 INIT 待处理 AUDIT 审核中 SIGN 待签约 REJECTED 失败 FINISH 已完成
|
|
||||||
*/
|
|
||||||
private String wechatStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付宝账号
|
|
||||||
*/
|
|
||||||
private String alipayAccount;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信进件错误信息
|
|
||||||
*/
|
|
||||||
private String wechatErrorMsg;
|
|
||||||
/**
|
|
||||||
* 微信进件签名地址
|
|
||||||
*/
|
|
||||||
private String wechatSignUrl;
|
|
||||||
private String wechatApplyId;
|
|
||||||
private String alipayOrderId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link com.czg.PayCst.EntryStatus}
|
|
||||||
* 支付宝状态
|
|
||||||
* WAIT 待提交 INIT 待处理 AUDIT 审核中 SIGN 待签约 REJECTED 失败 FINISH 已完成
|
|
||||||
*/
|
|
||||||
private String alipayStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付宝进件错误信息
|
|
||||||
*/
|
|
||||||
private String alipayErrorMsg;
|
|
||||||
/**
|
|
||||||
* 支付宝进件签名地址
|
|
||||||
*/
|
|
||||||
private String alipaySignUrl;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.czg.service.order.dto;
|
||||||
|
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建订单
|
||||||
|
* @author ww
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CreateOrderDTO {
|
||||||
|
@NotBlank(message = "桌号不能为空")
|
||||||
|
private String tableCode;
|
||||||
|
@NotBlank(message = "用餐模式 堂食 dine-in 外带 take-out 外卖 take-away")
|
||||||
|
private String dineMode;
|
||||||
|
/**
|
||||||
|
* 平台类型
|
||||||
|
* 微信小程序 WX
|
||||||
|
* 支付宝小程序 ALI
|
||||||
|
* 收银机客户端 PC
|
||||||
|
* PC管理端 APC
|
||||||
|
* APP管理端 APP
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "平台类型不能为空")
|
||||||
|
private String platformType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否使用了霸王餐
|
||||||
|
*/
|
||||||
|
private boolean isFreeDine = false;
|
||||||
|
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
// 使用的积分抵扣数量
|
||||||
|
private Integer pointsNum;
|
||||||
|
|
||||||
|
// 使用的优惠券
|
||||||
|
@Valid
|
||||||
|
private List<UserCouponInfoDTO> userCouponInfos = new ArrayList<>();
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package com.czg.service.order.dto;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.DecimalMin;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付接收参数 实体类
|
||||||
|
*
|
||||||
|
* @author ww
|
||||||
|
* @description
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class RechargeDTO {
|
||||||
|
@NotNull(message = "店铺不能为空")
|
||||||
|
private Long shopId;
|
||||||
|
private Long shopUserId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 充值金额id
|
||||||
|
*/
|
||||||
|
private Long rechargeDetailId;
|
||||||
|
@DecimalMin("0.01")
|
||||||
|
private BigDecimal amount;
|
||||||
|
private Integer allPack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 跳转地址
|
||||||
|
*/
|
||||||
|
private String returnUrl;
|
||||||
|
/**
|
||||||
|
* 平台类型 pc 收银机客户端 wechat 微信小程序 alipay 支付宝小程序 admin-pc PC管理端 admin-app APP管理端
|
||||||
|
*/
|
||||||
|
private String platformType;
|
||||||
|
|
||||||
|
private String openId;
|
||||||
|
|
||||||
|
private String buyerRemark;
|
||||||
|
|
||||||
|
private String payType;
|
||||||
|
|
||||||
|
private Long orderId;
|
||||||
|
private Integer seatNum;
|
||||||
|
/**
|
||||||
|
* 用户端 使用 全打包 或者 全不打包
|
||||||
|
*/
|
||||||
|
private Integer userAllPack;
|
||||||
|
|
||||||
|
public boolean isAllPack() {
|
||||||
|
return allPack != null && allPack == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.czg.service.order.dto;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.Min;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class UserCouponInfoDTO {
|
||||||
|
private Long userCouponId;
|
||||||
|
@Min(1)
|
||||||
|
private Integer num;
|
||||||
|
}
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
package com.czg.service.order.mapper;
|
|
||||||
|
|
||||||
import com.mybatisflex.core.BaseMapper;
|
|
||||||
import com.czg.order.entity.ShopDirectMerchant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商户进件 映射层。
|
|
||||||
*
|
|
||||||
* @author ww
|
|
||||||
* @since 2026-01-07
|
|
||||||
*/
|
|
||||||
public interface ShopDirectMerchantMapper extends BaseMapper<ShopDirectMerchant> {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -7,20 +7,33 @@ import java.util.Map;
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分销员支付
|
* 支付
|
||||||
*
|
*
|
||||||
* @author ww
|
* @author ww
|
||||||
*/
|
*/
|
||||||
public interface DistributionPayService {
|
public interface DistributionPayService {
|
||||||
|
/**
|
||||||
|
* 现金支付
|
||||||
|
*/
|
||||||
|
CzgResult<Object> cashPayOrder(MkDistributionPayDTO payParam);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 小程序支付
|
* 小程序支付
|
||||||
*/
|
*/
|
||||||
CzgResult<Map<String, Object>> ltPayOrder(String clintIp, MkDistributionPayDTO payParam);
|
CzgResult<Map<String, Object>> ltPayOrder(String clintIp, MkDistributionPayDTO payParam);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PC扫码支付
|
||||||
|
*/
|
||||||
|
CzgResult<Map<String, Object>> scanPayOrder(String clintIp, MkDistributionPayDTO payParam);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 运营端小程序余额充值
|
* 反扫
|
||||||
*/
|
*/
|
||||||
|
CzgResult<Map<String, Object>> microPayOrder(MkDistributionPayDTO payParam);
|
||||||
|
|
||||||
|
|
||||||
Map<String, String> mchRecharge(String clientIP, MkDistributionPayDTO payParam);
|
Map<String, String> mchRecharge(String clientIP, MkDistributionPayDTO payParam);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,73 +0,0 @@
|
|||||||
package com.czg.service.order.service;
|
|
||||||
|
|
||||||
import com.czg.order.dto.OrderInfoRefundDTO;
|
|
||||||
import com.czg.resp.CzgResult;
|
|
||||||
import com.czg.service.order.dto.OrderPayParamDTO;
|
|
||||||
import lombok.NonNull;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author ww
|
|
||||||
*/
|
|
||||||
public interface OrderPayService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 挂账
|
|
||||||
*/
|
|
||||||
CzgResult<Object> creditPayOrder(OrderPayParamDTO payParam);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 现金支付
|
|
||||||
*/
|
|
||||||
CzgResult<Object> cashPayOrder(OrderPayParamDTO payParam);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 余额支付
|
|
||||||
*/
|
|
||||||
CzgResult<Object> vipPayOrder(OrderPayParamDTO payParam);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* h5支付
|
|
||||||
*/
|
|
||||||
CzgResult<Map<String, Object>> h5PayOrder(String clintIp, OrderPayParamDTO payParam);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* js支付
|
|
||||||
*/
|
|
||||||
CzgResult<Map<String, Object>> jsPayOrder(String clintIp, OrderPayParamDTO payParam);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 空订单支付
|
|
||||||
*/
|
|
||||||
CzgResult<Map<String, Object>> js2PayOrder(@NonNull String clintIp, OrderPayParamDTO payParam);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 小程序支付
|
|
||||||
*/
|
|
||||||
CzgResult<Map<String, Object>> ltPayOrder(String clintIp, OrderPayParamDTO payParam);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PC扫码支付
|
|
||||||
*/
|
|
||||||
CzgResult<Map<String, Object>> scanPayOrder(String clintIp, OrderPayParamDTO payParam);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 聚合反扫
|
|
||||||
*/
|
|
||||||
CzgResult<Map<String, Object>> microPayOrder(OrderPayParamDTO payParam);
|
|
||||||
//-----------------------------------------------------------------订单+会员 一起支付-----------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 充值并付款
|
|
||||||
*/
|
|
||||||
CzgResult<Map<String, Object>> rechargePayOrder(String clintIp, OrderPayParamDTO payParam);
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------退款-----------------------------------------------------------------
|
|
||||||
|
|
||||||
//订单退款
|
|
||||||
CzgResult<Object> refundOrderBefore(OrderInfoRefundDTO param);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,11 +1,15 @@
|
|||||||
package com.czg.service.order.service;
|
package com.czg.service.order.service;
|
||||||
|
|
||||||
import com.czg.entity.req.*;
|
|
||||||
import com.czg.entity.resp.CzgBaseResp;
|
import com.czg.entity.resp.CzgBaseResp;
|
||||||
import com.czg.entity.resp.CzgRefundResp;
|
import com.czg.entity.resp.CzgRefundResp;
|
||||||
import com.czg.order.dto.LtPayOtherDTO;
|
import com.czg.order.dto.LtPayOtherDTO;
|
||||||
|
import com.czg.order.dto.OrderInfoRefundDTO;
|
||||||
import com.czg.order.entity.OrderPayment;
|
import com.czg.order.entity.OrderPayment;
|
||||||
import com.czg.resp.CzgResult;
|
import com.czg.resp.CzgResult;
|
||||||
|
import com.czg.service.order.dto.OrderPayParamDTO;
|
||||||
|
import com.czg.service.order.dto.VipMemberPayParamDTO;
|
||||||
|
import com.czg.service.order.dto.VipPayParamDTO;
|
||||||
|
import com.czg.service.order.dto.VipRefundDTO;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
@@ -18,45 +22,129 @@ import java.util.Map;
|
|||||||
* @author ww
|
* @author ww
|
||||||
*/
|
*/
|
||||||
public interface PayService {
|
public interface PayService {
|
||||||
BigDecimal MONEY_RATE = new BigDecimal("100");
|
//-----------------------------------------------------------------订单支付--------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 挂账
|
||||||
|
*/
|
||||||
|
CzgResult<Object> creditPayOrder(OrderPayParamDTO payParam);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 现金支付
|
||||||
|
*/
|
||||||
|
CzgResult<Object> cashPayOrder(OrderPayParamDTO payParam);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 余额支付
|
||||||
|
*/
|
||||||
|
CzgResult<Object> vipPayOrder(OrderPayParamDTO payParam);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* h5支付
|
||||||
|
*/
|
||||||
|
CzgResult<Map<String, Object>> h5PayOrder(String clintIp, OrderPayParamDTO payParam);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* js支付
|
||||||
|
*/
|
||||||
|
CzgResult<Map<String, Object>> jsPayOrder(String clintIp, OrderPayParamDTO payParam);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空订单支付
|
||||||
|
*/
|
||||||
|
CzgResult<Map<String, Object>> js2PayOrder(@NonNull String clintIp, OrderPayParamDTO payParam);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 小程序支付
|
||||||
|
*/
|
||||||
|
CzgResult<Map<String, Object>> ltPayOrder(String clintIp, OrderPayParamDTO payParam);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PC扫码支付
|
||||||
|
*/
|
||||||
|
CzgResult<Map<String, Object>> scanPayOrder(String clintIp, OrderPayParamDTO payParam);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 聚合反扫
|
||||||
|
*/
|
||||||
|
CzgResult<Map<String, Object>> microPayOrder(OrderPayParamDTO payParam);
|
||||||
|
//-----------------------------------------------------------------订单+会员 一起支付-----------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 充值并付款
|
||||||
|
*/
|
||||||
|
CzgResult<Map<String, Object>> rechargePayOrder(String clintIp, OrderPayParamDTO payParam);
|
||||||
|
//-----------------------------------------------------------------会员支付--------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 现金充值
|
||||||
|
*/
|
||||||
|
CzgResult<Object> cashPayVip(VipPayParamDTO payParam);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* js支付
|
||||||
|
*/
|
||||||
|
CzgResult<Map<String, Object>> jsPayVip(String clintIp, VipPayParamDTO payParam);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 小程序支付
|
||||||
|
*/
|
||||||
|
CzgResult<Map<String, Object>> ltPayVip(String clintIp, VipPayParamDTO payParam);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PC扫码支付
|
||||||
|
*/
|
||||||
|
CzgResult<Map<String, Object>> scanPayVip(String clintIp, VipPayParamDTO payParam);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 聚合反扫
|
||||||
|
*/
|
||||||
|
CzgResult<Map<String, Object>> microPayVip(VipPayParamDTO payParam);
|
||||||
|
//-----------------------------------------------------------------会员开通购买 ----------------------------------------------------------
|
||||||
|
|
||||||
|
CzgResult<Map<String, Object>> ltPayMember(String clientIP, VipMemberPayParamDTO payParam);
|
||||||
|
|
||||||
|
CzgResult<Map<String, Object>> recharge(String clientIP, VipPayParamDTO rechargeDTO, Long userId);
|
||||||
|
|
||||||
|
|
||||||
Long initOrderPayment(OrderPayment payment);
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------付款 ----------------------------------------------------------
|
|
||||||
CzgResult<Map<String, Object>> h5Pay(@NonNull Long shopId, CzgH5PayReq bizData);
|
|
||||||
CzgResult<Map<String, Object>> jsPay(@NonNull Long shopId, @NonNull String payType, CzgJsPayReq bizData);
|
|
||||||
CzgResult<Map<String, Object>> ltPay(@NonNull Long shopId, String payType, CzgLtPayReq bizData);
|
|
||||||
CzgResult<Map<String, Object>> scanPay(@NonNull Long shopId, CzgScanPayReq bizData);
|
|
||||||
CzgResult<Map<String, Object>> microPay(@NonNull Long shopId, CzgMicroPayReq bizData);
|
|
||||||
//-----------------------------------------------------------------积分商品/拼团 付款 ----------------------------------------------------------
|
//-----------------------------------------------------------------积分商品/拼团 付款 ----------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param param 支付参数
|
* @param param 支付参数
|
||||||
* @param payType {@link com.czg.constants.PayTypeConstants.SourceType} 常量
|
* @param payType 暂时只有 POINT 积分 和 WARE 拼团商品
|
||||||
* @param detail 操作描述 如 积分商品购买 / 拼团商品购买
|
* @param detail 操作描述 如 积分商品购买 / 拼团商品购买
|
||||||
*/
|
*/
|
||||||
CzgResult<Map<String, Object>> ltPayOther(LtPayOtherDTO param, String payType, String detail);
|
CzgResult<Map<String, Object>> ltPayOther(LtPayOtherDTO param, String payType, String detail);
|
||||||
|
|
||||||
//-----------------------------------------------------------------退款-----------------------------------------------------------------
|
//-----------------------------------------------------------------退款-----------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款前校验
|
||||||
|
*/
|
||||||
|
CzgResult<Map<String, BigDecimal>> refundVipBefore(VipRefundDTO payParam);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 退款
|
* 会员退款
|
||||||
* 目前订单 会员 使用
|
|
||||||
*/
|
*/
|
||||||
CzgResult<CzgRefundResp> refund(@NonNull Long shopId, CzgRefundReq bizData);
|
CzgResult<Object> refundVip(VipRefundDTO payParam);
|
||||||
|
|
||||||
|
CzgResult<Object> refundOrderBefore(OrderInfoRefundDTO param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单退款
|
||||||
|
*/
|
||||||
|
void refundOrder(Long shopId, Long orderId, Long payOrderId, String refPayOrderNo, String refundReason, BigDecimal refundAmount);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 统一退款接口
|
* 统一退款接口
|
||||||
* 目前 拼团商品 积分商品 套餐推广 使用
|
*
|
||||||
* @param refPayOrderNo 自定义退单号 {@link com.czg.enums.OrderNoPrefixEnum} + 雪花Id
|
* @param refPayOrderNo 自定义退单号 {@link com.czg.enums.OrderNoPrefixEnum} + 雪花Id
|
||||||
*/
|
*/
|
||||||
void unifyRefund(Long shopId, Long sourceId, Long payOrderId, String refPayOrderNo, String refundReason, BigDecimal refundAmount);
|
void unifyRefund(Long shopId, Long sourceId, Long payOrderId, String refPayOrderNo, String refundReason, BigDecimal refundAmount);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 退款补偿使用
|
* 退款补偿使用
|
||||||
* 目前 拼团商品 积分商品 套餐推广 使用
|
|
||||||
* (退款 账户余额不足时 会失败定时任务)
|
|
||||||
*/
|
*/
|
||||||
void unifyRefund(OrderPayment payment, String refPayOrderNo);
|
void unifyRefund(OrderPayment payment, String refPayOrderNo);
|
||||||
|
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
package com.czg.service.order.service;
|
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
|
||||||
import com.czg.dto.req.AggregateMerchantDto;
|
|
||||||
import com.czg.service.order.dto.AggregateMerchantVO;
|
|
||||||
import com.mybatisflex.core.service.IService;
|
|
||||||
import com.czg.order.entity.ShopDirectMerchant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商户进件 服务层。
|
|
||||||
*
|
|
||||||
* @author ww
|
|
||||||
* @since 2026-01-07
|
|
||||||
*/
|
|
||||||
public interface ShopDirectMerchantService extends IService<ShopDirectMerchant> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ocr识别图片
|
|
||||||
* @param url 图片地址
|
|
||||||
* @param type IdCard 身份证
|
|
||||||
* BankCard 银行卡
|
|
||||||
* BusinessLicense 营业执照
|
|
||||||
*/
|
|
||||||
JSONObject getInfoByImg(String url, String type) throws Exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取进件信息
|
|
||||||
*/
|
|
||||||
AggregateMerchantVO getEntry(Long shopId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 申请进件
|
|
||||||
*/
|
|
||||||
boolean entryManager(AggregateMerchantDto reqDto);
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
package com.czg.service.order.service;
|
|
||||||
|
|
||||||
import com.czg.resp.CzgResult;
|
|
||||||
import com.czg.service.order.dto.VipMemberPayParamDTO;
|
|
||||||
import com.czg.service.order.dto.VipPayParamDTO;
|
|
||||||
import com.czg.service.order.dto.VipRefundDTO;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户余额 充值/会员购买开通
|
|
||||||
* @author ww
|
|
||||||
*/
|
|
||||||
public interface ShopUserPayService {
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------会员支付--------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 现金充值
|
|
||||||
*/
|
|
||||||
CzgResult<Object> cashPayVip(VipPayParamDTO payParam);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* js支付
|
|
||||||
*/
|
|
||||||
CzgResult<Map<String, Object>> jsPayVip(String clintIp, VipPayParamDTO payParam);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 小程序支付
|
|
||||||
*/
|
|
||||||
CzgResult<Map<String, Object>> ltPayVip(String clintIp, VipPayParamDTO payParam);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PC扫码支付
|
|
||||||
*/
|
|
||||||
CzgResult<Map<String, Object>> scanPayVip(String clintIp, VipPayParamDTO payParam);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 聚合反扫
|
|
||||||
*/
|
|
||||||
CzgResult<Map<String, Object>> microPayVip(VipPayParamDTO payParam);
|
|
||||||
//-----------------------------------------------------------------会员开通购买 ----------------------------------------------------------
|
|
||||||
|
|
||||||
CzgResult<Map<String, Object>> ltPayMember(String clientIP, VipMemberPayParamDTO payParam);
|
|
||||||
|
|
||||||
CzgResult<Map<String, Object>> recharge(String clientIP, VipPayParamDTO rechargeDTO, Long userId);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------退款-----------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 退款前校验
|
|
||||||
*/
|
|
||||||
CzgResult<Map<String, BigDecimal>> refundVipBefore(VipRefundDTO payParam);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 会员退款
|
|
||||||
*/
|
|
||||||
CzgResult<Object> refundVip(VipRefundDTO payParam);
|
|
||||||
}
|
|
||||||
@@ -3,16 +3,17 @@ package com.czg.service.order.service.impl;
|
|||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
import com.czg.account.entity.ShopUser;
|
import com.czg.account.entity.ShopUser;
|
||||||
import com.czg.account.entity.UserInfo;
|
import com.czg.account.entity.UserInfo;
|
||||||
|
import com.czg.account.service.ShopInfoService;
|
||||||
import com.czg.account.service.ShopUserService;
|
import com.czg.account.service.ShopUserService;
|
||||||
import com.czg.account.service.UserInfoService;
|
import com.czg.account.service.UserInfoService;
|
||||||
import com.czg.constant.TableValueConstant;
|
import com.czg.constant.TableValueConstant;
|
||||||
import com.czg.constants.PayTypeConstants;
|
|
||||||
import com.czg.entity.req.CzgLtPayReq;
|
import com.czg.entity.req.CzgLtPayReq;
|
||||||
import com.czg.exception.CzgException;
|
import com.czg.exception.CzgException;
|
||||||
import com.czg.market.service.MkDistributionConfigService;
|
import com.czg.market.service.MkDistributionConfigService;
|
||||||
import com.czg.market.vo.MkDistributionConfigVO;
|
import com.czg.market.vo.MkDistributionConfigVO;
|
||||||
import com.czg.order.dto.MkDistributionPayDTO;
|
import com.czg.order.dto.MkDistributionPayDTO;
|
||||||
import com.czg.order.entity.OrderPayment;
|
import com.czg.order.entity.OrderPayment;
|
||||||
|
import com.czg.constants.PayTypeConstants;
|
||||||
import com.czg.order.service.OrderPaymentService;
|
import com.czg.order.service.OrderPaymentService;
|
||||||
import com.czg.resp.CzgResult;
|
import com.czg.resp.CzgResult;
|
||||||
import com.czg.service.market.service.impl.WxServiceImpl;
|
import com.czg.service.market.service.impl.WxServiceImpl;
|
||||||
@@ -43,6 +44,8 @@ public class DistributionPayServiceImpl implements DistributionPayService {
|
|||||||
@Resource
|
@Resource
|
||||||
private PayServiceImpl payService;
|
private PayServiceImpl payService;
|
||||||
|
|
||||||
|
@DubboReference
|
||||||
|
private ShopInfoService shopInfoService;
|
||||||
@DubboReference
|
@DubboReference
|
||||||
private ShopUserService shopUserService;
|
private ShopUserService shopUserService;
|
||||||
@DubboReference
|
@DubboReference
|
||||||
@@ -86,6 +89,11 @@ public class DistributionPayServiceImpl implements DistributionPayService {
|
|||||||
return initInfo;
|
return initInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CzgResult<Object> cashPayOrder(MkDistributionPayDTO payParam) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CzgResult<Map<String, Object>> ltPayOrder(String clintIp, MkDistributionPayDTO payParam) {
|
public CzgResult<Map<String, Object>> ltPayOrder(String clintIp, MkDistributionPayDTO payParam) {
|
||||||
InitInfo initInfo = initPayment(payParam.getUserId(), payParam, false);
|
InitInfo initInfo = initPayment(payParam.getUserId(), payParam, false);
|
||||||
@@ -98,4 +106,14 @@ public class DistributionPayServiceImpl implements DistributionPayService {
|
|||||||
InitInfo initInfo = initPayment(payParam.getUserId() == null ? payParam.getShopId() : payParam.getUserId(), payParam, true);
|
InitInfo initInfo = initPayment(payParam.getUserId() == null ? payParam.getShopId() : payParam.getUserId(), payParam, true);
|
||||||
return wxService.v3Pay(initInfo.openId, payParam.getAmount(), "商户运营余额充值", initInfo.payment.getOrderNo(), initInfo.payment.getSourceType());
|
return wxService.v3Pay(initInfo.openId, payParam.getAmount(), "商户运营余额充值", initInfo.payment.getOrderNo(), initInfo.payment.getSourceType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CzgResult<Map<String, Object>> scanPayOrder(String clintIp, MkDistributionPayDTO payParam) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CzgResult<Map<String, Object>> microPayOrder(MkDistributionPayDTO payParam) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1060,7 +1060,8 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService {
|
|||||||
distributionUserService.costUpgradeLevelBefore(orderInfo.getUserId(), orderInfo.getShopId());
|
distributionUserService.costUpgradeLevelBefore(orderInfo.getUserId(), orderInfo.getShopId());
|
||||||
// 分销奖励
|
// 分销奖励
|
||||||
distributionUserService.distribute(orderInfo.getId(), orderInfo.getOrderNo(), payment.getAmount(), orderInfo.getUserId(), orderInfo.getShopId(), "order");
|
distributionUserService.distribute(orderInfo.getId(), orderInfo.getOrderNo(), payment.getAmount(), orderInfo.getUserId(), orderInfo.getShopId(), "order");
|
||||||
} else if (PayTypeConstants.SourceType.MEMBER_IN.equals(payment.getSourceType()) || PayTypeConstants.SourceType.FREE.equals(payment.getSourceType())) {
|
}
|
||||||
|
else if (PayTypeConstants.SourceType.MEMBER_IN.equals(payment.getSourceType()) || PayTypeConstants.SourceType.FREE.equals(payment.getSourceType())) {
|
||||||
boolean isFree = PayTypeConstants.SourceType.FREE.equals(payment.getSourceType());
|
boolean isFree = PayTypeConstants.SourceType.FREE.equals(payment.getSourceType());
|
||||||
ShopUser shopUser = shopUserService.getById(payment.getSourceId());
|
ShopUser shopUser = shopUserService.getById(payment.getSourceId());
|
||||||
OrderInfo orderInfo = null;
|
OrderInfo orderInfo = null;
|
||||||
@@ -1112,17 +1113,22 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService {
|
|||||||
payment.getId(), payment.getSourceType(), bizEnum, orderInfo == null);
|
payment.getId(), payment.getSourceType(), bizEnum, orderInfo == null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (PayTypeConstants.SourceType.MEMBER_PAY.equals(payment.getSourceType())) {
|
}
|
||||||
|
else if (PayTypeConstants.SourceType.MEMBER_PAY.equals(payment.getSourceType())) {
|
||||||
//购买会员
|
//购买会员
|
||||||
ShopUser shopUser = shopUserService.getById(payment.getSourceId());
|
ShopUser shopUser = shopUserService.getById(payment.getSourceId());
|
||||||
memberConfigService.joinMember(payment.getShopId(), shopUser.getUserId(), payment.getRelatedId());
|
memberConfigService.joinMember(payment.getShopId(), shopUser.getUserId(), payment.getRelatedId());
|
||||||
} else if (PayTypeConstants.SourceType.DISTRIBUTION.equals(payment.getSourceType())) {
|
}
|
||||||
|
else if (PayTypeConstants.SourceType.DISTRIBUTION.equals(payment.getSourceType())) {
|
||||||
distributionUserService.open(payment.getSourceId(), payment.getAmount(), payment.getShopId(), payment.getId());
|
distributionUserService.open(payment.getSourceId(), payment.getAmount(), payment.getShopId(), payment.getId());
|
||||||
} else if (PayTypeConstants.SourceType.POINT.equals(payment.getSourceType())) {
|
}
|
||||||
|
else if (PayTypeConstants.SourceType.POINT.equals(payment.getSourceType())) {
|
||||||
goodPayService.payCallBack(payment.getSourceId(), payment.getId());
|
goodPayService.payCallBack(payment.getSourceId(), payment.getId());
|
||||||
} else if (PayTypeConstants.SourceType.WARE.equals(payment.getSourceType())) {
|
}
|
||||||
|
else if (PayTypeConstants.SourceType.WARE.equals(payment.getSourceType())) {
|
||||||
gbOrderService.payCallBack(payment.getSourceId(), payment.getId());
|
gbOrderService.payCallBack(payment.getSourceId(), payment.getId());
|
||||||
} else if (PayTypeConstants.SourceType.PP.equals(payment.getSourceType())) {
|
}
|
||||||
|
else if (PayTypeConstants.SourceType.PP.equals(payment.getSourceType())) {
|
||||||
ppPackageOrderService.paySuccess(payment.getSourceId(), payment.getId());
|
ppPackageOrderService.paySuccess(payment.getSourceId(), payment.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,561 +0,0 @@
|
|||||||
package com.czg.service.order.service.impl;
|
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
|
||||||
import cn.hutool.core.convert.Convert;
|
|
||||||
import cn.hutool.core.util.IdUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.hutool.crypto.SecureUtil;
|
|
||||||
import cn.hutool.crypto.digest.MD5;
|
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
|
||||||
import com.czg.account.dto.shopuser.ShopUserMoneyEditDTO;
|
|
||||||
import com.czg.account.entity.ShopInfo;
|
|
||||||
import com.czg.account.entity.ShopUser;
|
|
||||||
import com.czg.account.entity.UserInfo;
|
|
||||||
import com.czg.account.service.ShopInfoService;
|
|
||||||
import com.czg.account.service.ShopUserService;
|
|
||||||
import com.czg.account.service.UserInfoService;
|
|
||||||
import com.czg.config.RabbitPublisher;
|
|
||||||
import com.czg.config.RedisCst;
|
|
||||||
import com.czg.constants.PayTypeConstants;
|
|
||||||
import com.czg.entity.req.*;
|
|
||||||
import com.czg.entity.resp.CzgRefundResp;
|
|
||||||
import com.czg.enums.ShopUserFlowBizEnum;
|
|
||||||
import com.czg.exception.CzgException;
|
|
||||||
import com.czg.exception.PaySuccessException;
|
|
||||||
import com.czg.market.entity.MkShopRechargeDetail;
|
|
||||||
import com.czg.market.enums.PointsConstant;
|
|
||||||
import com.czg.market.service.*;
|
|
||||||
import com.czg.market.vo.MkShopRechargeVO;
|
|
||||||
import com.czg.order.dto.CheckOrderPay;
|
|
||||||
import com.czg.order.dto.OrderInfoRefundDTO;
|
|
||||||
import com.czg.order.entity.OrderDetail;
|
|
||||||
import com.czg.order.entity.OrderInfo;
|
|
||||||
import com.czg.order.entity.OrderPayment;
|
|
||||||
import com.czg.order.enums.PayEnums;
|
|
||||||
import com.czg.order.service.CreditBuyerOrderService;
|
|
||||||
import com.czg.order.service.OrderDetailService;
|
|
||||||
import com.czg.order.service.OrderInfoCustomService;
|
|
||||||
import com.czg.order.service.OrderPaymentService;
|
|
||||||
import com.czg.resp.CzgResult;
|
|
||||||
import com.czg.service.RedisService;
|
|
||||||
import com.czg.service.order.dto.OrderPayParamDTO;
|
|
||||||
import com.czg.service.order.enums.OrderStatusEnums;
|
|
||||||
import com.czg.service.order.service.OrderPayService;
|
|
||||||
import com.czg.service.order.service.PayService;
|
|
||||||
import com.czg.utils.AssertUtil;
|
|
||||||
import com.czg.utils.CzgRandomUtils;
|
|
||||||
import com.czg.utils.FunUtils;
|
|
||||||
import com.mybatisflex.core.query.QueryWrapper;
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import jakarta.validation.constraints.NotBlank;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.apache.dubbo.config.annotation.DubboReference;
|
|
||||||
import org.springframework.scheduling.annotation.Async;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.RoundingMode;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Service
|
|
||||||
public class OrderPayServiceImpl implements OrderPayService {
|
|
||||||
@Resource
|
|
||||||
private PayService payService;
|
|
||||||
@Resource
|
|
||||||
private OrderPaymentService paymentService;
|
|
||||||
@DubboReference
|
|
||||||
private ShopUserService shopUserService;
|
|
||||||
@DubboReference
|
|
||||||
private UserInfoService userInfoService;
|
|
||||||
@DubboReference
|
|
||||||
private ShopInfoService shopInfoService;
|
|
||||||
@Resource
|
|
||||||
private OrderInfoCustomService orderInfoCustomService;
|
|
||||||
@Resource
|
|
||||||
private OrderInfoService orderInfoService;
|
|
||||||
@Resource
|
|
||||||
private CreditBuyerOrderService buyerOrderService;
|
|
||||||
@Resource
|
|
||||||
private RedisService redisService;
|
|
||||||
@Resource
|
|
||||||
private RabbitPublisher rabbitPublisher;
|
|
||||||
@Resource
|
|
||||||
private MkShopRechargeService shopRechargeService;
|
|
||||||
@Resource
|
|
||||||
private MkShopRechargeDetailService shopRechargeDetailService;
|
|
||||||
@Resource
|
|
||||||
private OrderDetailService orderDetailService;
|
|
||||||
@Resource
|
|
||||||
private MkDistributionUserService distributionUserService;
|
|
||||||
@Resource
|
|
||||||
private MkShopConsumerCouponService consumerCouponService;
|
|
||||||
@Resource
|
|
||||||
private MkPointsUserService mkPointsUserService;
|
|
||||||
@Resource
|
|
||||||
private MkConsumeCashbackService consumeCashbackService;
|
|
||||||
@Resource
|
|
||||||
private MkPointsConfigService pointsConfigService;
|
|
||||||
|
|
||||||
private OrderInfo checkPay(CheckOrderPay checkOrderPay) {
|
|
||||||
OrderInfo orderInfo = orderInfoCustomService.checkOrderPay(checkOrderPay);
|
|
||||||
if (orderInfo.getOrderAmount().compareTo(BigDecimal.ZERO) == 0) {
|
|
||||||
//发送打票信息
|
|
||||||
//orderId_0_0 订单ID_先付后付(1先付0后付)_订单状态 0未完成 1完成
|
|
||||||
//orderInfo.getId() + "_" + (!"after-pay".equals(orderInfo.getPayMode()) ? 1 : 0) + "_0"
|
|
||||||
rabbitPublisher.sendOrderPrintMsg(orderInfo.getId() + "_" + (!"after-pay".equals(orderInfo.getPayMode()) ? 1 : 0) + "_1", orderInfo.getIsPrint() == 1);
|
|
||||||
redisService.del(RedisCst.classKeyExpired.EXPIRED_ORDER + orderInfo.getId());
|
|
||||||
throw new PaySuccessException("支付成功");
|
|
||||||
}
|
|
||||||
return orderInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(noRollbackFor = PaySuccessException.class)
|
|
||||||
public CzgResult<Object> creditPayOrder(OrderPayParamDTO payParam) {
|
|
||||||
AssertUtil.isNull(payParam.getCreditBuyerId(), "请选择挂账人后支付");
|
|
||||||
OrderInfo orderInfo = checkPay(payParam.getCheckOrderPay());
|
|
||||||
orderInfo.setCreditBuyerId(payParam.getCreditBuyerId());
|
|
||||||
orderInfoCustomService.upOrderInfo(orderInfo, orderInfo.getOrderAmount(),
|
|
||||||
LocalDateTime.now(), null, PayEnums.CREDIT_PAY);
|
|
||||||
//挂账后续逻辑
|
|
||||||
buyerOrderService.save(payParam.getCreditBuyerId().toString(), orderInfo.getId());
|
|
||||||
return CzgResult.success();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(noRollbackFor = PaySuccessException.class)
|
|
||||||
public CzgResult<Object> cashPayOrder(OrderPayParamDTO payParam) {
|
|
||||||
OrderInfo orderInfo = checkPay(payParam.getCheckOrderPay());
|
|
||||||
orderInfoCustomService.upOrderInfo(orderInfo, orderInfo.getOrderAmount(),
|
|
||||||
LocalDateTime.now(), null, PayEnums.CASH_PAY);
|
|
||||||
return CzgResult.success();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(noRollbackFor = PaySuccessException.class)
|
|
||||||
public CzgResult<Object> vipPayOrder(OrderPayParamDTO payParam) {
|
|
||||||
ShopInfo shopInfo = shopInfoService.getById(payParam.getShopId());
|
|
||||||
AssertUtil.isNull(shopInfo, "店铺不存在");
|
|
||||||
if (!shopInfo.getIsAccountPay().equals(1)) {
|
|
||||||
return CzgResult.failure("支付失败,店铺暂未开启会员余额支付。");
|
|
||||||
}
|
|
||||||
ShopUser shopUser = new ShopUser();
|
|
||||||
if ("scanCode".equals(payParam.getPayType())) {
|
|
||||||
AssertUtil.isBlank(payParam.getAuthCode(), "会员码不能为空");
|
|
||||||
Object o = redisService.get(RedisCst.SHOP_USER_DYNAMIC_CODE + payParam.getShopId() + ":" + payParam.getAuthCode());
|
|
||||||
AssertUtil.isNull(o, "会员码已失效");
|
|
||||||
shopUser = shopUserService.getById(o.toString());
|
|
||||||
} else {
|
|
||||||
if ("userPay".equals(payParam.getPayType())) {
|
|
||||||
AssertUtil.isNull(payParam.getShopUserId(), "请选择付款人后重试");
|
|
||||||
shopUser = shopUserService.getById(payParam.getShopUserId());
|
|
||||||
} else if ("accountPay".equals(payParam.getPayType())) {
|
|
||||||
shopUser = shopUserService.getById(payParam.getShopUserId());
|
|
||||||
AssertUtil.isNull(shopUser, "会员不存在");
|
|
||||||
UserInfo userInfo = userInfoService.getById(shopUser.getUserId());
|
|
||||||
AssertUtil.isNull(userInfo, "用户信息不存在");
|
|
||||||
if (userInfo.getUsePayPwd() == 1) {
|
|
||||||
AssertUtil.isBlank(payParam.getPwd(), "支付密码不能为空");
|
|
||||||
if (userInfo.getPayPwd() == null || !userInfo.getPayPwd().equals(MD5.create().digestHex((payParam.getPwd())))) {
|
|
||||||
return CzgResult.failure("支付密码错误");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (shopUser == null || shopUser.getId() == null) {
|
|
||||||
AssertUtil.isNull(shopUser, "会员不存在");
|
|
||||||
}
|
|
||||||
payParam.getCheckOrderPay().setUserId(shopUser.getUserId());
|
|
||||||
OrderInfo orderInfo = checkPay(payParam.getCheckOrderPay());
|
|
||||||
if (shopInfo.getIsHeadShop().equals(1)) {
|
|
||||||
if (!shopUser.getMainShopId().equals(orderInfo.getShopId())) {
|
|
||||||
return CzgResult.failure("违规操作,请确认店铺后重试");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
boolean exists = shopInfoService.exists(QueryWrapper.create()
|
|
||||||
.eq(ShopInfo::getMainId, shopInfo.getMainId())
|
|
||||||
.eq(ShopInfo::getId, orderInfo.getShopId()));
|
|
||||||
if (!exists) {
|
|
||||||
return CzgResult.failure("违规操作,请确认店铺后重试");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (shopUser.getAmount().compareTo(orderInfo.getOrderAmount()) < 0) {
|
|
||||||
return CzgResult.failure("会员余额不足");
|
|
||||||
}
|
|
||||||
ShopUserMoneyEditDTO shopUserMoneyEditDTO = new ShopUserMoneyEditDTO()
|
|
||||||
.setId(shopUser.getId())
|
|
||||||
.setMoney(orderInfo.getOrderAmount())
|
|
||||||
.setType(0)
|
|
||||||
.setBizEnum(ShopUserFlowBizEnum.ORDER_PAY)
|
|
||||||
.setRelationId(orderInfo.getId());
|
|
||||||
//更新会员余额 并生成流水
|
|
||||||
if (payParam.getCheckOrderPay() != null && StrUtil.isNotBlank(payParam.getCheckOrderPay().getRemark())) {
|
|
||||||
orderInfo.setRemark(payParam.getCheckOrderPay().getRemark());
|
|
||||||
}
|
|
||||||
|
|
||||||
Long flowId = shopUserService.updateMoney(shopUserMoneyEditDTO);
|
|
||||||
orderInfoCustomService.upOrderInfo(orderInfo, orderInfo.getOrderAmount(),
|
|
||||||
LocalDateTime.now(), flowId, PayEnums.VIP_PAY);
|
|
||||||
return CzgResult.success();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CzgResult<Map<String, Object>> rechargePayOrder(String clintIp, OrderPayParamDTO payParam) {
|
|
||||||
OrderInfo orderInfo = checkPay(payParam.getCheckOrderPay());
|
|
||||||
ShopInfo shopInfo = shopInfoService.getById(payParam.getShopId());
|
|
||||||
AssertUtil.isNull(shopInfo, "店铺不存在");
|
|
||||||
AssertUtil.isNull(payParam.getShopUserId(), "请选择付款人后重试");
|
|
||||||
ShopUser shopUser = shopUserService.getById(payParam.getShopUserId());
|
|
||||||
AssertUtil.isNull(shopUser, "支付失败 该店铺用户不存在");
|
|
||||||
AssertUtil.isBlank(payParam.getPayType(), "支付方式不能为空");
|
|
||||||
UserInfo userInfo = userInfoService.getById(shopUser.getUserId());
|
|
||||||
AssertUtil.isNull(payParam.getRechargeId(), "请选择充值配置后重试");
|
|
||||||
AssertUtil.isNull(payParam.getRechargeDetailId(), "请选择充值配置后重试");
|
|
||||||
//查询活动Id 获取金额字段
|
|
||||||
MkShopRechargeDetail rechargeDetail = shopRechargeDetailService.getOne(
|
|
||||||
new QueryWrapper().eq(MkShopRechargeDetail::getId, payParam.getRechargeDetailId())
|
|
||||||
.eq(MkShopRechargeDetail::getShopRechargeId, payParam.getRechargeId()));
|
|
||||||
AssertUtil.isNull(rechargeDetail, "充值配置不存在");
|
|
||||||
if (orderInfo.getOrderAmount().compareTo(rechargeDetail.getAmount()) >= 0) {
|
|
||||||
log.info("充值金额小于订单金额,充值金额:{} 订单金额:{}", rechargeDetail.getAmount(), orderInfo.getOrderAmount());
|
|
||||||
return CzgResult.failure("支付失败 充值金额必须大雨订单金额");
|
|
||||||
}
|
|
||||||
String payOrderNo = orderInfo.getPlatformType() + CzgRandomUtils.snowflake();
|
|
||||||
Long paymentId = payService.initOrderPayment(new OrderPayment(payParam.getShopId(), shopUser.getId(), PayTypeConstants.SourceType.MEMBER_IN, PayTypeConstants.PayType.PAY, payOrderNo,
|
|
||||||
"", rechargeDetail.getAmount(), rechargeDetail.getId()));
|
|
||||||
upOrderPayInfo(orderInfo.getId(), PayEnums.VIP_PAY, paymentId,
|
|
||||||
payParam.getCheckOrderPay() == null ? null : payParam.getCheckOrderPay().getRemark());
|
|
||||||
return payService.ltPay(payParam.getShopId(), payParam.getPayType(), new CzgLtPayReq(payOrderNo, rechargeDetail.getAmount().multiply(PayService.MONEY_RATE).longValue(),
|
|
||||||
payParam.getPayType(), "充值并支付", "wechatPay".equals(payParam.getPayType()) ? userInfo.getWechatOpenId() : userInfo.getAlipayOpenId(),
|
|
||||||
clintIp, payParam.getReturnUrl(), payParam.getBuyerRemark(), ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(noRollbackFor = PaySuccessException.class)
|
|
||||||
public CzgResult<Map<String, Object>> h5PayOrder(@NonNull String clintIp, OrderPayParamDTO payParam) {
|
|
||||||
OrderInfo orderInfo = checkPay(payParam.getCheckOrderPay());
|
|
||||||
String payOrderNo = orderInfo.getPlatformType() + CzgRandomUtils.snowflake();
|
|
||||||
Long paymentId = payService.initOrderPayment(new OrderPayment(payParam.getShopId(), orderInfo.getId(),
|
|
||||||
PayTypeConstants.SourceType.ORDER, PayTypeConstants.PayType.PAY, payOrderNo, "", orderInfo.getOrderAmount()));
|
|
||||||
upOrderPayInfo(orderInfo.getId(), PayEnums.H5_PAY, paymentId,
|
|
||||||
payParam.getCheckOrderPay() == null ? null : payParam.getCheckOrderPay().getRemark());
|
|
||||||
return payService.h5Pay(payParam.getShopId(), new CzgH5PayReq(payOrderNo, orderInfo.getOrderAmount().multiply(PayService.MONEY_RATE).longValue(),
|
|
||||||
"点餐支付", clintIp, payParam.getReturnUrl(), payParam.getBuyerRemark(), ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(noRollbackFor = PaySuccessException.class)
|
|
||||||
public CzgResult<Map<String, Object>> jsPayOrder(@NonNull String clintIp, OrderPayParamDTO payParam) {
|
|
||||||
OrderInfo orderInfo = checkPay(payParam.getCheckOrderPay());
|
|
||||||
AssertUtil.isBlank(payParam.getPayType(), "支付方式不能为空");
|
|
||||||
AssertUtil.isBlank(payParam.getOpenId(), "用户小程序ID不能为空");
|
|
||||||
String payOrderNo = orderInfo.getPlatformType() + CzgRandomUtils.snowflake();
|
|
||||||
Long paymentId = payService.initOrderPayment(new OrderPayment(payParam.getShopId(), orderInfo.getId(),
|
|
||||||
PayTypeConstants.SourceType.ORDER, PayTypeConstants.PayType.PAY, payOrderNo, "", orderInfo.getOrderAmount()));
|
|
||||||
upOrderPayInfo(orderInfo.getId(), "aliPay".equals(payParam.getPayType()) ? PayEnums.ALIPAY_MINI : PayEnums.WECHAT_MINI, paymentId,
|
|
||||||
payParam.getCheckOrderPay() == null ? null : payParam.getCheckOrderPay().getRemark());
|
|
||||||
return payService.jsPay(payParam.getShopId(), payParam.getPayType(), new CzgJsPayReq(payOrderNo, orderInfo.getOrderAmount().multiply(PayService.MONEY_RATE).longValue(),
|
|
||||||
"点餐支付", payParam.getOpenId(), clintIp, payParam.getReturnUrl(), payParam.getBuyerRemark(), ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(noRollbackFor = PaySuccessException.class)
|
|
||||||
public CzgResult<Map<String, Object>> js2PayOrder(@NonNull String clintIp, OrderPayParamDTO payParam) {
|
|
||||||
AssertUtil.isBlank(payParam.getPayType(), "支付方式不能为空");
|
|
||||||
AssertUtil.isBlank(payParam.getOpenId(), "用户小程序ID不能为空");
|
|
||||||
OrderInfo orderInfo;
|
|
||||||
if (payParam.getCheckOrderPay().getOrderId() == null) {
|
|
||||||
if (payParam.getCheckOrderPay().getOrderAmount() == null || payParam.getCheckOrderPay().getOrderAmount().compareTo(BigDecimal.ZERO) <= 0) {
|
|
||||||
throw new CzgException("支付金额不合法");
|
|
||||||
}
|
|
||||||
orderInfo = orderInfoCustomService.createPayOrder(payParam.getShopId(), payParam.getCheckOrderPay().getOrderAmount(),
|
|
||||||
payParam.getCheckOrderPay().getRemark());
|
|
||||||
} else {
|
|
||||||
orderInfo = orderInfoService.getById(payParam.getCheckOrderPay().getOrderId());
|
|
||||||
}
|
|
||||||
String payOrderNo = orderInfo.getPlatformType() + CzgRandomUtils.snowflake();
|
|
||||||
Long paymentId = payService.initOrderPayment(new OrderPayment(payParam.getShopId(), orderInfo.getId(),
|
|
||||||
PayTypeConstants.SourceType.ORDER, PayTypeConstants.PayType.PAY, payOrderNo, "", orderInfo.getOrderAmount()));
|
|
||||||
upOrderPayInfo(orderInfo.getId(), "aliPay".equals(payParam.getPayType()) ? PayEnums.ALIPAY_MINI : PayEnums.WECHAT_MINI, paymentId,
|
|
||||||
payParam.getCheckOrderPay() == null ? null : payParam.getCheckOrderPay().getRemark());
|
|
||||||
return payService.jsPay(payParam.getShopId(), payParam.getPayType(), new CzgJsPayReq(payOrderNo, orderInfo.getOrderAmount().multiply(PayService.MONEY_RATE).longValue(),
|
|
||||||
"点餐支付", payParam.getOpenId(), clintIp, payParam.getReturnUrl(), payParam.getBuyerRemark(), ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(noRollbackFor = PaySuccessException.class)
|
|
||||||
public CzgResult<Map<String, Object>> ltPayOrder(@NonNull String clintIp, OrderPayParamDTO payParam) {
|
|
||||||
OrderInfo orderInfo = checkPay(payParam.getCheckOrderPay());
|
|
||||||
AssertUtil.isBlank(payParam.getPayType(), "支付方式不能为空");
|
|
||||||
AssertUtil.isBlank(payParam.getOpenId(), "用户小程序ID不能为空");
|
|
||||||
String payOrderNo = orderInfo.getPlatformType() + CzgRandomUtils.snowflake();
|
|
||||||
Long paymentId = payService.initOrderPayment(new OrderPayment(payParam.getShopId(), orderInfo.getId(),
|
|
||||||
PayTypeConstants.SourceType.ORDER, PayTypeConstants.PayType.PAY, payOrderNo, "", orderInfo.getOrderAmount()));
|
|
||||||
upOrderPayInfo(orderInfo.getId(), "aliPay".equals(payParam.getPayType()) ? PayEnums.ALIPAY_MINI : PayEnums.WECHAT_MINI, paymentId,
|
|
||||||
payParam.getCheckOrderPay() == null ? null : payParam.getCheckOrderPay().getRemark());
|
|
||||||
return payService.ltPay(payParam.getShopId(), payParam.getPayType(), new CzgLtPayReq(payOrderNo, orderInfo.getOrderAmount().multiply(PayService.MONEY_RATE).longValue(),
|
|
||||||
payParam.getPayType(), "点餐支付", payParam.getOpenId(), clintIp, payParam.getReturnUrl(), payParam.getBuyerRemark(), ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(noRollbackFor = PaySuccessException.class)
|
|
||||||
public CzgResult<Map<String, Object>> scanPayOrder(@NonNull String clintIp, OrderPayParamDTO payParam) {
|
|
||||||
OrderInfo orderInfo = checkPay(payParam.getCheckOrderPay());
|
|
||||||
ShopUser shopUser = shopUserService.getById(payParam.getShopUserId());
|
|
||||||
MkShopRechargeVO rechargeVO = shopRechargeService.detail(payParam.getShopId());
|
|
||||||
if (payParam.getRechargeDetailId() == null && rechargeVO.getIsCustom() == 0) {
|
|
||||||
throw new CzgException("未开启自定义充值金额");
|
|
||||||
}
|
|
||||||
Long mainShopId = shopInfoService.getMainIdByShopId(payParam.getShopId());
|
|
||||||
BigDecimal amount = shopRechargeService.checkRecharge(mainShopId, payParam.getShopId(), shopUser.getUserId(), payParam.getRechargeDetailId(), payParam.getAmount());
|
|
||||||
payParam.setAmount(amount);
|
|
||||||
String payOrderNo = orderInfo.getPlatformType() + CzgRandomUtils.snowflake();
|
|
||||||
Long paymentId = payService.initOrderPayment(new OrderPayment(payParam.getShopId(), orderInfo.getId(),
|
|
||||||
PayTypeConstants.SourceType.ORDER, PayTypeConstants.PayType.PAY, payOrderNo, "", orderInfo.getOrderAmount()));
|
|
||||||
upOrderPayInfo(orderInfo.getId(), PayEnums.MAIN_SCAN, paymentId,
|
|
||||||
payParam.getCheckOrderPay() == null ? null : payParam.getCheckOrderPay().getRemark());
|
|
||||||
return payService.scanPay(payParam.getShopId(), new CzgScanPayReq(payOrderNo, orderInfo.getOrderAmount().multiply(PayService.MONEY_RATE).longValue(),
|
|
||||||
"点餐支付", clintIp, payParam.getReturnUrl(), payParam.getBuyerRemark(), ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(noRollbackFor = PaySuccessException.class)
|
|
||||||
public CzgResult<Map<String, Object>> microPayOrder(OrderPayParamDTO payParam) {
|
|
||||||
OrderInfo orderInfo = checkPay(payParam.getCheckOrderPay());
|
|
||||||
AssertUtil.isBlank(payParam.getAuthCode(), "扫描码不能为空");
|
|
||||||
|
|
||||||
|
|
||||||
if (payParam.getShopUserId() != null) {
|
|
||||||
ShopUser shopUser = shopUserService.getById(payParam.getShopUserId());
|
|
||||||
MkShopRechargeVO rechargeVO = shopRechargeService.detail(payParam.getShopId());
|
|
||||||
if (payParam.getRechargeDetailId() == null && rechargeVO.getIsCustom() == 0) {
|
|
||||||
throw new CzgException("未开启自定义充值金额");
|
|
||||||
}
|
|
||||||
Long mainShopId = shopInfoService.getMainIdByShopId(payParam.getShopId());
|
|
||||||
BigDecimal amount = shopRechargeService.checkRecharge(mainShopId, payParam.getShopId(), shopUser.getUserId(), payParam.getRechargeDetailId(), payParam.getAmount());
|
|
||||||
payParam.setAmount(amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
String payOrderNo = orderInfo.getPlatformType() + CzgRandomUtils.snowflake();
|
|
||||||
Long paymentId = payService.initOrderPayment(new OrderPayment(payParam.getShopId(), orderInfo.getId(),
|
|
||||||
PayTypeConstants.SourceType.ORDER, PayTypeConstants.PayType.PAY, payOrderNo, payParam.getAuthCode(), orderInfo.getOrderAmount()));
|
|
||||||
CzgResult<Map<String, Object>> mapCzgResult = payService.microPay(payParam.getShopId(), new CzgMicroPayReq(payOrderNo, orderInfo.getOrderAmount().multiply(PayService.MONEY_RATE).longValue(),
|
|
||||||
"点餐支付", payParam.getAuthCode(), payParam.getBuyerRemark(), ""));
|
|
||||||
if (mapCzgResult.getCode() == 200) {
|
|
||||||
orderInfoCustomService.upOrderInfo(orderInfo, orderInfo.getOrderAmount(),
|
|
||||||
LocalDateTime.now(), paymentId, PayEnums.BACK_SCAN);
|
|
||||||
} else {
|
|
||||||
upOrderPayInfo(orderInfo.getId(), PayEnums.BACK_SCAN, paymentId,
|
|
||||||
payParam.getCheckOrderPay() == null ? null : payParam.getCheckOrderPay().getRemark());
|
|
||||||
}
|
|
||||||
return mapCzgResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public CzgResult<Object> refundOrderBefore(OrderInfoRefundDTO param) {
|
|
||||||
OrderInfo orderInfo = orderInfoService.getById(param.getOrderId());
|
|
||||||
if (orderInfo.getStatus().equals(OrderStatusEnums.CANCELLED.getCode())) {
|
|
||||||
throw new CzgException("订单已过期不可退单");
|
|
||||||
}
|
|
||||||
boolean isFirstRefund = true;
|
|
||||||
if (orderInfo.getRefundAmount().compareTo(BigDecimal.ZERO) != 0) {
|
|
||||||
isFirstRefund = false;
|
|
||||||
}
|
|
||||||
ShopInfo shopInfo = shopInfoService.getById(orderInfo.getShopId());
|
|
||||||
Map<String, BigDecimal> returnProMap = new HashMap<>();
|
|
||||||
boolean isPay = true;
|
|
||||||
String refPayOrderNo = "REFO" + IdUtil.getSnowflakeNextId();
|
|
||||||
if (orderInfo.getStatus().equals(OrderStatusEnums.UNPAID.getCode())) {
|
|
||||||
isPay = false;
|
|
||||||
refPayOrderNo = "";
|
|
||||||
}
|
|
||||||
if (isPay) {
|
|
||||||
if (shopInfo.getIsReturnPwd().equals(1)) {
|
|
||||||
AssertUtil.isBlank(shopInfo.getOperationPwd(), "请设置操作密码后使用");
|
|
||||||
if (!SecureUtil.md5(param.getPwd()).equals(shopInfo.getOperationPwd())) {
|
|
||||||
throw new CzgException("操作密码错误");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
orderInfo.setRefundAmount(orderInfo.getRefundAmount().add(param.getRefundAmount()));
|
|
||||||
if (orderInfo.getRefundAmount().compareTo(orderInfo.getPayAmount()) > 0) {
|
|
||||||
throw new CzgException("退单失败,可退金额不足");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (CollUtil.isNotEmpty(param.getRefundDetails())) {
|
|
||||||
for (OrderDetail refundDetail : param.getRefundDetails()) {
|
|
||||||
AssertUtil.isNull(refundDetail.getNum(), "退单数量不能为空");
|
|
||||||
//退款数量
|
|
||||||
BigDecimal refNum = refundDetail.getNum();
|
|
||||||
OrderDetail orderDetail = orderDetailService.getById(refundDetail.getId());
|
|
||||||
//可退数量=订单数量-退单数量-退菜数量
|
|
||||||
BigDecimal returnNum = orderDetail.getNum().subtract(orderDetail.getRefundNum()).subtract(orderDetail.getReturnNum());
|
|
||||||
if (returnNum.compareTo(BigDecimal.ZERO) <= 0 || returnNum.compareTo(refundDetail.getNum()) < 0) {
|
|
||||||
throw new CzgException("退单失败," + orderDetail.getProductName() + "可退数量不足");
|
|
||||||
}
|
|
||||||
refundDetail.setReturnAmount(refundDetail.getNum().multiply(orderDetail.getUnitPrice()).setScale(2, RoundingMode.UP));
|
|
||||||
if (isPay) {
|
|
||||||
orderDetail.setRefundNum(orderDetail.getRefundNum().add(refNum));
|
|
||||||
if (orderDetail.getNum().compareTo(orderDetail.getRefundNum().add(orderDetail.getReturnNum())) == 0) {
|
|
||||||
orderDetail.setStatus(OrderStatusEnums.REFUND.getCode());
|
|
||||||
} else {
|
|
||||||
orderDetail.setStatus(OrderStatusEnums.PART_REFUND.getCode());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
orderDetail.setReturnNum(orderDetail.getReturnNum().add(refNum));
|
|
||||||
if (orderDetail.getPackNumber().compareTo(BigDecimal.ZERO) > 0 && orderDetail.getPackNumber().compareTo(orderDetail.getNum().subtract(orderDetail.getReturnNum())) > 0) {
|
|
||||||
orderDetail.setPackNumber(orderDetail.getNum().subtract(orderDetail.getReturnNum()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
orderDetail.setRefundNo(refPayOrderNo);
|
|
||||||
orderDetail.setRefundRemark(orderDetail.getRefundRemark() + param.getRefundReason());
|
|
||||||
// if (isPay) {
|
|
||||||
orderDetail.setReturnAmount(orderDetail.getReturnAmount().add(refundDetail.getReturnAmount()));
|
|
||||||
if (orderDetail.getReturnAmount().compareTo(orderDetail.getPayAmount()) > 0) {
|
|
||||||
orderDetail.setReturnAmount(orderDetail.getPayAmount());
|
|
||||||
}
|
|
||||||
// }
|
|
||||||
orderDetailService.updateById(orderDetail);
|
|
||||||
if (orderDetail.getProductId() != null && orderDetail.getProductId() > 0) {
|
|
||||||
returnProMap.put(Convert.toStr(orderDetail.getProductId()), refundDetail.getNum());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
long count = orderDetailService.queryChain()
|
|
||||||
.eq(OrderDetail::getOrderId, orderInfo.getId())
|
|
||||||
.ne(OrderDetail::getStatus, OrderStatusEnums.REFUND.getCode()).count();
|
|
||||||
if (count > 0 && isPay) {
|
|
||||||
orderInfo.setStatus(OrderStatusEnums.PART_REFUND.getCode());
|
|
||||||
} else if (isPay) {
|
|
||||||
orderInfo.setStatus(OrderStatusEnums.REFUND.getCode());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
orderInfo.setStatus(OrderStatusEnums.REFUND.getCode());
|
|
||||||
List<OrderDetail> orderDetails = orderDetailService.queryChain()
|
|
||||||
.select(OrderDetail::getId, OrderDetail::getProductId, OrderDetail::getNum, OrderDetail::getReturnNum, OrderDetail::getPackAmount, OrderDetail::getReturnNum)
|
|
||||||
.eq(OrderDetail::getOrderId, orderInfo.getId())
|
|
||||||
.list();
|
|
||||||
for (OrderDetail orderDetail : orderDetails) {
|
|
||||||
if (isPay) {
|
|
||||||
if (orderDetail.getProductId() != null && orderDetail.getProductId() > 0) {
|
|
||||||
returnProMap.put(Convert.toStr(orderDetail.getProductId()), orderDetail.getNum().subtract(orderDetail.getReturnNum()).subtract(orderDetail.getRefundNum()));
|
|
||||||
}
|
|
||||||
orderDetail.setReturnAmount(orderDetail.getPayAmount());
|
|
||||||
orderDetail.setRefundNum(orderDetail.getNum().subtract(orderDetail.getReturnNum()));
|
|
||||||
orderDetail.setStatus(OrderStatusEnums.REFUND.getCode());
|
|
||||||
} else {
|
|
||||||
if (orderDetail.getProductId() != null && orderDetail.getProductId() > 0) {
|
|
||||||
returnProMap.put(Convert.toStr(orderDetail.getProductId()), orderDetail.getNum().subtract(orderDetail.getReturnNum()));
|
|
||||||
}
|
|
||||||
orderDetail.setReturnNum(orderDetail.getNum());
|
|
||||||
orderDetail.setStatus(OrderStatusEnums.CANCELLED.getCode());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
orderDetailService.updateBatch(orderDetails);
|
|
||||||
}
|
|
||||||
//总退款金额
|
|
||||||
//TODO 退款 券 未处理
|
|
||||||
if (isPay) {
|
|
||||||
orderInfo.setRefundType("cash");
|
|
||||||
//非现金退款
|
|
||||||
if (!param.isCash()) {
|
|
||||||
if (orderInfo.getPayType().equals(PayEnums.VIP_PAY.getValue())) {
|
|
||||||
ShopUser shopUser = shopUserService.getShopUserInfo(orderInfo.getShopId(), orderInfo.getUserId());
|
|
||||||
//会员支付 退钱
|
|
||||||
ShopUserMoneyEditDTO shopUserMoneyEditDTO = new ShopUserMoneyEditDTO()
|
|
||||||
.setId(shopUser.getId())
|
|
||||||
.setMoney(param.getRefundAmount())
|
|
||||||
.setType(1)
|
|
||||||
.setRelationId(orderInfo.getId())
|
|
||||||
.setBizEnum(ShopUserFlowBizEnum.ORDER_REFUND);
|
|
||||||
shopUserService.updateMoney(shopUserMoneyEditDTO);
|
|
||||||
} else if (orderInfo.getPayType().equals(PayEnums.CREDIT_PAY.getValue())) {
|
|
||||||
AssertUtil.isNull(orderInfo.getCreditBuyerId(), "挂账单退款失败,未查询到挂账人");
|
|
||||||
buyerOrderService.partRefund(orderInfo.getCreditBuyerId().toString(), orderInfo.getId(), param.getRefundAmount());
|
|
||||||
} else if (!orderInfo.getPayType().equals(PayEnums.CASH_PAY.getValue())) {
|
|
||||||
//退款 param.getRefundAmount()
|
|
||||||
if (orderInfo.getPayOrderId() == null) {
|
|
||||||
throw new CzgException("退款失败,支付记录不存在");
|
|
||||||
}
|
|
||||||
refundOrder(orderInfo.getShopId(), orderInfo.getId(), orderInfo.getPayOrderId(),
|
|
||||||
refPayOrderNo, StrUtil.isBlank(param.getRefundReason()) ? "退款" : param.getRefundReason(), param.getRefundAmount());
|
|
||||||
}
|
|
||||||
orderInfo.setRefundType("payBack");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
orderInfo.setOrderAmount(orderInfo.getOrderAmount().subtract(param.getRefundAmount()));
|
|
||||||
}
|
|
||||||
orderInfo.setRefundRemark(orderInfo.getRefundRemark() + param.getRefundReason());
|
|
||||||
orderInfoService.updateById(orderInfo);
|
|
||||||
//退款后续
|
|
||||||
//退款返还库存
|
|
||||||
if (!returnProMap.isEmpty()) {
|
|
||||||
rabbitPublisher.sendOrderRefundMsg(JSONObject.toJSONString(Map.of("orderId", orderInfo.getId(), "returnProMap", returnProMap)));
|
|
||||||
}
|
|
||||||
refundOrderAfter(orderInfo.getId(), orderInfo.getShopId(), orderInfo.getUserId(), orderInfo.getOrderNo(),
|
|
||||||
orderInfo.getPointsNum(), isFirstRefund, orderInfo.getStatus().equals(OrderStatusEnums.REFUND.getCode()));
|
|
||||||
return CzgResult.success();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void refundOrder(@NonNull Long shopId, @NonNull Long orderId, @NonNull Long payOrderId, @NonNull String refPayOrderNo,
|
|
||||||
@NonNull String refundReason, @NonNull BigDecimal refundAmount) {
|
|
||||||
OrderPayment payment = paymentService.getById(payOrderId);
|
|
||||||
AssertUtil.isNull(payment, "退款失败支付记录不存在");
|
|
||||||
Long refundId = payService.initOrderPayment(new OrderPayment(shopId, orderId, PayTypeConstants.SourceType.ORDER, PayTypeConstants.PayType.REFUND, refPayOrderNo, null, refundAmount, payment.getId()));
|
|
||||||
CzgResult<CzgRefundResp> refund = payService.refund(shopId, new CzgRefundReq(refPayOrderNo, refundReason, refundAmount.multiply(PayService.MONEY_RATE).longValue(), payment.getOrderNo(), ""));
|
|
||||||
if (refund.getCode() != 200 || refund.getData() == null || !"SUCCESS".equals(refund.getData().getState())) {
|
|
||||||
if (refund.getData() != null && refund.getData().getNote() != null) {
|
|
||||||
throw new CzgException(refund.getData().getNote());
|
|
||||||
}
|
|
||||||
throw new CzgException(refund.getMsg());
|
|
||||||
} else {
|
|
||||||
paymentService.updateChain()
|
|
||||||
.eq(OrderPayment::getId, refundId)
|
|
||||||
.set(OrderPayment::getPayTime, refund.getData().getRefundTime())
|
|
||||||
.set(OrderPayment::getTradeNumber, refund.getData().getRefundOrderId())
|
|
||||||
.set(OrderPayment::getRespJson, JSONObject.toJSONString(refund.getData()))
|
|
||||||
.update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//触发订单退款时 后续处理
|
|
||||||
@Async
|
|
||||||
public void refundOrderAfter(@NonNull Long orderId, @NonNull Long shopId, Long userId, String orderNo,
|
|
||||||
Integer pointsNum, boolean isFirstRefund, boolean isAllRefund) {
|
|
||||||
if (isFirstRefund) {
|
|
||||||
// 退款分销还原
|
|
||||||
FunUtils.safeRunVoid(() -> distributionUserService.refund(orderId, orderNo),
|
|
||||||
"订单id:{} 退款,分销处理失败", orderId);
|
|
||||||
if (userId == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
FunUtils.safeRunVoid(() -> consumerCouponService.removeConsumerCoupon(shopId, userId, orderId),
|
|
||||||
"订单id:{} 退款,消费赠券回撤处理失败", orderId);
|
|
||||||
FunUtils.safeRunVoid(() -> consumeCashbackService.removeCashback(shopId, userId, orderId, orderNo),
|
|
||||||
"订单id:{} 退款,消费返现扣除处理失败", orderId);
|
|
||||||
FunUtils.safeRunVoid(() -> pointsConfigService.removeConsumeAwardPoints(shopId, userId, orderId, orderNo),
|
|
||||||
"订单id:{} 退款,赠送积分扣除失败", orderId);
|
|
||||||
}
|
|
||||||
if (isAllRefund && userId != null && pointsNum != null && pointsNum > 0) {
|
|
||||||
FunUtils.safeRunVoid(() -> mkPointsUserService.alterPoints(userId, null, shopId, PointsConstant.ADD,
|
|
||||||
pointsNum, orderId, StrUtil.format("订单退款返还{}积分", pointsNum)),
|
|
||||||
"订单id:{} 退款,赠送积分扣除失败", orderId);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void upOrderPayInfo(@NonNull Long orderId, @NonNull PayEnums payType, @NotBlank Long paymentId, String remark) {
|
|
||||||
if (paymentId == null) {
|
|
||||||
throw new CzgException("未获取到支付记录");
|
|
||||||
}
|
|
||||||
orderInfoCustomService.updatePayOrderId(orderId, paymentId, payType.getValue(), remark);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user