diff --git a/_doc/Task.md b/_doc/Task.md
index 123924831..fec586440 100644
--- a/_doc/Task.md
+++ b/_doc/Task.md
@@ -7,12 +7,12 @@
- [x] 支付/退款/转账商户订单号查询时根据AppId做隔离
- [x] 支付通道支持启停用功能
- [x] 支付订单超时时间不得早于当前时间
-- [ ] 云闪付支付通道对接
+- [x] 云闪付支付通道对接
- [x] 支付
- [x] 回调
- [x] 退款
- [x] 同步
- - [ ] 对账
+ - [x] 对账
- [ ] 分账功能
- [x] 分账接收方配置
- [x] 分账组管理
diff --git a/bootx-platform/bootx-platform-common/common-cache/src/main/java/cn/bootx/platform/common/cache/configuration/BootxRedisCache.java b/bootx-platform/bootx-platform-common/common-cache/src/main/java/cn/bootx/platform/common/cache/configuration/BootxRedisCache.java
index cf12aca7f..418d28536 100644
--- a/bootx-platform/bootx-platform-common/common-cache/src/main/java/cn/bootx/platform/common/cache/configuration/BootxRedisCache.java
+++ b/bootx-platform/bootx-platform-common/common-cache/src/main/java/cn/bootx/platform/common/cache/configuration/BootxRedisCache.java
@@ -3,7 +3,7 @@ package cn.bootx.platform.common.cache.configuration;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheWriter;
-import org.springframework.lang.Nullable;
+import jakarta.annotation.Nullable;
import java.util.Objects;
diff --git a/bootx-platform/bootx-platform-common/common-cache/src/main/java/cn/bootx/platform/common/cache/configuration/BootxRedisCacheManager.java b/bootx-platform/bootx-platform-common/common-cache/src/main/java/cn/bootx/platform/common/cache/configuration/BootxRedisCacheManager.java
index e9c7a3ee6..d9f3c7c9c 100644
--- a/bootx-platform/bootx-platform-common/common-cache/src/main/java/cn/bootx/platform/common/cache/configuration/BootxRedisCacheManager.java
+++ b/bootx-platform/bootx-platform-common/common-cache/src/main/java/cn/bootx/platform/common/cache/configuration/BootxRedisCacheManager.java
@@ -6,7 +6,7 @@ import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
-import org.springframework.lang.Nullable;
+import jakarta.annotation.Nullable;
import java.time.Duration;
import java.util.Map;
diff --git a/bootx-platform/bootx-platform-common/common-log/pom.xml b/bootx-platform/bootx-platform-common/common-log/pom.xml
new file mode 100644
index 000000000..8e3270f37
--- /dev/null
+++ b/bootx-platform/bootx-platform-common/common-log/pom.xml
@@ -0,0 +1,26 @@
+
+
+ 4.0.0
+
+ cn.bootx.platform
+ bootx-platform-common
+ 3.0.0.beta1
+
+
+ common-log
+ 日志模块
+
+
+
+ ch.qos.logback
+ logback-classic
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
diff --git a/bootx-platform/bootx-platform-common/common-log/src/main/java/cn/bootx/platform/common/log/LogAutoConfigurationLogAutoConfiguration.java b/bootx-platform/bootx-platform-common/common-log/src/main/java/cn/bootx/platform/common/log/LogAutoConfigurationLogAutoConfiguration.java
new file mode 100644
index 000000000..40e9b30eb
--- /dev/null
+++ b/bootx-platform/bootx-platform-common/common-log/src/main/java/cn/bootx/platform/common/log/LogAutoConfigurationLogAutoConfiguration.java
@@ -0,0 +1,17 @@
+package cn.bootx.platform.common.log;
+
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
+import org.springframework.context.annotation.ComponentScan;
+
+/**
+ * 日志扫描
+ *
+ * @author xxm
+ * @since 2022/6/6
+ */
+@ComponentScan
+@ConfigurationPropertiesScan
+@AutoConfiguration
+public class LogAutoConfigurationLogAutoConfiguration {
+}
diff --git a/bootx-platform/bootx-platform-common/common-log/src/main/java/cn/bootx/platform/common/log/handler/LogTraceHeaderHolderFilter.java b/bootx-platform/bootx-platform-common/common-log/src/main/java/cn/bootx/platform/common/log/handler/LogTraceHeaderHolderFilter.java
new file mode 100644
index 000000000..e1ee71796
--- /dev/null
+++ b/bootx-platform/bootx-platform-common/common-log/src/main/java/cn/bootx/platform/common/log/handler/LogTraceHeaderHolderFilter.java
@@ -0,0 +1,44 @@
+package cn.bootx.platform.common.log.handler;
+
+import cn.bootx.platform.core.code.CommonCode;
+import cn.hutool.core.util.RandomUtil;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import org.slf4j.MDC;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import java.io.IOException;
+
+/**
+ * 针对请求生成链路追踪ID
+ *
+ * @author xxm
+ * @since 2021/4/20
+ */
+@Order(value = Integer.MIN_VALUE)
+@Component
+@RequiredArgsConstructor
+@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
+public class LogTraceHeaderHolderFilter extends OncePerRequestFilter {
+
+ @Override
+ public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
+ throws ServletException, IOException {
+ try {
+ String traceId = RandomUtil.randomString(12);
+ // 添加普通日志 TraceId
+ MDC.put(CommonCode.TRACE_ID, traceId);
+ chain.doFilter(request, response);
+ }
+ finally {
+ MDC.clear();
+ }
+ }
+
+}
diff --git a/bootx-platform/bootx-platform-common/common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/bootx-platform/bootx-platform-common/common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
new file mode 100644
index 000000000..d727afa4f
--- /dev/null
+++ b/bootx-platform/bootx-platform-common/common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -0,0 +1 @@
+cn.bootx.platform.common.log.LogAutoConfigurationLogAutoConfiguration
diff --git a/bootx-platform/bootx-platform-common/pom.xml b/bootx-platform/bootx-platform-common/pom.xml
index d78834a7e..6b20ba44b 100644
--- a/bootx-platform/bootx-platform-common/pom.xml
+++ b/bootx-platform/bootx-platform-common/pom.xml
@@ -23,6 +23,7 @@
common-header-holder
common-redis
common-cache
+ common-log
diff --git a/bootx-platform/bootx-platform-service/pom.xml b/bootx-platform/bootx-platform-service/pom.xml
index e58b127a2..dba99229a 100644
--- a/bootx-platform/bootx-platform-service/pom.xml
+++ b/bootx-platform/bootx-platform-service/pom.xml
@@ -95,6 +95,13 @@
${bootx-platform.version}
+
+
+ cn.bootx.platform
+ common-log
+ ${bootx-platform.version}
+
+
diff --git a/bootx-platform/bootx-platform-service/service-baseapi/src/main/java/cn/bootx/platform/baseapi/controller/BaseController.java b/bootx-platform/bootx-platform-service/service-baseapi/src/main/java/cn/bootx/platform/baseapi/controller/BaseController.java
index 10d692ca7..83c96964c 100644
--- a/bootx-platform/bootx-platform-service/service-baseapi/src/main/java/cn/bootx/platform/baseapi/controller/BaseController.java
+++ b/bootx-platform/bootx-platform-service/service-baseapi/src/main/java/cn/bootx/platform/baseapi/controller/BaseController.java
@@ -8,8 +8,10 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@@ -20,6 +22,7 @@ import java.nio.charset.StandardCharsets;
* @author xxm
* @since 2023/10/14
*/
+@Slf4j
@Tag(name = "系统基础接口")
@RestController
@RequiredArgsConstructor
@@ -43,7 +46,7 @@ public class BaseController {
@IgnoreAuth
@Operation(summary = "读取文件文本内容")
@PostMapping("/readText")
- public Result readText(MultipartFile file){
+ public Result readText(@RequestPart MultipartFile file){
return Res.ok(new String(file.getBytes(), StandardCharsets.UTF_8));
}
diff --git a/bootx-platform/bootx-platform-service/service-iam/src/main/java/cn/bootx/platform/iam/auth/login/PasswordLoginHandler.java b/bootx-platform/bootx-platform-service/service-iam/src/main/java/cn/bootx/platform/iam/auth/login/PasswordLoginHandler.java
index eca99f1e0..e924df47d 100644
--- a/bootx-platform/bootx-platform-service/service-iam/src/main/java/cn/bootx/platform/iam/auth/login/PasswordLoginHandler.java
+++ b/bootx-platform/bootx-platform-service/service-iam/src/main/java/cn/bootx/platform/iam/auth/login/PasswordLoginHandler.java
@@ -16,7 +16,7 @@ import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.lang.Nullable;
+import jakarta.annotation.Nullable;
import org.springframework.stereotype.Component;
import java.util.Objects;
diff --git a/bootx-platform/bootx-platform-starter/starter-auth/src/main/java/cn/bootx/platform/starter/auth/util/SecurityUtil.java b/bootx-platform/bootx-platform-starter/starter-auth/src/main/java/cn/bootx/platform/starter/auth/util/SecurityUtil.java
index b76cb708f..5949aaaaa 100644
--- a/bootx-platform/bootx-platform-starter/starter-auth/src/main/java/cn/bootx/platform/starter/auth/util/SecurityUtil.java
+++ b/bootx-platform/bootx-platform-starter/starter-auth/src/main/java/cn/bootx/platform/starter/auth/util/SecurityUtil.java
@@ -11,7 +11,7 @@ import cn.hutool.core.util.DesensitizedUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.lang.Nullable;
+import jakarta.annotation.Nullable;
import java.util.Objects;
import java.util.Optional;
diff --git a/bootx-platform/bootx-platform-starter/starter-delay-queue/src/main/java/cn/bootx/platform/starter/redis/delay/annotation/DelayJobProcessor.java b/bootx-platform/bootx-platform-starter/starter-delay-queue/src/main/java/cn/bootx/platform/starter/redis/delay/annotation/DelayJobProcessor.java
index 7d07f85e7..3a9de951f 100644
--- a/bootx-platform/bootx-platform-starter/starter-delay-queue/src/main/java/cn/bootx/platform/starter/redis/delay/annotation/DelayJobProcessor.java
+++ b/bootx-platform/bootx-platform-starter/starter-delay-queue/src/main/java/cn/bootx/platform/starter/redis/delay/annotation/DelayJobProcessor.java
@@ -6,7 +6,7 @@ import cn.hutool.core.util.StrUtil;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Configuration;
-import org.springframework.lang.Nullable;
+import jakarta.annotation.Nullable;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.InvocationTargetException;
diff --git a/bootx-platform/bootx-platform-starter/starter-file/src/main/java/cn/bootx/platform/starter/file/service/FileUploadService.java b/bootx-platform/bootx-platform-starter/starter-file/src/main/java/cn/bootx/platform/starter/file/service/FileUploadService.java
index 8c380a359..8d5ffcbec 100644
--- a/bootx-platform/bootx-platform-starter/starter-file/src/main/java/cn/bootx/platform/starter/file/service/FileUploadService.java
+++ b/bootx-platform/bootx-platform-starter/starter-file/src/main/java/cn/bootx/platform/starter/file/service/FileUploadService.java
@@ -27,6 +27,7 @@ import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
@@ -89,7 +90,7 @@ public class FileUploadService {
* @param fileName 文件名称
*/
@Transactional(rollbackFor = Exception.class)
- public UploadFileResult upload(MultipartFile file, String fileName) {
+ public UploadFileResult upload(@RequestPart MultipartFile file, String fileName) {
UploadPretreatment uploadPretreatment = fileStorageService.of(file);
if (StrUtil.isNotBlank(fileName)){
uploadPretreatment.setOriginalFilename(fileName);
diff --git a/daxpay-single-sdk/pom.xml b/daxpay-single-sdk/pom.xml
index e016a99fc..89e99d014 100644
--- a/daxpay-single-sdk/pom.xml
+++ b/daxpay-single-sdk/pom.xml
@@ -3,14 +3,203 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
- org.dromara.daxpay.single
+ cn.daxpay.single
daxpay-single-sdk
3.0.0.beta1
+ jar
+
+ daxpay-single-sdk
+ daxpay-multi-sdk 是 daxpay单商户版的JavaSDK,用于业务系统快速接入到支付网关中
+ https://github.com/dromara/dax-pay
+
+
+
+
+ The Apache Software License, Version 2.0
+ http://www.apache.org/licenses/LICENSE-2.0.txt
+ repo
+
+
+
+
+
+
+ daxpay
+ xxm1995@outlook.com
+ daxpay
+ https://gitee.com/dromara/dax-pay
+
+
+
+
+ scm:git:git@github.com:dromara/daxpay.git
+ scm:git:git@github.com:dromara/daxpay.git
+ https://github.com/dromara/dax-pay
+
8
8
+ 1.8
UTF-8
+ 1.5.6
+ 5.8.31
+ 1.78.1
+ 2.5.0
+ 1.18.30
+ 4.13.2
+
+
+
+ cn.hutool
+ hutool-http
+ ${hutool.version}
+
+
+ cn.hutool
+ hutool-json
+ ${hutool.version}
+
+
+ cn.hutool
+ hutool-crypto
+ ${hutool.version}
+
+
+
+ org.bouncycastle
+ bcpkix-jdk18on
+ ${bouncycastle.version}
+
+
+
+ org.springdoc
+ springdoc-openapi-starter-common
+ ${springdoc.version}
+ provided
+
+
+
+ ch.qos.logback
+ logback-classic
+ ${logback-classic.version}
+ provided
+
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+ provided
+
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.10.1
+
+ ${java.version}
+ ${java.version}
+ -parameters
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 3.2.1
+
+
+ attach-sources
+
+ jar-no-fork
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.6.0
+
+ false
+ none
+
+
+
+ attach-javadocs
+ package
+
+ jar
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 1.6
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
+
+
+
+ org.sonatype.central
+ central-publishing-maven-plugin
+ 0.4.0
+ true
+
+ daxpay
+ true
+
+
+
+
+
+
+
+ src/main/resources
+
+ **/*
+
+ true
+
+
+
+ src/main/java
+
+
+
+
+
+
+
+
+ daxpay
+ https://central.sonatype.com/
+
+
+
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/AllocReceiverTypeEnum.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/AllocReceiverTypeEnum.java
new file mode 100644
index 000000000..372525e8f
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/AllocReceiverTypeEnum.java
@@ -0,0 +1,40 @@
+package cn.daxpay.single.sdk.code;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * 分账接收方类型
+ * @author xxm
+ * @since 2024/4/1
+ */
+@Getter
+@AllArgsConstructor
+public enum AllocReceiverTypeEnum {
+ /** 商户号 */
+ MERCHANT_NO("merchant_no", "商户号"),
+ /** userId */
+ USER_ID("user_id", "用户ID"),
+ /** openId */
+ OPEN_ID("open_id", "openId"),
+ /** 账号 */
+ LOGIN_NAME("login_name", "登录账号");
+
+ /** 编码 */
+ private final String code;
+ /** 名称 */
+ private final String name;
+
+ /**
+ * 根据编码查找
+ */
+ public static AllocReceiverTypeEnum findByCode(String code) {
+ return Arrays.stream(AllocReceiverTypeEnum.values())
+ .filter(e -> e.getCode().equals(code))
+ .findFirst()
+ .orElseThrow(() -> new IllegalArgumentException("未找到对应的分账接收方类型"));
+ }
+
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/AllocRelationTypeEnum.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/AllocRelationTypeEnum.java
new file mode 100644
index 000000000..4fb483586
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/AllocRelationTypeEnum.java
@@ -0,0 +1,28 @@
+package cn.daxpay.single.sdk.code;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 分账关系类型
+ * @author xxm
+ * @since 2024/3/27
+ */
+@Getter
+@AllArgsConstructor
+public enum AllocRelationTypeEnum {
+ SERVICE_PROVIDER("service_provider","服务商"),
+ STORE("store","门店"),
+ STAFF("staff","员工"),
+ STORE_OWNER("store_owner","店主"),
+ PARTNER("partner","合作伙伴"),
+ HEADQUARTER("headquarter","总部"),
+ BRAND("brand","品牌方"),
+ DISTRIBUTOR("distributor","分销商"),
+ USER("user","用户"),
+ SUPPLIER("supplier","供应商"),
+ CUSTOM("custom","自定义");
+
+ private final String code;
+ private final String name;
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/ChannelEnum.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/ChannelEnum.java
new file mode 100644
index 000000000..b15dd22f6
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/ChannelEnum.java
@@ -0,0 +1,30 @@
+package cn.daxpay.single.sdk.code;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * 支付通道枚举
+ *
+ * @author xxm
+ * @since 2021/7/26
+ */
+@Getter
+@RequiredArgsConstructor
+public enum ChannelEnum {
+
+ /** 支付宝 - 直连商户 */
+ ALI("ali_pay"),
+ /** 支付宝 - 服务商商户 */
+ ALI_SERVICE("ali_service"),
+ /** 微信支付 */
+ WECHAT("wechat_pay"),
+ /** 微信支付服务商 */
+ WECHAT_SERVICE("wechat_service"),
+ /** 云闪付 */
+ UNION_PAY("union_pay"),
+ ;
+ /** 支付通道编码 */
+ private final String code;
+
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/DaxPayErrorCode.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/DaxPayErrorCode.java
new file mode 100644
index 000000000..af60ca29b
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/DaxPayErrorCode.java
@@ -0,0 +1,77 @@
+package cn.daxpay.single.sdk.code;
+
+/**
+ * 公共错误码
+ * @author xxm
+ * @since 2024/6/17
+ */
+public interface DaxPayErrorCode {
+ /** 未归类的错误 */
+ int UNCLASSIFIED_ERROR = 20000;
+
+ /** 不存在的支付通道 */
+ int CHANNEL_NOT_EXIST = 20011;
+
+ /** 不存在的支付方式 */
+ int METHOD_NOT_EXIST = 20012;
+
+ /** 不存在的状态 */
+ int STATUS_NOT_EXIST = 20013;
+
+ /** 支付通道未启用 */
+ int CHANNEL_NOT_ENABLE = 20021;
+
+ /** 支付方式未启用 */
+ int METHOD_NOT_ENABLE = 20022;
+
+ /** 配置未启用 */
+ int CONFIG_NOT_ENABLE = 20023;
+
+ /** 配置错误 */
+ int CONFIG_ERROR = 20024;
+
+ /** 配置不存在 */
+ int CONFIG_NOT_EXIST = 20025;
+
+ /** 不支持该能力 */
+ int UNSUPPORTED_ABILITY = 20030;
+
+ /** 交易不存在 */
+ int TRADE_NOT_EXIST = 20041;
+
+ /** 交易已关闭 */
+ int TRADE_CLOSED = 20042;
+
+ /** 交易处理中, 请勿重复操作 */
+ int TRADE_PROCESSING = 20043;
+
+ /** 交易状态错误 */
+ int TRADE_STATUS_ERROR = 20044;
+
+ /** 交易失败 */
+ int TRADE_FAIL = 20045;
+
+ /** 验签失败 */
+ int VERIFY_SIGN_FAILED = 20052;
+
+ /** 金额超过限额 */
+ int AMOUNT_EXCEED_LIMIT = 20060;
+
+ /** 对账失败 */
+ int RECONCILE_FAIL = 20071;
+
+ /** 操作失败 */
+ int OPERATION_FAIL = 20080;
+
+ /** 操作处理中, 请勿重复操作 */
+ int OPERATION_PROCESSING = 20081;
+
+ /** 不支持的操作 */
+ int OPERATION_UNSUPPORTED = 20082;
+
+ /** 数据错误 */
+ int DATA_ERROR = 20091;
+
+ /** 未知异常,系统无法处理 */
+ int SYSTEM_UNKNOWN_ERROR = 30000;
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/PayAllocStatusEnum.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/PayAllocStatusEnum.java
new file mode 100644
index 000000000..9251ae4d9
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/PayAllocStatusEnum.java
@@ -0,0 +1,20 @@
+package cn.daxpay.single.sdk.code;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 支付订单分账状态
+ * @author xxm
+ * @since 2024/4/16
+ */
+@Getter
+@AllArgsConstructor
+public enum PayAllocStatusEnum {
+ WAITING("waiting", "待分账"),
+ ALLOCATION("allocation", "已分账"),
+ ;
+
+ private final String code;
+ private final String name;
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/PayMethodEnum.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/PayMethodEnum.java
new file mode 100644
index 000000000..dd0c6ddc2
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/PayMethodEnum.java
@@ -0,0 +1,38 @@
+package cn.daxpay.single.sdk.code;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * 支付方式
+ * @author xxm
+ * @since 2021/7/26
+ */
+@Getter
+@AllArgsConstructor
+public enum PayMethodEnum {
+
+ WAP("wap", "wap支付"),
+ APP("app", "应用支付"),
+ WEB("web", "web支付"),
+ QRCODE("qrcode", "扫码支付"),
+ BARCODE("barcode", "付款码"),
+ JSAPI("jsapi", "公众号/小程序支付");
+
+ /** 编码 */
+ private final String code;
+ /** 名称 */
+ private final String name;
+ /**
+ * 根据编码获取枚举
+ */
+ public static PayMethodEnum findByCode(String code){
+ return Arrays.stream(values())
+ .filter(o -> Objects.equals(o.getCode(), code))
+ .findFirst()
+ .orElseThrow(() -> new IllegalArgumentException("该枚举不存在"));
+ }
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/PayRefundStatusEnum.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/PayRefundStatusEnum.java
new file mode 100644
index 000000000..197ef2109
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/PayRefundStatusEnum.java
@@ -0,0 +1,34 @@
+package cn.daxpay.single.sdk.code;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * 支付订单的退款状态
+ * @author xxm
+ * @since 2024/6/7
+ */
+@Getter
+@AllArgsConstructor
+public enum PayRefundStatusEnum {
+ NO_REFUND("no_refund","未退款"),
+ REFUNDING("refunding","退款中"),
+ PARTIAL_REFUND("partial_refund","部分退款"),
+ REFUNDED("refunded","全部退款"),
+ ;
+ private final String code;
+ private final String name;
+
+ /**
+ * 根据编码获取枚举
+ */
+ public static PayRefundStatusEnum findByCode(String code){
+ return Arrays.stream(values())
+ .filter(payStatusEnum -> Objects.equals(payStatusEnum.getCode(), code))
+ .findFirst()
+ .orElseThrow(() -> new IllegalStateException("该退款状态不存在"));
+ }
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/PayStatusEnum.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/PayStatusEnum.java
new file mode 100644
index 000000000..a07c40edc
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/PayStatusEnum.java
@@ -0,0 +1,41 @@
+package cn.daxpay.single.sdk.code;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * 支付状态
+ * @author xxm
+ * @since 2023/12/17
+ */
+@Getter
+@RequiredArgsConstructor
+public enum PayStatusEnum {
+ PROGRESS("progress","支付中"),
+ SUCCESS("success","成功"),
+ CLOSE("close","支付关闭"),
+ REFUNDING("refunding","退款中"),
+ PARTIAL_REFUND("partial_refund","部分退款"),
+ REFUNDED("refunded","全部退款"),
+ FAIL("fail","失败");
+
+ /** 编码 */
+ private final String code;
+
+ /** 名称 */
+ private final String name;
+
+ /**
+ * 根据编码获取枚举
+ */
+ public static PayStatusEnum findByCode(String code){
+ return Arrays.stream(values())
+ .filter(o -> Objects.equals(o.getCode(), code))
+ .findFirst()
+ .orElseThrow(() -> new IllegalArgumentException("该枚举不存在"));
+ }
+
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/PaySyncStatusEnum.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/PaySyncStatusEnum.java
new file mode 100644
index 000000000..6317a0bf9
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/PaySyncStatusEnum.java
@@ -0,0 +1,44 @@
+package cn.daxpay.single.sdk.code;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * 支付同步结果
+ *
+ * @author xxm
+ * @since 2021/4/21
+ */
+@Getter
+@AllArgsConstructor
+public enum PaySyncStatusEnum {
+ FAIL("pay_fail", "支付查询失败"),
+ SUCCESS("pay_success", "支付成功"),
+ PROGRESS("pay_progress", "支付中"),
+ CLOSED("pay_closed", "支付已关闭"),
+ REFUND("pay_refund", "支付退款"),
+ NOT_FOUND("pay_not_found", "交易不存在"),
+ /**
+ * 未查询到订单(具体类型未知)
+ * 区别于上面的未查询到订单,有些支付方式如支付宝,发起支付后并不能查询到订单,需要用户进行操作后才能查询到订单,
+ * 所以查询为了区分,增加一个未知的状态, 用于处理这种特殊情况, 然后根据业务需要,关闭订单或者进行其他操作
+ */
+ NOT_FOUND_UNKNOWN("pay_not_found_unknown","交易不存在(特殊)"),
+ /** 不属于网关同步过来的状态, 需要手动设置, 处理本地订单到了超时时间, 但是网关和本地都未关闭, 需要触发关闭相关处理 */
+ TIMEOUT("pay_timeout", "支付超时");
+
+ /** 编码 */
+ private final String code;
+ /** 名称 */
+ private final String name;
+
+ public static PaySyncStatusEnum getByCode(String code) {
+ return Arrays.stream(values())
+ .filter(item -> Objects.equals(item.getCode(), code))
+ .findFirst()
+ .orElseThrow(() -> new IllegalArgumentException("该枚举不存在"));
+ }
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/RefundStatusEnum.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/RefundStatusEnum.java
new file mode 100644
index 000000000..7adeb876e
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/RefundStatusEnum.java
@@ -0,0 +1,40 @@
+package cn.daxpay.single.sdk.code;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * 退款状态枚举
+ * @author xxm
+ * @since 2023/12/18
+ */
+@Getter
+@AllArgsConstructor
+public enum RefundStatusEnum {
+
+ /**
+ * 接口调用成功不代表成功
+ */
+ PROGRESS("progress","退款中"),
+ SUCCESS("success","成功"),
+ CLOSE("close","关闭"),
+ FAIL("fail","失败");
+
+ /** 编码 */
+ private final String code;
+ /** 名称 */
+ private final String name;
+
+ /**
+ * 根据编码获取枚举
+ */
+ public static RefundStatusEnum findByCode(String code){
+ return Arrays.stream(values())
+ .filter(statusEnum -> Objects.equals(statusEnum.getCode(), code))
+ .findFirst()
+ .orElseThrow(() -> new IllegalStateException("该枚举不存在"));
+ }
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/RefundSyncStatusEnum.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/RefundSyncStatusEnum.java
new file mode 100644
index 000000000..d4e9e22ce
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/RefundSyncStatusEnum.java
@@ -0,0 +1,23 @@
+package cn.daxpay.single.sdk.code;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 退款同步状态枚举
+ * @author xxm
+ * @since 2024/1/29
+ */
+@Getter
+@AllArgsConstructor
+public enum RefundSyncStatusEnum {
+ SUCCESS("refund_success","退款成功"),
+ FAIL("refund_fail","退款失败"),
+ PROGRESS("refund_progress","退款中"),
+ NOT_FOUND("pay_not_found", "交易不存在");
+
+ /** 编码 */
+ private final String code;
+ /** 名称 */
+ private final String name;
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/SignTypeEnum.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/SignTypeEnum.java
new file mode 100644
index 000000000..455628b83
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/SignTypeEnum.java
@@ -0,0 +1,37 @@
+package cn.daxpay.single.sdk.code;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * 支付签名类型
+ * @author xxm
+ * @since 2023/12/24
+ */
+@Getter
+@AllArgsConstructor
+public enum SignTypeEnum {
+
+ HMAC_SHA256("HMAC_SHA256"),
+ MD5("MD5"),
+ SM3("SM3"),
+ ;
+
+ /** 支付方式 */
+ private final String code;
+
+
+ /**
+ * 根据编码获取枚举
+ */
+ public static SignTypeEnum findByCode(String code){
+ return Arrays.stream(values())
+ .filter(o -> Objects.equals(o.getCode(), code))
+ .findFirst()
+ .orElseThrow(() -> new IllegalArgumentException("该枚举不存在"));
+ }
+
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/TransferPayeeTypeEnum.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/TransferPayeeTypeEnum.java
new file mode 100644
index 000000000..b1019ecc1
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/TransferPayeeTypeEnum.java
@@ -0,0 +1,38 @@
+package cn.daxpay.single.sdk.code;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * 转账接收方类型
+ * @author xxm
+ * @since 2024/4/1
+ */
+@Getter
+@AllArgsConstructor
+public enum TransferPayeeTypeEnum {
+ /** userId */
+ USER_ID("ali_user_id", "用户ID"),
+ /** openId */
+ OPEN_ID("ali_open_id", "OpenId"),
+ /** 用户账号 */
+ LOGIN_NAME("ali_login_name", "用户账号");
+
+ /** 编码 */
+ private final String code;
+ /** 名称 */
+ private final String name;
+
+ /**
+ * 根据编码查找
+ */
+ public static TransferPayeeTypeEnum findByCode(String code) {
+ return Arrays.stream(TransferPayeeTypeEnum.values())
+ .filter(e -> e.getCode().equals(code))
+ .findFirst()
+ .orElseThrow(() -> new IllegalArgumentException("未找到对应的分账接收方类型"));
+ }
+
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/TransferStatusEnum.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/TransferStatusEnum.java
new file mode 100644
index 000000000..ccc771c97
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/TransferStatusEnum.java
@@ -0,0 +1,23 @@
+package cn.daxpay.single.sdk.code;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 转账状态
+ * @author xxm
+ * @since 2024/6/11
+ */
+@Getter
+@AllArgsConstructor
+public enum TransferStatusEnum {
+
+ TRANSFERRING("transferring", "转账中"),
+ SUCCESS("success", "转账成功"),
+ FAIL("fail", "转账失败"),
+ ;
+
+ private final String code;
+ private final String name;
+
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/allocation/AllocReceiverAddModel.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/allocation/AllocReceiverAddModel.java
new file mode 100644
index 000000000..9e0856c11
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/allocation/AllocReceiverAddModel.java
@@ -0,0 +1,12 @@
+package cn.daxpay.single.sdk.model.allocation;
+
+import lombok.Data;
+
+/**
+ * 分账接收方添加返回结果
+ * @author xxm
+ * @since 2024/5/21
+ */
+@Data
+public class AllocReceiverAddModel{
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/allocation/AllocReceiverModel.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/allocation/AllocReceiverModel.java
new file mode 100644
index 000000000..59129510b
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/allocation/AllocReceiverModel.java
@@ -0,0 +1,46 @@
+package cn.daxpay.single.sdk.model.allocation;
+
+import cn.daxpay.single.sdk.code.AllocReceiverTypeEnum;
+import cn.daxpay.single.sdk.code.AllocRelationTypeEnum;
+import cn.daxpay.single.sdk.code.ChannelEnum;
+import lombok.Data;
+
+/**
+ * 分账接收方
+ * @author xxm
+ * @since 2024/5/21
+ */
+@Data
+public class AllocReceiverModel {
+
+ /** 分账接收方编号, 需要保证唯一 */
+ private String receiverNo;
+
+ /**
+ * 所属通道
+ * @see ChannelEnum
+ */
+ private String channel;
+
+ /**
+ * 分账接收方类型
+ * @see AllocReceiverTypeEnum
+ */
+ private String receiverType;
+
+ /** 接收方账号 */
+ private String receiverAccount;
+
+ /** 接收方姓名 */
+ private String receiverName;
+
+ /**
+ * 分账关系类型
+ * @see AllocRelationTypeEnum
+ */
+ private String relationType;
+
+ /** 关系名称 */
+ private String relationName;
+
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/allocation/AllocReceiverRemoveModel.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/allocation/AllocReceiverRemoveModel.java
new file mode 100644
index 000000000..af92bf008
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/allocation/AllocReceiverRemoveModel.java
@@ -0,0 +1,12 @@
+package cn.daxpay.single.sdk.model.allocation;
+
+import lombok.Data;
+
+/**
+ * 分账接收方删除返回结果
+ * @author xxm
+ * @since 2024/5/21
+ */
+@Data
+public class AllocReceiverRemoveModel{
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/allocation/AllocReceiversModel.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/allocation/AllocReceiversModel.java
new file mode 100644
index 000000000..20954544f
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/allocation/AllocReceiversModel.java
@@ -0,0 +1,18 @@
+package cn.daxpay.single.sdk.model.allocation;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 分账接收方返回结果
+ * @author xxm
+ * @since 2024/5/21
+ */
+@Data
+public class AllocReceiversModel{
+
+ /** 接收方列表 */
+ private List receivers;
+
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/assist/WxAccessTokenModel.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/assist/WxAccessTokenModel.java
new file mode 100644
index 000000000..aaae8810b
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/assist/WxAccessTokenModel.java
@@ -0,0 +1,18 @@
+package cn.daxpay.single.sdk.model.assist;
+
+import lombok.Data;
+
+/**
+ * 微信AccessToken
+ * @author xxm
+ * @since 2024/2/10
+ */
+@Data
+public class WxAccessTokenModel{
+
+ /** 微信AccessToken, 目前无返回 */
+ private String accessToken;
+
+ /** 微信用户唯一标识 */
+ private String openId;
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/assist/WxAuthUrlModel.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/assist/WxAuthUrlModel.java
new file mode 100644
index 000000000..d250f0151
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/assist/WxAuthUrlModel.java
@@ -0,0 +1,15 @@
+package cn.daxpay.single.sdk.model.assist;
+
+import lombok.Data;
+
+/**
+ * 微信oauth2授权的url连接
+ * @author xxm
+ * @since 2024/2/10
+ */
+@Data
+public class WxAuthUrlModel{
+
+ /** 微信oauth2授权的url连接 */
+ private String url;
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/notice/PayNoticeModel.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/notice/PayNoticeModel.java
new file mode 100644
index 000000000..e01493f89
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/notice/PayNoticeModel.java
@@ -0,0 +1,91 @@
+package cn.daxpay.single.sdk.model.notice;
+
+import cn.daxpay.single.sdk.code.ChannelEnum;
+import cn.daxpay.single.sdk.code.PayAllocStatusEnum;
+import cn.daxpay.single.sdk.code.PayRefundStatusEnum;
+import cn.daxpay.single.sdk.code.PayStatusEnum;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 支付异步通知类
+ * @author xxm
+ * @since 2024/1/7
+ */
+@Data
+public class PayNoticeModel{
+
+ /** 订单号 */
+ private String orderNo;
+
+ /** 商户订单号 */
+ private String bizOrderNo;
+
+ /** 通道系统交易号 */
+ private String outOrderNo;
+
+ /** 标题 */
+ private String title;
+
+ /** 描述 */
+ private String description;
+
+ /** 是否支持分账 */
+ private Boolean allocation;
+
+ /** 是否开启自动分账,*/
+ private Boolean autoAllocation;
+ /**
+ * 支付通道
+ * @see ChannelEnum
+ */
+ private String channel;
+
+ /** 支付方式 */
+ private String method;
+
+ /** 支付金额 */
+ private BigDecimal amount;
+
+ /**
+ * 支付状态
+ * @see PayStatusEnum
+ */
+ private String status;
+
+
+ /**
+ * 退款状态
+ * @see PayRefundStatusEnum
+ */
+ private String refundStatus;
+
+ /**
+ * 分账状态
+ * @see PayAllocStatusEnum
+ */
+ private String allocStatus;
+
+ /** 支付成功时间 */
+ private String payTime;
+
+ /** 过期时间 */
+ private String expiredTime;
+
+ /** 支付关闭时间 */
+ private String closeTime;
+
+ /** 支付创建时间 */
+ private String createTime;
+
+ /** 商户扩展参数,回调时会原样返回 */
+ private String attach;
+
+ /** 错误码 */
+ private String errorCode;
+
+ /** 错误原因 */
+ private String errorMsg;
+
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/notice/RefundNoticeModel.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/notice/RefundNoticeModel.java
new file mode 100644
index 000000000..cfd4acc7e
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/notice/RefundNoticeModel.java
@@ -0,0 +1,72 @@
+package cn.daxpay.single.sdk.model.notice;
+
+import cn.daxpay.single.sdk.code.ChannelEnum;
+import cn.daxpay.single.sdk.code.RefundStatusEnum;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 退款通知消息
+ * @author xxm
+ * @since 2024/2/22
+ */
+@Data
+public class RefundNoticeModel{
+
+ /** 支付订单号 */
+ private String orderNo;
+
+ /** 商户支付订单号 */
+ private String bizOrderNo;
+
+ /** 通道支付订单号 */
+ private String outOrderNo;
+
+ /** 支付标题 */
+ private String title;
+
+ /** 退款号 */
+ private String refundNo;
+
+ /** 商户退款号 */
+ private String bizRefundNo;
+
+ /** 通道退款交易号 */
+ private String outRefundNo;
+
+ /**
+ * 退款通道
+ * @see ChannelEnum
+ */
+ private String channel;
+
+ /** 订单金额 */
+ private Integer orderAmount;
+
+ /** 退款金额 */
+ private BigDecimal amount;
+
+ /** 退款原因 */
+ private String reason;
+
+ /** 退款成功时间 */
+ private Long finishTime;
+
+ /** 退款创建时间 */
+ private Long createTime;
+ /**
+ * 退款状态
+ * @see RefundStatusEnum
+ */
+ private String status;
+
+ /** 商户扩展参数,回调时会原样返回 */
+ private String attach;
+
+ /** 错误码 */
+ private String errorCode;
+
+ /** 错误原因 */
+ private String errorMsg;
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/reconcile/ReconcileDownModel.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/reconcile/ReconcileDownModel.java
new file mode 100644
index 000000000..3a81d8fcc
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/reconcile/ReconcileDownModel.java
@@ -0,0 +1,16 @@
+package cn.daxpay.single.sdk.model.reconcile;
+
+import lombok.Data;
+
+/**
+ * 对账单文件下载链接
+ * @author xxm
+ * @since 2024/8/21
+ */
+@Data
+public class ReconcileDownModel {
+ /**
+ * 文件下载链接
+ */
+ private String fileUrl;
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/pay/PayOrderModel.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/pay/PayOrderModel.java
new file mode 100644
index 000000000..6015fb479
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/pay/PayOrderModel.java
@@ -0,0 +1,111 @@
+package cn.daxpay.single.sdk.model.trade.pay;
+
+import cn.daxpay.single.sdk.code.ChannelEnum;
+import cn.daxpay.single.sdk.code.PayAllocStatusEnum;
+import cn.daxpay.single.sdk.code.PayRefundStatusEnum;
+import cn.daxpay.single.sdk.code.PayStatusEnum;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 支付订单查询响应参数
+ * @author xxm
+ * @since 2024/1/16
+ */
+@Data
+public class PayOrderModel{
+
+ /** 商户订单号 */
+ @Schema(description = "商户订单号")
+ private String bizOrderNo;
+
+ @Schema(description = "支付订单号")
+ private String orderNo;
+
+ /**
+ * 通道系统交易号
+ */
+ @Schema(description = "通道支付订单号")
+ private String outOrderNo;
+
+ /** 标题 */
+ @Schema(description = "标题")
+ private String title;
+
+ /** 描述 */
+ @Schema(description = "描述")
+ private String description;
+
+ /** 是否支持分账 */
+ @Schema(description = "是否需要分账")
+ private Boolean allocation;
+
+ /** 是否开启自动分账, 不传输为不开启 */
+ @Schema(description = "是否开启自动分账")
+ private Boolean autoAllocation;
+
+ /**
+ * 支付通道
+ * @see ChannelEnum
+ */
+ @Schema(description = "异步支付通道")
+ private String channel;
+
+ /**
+ * 支付方式
+ */
+ @Schema(description = "支付方式")
+ private String method;
+
+ /** 金额 */
+ @Schema(description = "金额")
+ private BigDecimal amount;
+
+ /** 可退款余额 */
+ @Schema(description = "可退款余额")
+ private BigDecimal refundableBalance;
+
+ /**
+ * 支付状态
+ * @see PayStatusEnum
+ */
+ @Schema(description = "支付状态")
+ private String status;
+
+ /**
+ * 退款状态
+ * @see PayRefundStatusEnum
+ */
+ @Schema(description = "退款状态")
+ private String refundStatus;
+
+ /**
+ * 分账状态
+ * @see PayAllocStatusEnum
+ */
+ @Schema(description = "分账状态")
+ private String allocStatus;
+
+ /** 支付时间 */
+ @Schema(description = "支付时间")
+ private LocalDateTime payTime;
+
+ /** 关闭时间 */
+ @Schema(description = "关闭时间")
+ private LocalDateTime closeTime;
+
+ /** 过期时间 */
+ @Schema(description = "过期时间")
+ private LocalDateTime expiredTime;
+
+ /** 商户扩展参数,回调时会原样返回 */
+ @Schema(description = "商户扩展参数")
+ private String attach;
+
+ /** 错误信息 */
+ @Schema(description = "错误信息")
+ private String errorMsg;
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/pay/PayResultModel.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/pay/PayResultModel.java
new file mode 100644
index 000000000..1b77e4d16
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/pay/PayResultModel.java
@@ -0,0 +1,24 @@
+package cn.daxpay.single.sdk.model.trade.pay;
+
+import lombok.Data;
+
+/**
+ * 发起支付后响应对象
+ * @author xxm
+ * @since 2024/2/2
+ */
+@Data
+public class PayResultModel {
+
+ /** 商户订单号 */
+ private String bizOrderNo;
+
+ /** 订单号 */
+ private String orderNo;
+
+ /** 支付状态 */
+ private String status;
+
+ /** 支付参数体(通常用于发起支付的参数) */
+ private String payBody;
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/pay/PaySyncModel.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/pay/PaySyncModel.java
new file mode 100644
index 000000000..cd1a526ac
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/pay/PaySyncModel.java
@@ -0,0 +1,20 @@
+package cn.daxpay.single.sdk.model.trade.pay;
+
+import cn.daxpay.single.sdk.code.PaySyncStatusEnum;
+import lombok.Data;
+
+/**
+ * 交易同步结果
+ * @author xxm
+ * @since 2023/12/27
+ */
+@Data
+public class PaySyncModel{
+
+ /**
+ * 同步结果
+ * @see PaySyncStatusEnum
+ */
+ private String status;
+
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/refund/RefundModel.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/refund/RefundModel.java
new file mode 100644
index 000000000..77973f59d
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/refund/RefundModel.java
@@ -0,0 +1,21 @@
+package cn.daxpay.single.sdk.model.trade.refund;
+
+import lombok.Data;
+
+/**
+ * 退款响应参数
+ * @author xxm
+ * @since 2023/12/18
+ */
+@Data
+public class RefundModel{
+
+ /** 退款号 */
+ private String refundNo;
+
+ /** 商户退款号 */
+ private String bizRefundNo;
+
+ /** 退款状态 */
+ private String status;
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/refund/RefundOrderModel.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/refund/RefundOrderModel.java
new file mode 100644
index 000000000..27b42592d
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/refund/RefundOrderModel.java
@@ -0,0 +1,84 @@
+package cn.daxpay.single.sdk.model.trade.refund;
+
+import cn.daxpay.single.sdk.code.ChannelEnum;
+import cn.daxpay.single.sdk.code.RefundStatusEnum;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 退款订单数据
+ * @author xxm
+ * @since 2024/1/16
+ */
+@Data
+public class RefundOrderModel{
+
+ /** 支付订单号 */
+ @Schema(description = "支付订单号")
+ private String orderNo;
+
+ /** 通道支付订单号 */
+ @Schema(description = "通道支付订单号")
+ private String outOrderNo;
+
+ /** 商户支付订单号 */
+ @Schema(description = "商户支付订单号")
+ private String bizOrderNo;
+
+ /** 支付标题 */
+ @Schema(description = "支付标题")
+ private String title;
+
+ /** 退款号 */
+ @Schema(description = "退款号")
+ private String refundNo;
+
+ /** 商户退款号 */
+ @Schema(description = "商户退款号")
+ private String bizRefundNo;
+
+ /** 通道退款交易号 */
+ @Schema(description = "通道退款交易号")
+ private String outRefundNo;
+
+ /**
+ * 退款通道
+ * @see ChannelEnum
+ */
+ @Schema(description = "支付通道")
+ private String channel;
+
+ /** 订单金额 */
+ @Schema(description = "订单金额")
+ private Integer orderAmount;
+
+ /** 退款金额 */
+ @Schema(description = "退款金额")
+ private BigDecimal amount;
+
+ /** 退款原因 */
+ @Schema(description = "退款原因")
+ private String reason;
+
+ /** 退款结束时间 */
+ @Schema(description = "退款结束时间")
+ private LocalDateTime finishTime;
+
+ /**
+ * 退款状态
+ * @see RefundStatusEnum
+ */
+ @Schema(description = "退款状态")
+ private String status;
+
+ /** 商户扩展参数,回调时会原样返回, 以最后一次为准 */
+ @Schema(description = "商户扩展参数,回调时会原样返回, 以最后一次为准")
+ private String attach;
+
+ /** 错误信息 */
+ @Schema(description = "错误信息")
+ private String errorMsg;
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/refund/RefundSyncModel.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/refund/RefundSyncModel.java
new file mode 100644
index 000000000..36a20bd57
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/refund/RefundSyncModel.java
@@ -0,0 +1,20 @@
+package cn.daxpay.single.sdk.model.trade.refund;
+
+import cn.daxpay.single.sdk.code.RefundSyncStatusEnum;
+import lombok.Data;
+
+/**
+ * 交易同步结果
+ * @author xxm
+ * @since 2023/12/27
+ */
+@Data
+public class RefundSyncModel{
+
+ /**
+ * 同步结果
+ * @see RefundSyncStatusEnum
+ */
+ private String status;
+
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/transfer/TransferModel.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/transfer/TransferModel.java
new file mode 100644
index 000000000..3765a27bf
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/transfer/TransferModel.java
@@ -0,0 +1,31 @@
+package cn.daxpay.single.sdk.model.trade.transfer;
+
+import cn.daxpay.single.sdk.code.TransferStatusEnum;
+import lombok.Data;
+
+/**
+ * 转账结果
+ * @author xxm
+ * @since 2024/6/19
+ */
+@Data
+public class TransferModel{
+
+ /** 商户转账号 */
+ private String bizTransferNo;
+
+ /** 转账号 */
+ private String transferNo;
+
+ /**
+ * 状态
+ * @see TransferStatusEnum
+ */
+ private String status;
+
+
+ /**
+ * 提示信息
+ */
+ private String errorMsg;
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/transfer/TransferOrderModel.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/transfer/TransferOrderModel.java
new file mode 100644
index 000000000..92594ba33
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/transfer/TransferOrderModel.java
@@ -0,0 +1,86 @@
+package cn.daxpay.single.sdk.model.trade.transfer;
+
+import cn.daxpay.single.sdk.code.ChannelEnum;
+import cn.daxpay.single.sdk.code.TransferPayeeTypeEnum;
+import cn.daxpay.single.sdk.code.TransferStatusEnum;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 转账订单
+ * @author xxm
+ * @since 2024/6/20
+ */
+@Data
+public class TransferOrderModel{
+
+ /** 商户转账号 */
+ @Schema(description = "商户转账号")
+ private String bizTransferNo;
+
+ /** 转账号 */
+ @Schema(description = "转账号")
+ private String transferNo;
+
+ /** 通道转账号 */
+ @Schema(description = "通道转账号")
+ private String outTransferNo;
+
+ /**
+ * 支付通道
+ * @see ChannelEnum
+ */
+ @Schema(description = "支付通道")
+ private String channel;
+
+ /** 转账金额 */
+ @Schema(description = "转账金额")
+ private BigDecimal amount;
+
+ /** 标题 */
+ @Schema(description = "标题")
+ private String title;
+
+ /** 转账原因/备注 */
+ @Schema(description = "转账原因/备注")
+ private String reason;
+
+ /**
+ * 收款人类型
+ * @see TransferPayeeTypeEnum
+ */
+ @Schema(description = "收款人类型")
+ private String payeeType;
+
+ /** 收款人账号 */
+ @Schema(description = "收款人账号")
+ private String payeeAccount;
+
+ /** 收款人姓名 */
+ @Schema(description = "收款人姓名")
+ private String payeeName;
+
+ /**
+ * 状态
+ * @see TransferStatusEnum
+ */
+ @Schema(description = "状态")
+ private String status;
+
+ /** 完成时间 */
+ @Schema(description = "完成时间")
+ private LocalDateTime finishTime;
+
+ /** 商户扩展参数,回调时会原样返回, 以最后一次为准 */
+ @Schema(description = "商户扩展参数")
+ private String attach;
+
+ /**
+ * 错误原因
+ */
+ @Schema(description = "错误原因")
+ private String errorMsg;
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/net/DaxPayConfig.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/net/DaxPayConfig.java
new file mode 100644
index 000000000..58c7ca4b7
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/net/DaxPayConfig.java
@@ -0,0 +1,38 @@
+package cn.daxpay.single.sdk.net;
+
+import cn.daxpay.single.sdk.code.SignTypeEnum;
+import cn.hutool.core.util.StrUtil;
+import lombok.Builder;
+import lombok.Getter;
+
+/**
+ * 支付配置
+ * @author xxm
+ * @since 2024/2/2
+ */
+@Getter
+@Builder
+public class DaxPayConfig {
+
+ /** 服务地址 */
+ private String serviceUrl;
+
+ /** 应用号 */
+ private String appId;
+
+ /** 签名方式 */
+ @Builder.Default
+ private SignTypeEnum signType = SignTypeEnum.HMAC_SHA256;
+
+ /** 签名秘钥 */
+ private String signSecret;
+
+ /** 请求超时时间 */
+ @Builder.Default
+ private int reqTimeout = 30000;
+
+
+ public String getServiceUrl() {
+ return StrUtil.removeSuffix(serviceUrl, "/");
+ }
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/net/DaxPayKit.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/net/DaxPayKit.java
new file mode 100644
index 000000000..bc91b8121
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/net/DaxPayKit.java
@@ -0,0 +1,81 @@
+package cn.daxpay.single.sdk.net;
+
+import cn.daxpay.single.sdk.code.SignTypeEnum;
+import cn.daxpay.single.sdk.response.DaxPayResult;
+import cn.daxpay.single.sdk.util.JsonUtil;
+import cn.daxpay.single.sdk.util.PaySignUtil;
+import cn.hutool.http.*;
+import lombok.experimental.UtilityClass;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.Objects;
+
+/**
+ * 支付发起工具包
+ * @author xxm
+ * @since 2024/2/2
+ */
+@Slf4j
+@UtilityClass
+public class DaxPayKit {
+
+ private DaxPayConfig config;
+
+ public void initConfig(DaxPayConfig config){
+ log.debug("DaxPayKit初始化...");
+ DaxPayKit.config = config;
+ }
+
+ /**
+ * 支付请求执行类, 默认对请求参数进行签名
+ * @param request 请求参数
+ * @return DaxPayResult 响应类
+ * @param 业务对象
+ */
+ public DaxPayResult execute(DaxPayRequest request){
+ return execute(request, true);
+ }
+
+ /**
+ * 支付请求执行类
+ * @param request 请求参数
+ * @param sign 是否进行签名
+ * @return DaxPayResult 响应类
+ * @param 业务对象
+ */
+ public DaxPayResult execute(DaxPayRequest request, boolean sign){
+ // 判断是否需要填充和应用号
+ if (Objects.isNull(request.getAppId())){
+ request.setAppId(config.getAppId());
+ }
+ // 判断是是否进行签名
+ if (sign) {
+ if (Objects.equals(SignTypeEnum.MD5,config.getSignType())){
+ request.setSign(PaySignUtil.md5Sign(request, config.getSignSecret()));
+ } else if (Objects.equals(SignTypeEnum.HMAC_SHA256,config.getSignType())){
+ request.setSign(PaySignUtil.hmacSha256Sign(request, config.getSignSecret()));
+ } else if (Objects.equals(SignTypeEnum.SM3,config.getSignType())){
+ request.setSign(PaySignUtil.sm3Sign(request, config.getSignSecret()));
+ }
+ }
+ // 参数序列化
+ String data = JsonUtil.toJsonStr(request);
+ log.debug("请求参数:{}", data);
+
+ String path = config.getServiceUrl() + request.path();
+ String body;
+ try (HttpResponse execute = HttpUtil.createPost(path)
+ .body(data, ContentType.JSON.getValue())
+ .timeout(config.getReqTimeout())
+ .execute()) {
+ // 响应码只有200 才可以进行支付
+ if (execute.getStatus() != HttpStatus.HTTP_OK) {
+ log.error("请求第支付网关失败,请排查配置的支付网关地址是否正常");
+ throw new HttpException("请求失败,内部异常");
+ }
+ body = execute.body();
+ }
+ log.debug("响应参数:{}", body);
+ return request.toModel(body);
+ }
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/net/DaxPayRequest.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/net/DaxPayRequest.java
new file mode 100644
index 000000000..e49fa7906
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/net/DaxPayRequest.java
@@ -0,0 +1,46 @@
+package cn.daxpay.single.sdk.net;
+
+import cn.daxpay.single.sdk.response.DaxPayResult;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.time.LocalDateTime;
+
+/**
+ * 请求接口
+ * @author xxm
+ * @since 2024/2/2
+ */
+@Getter
+@Setter
+public abstract class DaxPayRequest {
+
+ /** 应用号 */
+ private String appId;
+
+ /** 客户端ip */
+ private String clientIp;
+
+ /** 签名 */
+ private String sign;
+
+ /** 请求时间,yyyy-MM-dd HH:mm:ss 格式 */
+ private LocalDateTime reqTime = LocalDateTime.now();
+
+ /** 随机数 */
+ private String nonceStr;
+
+ /**
+ * 方法请求路径
+ * @return 请求路径
+ */
+ public abstract String path();
+
+ /**
+ * 将请求返回结果反序列化为实体类
+ * @param json json字符串
+ * @return 反序列后的对象
+ */
+ public abstract DaxPayResult toModel(String json);
+
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/ChannelParam.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/ChannelParam.java
new file mode 100644
index 000000000..3cd3ab192
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/ChannelParam.java
@@ -0,0 +1,19 @@
+package cn.daxpay.single.sdk.param;
+
+
+import cn.daxpay.single.sdk.util.JsonUtil;
+
+/**
+ * 通道支付参数标识接口
+ * @author xxm
+ * @since 2023/12/17
+ */
+public interface ChannelParam extends SortMapParam {
+
+ /**
+ * 转换成字符串
+ */
+ default String toJson(){
+ return JsonUtil.toJsonStr(this);
+ }
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/SortMapParam.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/SortMapParam.java
new file mode 100644
index 000000000..604729c6d
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/SortMapParam.java
@@ -0,0 +1,9 @@
+package cn.daxpay.single.sdk.param;
+
+/**
+ * 标示字段可以转换为MAP进行排序
+ * @author xxm
+ * @since 2024/2/8
+ */
+public interface SortMapParam {
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/allocation/AllocReceiverAddParam.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/allocation/AllocReceiverAddParam.java
new file mode 100644
index 000000000..ea308ed7c
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/allocation/AllocReceiverAddParam.java
@@ -0,0 +1,70 @@
+package cn.daxpay.single.sdk.param.allocation;
+
+import cn.daxpay.single.sdk.code.AllocReceiverTypeEnum;
+import cn.daxpay.single.sdk.code.AllocRelationTypeEnum;
+import cn.daxpay.single.sdk.code.ChannelEnum;
+import cn.daxpay.single.sdk.net.DaxPayRequest;
+import cn.daxpay.single.sdk.response.DaxPayResult;
+import cn.daxpay.single.sdk.model.allocation.AllocReceiverAddModel;
+import cn.daxpay.single.sdk.util.JsonUtil;
+import cn.hutool.core.lang.TypeReference;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * 分账接收者添加参数
+ * @author xxm
+ * @since 2024/5/20
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Accessors(chain = true)
+public class AllocReceiverAddParam extends DaxPayRequest {
+
+ /** 接收者编号 */
+ private String receiverNo;
+
+ /**
+ * 所属通道
+ * @see ChannelEnum
+ */
+ private String channel;
+
+ /**
+ * 分账接收方类型 根据不同类型的通道进行传输
+ * @see AllocReceiverTypeEnum
+ */
+ private String receiverType;
+
+ /** 接收方账号 */
+ private String receiverAccount;
+
+ /** 接收方姓名 */
+ private String receiverName;
+
+ /**
+ * 分账关系类型
+ * @see AllocRelationTypeEnum
+ */
+ private String relationType;
+
+ /** 关系名称 关系类型为自定义是填写 */
+ private String relationName;
+
+ /**
+ * 方法请求路径
+ */
+ @Override
+ public String path() {
+ return "/unipay/allocation/receiver/add";
+ }
+
+ /**
+ * 将请求返回结果反序列化为实体类
+ */
+ @Override
+ public DaxPayResult toModel(String json) {
+ return JsonUtil.toBean(json, new TypeReference>() {});
+ }
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/allocation/AllocReceiverParam.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/allocation/AllocReceiverParam.java
new file mode 100644
index 000000000..12b4f844d
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/allocation/AllocReceiverParam.java
@@ -0,0 +1,22 @@
+package cn.daxpay.single.sdk.param.allocation;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * 分账接收方列表参数
+ * @author xxm
+ * @since 2024/5/21
+ */
+@Getter
+@Setter
+public class AllocReceiverParam {
+
+ /** 分账接收方编号 */
+ private String receiverNo;
+
+ /** 分账金额 */
+ private BigDecimal amount;
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/allocation/AllocReceiverRemoveParam.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/allocation/AllocReceiverRemoveParam.java
new file mode 100644
index 000000000..5cc24967f
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/allocation/AllocReceiverRemoveParam.java
@@ -0,0 +1,40 @@
+package cn.daxpay.single.sdk.param.allocation;
+
+import cn.daxpay.single.sdk.net.DaxPayRequest;
+import cn.daxpay.single.sdk.response.DaxPayResult;
+import cn.daxpay.single.sdk.model.allocation.AllocReceiverRemoveModel;
+import cn.daxpay.single.sdk.util.JsonUtil;
+import cn.hutool.core.lang.TypeReference;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * 分账接收者删除参数
+ * @author xxm
+ * @since 2024/5/20
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Accessors(chain = true)
+public class AllocReceiverRemoveParam extends DaxPayRequest {
+
+ /** 接收者编号 */
+ private String receiverNo;
+
+ /**
+ * 方法请求路径
+ */
+ @Override
+ public String path() {
+ return "/unipay/allocation/receiver/remove";
+ }
+
+ /**
+ * 将请求返回结果反序列化为实体类
+ */
+ @Override
+ public DaxPayResult toModel(String json) {
+ return JsonUtil.toBean(json, new TypeReference>() {});
+ }
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/channel/AlipayParam.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/channel/AlipayParam.java
new file mode 100644
index 000000000..7ec15e163
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/channel/AlipayParam.java
@@ -0,0 +1,39 @@
+package cn.daxpay.single.sdk.param.channel;
+
+import cn.daxpay.single.sdk.param.ChannelParam;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 支付宝支付参数
+ * @author xxm
+ * @since 2021/2/27
+ */
+@Getter
+@Setter
+public class AlipayParam implements ChannelParam {
+
+ /**
+ * 授权码(主动扫描用户的付款码)
+ */
+ private String authCode;
+
+ /**
+ * 【描述】小程序支付中,商户实际经营主体的小程序应用的appid,也即最终唤起收银台支付所在的小程序的应用id
+ * 【注意事项】商户需要先在产品管理中心绑定该小程序appid,否则下单会失败
+ */
+ private String opAppId;
+
+ /**
+ * 买家支付宝用户唯一标识
+ */
+ private String openId;
+
+
+ /**
+ * 买家支付宝用户ID
+ * 新商户建议使用buyer_open_id替代该字段。对于新商户,buyer_id字段未来计划逐步回收,存量商户可继续使用
+ */
+ private String buyerId;
+
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/channel/UnionPayParam.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/channel/UnionPayParam.java
new file mode 100644
index 000000000..ee159cd5c
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/channel/UnionPayParam.java
@@ -0,0 +1,19 @@
+package cn.daxpay.single.sdk.param.channel;
+
+import cn.daxpay.single.sdk.param.ChannelParam;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 云闪付参数
+ * @author xxm
+ * @since 2024/3/13
+ */
+@Getter
+@Setter
+public class UnionPayParam implements ChannelParam {
+
+ /** 授权码(主动扫描用户的付款码) */
+ private String authCode;
+
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/channel/WechatPayParam.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/channel/WechatPayParam.java
new file mode 100644
index 000000000..d412ba8ea
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/channel/WechatPayParam.java
@@ -0,0 +1,22 @@
+package cn.daxpay.single.sdk.param.channel;
+
+import cn.daxpay.single.sdk.param.ChannelParam;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 微信支付参数
+ * @author xxm
+ * @since 2021/6/21
+ */
+@Getter
+@Setter
+public class WechatPayParam implements ChannelParam {
+
+ /** 微信openId */
+ private String openId;
+
+ /** 授权码(主动扫描用户的付款码) */
+ private String authCode;
+
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/reconcile/ChannelReconcileDownParam.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/reconcile/ChannelReconcileDownParam.java
new file mode 100644
index 000000000..8da2fa595
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/reconcile/ChannelReconcileDownParam.java
@@ -0,0 +1,49 @@
+package cn.daxpay.single.sdk.param.reconcile;
+
+import cn.daxpay.single.sdk.net.DaxPayRequest;
+import cn.daxpay.single.sdk.response.DaxPayResult;
+import cn.daxpay.single.sdk.model.reconcile.ReconcileDownModel;
+import cn.daxpay.single.sdk.util.JsonUtil;
+import cn.hutool.core.lang.TypeReference;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.time.LocalDate;
+
+/**
+ * 通道对账文件下载参数
+ * @author xxm
+ * @since 2024/8/21
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Schema(title = "对账下载参数")
+public class ChannelReconcileDownParam extends DaxPayRequest {
+ @Schema(description = "通道")
+ private String channel;
+
+ @Schema(description = "日期")
+ private LocalDate date;
+
+ /**
+ * 方法请求路径
+ *
+ * @return 请求路径
+ */
+ @Override
+ public String path() {
+ return "/unipay/reconcile/channelDownUrl";
+ }
+
+ /**
+ * 将请求返回结果反序列化为实体类
+ *
+ * @param json json字符串
+ * @return 反序列后的对象
+ */
+ @Override
+ public DaxPayResult toModel(String json) {
+ return JsonUtil.toBean(json, new TypeReference>() {});
+ }
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/reconcile/PlatformReconcileDownParam.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/reconcile/PlatformReconcileDownParam.java
new file mode 100644
index 000000000..735b27921
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/reconcile/PlatformReconcileDownParam.java
@@ -0,0 +1,44 @@
+package cn.daxpay.single.sdk.param.reconcile;
+
+import cn.daxpay.single.sdk.net.DaxPayRequest;
+import cn.daxpay.single.sdk.response.DaxPayResult;
+import cn.daxpay.single.sdk.model.reconcile.ReconcileDownModel;
+import cn.daxpay.single.sdk.util.JsonUtil;
+import cn.hutool.core.lang.TypeReference;
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import java.time.LocalDate;
+
+/**
+ * 平台对账文件下载参数
+ * @author xxm
+ * @since 2024/8/21
+ */
+public class PlatformReconcileDownParam extends DaxPayRequest {
+ @Schema(description = "通道")
+ private String channel;
+
+ @Schema(description = "日期")
+ private LocalDate date;
+
+ /**
+ * 方法请求路径
+ *
+ * @return 请求路径
+ */
+ @Override
+ public String path() {
+ return "/unipay/reconcile/platformDownUrl";
+ }
+
+ /**
+ * 将请求返回结果反序列化为实体类
+ *
+ * @param json json字符串
+ * @return 反序列后的对象
+ */
+ @Override
+ public DaxPayResult toModel(String json) {
+ return JsonUtil.toBean(json, new TypeReference>() {});
+ }
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/pay/PayCloseParam.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/pay/PayCloseParam.java
new file mode 100644
index 000000000..a4a87e280
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/pay/PayCloseParam.java
@@ -0,0 +1,55 @@
+package cn.daxpay.single.sdk.param.trade.pay;
+
+import cn.daxpay.single.sdk.net.DaxPayRequest;
+import cn.daxpay.single.sdk.response.DaxPayResult;
+import cn.daxpay.single.sdk.util.JsonUtil;
+import cn.hutool.core.lang.TypeReference;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 支付关闭参数
+ * @author xxm
+ * @since 2023/12/17
+ */
+@Getter
+@Setter
+public class PayCloseParam extends DaxPayRequest {
+
+ /**
+ * 订单号
+ * 订单号和商户订单号必传一个
+ * 长度不可超过32位
+ */
+ private String orderNo;
+
+ /**
+ * 商户订单号
+ * 订单号和商户订单号必传一个
+ * 长度不可超过100位
+ */
+ private String bizOrderNo;
+
+ /**
+ * 是否使用撤销方式进行订单关闭, 只
+ * 有部分支付通道的支付方式才可以使用,
+ * 如果支付订单不支持撤销, 这个参数将不会生效
+ */
+ private boolean useCancel;
+
+ /**
+ * 方法请求路径
+ */
+ @Override
+ public String path() {
+ return "/unipay/close";
+ }
+
+ /**
+ * 将请求返回结果反序列化为实体类
+ */
+ @Override
+ public DaxPayResult toModel(String json) {
+ return JsonUtil.toBean(json, new TypeReference>() {});
+ }
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/pay/PayParam.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/pay/PayParam.java
new file mode 100644
index 000000000..d257debce
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/pay/PayParam.java
@@ -0,0 +1,94 @@
+package cn.daxpay.single.sdk.param.trade.pay;
+
+import cn.daxpay.single.sdk.code.ChannelEnum;
+import cn.daxpay.single.sdk.code.PayMethodEnum;
+import cn.daxpay.single.sdk.net.DaxPayRequest;
+import cn.daxpay.single.sdk.param.channel.AlipayParam;
+import cn.daxpay.single.sdk.param.channel.WechatPayParam;
+import cn.daxpay.single.sdk.response.DaxPayResult;
+import cn.daxpay.single.sdk.model.trade.pay.PayResultModel;
+import cn.daxpay.single.sdk.util.JsonUtil;
+import cn.hutool.core.lang.TypeReference;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 支付参数
+ * @author xxm
+ * @since 2024/2/2
+ */
+@Getter
+@Setter
+public class PayParam extends DaxPayRequest {
+
+ /** 商户订单号 */
+ private String bizOrderNo;
+
+ /** 支付标题 */
+ private String title;
+
+ /** 支付描述 */
+ private String description;
+
+ /** 是否开启分账, 不传输为不开启 */
+ private Boolean allocation;
+
+ /** 是否开启自动分账, 不传输为不开启 */
+ private Boolean autoAllocation;
+
+ /** 过期时间 */
+ private LocalDateTime expiredTime;
+
+ /**
+ * 支付通道编码
+ * @see ChannelEnum#getCode()
+ */
+ private String channel;
+
+ /**
+ * 支付方式编码
+ * @see PayMethodEnum#getCode()
+ */
+ private String method;
+
+ /** 支付金额 */
+ private BigDecimal amount;
+
+ /**
+ * 支付扩展参数, json字符串格式
+ * @see AlipayParam
+ * @see WechatPayParam
+ */
+ private String extraParam;
+
+ /** 商户扩展参数,回调时会原样返回 */
+ private String attach;
+
+ /** 同步跳转地址, 支付完毕后用户浏览器返回到该地址, 不传输跳转到默认地址 */
+ private String returnUrl;
+
+ /** 退出地址 */
+ private String quitUrl;
+
+ /** 异步通知地址 */
+ private String notifyUrl;
+
+ /**
+ * 方法请求路径
+ */
+ @Override
+ public String path() {
+ return "/unipay/pay";
+ }
+
+ /**
+ * 将请求返回结果反序列化为实体类
+ */
+ @Override
+ public DaxPayResult toModel(String json) {
+ return JsonUtil.toBean(json, new TypeReference>() {});
+ }
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/pay/PaySyncParam.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/pay/PaySyncParam.java
new file mode 100644
index 000000000..3cac4bef6
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/pay/PaySyncParam.java
@@ -0,0 +1,41 @@
+package cn.daxpay.single.sdk.param.trade.pay;
+
+import cn.daxpay.single.sdk.net.DaxPayRequest;
+import cn.daxpay.single.sdk.response.DaxPayResult;
+import cn.daxpay.single.sdk.model.trade.pay.PaySyncModel;
+import cn.daxpay.single.sdk.util.JsonUtil;
+import cn.hutool.core.lang.TypeReference;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ *支付同步参数
+ * @author xxm
+ * @since 2024/2/5
+ */
+@Getter
+@Setter
+public class PaySyncParam extends DaxPayRequest {
+
+ /** 订单号 */
+ private String orderNo;
+
+ /** 商户订单号 */
+ private String bizOrderNo;
+
+ /**
+ * 方法请求路径
+ */
+ @Override
+ public String path() {
+ return "/unipay/sync/pay";
+ }
+
+ /**
+ * 将请求返回结果反序列化为实体类
+ */
+ @Override
+ public DaxPayResult toModel(String json) {
+ return JsonUtil.toBean(json, new TypeReference>() {});
+ }
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/pay/QueryPayParam.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/pay/QueryPayParam.java
new file mode 100644
index 000000000..e6e9ab044
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/pay/QueryPayParam.java
@@ -0,0 +1,41 @@
+package cn.daxpay.single.sdk.param.trade.pay;
+
+import cn.daxpay.single.sdk.net.DaxPayRequest;
+import cn.daxpay.single.sdk.response.DaxPayResult;
+import cn.daxpay.single.sdk.model.trade.pay.PayOrderModel;
+import cn.daxpay.single.sdk.util.JsonUtil;
+import cn.hutool.core.lang.TypeReference;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 支付单查询参数
+ * @author xxm
+ * @since 2024/1/16
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class QueryPayParam extends DaxPayRequest {
+
+ /** 订单号 */
+ private String orderNo;
+
+ /** 商户订单号 */
+ private String bizOrderNoeNo;
+
+ /**
+ * 方法请求路径
+ */
+ @Override
+ public String path() {
+ return "/unipay/query/payOrder";
+ }
+
+ /**
+ * 将请求返回结果反序列化为实体类
+ */
+ @Override
+ public DaxPayResult toModel(String json) {
+ return JsonUtil.toBean(json, new TypeReference>() {});
+ }
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/refund/QueryRefundParam.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/refund/QueryRefundParam.java
new file mode 100644
index 000000000..941ebbc70
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/refund/QueryRefundParam.java
@@ -0,0 +1,42 @@
+package cn.daxpay.single.sdk.param.trade.refund;
+
+import cn.daxpay.single.sdk.net.DaxPayRequest;
+import cn.daxpay.single.sdk.response.DaxPayResult;
+import cn.daxpay.single.sdk.model.trade.refund.RefundOrderModel;
+import cn.daxpay.single.sdk.util.JsonUtil;
+import cn.hutool.core.lang.TypeReference;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 查询退款订单参数类
+ * @author xxm
+ * @since 2024/1/16
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class QueryRefundParam extends DaxPayRequest {
+
+
+ /** 退款号 */
+ private String refundNo;
+
+ /** 商户退款号 */
+ private String bizRefundNo;
+
+ /**
+ * 方法请求路径
+ */
+ @Override
+ public String path() {
+ return "/unipay/query/refundOrder";
+ }
+
+ /**
+ * 将请求返回结果反序列化为实体类
+ */
+ @Override
+ public DaxPayResult toModel(String json) {
+ return JsonUtil.toBean(json, new TypeReference>() {});
+ }
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/refund/RefundParam.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/refund/RefundParam.java
new file mode 100644
index 000000000..d5ec8bc04
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/refund/RefundParam.java
@@ -0,0 +1,80 @@
+package cn.daxpay.single.sdk.param.trade.refund;
+
+import cn.daxpay.single.sdk.net.DaxPayRequest;
+import cn.daxpay.single.sdk.param.ChannelParam;
+import cn.daxpay.single.sdk.param.channel.AlipayParam;
+import cn.daxpay.single.sdk.param.channel.UnionPayParam;
+import cn.daxpay.single.sdk.param.channel.WechatPayParam;
+import cn.daxpay.single.sdk.response.DaxPayResult;
+import cn.daxpay.single.sdk.model.trade.refund.RefundModel;
+import cn.daxpay.single.sdk.util.JsonUtil;
+import cn.hutool.core.lang.TypeReference;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+import java.math.BigDecimal;
+
+/**
+ * 退款参数,适用于组合支付的订单退款操作中,
+ * @author xxm
+ * @since 2023/12/18
+ */
+@Getter
+@Setter
+@ToString(callSuper = true)
+public class RefundParam extends DaxPayRequest {
+
+
+ /**
+ * 商户退款号,不可以为空,同样的商户退款号多次请求,同一退款单号多次请求只退一笔
+ */
+ private String bizRefundNo;
+
+ /**
+ * 支付订单号,与商户订单号至少要传输一个,同时传输以订单号为准
+ */
+ private String orderNo;
+
+ /**
+ * 商户支付订单号,与订单号至少要传输一个,同时传输以订单号为准
+ */
+ private String bizOrderNo;
+
+ /** 退款金额 */
+ private BigDecimal amount;
+
+
+ /** 退款原因 */
+ private String reason;
+
+ /**
+ * 预留的退款扩展参数
+ * @see AlipayParam
+ * @see WechatPayParam
+ * @see UnionPayParam
+ */
+ private ChannelParam extraParam;
+
+ /** 商户扩展参数,回调时会原样返回 */
+ private String attach;
+
+ /** 异步通知地址 */
+ private String notifyUrl;
+
+ /**
+ * 方法请求路径
+ */
+ @Override
+ public String path() {
+ return "/unipay/refund";
+ }
+
+ /**
+ * 将请求返回结果反序列化为实体类
+ */
+ @Override
+ public DaxPayResult toModel(String json) {
+ return JsonUtil.toBean(json, new TypeReference>() {});
+ }
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/refund/RefundSyncParam.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/refund/RefundSyncParam.java
new file mode 100644
index 000000000..7bf8f07e0
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/refund/RefundSyncParam.java
@@ -0,0 +1,41 @@
+package cn.daxpay.single.sdk.param.trade.refund;
+
+import cn.daxpay.single.sdk.net.DaxPayRequest;
+import cn.daxpay.single.sdk.response.DaxPayResult;
+import cn.daxpay.single.sdk.model.trade.refund.RefundSyncModel;
+import cn.daxpay.single.sdk.util.JsonUtil;
+import cn.hutool.core.lang.TypeReference;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 退款同步参数
+ * @author xxm
+ * @since 2024/2/7
+ */
+@Getter
+@Setter
+public class RefundSyncParam extends DaxPayRequest {
+
+ /** 退款号 */
+ private String refundNo;
+
+ /** 商户退款号 */
+ private String bizRefundNo;
+
+ /**
+ * 方法请求路径
+ */
+ @Override
+ public String path() {
+ return "/unipay/sync/refund";
+ }
+
+ /**
+ * 将请求返回结果反序列化为实体类
+ */
+ @Override
+ public DaxPayResult toModel(String json) {
+ return JsonUtil.toBean(json, new TypeReference>() {});
+ }
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/transfer/QueryTransferParam.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/transfer/QueryTransferParam.java
new file mode 100644
index 000000000..1c9c58583
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/transfer/QueryTransferParam.java
@@ -0,0 +1,43 @@
+package cn.daxpay.single.sdk.param.trade.transfer;
+
+import cn.daxpay.single.sdk.net.DaxPayRequest;
+import cn.daxpay.single.sdk.response.DaxPayResult;
+import cn.daxpay.single.sdk.model.trade.transfer.TransferOrderModel;
+import cn.daxpay.single.sdk.util.JsonUtil;
+import cn.hutool.core.lang.TypeReference;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ *
+ * @author xxm
+ * @since 2024/6/20
+ */
+@Getter
+@Setter
+@ToString(callSuper = true)
+public class QueryTransferParam extends DaxPayRequest {
+
+ /** 商户转账号 */
+ private String bizTransferNo;
+
+ /** 转账号 */
+ private String transferNo;
+
+ /**
+ * 方法请求路径
+ */
+ @Override
+ public String path() {
+ return "/unipay/query/transfer";
+ }
+
+ /**
+ * 将请求返回结果反序列化为实体类
+ */
+ @Override
+ public DaxPayResult toModel(String json) {
+ return JsonUtil.toBean(json, new TypeReference>() {});
+ }
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/transfer/TransferParam.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/transfer/TransferParam.java
new file mode 100644
index 000000000..1ebd00339
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/transfer/TransferParam.java
@@ -0,0 +1,77 @@
+package cn.daxpay.single.sdk.param.trade.transfer;
+
+import cn.daxpay.single.sdk.code.ChannelEnum;
+import cn.daxpay.single.sdk.code.TransferPayeeTypeEnum;
+import cn.daxpay.single.sdk.net.DaxPayRequest;
+import cn.daxpay.single.sdk.response.DaxPayResult;
+import cn.daxpay.single.sdk.model.trade.transfer.TransferModel;
+import cn.daxpay.single.sdk.util.JsonUtil;
+import cn.hutool.core.lang.TypeReference;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+import java.math.BigDecimal;
+
+/**
+ * 转账参数
+ * @author xxm
+ * @since 2024/6/19
+ */
+@Getter
+@Setter
+@ToString(callSuper = true)
+public class TransferParam extends DaxPayRequest {
+
+ /** 商户转账号 */
+ private String bizTransferNo;
+
+ /**
+ * 支付通道
+ * @see ChannelEnum
+ */
+ private String channel;
+
+ /** 转账金额 */
+ private BigDecimal amount;
+
+ /** 标题 */
+ private String title;
+
+ /** 转账原因/备注 */
+ private String reason;
+
+ /**
+ * 收款人账号类型
+ * @see TransferPayeeTypeEnum
+ */
+ private String payeeType;
+
+ /** 收款人账号 */
+ private String payeeAccount;
+
+ /** 收款人姓名 */
+ private String payeeName;
+
+ /** 回调通知地址 */
+ private String notifyUrl;
+
+ /** 商户扩展参数,回调时会原样返回 */
+ private String attach;
+
+ /**
+ * 方法请求路径
+ */
+ @Override
+ public String path() {
+ return "/unipay/transfer";
+ }
+
+ /**
+ * 将请求返回结果反序列化为实体类
+ */
+ @Override
+ public DaxPayResult toModel(String json) {
+ return JsonUtil.toBean(json, new TypeReference>() {});
+ }
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/response/DaxPayResult.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/response/DaxPayResult.java
new file mode 100644
index 000000000..68c780e55
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/response/DaxPayResult.java
@@ -0,0 +1,44 @@
+package cn.daxpay.single.sdk.response;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+import java.time.LocalDateTime;
+
+/**
+ * 响应参数接收类
+ * @author xxm
+ * @since 2024/2/2
+ */
+@Getter
+@Setter
+@ToString
+public class DaxPayResult {
+
+ /** 状态码 */
+ @Schema(description = "状态码")
+ private int code;
+
+ /** 提示信息 */
+ @Schema(description = "提示信息")
+ private String msg;
+
+ /** 业务内容 */
+ @Schema(description = "业务内容")
+ private T data;
+
+ /** 签名 */
+ @Schema(description = "签名")
+ private String sign;
+
+ /** 响应时间 */
+ @Schema(description = "响应时间")
+ private LocalDateTime resTime;
+
+ /** 追踪ID */
+ @Schema(description = "追踪ID")
+ private String traceId;
+
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/util/JsonUtil.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/util/JsonUtil.java
new file mode 100644
index 000000000..ba63746d0
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/util/JsonUtil.java
@@ -0,0 +1,51 @@
+package cn.daxpay.single.sdk.util;
+
+import cn.hutool.core.date.DatePattern;
+import cn.hutool.core.lang.TypeReference;
+import cn.hutool.json.JSON;
+import cn.hutool.json.JSONConfig;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import lombok.experimental.UtilityClass;
+
+/**
+ * json工具类, 基于hutool的进行封装, 对java8的时间格式进行转换
+ * @author xxm
+ * @since 2024/6/28
+ */
+@UtilityClass
+public class JsonUtil {
+ private final JSONConfig JSON_CONFIG = JSONConfig.create()
+ .setDateFormat(DatePattern.NORM_DATETIME_PATTERN);
+
+ /**
+ * 转换为实体
+ */
+ public T toBean(String json, Class clazz) {
+ JSONObject jsonObject = new JSONObject(json, JSON_CONFIG);
+ return JSONUtil.toBean(jsonObject, clazz);
+ }
+
+ /**
+ * 转换为实体
+ */
+ public T toBean(String json, TypeReference reference) {
+ JSON parse = JSONUtil.parse(json, JSON_CONFIG);
+ return parse.toBean(reference);
+ }
+
+ /**
+ * 序列化为字符串
+ */
+ public String toJsonStr(Object object) {
+ JSONObject jsonObject = new JSONObject(object, JSON_CONFIG);
+ return JSONUtil.toJsonStr(jsonObject);
+ }
+
+ /**
+ * JSON字符串转JSONObject对象
+ */
+ public JSONObject parseObj(String jsonStr) {
+ return JSONUtil.parseObj(jsonStr, JSON_CONFIG);
+ }
+}
diff --git a/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/util/PaySignUtil.java b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/util/PaySignUtil.java
new file mode 100644
index 000000000..1805e5732
--- /dev/null
+++ b/daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/util/PaySignUtil.java
@@ -0,0 +1,244 @@
+package cn.daxpay.single.sdk.util;
+
+import cn.hutool.core.date.DatePattern;
+import cn.hutool.core.date.LocalDateTimeUtil;
+import cn.hutool.core.util.ClassUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.crypto.SmUtil;
+import cn.hutool.crypto.digest.HmacAlgorithm;
+import lombok.SneakyThrows;
+import lombok.experimental.UtilityClass;
+
+import java.lang.reflect.Field;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 如果需要进行签名,
+ * 1. 参数名ASCII码从小到大排序(字典序)
+ * 2. 如果参数的值为空不参与签名
+ * 3. 参数名不区分大小写
+ * 4. 嵌套对象转换成先转换成MAP再序列化为字符串
+ * 5. 支持两层嵌套, 更多层级嵌套未测试, 可能会导致不可预知的问题
+ */
+@UtilityClass
+public class PaySignUtil {
+
+ private final String FIELD_SIGN = "sign";
+
+
+ /**
+ * 将参数转换为map对象. 使用ChatGPT生成
+ * 1. 参数名ASCII码从小到大排序(字典序)
+ * 2. 如果参数的值为空不参与签名;
+ * 3. 参数名不区分大小写;
+ */
+ public Map toMap(Object object) {
+ Map map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+ toMap(object, map);
+ return map;
+ }
+
+ /**
+ * 将参数转换为map对象. 使用ChatGPT生成, 仅局限于对支付相关参数和返回值进行签名
+ */
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ @SneakyThrows
+ private void toMap(Object object, Map map) {
+ Class> clazz = object.getClass();
+ while (clazz != null) {
+ Field[] fields = clazz.getDeclaredFields();
+ for (Field field : fields) {
+ field.setAccessible(true);
+ String fieldName = field.getName();
+ Object fieldValue = field.get(object);
+ if (fieldValue != null) {
+ // 基础类型及包装类 和 字符串类型
+ if (ClassUtil.isBasicType(field.getType())|| field.getType().equals(String.class)) {
+ String fieldValueString = String.valueOf(fieldValue);
+ map.put(fieldName, fieldValueString);
+
+ }
+ // java8时间类型 转为 yyyy-MM-dd HH:mm:ss 格式
+ else if (field.getType().equals(LocalDateTime.class)) {
+ LocalDateTime localDateTime = (LocalDateTime) fieldValue;
+ String datetime = LocalDateTimeUtil.format(localDateTime, DatePattern.NORM_DATETIME_PATTERN);
+ map.put(fieldName, datetime);
+ }
+ // map类型
+ else if (Map.class.isAssignableFrom(field.getType())) {
+ Map m = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+ m.putAll((Map) fieldValue);
+ map.put(fieldName, JsonUtil.toJsonStr(m));
+ }
+ // BigDecimal类型
+ else if (field.getType().equals(BigDecimal.class)) {
+ BigDecimal bigDecimal = (BigDecimal) fieldValue;
+ String decimalString = bigDecimal.toString();
+ map.put(fieldName, decimalString);
+ }
+ // 集合类型
+ else if (Collection.class.isAssignableFrom(field.getType())) {
+ Collection> collection = (Collection>) fieldValue;
+ if (!collection.isEmpty()) {
+ List