diff --git a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/pay/PayParam.java b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/pay/PayParam.java index cbdf98eb3..0ec9cfd4e 100644 --- a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/pay/PayParam.java +++ b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/pay/PayParam.java @@ -33,6 +33,9 @@ public class PayParam extends DaxPayRequest { /** 过期时间, 多次传输以第一次为准 */ private Long expiredTime; + /** 是否开启分账 */ + private boolean allocation; + /** 用户付款中途退出返回商户网站的地址(部分支付场景中可用) */ private String quitUrl; diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/AllocationRelationTypeEnum.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/AllocationRelationTypeEnum.java new file mode 100644 index 000000000..57ef4c96e --- /dev/null +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/AllocationRelationTypeEnum.java @@ -0,0 +1,9 @@ +package cn.bootx.platform.daxpay.code; + +/** + * 分账关系类型 + * @author xxm + * @since 2024/3/27 + */ +public enum AllocationRelationTypeEnum { +} diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/PayParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/PayParam.java index 949bd7b90..027b5e9ed 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/PayParam.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/PayParam.java @@ -35,6 +35,9 @@ public class PayParam extends PaymentCommonParam { @Schema(description = "支付描述") private String description; + @Schema(description = "是否开启分账") + private boolean allocation; + @Schema(description = "过期时间, 多次传输以第一次为准") @JsonDeserialize(using = TimestampToLocalDateTimeDeserializer.class) private LocalDateTime expiredTime; @@ -55,6 +58,7 @@ public class PayParam extends PaymentCommonParam { @Schema(description = "同步跳转URL") private String returnUrl; + /** 是否不启用异步通知 */ @Schema(description = "是否不启用异步通知") private boolean notNotify; diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/util/PayUtil.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/util/PayUtil.java index 497bda70e..743ccfe87 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/util/PayUtil.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/util/PayUtil.java @@ -7,7 +7,6 @@ import cn.bootx.platform.daxpay.exception.pay.PayFailureException; import cn.bootx.platform.daxpay.param.pay.PayChannelParam; import cn.bootx.platform.daxpay.param.pay.PayParam; import cn.hutool.core.date.DatePattern; -import cn.hutool.core.util.IdUtil; import lombok.experimental.UtilityClass; import java.time.LocalDateTime; @@ -21,6 +20,34 @@ import java.util.List; */ @UtilityClass public class PayUtil { + + /** + * 校验参数 + */ + public void validation(PayParam payParam) { + // 验证支付金额 + validationAmount(payParam.getPayChannels()); + // 验证异步支付方式 + validationAsyncPay(payParam); + // 验证是否可以分账 + validationAllocation(payParam); + } + + /** + * 验证是否可以分账 + */ + private void validationAllocation(PayParam payParam) { + // 如果分账不启用, 不需要校验 + if (!payParam.isAllocation()) { + return; + } + // 只有异步支付方式支持分账 + if (!isNotSync(payParam.getPayChannels())) { + throw new PayFailureException("分账只支持包含异步支付通道的订单"); + } + } + + /** * 检查异步支付方式 */ @@ -36,8 +63,8 @@ public class PayUtil { if (asyncPayCount > 1) { throw new PayFailureException("组合支付时只允许有一个异步支付方式"); } - } + } /** * 检查支付金额 @@ -52,13 +79,6 @@ public class PayUtil { } } - /** - * 获取支付宝的过期时间 - */ - public String getAliExpiredTime(int minute) { - return minute + "m"; - } - /** * 获取支付宝的过期时间 yyyy-MM-dd HH:mm:ss */ @@ -96,11 +116,4 @@ public class PayUtil { .noneMatch(PayChannelEnum.ASYNC_TYPE_CODE::contains); } - /** - * 生成退款号 - */ - public String getRefundNo(){ -// return "R" + IdUtil.getSnowflakeNextIdStr(); - return IdUtil.getSnowflakeNextIdStr(); - } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayService.java index 78b716de3..76613b047 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayService.java @@ -109,6 +109,12 @@ public class AliPayService { model.setProductCode(AliPayCode.QUICK_WAP_PAY); // 中途退出地址 model.setQuitUrl(noticeInfo.getQuitUrl()); + // 是否分账 + if (payOrder.isAllocation()){ + ExtendParams extendParams = new ExtendParams(); + extendParams.setRoyaltyFreeze("true"); + model.setExtendParams(extendParams); + } AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest(); request.setBizModel(model); @@ -140,6 +146,12 @@ public class AliPayService { // 过期时间 model.setTimeExpire(PayUtil.getAliTimeExpire(payOrder.getExpiredTime())); model.setTotalAmount(String.valueOf(amount*0.01)); + // 是否分账 + if (payOrder.isAllocation()){ + ExtendParams extendParams = new ExtendParams(); + extendParams.setRoyaltyFreeze("true"); + model.setExtendParams(extendParams); + } try { // 异步回调必须到当前系统中 @@ -156,7 +168,6 @@ public class AliPayService { * PC支付 */ public String webPay(int amount, PayOrder payOrder, AliPayConfig alipayConfig) { - NoticeLocal noticeInfo = PaymentContextLocal.get().getNoticeInfo(); AlipayTradePagePayModel model = new AlipayTradePagePayModel(); model.setSubject(payOrder.getTitle()); @@ -167,6 +178,13 @@ public class AliPayService { // 目前仅支持FAST_INSTANT_TRADE_PAY model.setProductCode(AliPayCode.FAST_INSTANT_TRADE_PAY); + // 是否分账 + if (payOrder.isAllocation()){ + ExtendParams extendParams = new ExtendParams(); + extendParams.setRoyaltyFreeze("true"); + model.setExtendParams(extendParams); + } + AlipayTradePagePayRequest request = new AlipayTradePagePayRequest(); request.setBizModel(model); // 异步回调必须到当前系统中 @@ -192,7 +210,12 @@ public class AliPayService { model.setSubject(payOrder.getTitle()); model.setOutTradeNo(String.valueOf(payOrder.getId())); model.setTotalAmount(String.valueOf(amount*0.01)); - + // 是否分账 + if (payOrder.isAllocation()){ + ExtendParams extendParams = new ExtendParams(); + extendParams.setRoyaltyFreeze("true"); + model.setExtendParams(extendParams); + } // 过期时间 model.setTimeExpire(PayUtil.getAliTimeExpire(payOrder.getExpiredTime())); @@ -218,7 +241,12 @@ public class AliPayService { model.setOutTradeNo(String.valueOf(payOrder.getId())); model.setScene(AliPayCode.BAR_CODE); model.setAuthCode(aliPayParam.getAuthCode()); - + // 是否分账 + if (payOrder.isAllocation()){ + ExtendParams extendParams = new ExtendParams(); + extendParams.setRoyaltyFreeze("true"); + model.setExtendParams(extendParams); + } // 过期时间 model.setTimeExpire(PayUtil.getAliTimeExpire(payOrder.getExpiredTime())); model.setTotalAmount(String.valueOf(amount*0.01)); diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayService.java index fe6a773a9..19e741ef7 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayService.java @@ -16,6 +16,7 @@ import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WeChatPayConf import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder; import cn.bootx.platform.daxpay.service.core.payment.sync.service.PaySyncService; import cn.bootx.platform.daxpay.service.param.channel.wechat.WeChatPayParam; +import cn.bootx.platform.daxpay.service.sdk.wechat.BarPayModel; import cn.bootx.platform.daxpay.util.PayUtil; import cn.hutool.core.date.DatePattern; import cn.hutool.core.net.NetUtil; @@ -25,7 +26,6 @@ import com.ijpay.core.enums.SignType; import com.ijpay.core.enums.TradeType; import com.ijpay.core.kit.WxPayKit; import com.ijpay.wxpay.WxPayApi; -import com.ijpay.wxpay.model.MicroPayModel; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.retry.annotation.Backoff; @@ -66,7 +66,7 @@ public class WeChatPayService { } PayWayEnum payWayEnum = Optional.ofNullable(WeChatPayWay.findByCode(payChannelParam.getWay())) - .orElseThrow(() -> new PayFailureException("非法的微信支付类型")); + .orElseThrow(() -> new PayFailureException("非法的微信支付类型")); if (!payWays.contains(payWayEnum.getCode())) { throw new PayFailureException("该微信支付方式不可用"); } @@ -105,7 +105,7 @@ public class WeChatPayService { } // 付款码支付 else if (payWayEnum == PayWayEnum.BARCODE) { - this.barCodePay(totalFee, payOrder, weChatPayParam.getAuthCode(), weChatPayConfig); + this.barCodePay(totalFee, payOrder, weChatPayParam.getAuthCode(), weChatPayConfig); } asyncPayInfo.setPayBody(payBody); } @@ -113,10 +113,10 @@ public class WeChatPayService { /** * wap支付 */ - private String wapPay(String amount, PayOrder payment, WeChatPayConfig weChatPayConfig) { - Map params = this.buildParams(amount, payment, weChatPayConfig, TradeType.MWEB.getTradeType()) - .build() - .createSign(weChatPayConfig.getApiKeyV2(), SignType.HMACSHA256); + private String wapPay(String amount, PayOrder payOrder, WeChatPayConfig weChatPayConfig) { + Map params = this.buildParams(amount, payOrder, weChatPayConfig, TradeType.MWEB.getTradeType()) + .build() + .createSign(weChatPayConfig.getApiKeyV2(), SignType.HMACSHA256); String xmlResult = WxPayApi.pushOrder(false, params); Map result = WxPayKit.xmlToMap(xmlResult); @@ -127,10 +127,10 @@ public class WeChatPayService { /** * 程序支付 */ - private String appPay(String amount, PayOrder payment, WeChatPayConfig weChatPayConfig) { - Map params = this.buildParams(amount, payment, weChatPayConfig, TradeType.APP.getTradeType()) - .build() - .createSign(weChatPayConfig.getApiKeyV2(), SignType.HMACSHA256); + private String appPay(String amount, PayOrder payOrder, WeChatPayConfig weChatPayConfig) { + Map params = this.buildParams(amount, payOrder, weChatPayConfig, TradeType.APP.getTradeType()) + .build() + .createSign(weChatPayConfig.getApiKeyV2(), SignType.HMACSHA256); String xmlResult = WxPayApi.pushOrder(false, params); Map result = WxPayKit.xmlToMap(xmlResult); @@ -141,11 +141,11 @@ public class WeChatPayService { /** * 微信公众号支付或者小程序支付 */ - private String jsPay(String amount, PayOrder payment, String openId, WeChatPayConfig weChatPayConfig) { - Map params = this.buildParams(amount, payment, weChatPayConfig, TradeType.JSAPI.getTradeType()) - .openid(openId) - .build() - .createSign(weChatPayConfig.getApiKeyV2(), SignType.HMACSHA256); + private String jsPay(String amount, PayOrder payOrder, String openId, WeChatPayConfig weChatPayConfig) { + Map params = this.buildParams(amount, payOrder, weChatPayConfig, TradeType.JSAPI.getTradeType()) + .openid(openId) + .build() + .createSign(weChatPayConfig.getApiKeyV2(), SignType.HMACSHA256); String xmlResult = WxPayApi.pushOrder(false, params); Map result = WxPayKit.xmlToMap(xmlResult); @@ -161,11 +161,11 @@ public class WeChatPayService { /** * 二维码支付 */ - private String qrCodePay(String amount, PayOrder payment, WeChatPayConfig weChatPayConfig) { + private String qrCodePay(String amount, PayOrder payOrder, WeChatPayConfig weChatPayConfig) { - Map params = this.buildParams(amount, payment, weChatPayConfig, TradeType.NATIVE.getTradeType()) - .build() - .createSign(weChatPayConfig.getApiKeyV2(), SignType.HMACSHA256); + Map params = this.buildParams(amount, payOrder, weChatPayConfig, TradeType.NATIVE.getTradeType()) + .build() + .createSign(weChatPayConfig.getApiKeyV2(), SignType.HMACSHA256); String xmlResult = WxPayApi.pushOrder(false, params); Map result = WxPayKit.xmlToMap(xmlResult); @@ -176,20 +176,21 @@ public class WeChatPayService { /** * 付款码支付 */ - private void barCodePay(String amount, PayOrder payment, String authCode, WeChatPayConfig weChatPayConfig) { + private void barCodePay(String amount, PayOrder payOrder, String authCode, WeChatPayConfig weChatPayConfig) { PayLocal asyncPayInfo = PaymentContextLocal.get().getPayInfo(); - Map params = MicroPayModel.builder() - .appid(weChatPayConfig.getWxAppId()) - .mch_id(weChatPayConfig.getWxMchId()) - .nonce_str(WxPayKit.generateStr()) - .body(payment.getTitle()) - .auth_code(authCode) - .out_trade_no(String.valueOf(payment.getId())) - .total_fee(amount) - .spbill_create_ip(NetUtil.getLocalhostStr()) - .build() - .createSign(weChatPayConfig.getApiKeyV2(), SignType.HMACSHA256); + Map params = BarPayModel.builder() + .appid(weChatPayConfig.getWxAppId()) + .mch_id(weChatPayConfig.getWxMchId()) + .nonce_str(WxPayKit.generateStr()) + .profit_sharing(payOrder.isAllocation()?"Y":"N") + .body(payOrder.getTitle()) + .auth_code(authCode) + .out_trade_no(String.valueOf(payOrder.getId())) + .total_fee(amount) + .spbill_create_ip(NetUtil.getLocalhostStr()) + .build() + .createSign(weChatPayConfig.getApiKeyV2(), SignType.HMACSHA256); String xmlResult = WxPayApi.microPay(false, params); Map result = WxPayKit.xmlToMap(xmlResult); @@ -211,7 +212,7 @@ public class WeChatPayService { // 支付中, 发起轮训同步 if (Objects.equals(resultCode, WeChatPayCode.PAY_FAIL) && Objects.equals(errCode, WeChatPayCode.PAY_USERPAYING)) { - SpringUtil.getBean(this.getClass()).rotationSync(payment); + SpringUtil.getBean(this.getClass()).rotationSync(payOrder); asyncPayInfo.setGatewayOrderNo(result.get(WeChatPayCode.TRANSACTION_ID)); return; } @@ -233,18 +234,19 @@ public class WeChatPayService { private UnifiedOrderModelBuilder buildParams(String amount, PayOrder payOrder, WeChatPayConfig weChatPayConfig, String tradeType) { return builder() - .appid(weChatPayConfig.getWxAppId()) - .mch_id(weChatPayConfig.getWxMchId()) - .nonce_str(WxPayKit.generateStr()) - .time_start(LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN)) - // 反正v2版本的超时时间无效 - .time_expire(PayUtil.getWxExpiredTime(payOrder.getExpiredTime())) - .body(payOrder.getTitle()) - .out_trade_no(String.valueOf(payOrder.getId())) - .total_fee(amount) - .spbill_create_ip(NetUtil.getLocalhostStr()) - .notify_url(weChatPayConfig.getNotifyUrl()) - .trade_type(tradeType); + .appid(weChatPayConfig.getWxAppId()) + .mch_id(weChatPayConfig.getWxMchId()) + .nonce_str(WxPayKit.generateStr()) + .time_start(LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN)) + // 反正v2版本的超时时间无效 + .time_expire(PayUtil.getWxExpiredTime(payOrder.getExpiredTime())) + .body(payOrder.getTitle()) + .profit_sharing(payOrder.isAllocation()?"Y":"N") + .out_trade_no(String.valueOf(payOrder.getId())) + .total_fee(amount) + .spbill_create_ip(NetUtil.getLocalhostStr()) + .notify_url(weChatPayConfig.getNotifyUrl()) + .trade_type(tradeType); } /** diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/entity/PayOrder.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/entity/PayOrder.java index dcbfe8b8b..3ceff7b85 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/entity/PayOrder.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/entity/PayOrder.java @@ -48,6 +48,10 @@ public class PayOrder extends MpBaseEntity implements EntityBaseFunction { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/dao/AllocationGroupMapper.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/dao/AllocationGroupMapper.java new file mode 100644 index 000000000..3728774f8 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/dao/AllocationGroupMapper.java @@ -0,0 +1,15 @@ +package cn.bootx.platform.daxpay.service.core.payment.allocation.dao; + + +import cn.bootx.platform.daxpay.service.core.payment.allocation.entity.AllocationGroup; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * + * @author xxm + * @since 2024/3/27 + */ +@Mapper +public interface AllocationGroupMapper extends BaseMapper { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/dao/AllocationReceiverGroupManager.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/dao/AllocationReceiverGroupManager.java new file mode 100644 index 000000000..6bdf984ab --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/dao/AllocationReceiverGroupManager.java @@ -0,0 +1,18 @@ +package cn.bootx.platform.daxpay.service.core.payment.allocation.dao; + +import cn.bootx.platform.common.mybatisplus.impl.BaseManager; +import cn.bootx.platform.daxpay.service.core.payment.allocation.entity.AllocationReceiverGroup; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Repository; + +/** + * + * @author xxm + * @since 2024/3/27 + */ +@Slf4j +@Repository +@RequiredArgsConstructor +public class AllocationReceiverGroupManager extends BaseManager { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/dao/AllocationReceiverGroupMapper.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/dao/AllocationReceiverGroupMapper.java new file mode 100644 index 000000000..8c3692744 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/dao/AllocationReceiverGroupMapper.java @@ -0,0 +1,14 @@ +package cn.bootx.platform.daxpay.service.core.payment.allocation.dao; + +import cn.bootx.platform.daxpay.service.core.payment.allocation.entity.AllocationReceiverGroup; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * + * @author xxm + * @since 2024/3/27 + */ +@Mapper +public interface AllocationReceiverGroupMapper extends BaseMapper { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/dao/AllocationReceiverManager.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/dao/AllocationReceiverManager.java new file mode 100644 index 000000000..4b2457f36 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/dao/AllocationReceiverManager.java @@ -0,0 +1,18 @@ +package cn.bootx.platform.daxpay.service.core.payment.allocation.dao; + +import cn.bootx.platform.common.mybatisplus.impl.BaseManager; +import cn.bootx.platform.daxpay.service.core.payment.allocation.entity.AllocationReceiver; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Repository; + +/** + * + * @author xxm + * @since 2024/3/27 + */ +@Slf4j +@Repository +@RequiredArgsConstructor +public class AllocationReceiverManager extends BaseManager { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/dao/AllocationReceiverMapper.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/dao/AllocationReceiverMapper.java new file mode 100644 index 000000000..e3bd557ac --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/dao/AllocationReceiverMapper.java @@ -0,0 +1,14 @@ +package cn.bootx.platform.daxpay.service.core.payment.allocation.dao; + +import cn.bootx.platform.daxpay.service.core.payment.allocation.entity.AllocationReceiver; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * + * @author xxm + * @since 2024/3/27 + */ +@Mapper +public interface AllocationReceiverMapper extends BaseMapper { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/entity/AllocationGroup.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/entity/AllocationGroup.java new file mode 100644 index 000000000..5479d292c --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/entity/AllocationGroup.java @@ -0,0 +1,30 @@ +package cn.bootx.platform.daxpay.service.core.payment.allocation.entity; + +import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity; +import cn.bootx.table.modify.annotation.DbColumn; +import cn.bootx.table.modify.annotation.DbComment; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 分账组 + * @author xxm + * @since 2024/3/27 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +@TableName("pay_allocation_receiver_group") +public class AllocationGroup extends MpBaseEntity { + + @DbComment("名称") + private String name; + + @DbColumn("通道") + private String channel; + + @DbColumn("备注") + private String remark; +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/entity/AllocationReceiver.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/entity/AllocationReceiver.java new file mode 100644 index 000000000..09bb90def --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/entity/AllocationReceiver.java @@ -0,0 +1,50 @@ +package cn.bootx.platform.daxpay.service.core.payment.allocation.entity; + +import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity; +import cn.bootx.platform.daxpay.code.AllocationRelationTypeEnum; +import cn.bootx.table.modify.annotation.DbColumn; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 分账接收方 + * @author xxm + * @since 2024/3/27 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +public class AllocationReceiver extends MpBaseEntity { + + @DbColumn(name = "账号别名") + private String name; + + @DbColumn(name = "所属通道") + private String channel; + + /** + * 分账接收方类型 个人/商户 + */ + @DbColumn(name = "分账接收方类型") + private String receiverType; + + + @DbColumn(name = "接收方账号") + private String receiverAccount; + + /** 接收方姓名 */ + @DbColumn(name = "接收方姓名") + private String receiverName; + + /** + * 分账关系类型 + * @see AllocationRelationTypeEnum + */ + @DbColumn(name = "分账关系类型") + private String relationType; + + @DbColumn(name = "关系名称") + private String relationName; + +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/entity/AllocationReceiverGroup.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/entity/AllocationReceiverGroup.java new file mode 100644 index 000000000..11130808e --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/entity/AllocationReceiverGroup.java @@ -0,0 +1,24 @@ +package cn.bootx.platform.daxpay.service.core.payment.allocation.entity; + +import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity; +import cn.bootx.table.modify.annotation.DbColumn; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 分账接收组关系 + * @author xxm + * @since 2024/3/27 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +public class AllocationReceiverGroup extends MpCreateEntity { + + @DbColumn("分账ID") + private Long groupId; + + @DbColumn("接收者ID") + private Long receiverId; +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/service/AllocationReceiverService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/service/AllocationReceiverService.java new file mode 100644 index 000000000..28cd08b76 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/service/AllocationReceiverService.java @@ -0,0 +1,16 @@ +package cn.bootx.platform.daxpay.service.core.payment.allocation.service; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +/** + * 分账接收方服务类 + * @author xxm + * @since 2024/3/27 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class AllocationReceiverService { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/service/PayService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/service/PayService.java index 1f57d35d2..31eec4aeb 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/service/PayService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/service/PayService.java @@ -93,14 +93,12 @@ public class PayService { * 执行异步通道支付的逻辑与上面异步支付的逻辑一致 * 4. 同步支付一次支付完成,不允许重复发起支付 * 5. 重复支付时,不允许中途将异步支付换为同步支付,也不允许更改出支付通道和支付方式之外的支付参数(请求时间、IP、签名等可以更改) - * + * 6. 如果要进行分账, 请求时就需要将分账标识字段穿true */ public PayResult pay(PayParam payParam){ - // 异步支付方式检查 - PayUtil.validationAsyncPay(payParam); - // 检查支付金额 - PayUtil.validationAmount(payParam.getPayChannels()); + // 支付参数检查 + PayUtil.validation(payParam); // 校验支付限额 payAssistService.validationLimitAmount(payParam); diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/pay/PayOrderDto.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/pay/PayOrderDto.java index e44e1f77e..7ca9da6c4 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/pay/PayOrderDto.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/pay/PayOrderDto.java @@ -36,6 +36,10 @@ public class PayOrderDto extends BaseDto { @Schema(description = "是否是组合支付") private boolean combinationPay; + /** 是否需要分账 */ + @Schema(description = "是否需要分账") + private boolean allocation; + /** * 异步支付通道 * @see PayChannelEnum#ASYNC_TYPE_CODE diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/sdk/wechat/BarPayModel.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/sdk/wechat/BarPayModel.java new file mode 100644 index 000000000..5321b3388 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/sdk/wechat/BarPayModel.java @@ -0,0 +1,51 @@ +package cn.bootx.platform.daxpay.service.sdk.wechat; + +import com.ijpay.wxpay.model.MicroPayModel; +import lombok.*; +import lombok.experimental.Accessors; + +/** + * 付款码支付, 增加分账字段 + * @author xxm + * @since 2024/3/27 + */ +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class BarPayModel extends MicroPayModel { + /** + * 是否押金支付 + */ + private String deposit; + private String appid; + private String sub_appid; + private String mch_id; + private String sub_mch_id; + private String device_info; + private String nonce_str; + private String sign; + private String sign_type; + private String body; + private String detail; + private String attach; + private String out_trade_no; + private String total_fee; + private String fee_type; + private String spbill_create_ip; + private String goods_tag; + private String limit_pay; + private String time_start; + private String time_expire; + private String auth_code; + private String receipt; + private String scene_info; + private String openid; + /** + * 人脸凭证,用于人脸支付 + */ + private String face_code; + private String profit_sharing; +}