From 986c3031f457aad9bc3e56f950ae666f026d30fa Mon Sep 17 00:00:00 2001 From: DaxPay Date: Sat, 12 Oct 2024 15:39:16 +0800 Subject: [PATCH] =?UTF-8?q?feat=20=E6=97=A5=E5=BF=97=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _doc/Task.md | 4 +- .../cache/configuration/BootxRedisCache.java | 2 +- .../configuration/BootxRedisCacheManager.java | 2 +- .../bootx-platform-common/common-log/pom.xml | 26 ++ ...AutoConfigurationLogAutoConfiguration.java | 17 + .../handler/LogTraceHeaderHolderFilter.java | 44 +++ ...ot.autoconfigure.AutoConfiguration.imports | 1 + bootx-platform/bootx-platform-common/pom.xml | 1 + bootx-platform/bootx-platform-service/pom.xml | 7 + .../baseapi/controller/BaseController.java | 5 +- .../iam/auth/login/PasswordLoginHandler.java | 2 +- .../starter/auth/util/SecurityUtil.java | 2 +- .../delay/annotation/DelayJobProcessor.java | 2 +- .../file/service/FileUploadService.java | 3 +- daxpay-single-sdk/pom.xml | 191 ++++++++++- .../sdk/code/AllocReceiverTypeEnum.java | 40 +++ .../sdk/code/AllocRelationTypeEnum.java | 28 ++ .../daxpay/single/sdk/code/ChannelEnum.java | 30 ++ .../single/sdk/code/DaxPayErrorCode.java | 77 +++++ .../single/sdk/code/PayAllocStatusEnum.java | 20 ++ .../daxpay/single/sdk/code/PayMethodEnum.java | 38 +++ .../single/sdk/code/PayRefundStatusEnum.java | 34 ++ .../daxpay/single/sdk/code/PayStatusEnum.java | 41 +++ .../single/sdk/code/PaySyncStatusEnum.java | 44 +++ .../single/sdk/code/RefundStatusEnum.java | 40 +++ .../single/sdk/code/RefundSyncStatusEnum.java | 23 ++ .../daxpay/single/sdk/code/SignTypeEnum.java | 37 +++ .../sdk/code/TransferPayeeTypeEnum.java | 38 +++ .../single/sdk/code/TransferStatusEnum.java | 23 ++ .../allocation/AllocReceiverAddModel.java | 12 + .../model/allocation/AllocReceiverModel.java | 46 +++ .../allocation/AllocReceiverRemoveModel.java | 12 + .../model/allocation/AllocReceiversModel.java | 18 ++ .../sdk/model/assist/WxAccessTokenModel.java | 18 ++ .../sdk/model/assist/WxAuthUrlModel.java | 15 + .../sdk/model/notice/PayNoticeModel.java | 91 ++++++ .../sdk/model/notice/RefundNoticeModel.java | 72 +++++ .../model/reconcile/ReconcileDownModel.java | 16 + .../sdk/model/trade/pay/PayOrderModel.java | 111 +++++++ .../sdk/model/trade/pay/PayResultModel.java | 24 ++ .../sdk/model/trade/pay/PaySyncModel.java | 20 ++ .../sdk/model/trade/refund/RefundModel.java | 21 ++ .../model/trade/refund/RefundOrderModel.java | 84 +++++ .../model/trade/refund/RefundSyncModel.java | 20 ++ .../model/trade/transfer/TransferModel.java | 31 ++ .../trade/transfer/TransferOrderModel.java | 86 +++++ .../daxpay/single/sdk/net/DaxPayConfig.java | 38 +++ .../cn/daxpay/single/sdk/net/DaxPayKit.java | 81 +++++ .../daxpay/single/sdk/net/DaxPayRequest.java | 46 +++ .../daxpay/single/sdk/param/ChannelParam.java | 19 ++ .../daxpay/single/sdk/param/SortMapParam.java | 9 + .../allocation/AllocReceiverAddParam.java | 70 +++++ .../param/allocation/AllocReceiverParam.java | 22 ++ .../allocation/AllocReceiverRemoveParam.java | 40 +++ .../single/sdk/param/channel/AlipayParam.java | 39 +++ .../sdk/param/channel/UnionPayParam.java | 19 ++ .../sdk/param/channel/WechatPayParam.java | 22 ++ .../reconcile/ChannelReconcileDownParam.java | 49 +++ .../reconcile/PlatformReconcileDownParam.java | 44 +++ .../sdk/param/trade/pay/PayCloseParam.java | 55 ++++ .../single/sdk/param/trade/pay/PayParam.java | 94 ++++++ .../sdk/param/trade/pay/PaySyncParam.java | 41 +++ .../sdk/param/trade/pay/QueryPayParam.java | 41 +++ .../param/trade/refund/QueryRefundParam.java | 42 +++ .../sdk/param/trade/refund/RefundParam.java | 80 +++++ .../param/trade/refund/RefundSyncParam.java | 41 +++ .../trade/transfer/QueryTransferParam.java | 43 +++ .../param/trade/transfer/TransferParam.java | 77 +++++ .../single/sdk/response/DaxPayResult.java | 44 +++ .../cn/daxpay/single/sdk/util/JsonUtil.java | 51 +++ .../daxpay/single/sdk/util/PaySignUtil.java | 244 ++++++++++++++ .../test/allocation/AllocReceiverTest.java | 64 ++++ .../sdk/test/query/QueryPayOrderTest.java | 42 +++ .../sdk/test/query/QueryRefundOrderTest.java | 42 +++ .../single/sdk/test/trade/CloseOrderTest.java | 55 ++++ .../sdk/test/trade/PayOrderSyncTest.java | 45 +++ .../single/sdk/test/trade/PayOrderTest.java | 297 ++++++++++++++++++ .../sdk/test/trade/RefundOrderSyncTest.java | 41 +++ .../sdk/test/trade/RefundOrderTest.java | 54 ++++ .../sdk/test/trade/TransferOrderTest.java | 78 +++++ .../sdk/test/util/PayParamSignTest.java | 71 +++++ .../single/sdk/test/util/SmSignTest.java | 18 ++ 82 files changed, 3667 insertions(+), 10 deletions(-) create mode 100644 bootx-platform/bootx-platform-common/common-log/pom.xml create mode 100644 bootx-platform/bootx-platform-common/common-log/src/main/java/cn/bootx/platform/common/log/LogAutoConfigurationLogAutoConfiguration.java create mode 100644 bootx-platform/bootx-platform-common/common-log/src/main/java/cn/bootx/platform/common/log/handler/LogTraceHeaderHolderFilter.java create mode 100644 bootx-platform/bootx-platform-common/common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/AllocReceiverTypeEnum.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/AllocRelationTypeEnum.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/ChannelEnum.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/DaxPayErrorCode.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/PayAllocStatusEnum.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/PayMethodEnum.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/PayRefundStatusEnum.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/PayStatusEnum.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/PaySyncStatusEnum.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/RefundStatusEnum.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/RefundSyncStatusEnum.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/SignTypeEnum.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/TransferPayeeTypeEnum.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/code/TransferStatusEnum.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/allocation/AllocReceiverAddModel.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/allocation/AllocReceiverModel.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/allocation/AllocReceiverRemoveModel.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/allocation/AllocReceiversModel.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/assist/WxAccessTokenModel.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/assist/WxAuthUrlModel.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/notice/PayNoticeModel.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/notice/RefundNoticeModel.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/reconcile/ReconcileDownModel.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/pay/PayOrderModel.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/pay/PayResultModel.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/pay/PaySyncModel.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/refund/RefundModel.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/refund/RefundOrderModel.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/refund/RefundSyncModel.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/transfer/TransferModel.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/model/trade/transfer/TransferOrderModel.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/net/DaxPayConfig.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/net/DaxPayKit.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/net/DaxPayRequest.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/ChannelParam.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/SortMapParam.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/allocation/AllocReceiverAddParam.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/allocation/AllocReceiverParam.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/allocation/AllocReceiverRemoveParam.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/channel/AlipayParam.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/channel/UnionPayParam.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/channel/WechatPayParam.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/reconcile/ChannelReconcileDownParam.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/reconcile/PlatformReconcileDownParam.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/pay/PayCloseParam.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/pay/PayParam.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/pay/PaySyncParam.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/pay/QueryPayParam.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/refund/QueryRefundParam.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/refund/RefundParam.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/refund/RefundSyncParam.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/transfer/QueryTransferParam.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/param/trade/transfer/TransferParam.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/response/DaxPayResult.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/util/JsonUtil.java create mode 100644 daxpay-single-sdk/src/main/java/cn/daxpay/single/sdk/util/PaySignUtil.java create mode 100644 daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/allocation/AllocReceiverTest.java create mode 100644 daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/query/QueryPayOrderTest.java create mode 100644 daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/query/QueryRefundOrderTest.java create mode 100644 daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/CloseOrderTest.java create mode 100644 daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/PayOrderSyncTest.java create mode 100644 daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/PayOrderTest.java create mode 100644 daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/RefundOrderSyncTest.java create mode 100644 daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/RefundOrderTest.java create mode 100644 daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/TransferOrderTest.java create mode 100644 daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/util/PayParamSignTest.java create mode 100644 daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/util/SmSignTest.java 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> maps = collection.stream() + .filter(Objects::nonNull) + .map(item -> { + Map nestedMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + toMap(item, nestedMap); + return nestedMap; + }) + .collect(Collectors.toList()); + map.put(fieldName, JsonUtil.toJsonStr(maps)); + } + // 其他类型直接转换为json + } else { + Map nestedMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + toMap(fieldValue, nestedMap); + String nestedJson = JsonUtil.toJsonStr(fieldValue); + map.put(fieldName, nestedJson); + } + } + } + clazz = clazz.getSuperclass(); + } + } + + + /** + * 把所有元素排序, 并拼接成字符, 用于签名, 同时会过滤掉 " 和 \ 字符 + */ + public static String createLinkString(Map params) { + String connStr = "&"; + List keys = new ArrayList<>(params.keySet()); + Collections.sort(keys); + StringBuilder content = new StringBuilder(); + for (int i = 0; i < keys.size(); i++) { + String key = keys.get(i); + String value = params.get(key); + // 拼接时,不包括最后一个&字符 + if (i == keys.size() - 1) { + content.append(key) + .append("=") + .append(value); + } else { + content.append(key) + .append("=") + .append(value) + .append(connStr); + } + } + String s = content.toString(); + s = StrUtil.replace(s,"\\",""); + s = StrUtil.replace(s,"\"",""); + return s; + } + + + /** + * 生成16进制 MD5 字符串 + * + * @param data 数据 + * @return MD5 字符串 + */ + public String md5(String data) { + return SecureUtil.md5(data); + } + + /** + * 生成16进制的 sha256 字符串 + * + * @param data 数据 + * @param signKey 密钥 + * @return sha256 字符串 + */ + public String hmacSha256(String data, String signKey) { + return SecureUtil.hmac(HmacAlgorithm.HmacSHA256, signKey).digestHex(data); + } + + + /** + * 生成16进制 sm3 字符串 + * + * @param data 数据 + * @return SM3方式进行签名 字符串 + */ + public String sm3(String data) { + return SmUtil.sm3(data); + } + + /** + * 生成待签名字符串 + * @param object 待签名对象 + * @param signKey 签名Key + * @return 待签名字符串 + */ + public String signString(Object object, String signKey){ + // 签名 + Map map = toMap(object); + // 生成签名前先去除sign参数 + map.remove(FIELD_SIGN); + // 创建待签名字符串 + String data = createLinkString(map); + // 将签名key追加到字符串最后 + return data + "&key=" + signKey; + } + + /** + * md5方式进行签名 + * + * @return 签名值 + */ + public String md5Sign(Object object, String signKey){ + String data = signString(object, signKey); + return md5(data); + } + + /** + * hmacSha256方式进行签名 + * + * @return 签名值 + */ + public String hmacSha256Sign(Object object, String signKey){ + String data = signString(object, signKey); + return hmacSha256(data, signKey); + } + + /** + * sm3方式进行签名 + * + * @return 签名值 + */ + public String sm3Sign(Object object, String signKey){ + String data = signString(object, signKey); + return sm3(data); + } + + /** + * MD5签名验证 + */ + public boolean verifyMd5Sign(Object object, String signKey, String sign){ + String md5Sign = md5Sign(object, signKey); + return md5Sign.equals(sign); + } + + /** + * hmacSha256签名验证 + */ + public boolean verifyHmacSha256Sign(Object object, String signKey, String sign){ + String hmacSha256Sign = hmacSha256Sign(object, signKey); + return hmacSha256Sign.equals(sign); + } + + + /** + * SM3签名验证 + */ + public boolean verifySm3Sign(Object object, String signKey, String sign){ + String sm3Sign = sm3Sign(object, signKey); + return sm3Sign.equals(sign); + } +} diff --git a/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/allocation/AllocReceiverTest.java b/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/allocation/AllocReceiverTest.java new file mode 100644 index 000000000..0569adbe7 --- /dev/null +++ b/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/allocation/AllocReceiverTest.java @@ -0,0 +1,64 @@ +package cn.daxpay.single.sdk.test.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.code.SignTypeEnum; +import cn.daxpay.single.sdk.model.allocation.AllocReceiverAddModel; +import cn.daxpay.single.sdk.model.allocation.AllocReceiverRemoveModel; +import cn.daxpay.single.sdk.net.DaxPayConfig; +import cn.daxpay.single.sdk.net.DaxPayKit; +import cn.daxpay.single.sdk.param.allocation.AllocReceiverAddParam; +import cn.daxpay.single.sdk.param.allocation.AllocReceiverRemoveParam; +import cn.daxpay.single.sdk.response.DaxPayResult; +import cn.daxpay.single.sdk.util.JsonUtil; +import org.junit.Before; +import org.junit.Test; + +/** + * 分账接收者测试类 + * @author xxm + * @since 2024/5/27 + */ +public class AllocReceiverTest { + + @Before + public void init() { + // 初始化支付配置 + DaxPayConfig config = DaxPayConfig.builder() + .serviceUrl("http://127.0.0.1:10880") + .signSecret("123456") + .signType(SignTypeEnum.HMAC_SHA256) + .build(); + DaxPayKit.initConfig(config); + } + + /** + * 添加 + */ + @Test + public void add() { + AllocReceiverAddParam param = new AllocReceiverAddParam(); + param.setChannel(ChannelEnum.ALI.getCode()); + param.setClientIp("127.0.0.1"); + param.setRelationType(AllocRelationTypeEnum.HEADQUARTER.getCode()); + param.setReceiverNo("123456"); + param.setReceiverType(AllocReceiverTypeEnum.USER_ID.getCode()); + param.setReceiverAccount("20881233343"); + DaxPayResult execute = DaxPayKit.execute(param); + System.out.println(JsonUtil.toJsonStr(execute)); + } + + /** + * 删除 + */ + @Test + public void remove() { + AllocReceiverRemoveParam param = new AllocReceiverRemoveParam(); + param.setClientIp("127.0.0.1"); + param.setReceiverNo("123456"); + DaxPayResult execute = DaxPayKit.execute(param); + System.out.println(JsonUtil.toJsonStr(execute)); + } + +} diff --git a/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/query/QueryPayOrderTest.java b/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/query/QueryPayOrderTest.java new file mode 100644 index 000000000..487692173 --- /dev/null +++ b/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/query/QueryPayOrderTest.java @@ -0,0 +1,42 @@ +package cn.daxpay.single.sdk.test.query; + +import cn.daxpay.single.sdk.code.SignTypeEnum; +import cn.daxpay.single.sdk.model.trade.pay.PayOrderModel; +import cn.daxpay.single.sdk.net.DaxPayConfig; +import cn.daxpay.single.sdk.net.DaxPayKit; +import cn.daxpay.single.sdk.param.trade.pay.QueryPayParam; +import cn.daxpay.single.sdk.response.DaxPayResult; +import cn.daxpay.single.sdk.util.JsonUtil; +import org.junit.Before; +import org.junit.Test; + +/** + * 查询支付订单测试类 + * @author xxm + * @since 2024/2/7 + */ +public class QueryPayOrderTest { + + @Before + public void init() { + // 初始化支付配置 + DaxPayConfig config = DaxPayConfig.builder() + .serviceUrl("http://127.0.0.1:10880") + .signSecret("123456") + .signType(SignTypeEnum.HMAC_SHA256) + .build(); + DaxPayKit.initConfig(config); + } + + @Test + public void testPay() { + QueryPayParam param = new QueryPayParam(); + + param.setBizOrderNoeNo("P17141882417921"); + param.setClientIp("127.0.0.1"); + + DaxPayResult execute = DaxPayKit.execute(param); + System.out.println(JsonUtil.toJsonStr(execute)); + + } +} diff --git a/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/query/QueryRefundOrderTest.java b/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/query/QueryRefundOrderTest.java new file mode 100644 index 000000000..a94a13cb1 --- /dev/null +++ b/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/query/QueryRefundOrderTest.java @@ -0,0 +1,42 @@ +package cn.daxpay.single.sdk.test.query; + +import cn.daxpay.single.sdk.code.SignTypeEnum; +import cn.daxpay.single.sdk.model.trade.refund.RefundOrderModel; +import cn.daxpay.single.sdk.net.DaxPayConfig; +import cn.daxpay.single.sdk.net.DaxPayKit; +import cn.daxpay.single.sdk.param.trade.refund.QueryRefundParam; +import cn.daxpay.single.sdk.response.DaxPayResult; +import cn.daxpay.single.sdk.util.JsonUtil; +import org.junit.Before; +import org.junit.Test; + +/** + * 退款订单查询接口 + * @author xxm + * @since 2024/2/7 + */ +public class QueryRefundOrderTest { + + @Before + public void init() { + // 初始化支付配置 + DaxPayConfig config = DaxPayConfig.builder() + .serviceUrl("http://127.0.0.1:10880") + .signSecret("123456") + .signType(SignTypeEnum.HMAC_SHA256) + .build(); + DaxPayKit.initConfig(config); + } + + @Test + public void testRefund() { + QueryRefundParam param = new QueryRefundParam(); + + param.setRefundNo("DEVR24051020531763000014"); + param.setClientIp("127.0.0.1"); + + DaxPayResult execute = DaxPayKit.execute(param); + System.out.println(JsonUtil.toJsonStr(execute)); + + } +} diff --git a/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/CloseOrderTest.java b/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/CloseOrderTest.java new file mode 100644 index 000000000..be5889672 --- /dev/null +++ b/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/CloseOrderTest.java @@ -0,0 +1,55 @@ +package cn.daxpay.single.sdk.test.trade; + +import cn.daxpay.single.sdk.code.SignTypeEnum; +import cn.daxpay.single.sdk.net.DaxPayConfig; +import cn.daxpay.single.sdk.net.DaxPayKit; +import cn.daxpay.single.sdk.param.trade.pay.PayCloseParam; +import cn.daxpay.single.sdk.response.DaxPayResult; +import cn.daxpay.single.sdk.util.JsonUtil; +import org.junit.Before; +import org.junit.Test; + +/** + * 支付关闭接口测试类 + * @author xxm + * @since 2024/2/5 + */ +public class CloseOrderTest { + + @Before + public void init() { + // 初始化支付配置 + DaxPayConfig config = DaxPayConfig.builder() + .serviceUrl("http://127.0.0.1:10880") + .signSecret("123456") + .signType(SignTypeEnum.HMAC_SHA256) + .appId("M8088873888246277") + .build(); + DaxPayKit.initConfig(config); + } + + /** + * 关闭 + */ + @Test + public void close(){ + PayCloseParam param = new PayCloseParam(); + param.setOrderNo("DEVP24051019404463000001"); + param.setClientIp("127.0.0.1"); + DaxPayResult execute = DaxPayKit.execute(param); + System.out.println(JsonUtil.toJsonStr(execute)); + } + + /** + * 撤销 + */ + @Test + public void cancel(){ + PayCloseParam param = new PayCloseParam(); + param.setBizOrderNo("SDK_1721807811589"); + param.setClientIp("127.0.0.1"); + param.setUseCancel(true); + DaxPayResult execute = DaxPayKit.execute(param); + System.out.println(JsonUtil.toJsonStr(execute)); + } +} diff --git a/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/PayOrderSyncTest.java b/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/PayOrderSyncTest.java new file mode 100644 index 000000000..766b13295 --- /dev/null +++ b/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/PayOrderSyncTest.java @@ -0,0 +1,45 @@ +package cn.daxpay.single.sdk.test.trade; + +import cn.daxpay.single.sdk.code.SignTypeEnum; +import cn.daxpay.single.sdk.net.DaxPayConfig; +import cn.daxpay.single.sdk.net.DaxPayKit; +import cn.daxpay.single.sdk.param.trade.pay.PaySyncParam; +import cn.daxpay.single.sdk.response.DaxPayResult; +import cn.daxpay.single.sdk.model.trade.pay.PaySyncModel; +import cn.daxpay.single.sdk.util.JsonUtil; +import org.junit.Before; +import org.junit.Test; + +/** + * 支付同步接口 + * @author xxm + * @since 2024/2/5 + */ +public class PayOrderSyncTest { + + @Before + public void init() { + // 初始化支付配置 + DaxPayConfig config = DaxPayConfig.builder() + .serviceUrl("http://127.0.0.1:10880") + .signSecret("123456") + .signType(SignTypeEnum.HMAC_SHA256) + .build(); + DaxPayKit.initConfig(config); + } + + /** + * 支付订单同步 + * 1. 微信 + * 2. 支付宝 + */ + @Test + public void testPay() { + PaySyncParam param = new PaySyncParam(); + param.setBizOrderNo("SDK_1715341621498"); + DaxPayResult execute = DaxPayKit.execute(param); + System.out.println(JsonUtil.toJsonStr(execute)); + + } + +} diff --git a/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/PayOrderTest.java b/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/PayOrderTest.java new file mode 100644 index 000000000..41992eb85 --- /dev/null +++ b/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/PayOrderTest.java @@ -0,0 +1,297 @@ +package cn.daxpay.single.sdk.test.trade; + +import cn.daxpay.single.sdk.code.ChannelEnum; +import cn.daxpay.single.sdk.code.PayMethodEnum; +import cn.daxpay.single.sdk.code.SignTypeEnum; +import cn.daxpay.single.sdk.model.trade.pay.PayResultModel; +import cn.daxpay.single.sdk.net.DaxPayConfig; +import cn.daxpay.single.sdk.net.DaxPayKit; +import cn.daxpay.single.sdk.param.channel.AlipayParam; +import cn.daxpay.single.sdk.param.channel.WechatPayParam; +import cn.daxpay.single.sdk.param.trade.pay.PayParam; +import cn.daxpay.single.sdk.response.DaxPayResult; +import cn.daxpay.single.sdk.util.JsonUtil; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigDecimal; + +/** + * 统一支付接口 + * @author xxm + * @since 2024/2/5 + */ +public class PayOrderTest { + + @Before + public void init() { + // 初始化支付配置 + DaxPayConfig config = DaxPayConfig.builder() + .serviceUrl("http://127.0.0.1:10880") + .signSecret("123456") + .signType(SignTypeEnum.HMAC_SHA256) + .appId("M8088873888246277") + .build(); + DaxPayKit.initConfig(config); + } + + /** + * 微信支付(二维码扫码) + */ + @Test + public void wxQrPay() { + PayParam param = new PayParam(); + param.setClientIp("127.0.0.1"); + param.setBizOrderNo("SDK_"+ System.currentTimeMillis()); + param.setTitle("测试微信扫码支付"); + param.setDescription("这是支付备注"); + param.setAmount(BigDecimal.valueOf(0.01)); + param.setChannel(ChannelEnum.WECHAT.getCode()); + param.setMethod(PayMethodEnum.QRCODE.getCode()); + param.setAttach("{回调参数}"); + param.setAllocation(false); + param.setReturnUrl("https://abc.com/returnurl"); + param.setNotifyUrl("http://127.0.0.1:10880/test/callback/notify"); + + DaxPayResult execute = DaxPayKit.execute(param); + System.out.println(JsonUtil.toJsonStr(execute)); + } + + /** + * 微信付款码 + */ + @Test + public void wxBarCode(){ + PayParam param = new PayParam(); + param.setClientIp("127.0.0.1"); + param.setBizOrderNo("SDK_"+ System.currentTimeMillis()); + param.setTitle("测试微信条码支付"); + param.setAmount(BigDecimal.valueOf(0.01)); + param.setChannel(ChannelEnum.WECHAT.getCode()); + param.setMethod(PayMethodEnum.BARCODE.getCode()); + + WechatPayParam wechatPayParam = new WechatPayParam(); + wechatPayParam.setAuthCode("131513396074955617"); + param.setExtraParam(JsonUtil.toJsonStr(wechatPayParam)); + param.setAttach("{回调参数}"); + param.setAllocation(false); + param.setReturnUrl("https://abc.com/returnurl"); + param.setNotifyUrl("http://127.0.0.1:10880/test/callback/notify"); + + DaxPayResult execute = DaxPayKit.execute(param); + System.out.println(JsonUtil.toJsonStr(execute)); + } + + /** + * 微信jsapi + */ + @Test + public void wxPayJsApi() { + PayParam param = new PayParam(); + param.setClientIp("127.0.0.1"); + param.setBizOrderNo("SDK_"+ System.currentTimeMillis()); + param.setTitle("测试微信公众号预支付"); + param.setAmount(BigDecimal.valueOf(0.01)); + param.setChannel(ChannelEnum.WECHAT.getCode()); + param.setMethod(PayMethodEnum.JSAPI.getCode()); + + WechatPayParam wechatPayParam = new WechatPayParam(); + wechatPayParam.setOpenId(""); + param.setExtraParam(JsonUtil.toJsonStr(wechatPayParam)); + + param.setAttach("{回调参数}"); + param.setAllocation(false); + param.setReturnUrl("https://abc.com/returnurl"); + param.setNotifyUrl("http://127.0.0.1:10880/test/callback/notify"); + + DaxPayResult execute = DaxPayKit.execute(param); + System.out.println(JsonUtil.toJsonStr(execute)); + } + + /** + * 微信h5支付 + */ + @Test + public void wxPayH5Pay() { + PayParam param = new PayParam(); + param.setClientIp("127.0.0.1"); + param.setBizOrderNo("SDK_"+ System.currentTimeMillis()); + param.setTitle("测试微信h5支付"); + param.setAmount(BigDecimal.valueOf(0.01)); + param.setChannel(ChannelEnum.WECHAT.getCode()); + param.setMethod(PayMethodEnum.WAP.getCode()); + + param.setAttach("{回调参数}"); + param.setAllocation(false); + param.setReturnUrl("https://abc.com/returnurl"); + param.setNotifyUrl("http://127.0.0.1:10880/test/callback/notify"); + + DaxPayResult execute = DaxPayKit.execute(param); + System.out.println(JsonUtil.toJsonStr(execute)); + } + + /** + * 微信APP支付 + */ + @Test + public void wxPayAppPay() { + PayParam param = new PayParam(); + param.setClientIp("127.0.0.1"); + param.setBizOrderNo("SDK_"+ System.currentTimeMillis()); + param.setTitle("测试微信应用支付"); + param.setDescription("这是备注"); + param.setAmount(BigDecimal.valueOf(10)); + param.setChannel(ChannelEnum.WECHAT.getCode()); + param.setMethod(PayMethodEnum.APP.getCode()); + param.setAttach("{回调参数}"); + param.setAllocation(false); + param.setReturnUrl("https://abc.com/returnurl"); + param.setNotifyUrl("http://127.0.0.1:10880/test/callback/notify"); + + DaxPayResult execute = DaxPayKit.execute(param); + System.out.println(JsonUtil.toJsonStr(execute)); + } + + /** + * 支付宝支付(二维码扫码) + */ + @Test + public void aliPayQrPay() { + PayParam param = new PayParam(); + param.setClientIp("127.0.0.1"); + param.setBizOrderNo("SDK_"+ System.currentTimeMillis()); + param.setTitle("测试支付宝扫码支付"); + param.setDescription("这是支付宝扫码支付"); + param.setAmount(BigDecimal.valueOf(10)); + param.setChannel(ChannelEnum.ALI.getCode()); + param.setMethod(PayMethodEnum.QRCODE.getCode()); + param.setAttach("{回调参数}"); + param.setAllocation(false); + param.setReturnUrl("https://abc.com/returnurl"); + param.setNotifyUrl("http://127.0.0.1:10880/test/callback/notify"); + + DaxPayResult execute = DaxPayKit.execute(param); + System.out.println(JsonUtil.toJsonStr(execute)); + } + + + /** + * 支付宝付款码 + */ + @Test + public void aliPayBarCode(){ + PayParam param = new PayParam(); + param.setClientIp("127.0.0.1"); + param.setBizOrderNo("SDK_"+ System.currentTimeMillis()); + param.setTitle("测试支付宝付款码支付"); + param.setDescription("这是支付宝付款码支付"); + param.setAmount(BigDecimal.valueOf(1)); + param.setChannel(ChannelEnum.ALI.getCode()); + param.setMethod(PayMethodEnum.BARCODE.getCode()); + + AlipayParam alipayParam = new AlipayParam(); + alipayParam.setAuthCode("287109871028487115"); + param.setExtraParam(JsonUtil.toJsonStr(alipayParam)); + + param.setAttach("{回调参数}"); + param.setAllocation(false); + param.setReturnUrl("https://abc.com/returnurl"); + param.setNotifyUrl("http://127.0.0.1:10880/test/callback/notify"); + + DaxPayResult execute = DaxPayKit.execute(param); + System.out.println(JsonUtil.toJsonStr(execute)); + } + + /** + * 支付宝h5支付 + */ + @Test + public void aliPayH5Pay() { + PayParam param = new PayParam(); + param.setClientIp("127.0.0.1"); + param.setBizOrderNo("SDK_"+ System.currentTimeMillis()); + param.setTitle("测试支付宝H5支付"); + param.setDescription("这是支付宝H5支付"); + param.setAmount(BigDecimal.valueOf(1.53)); + param.setChannel(ChannelEnum.ALI.getCode()); + param.setMethod(PayMethodEnum.QRCODE.getCode()); + param.setAttach("{回调参数}"); + param.setAllocation(false); + param.setReturnUrl("https://abc.com/returnurl"); + param.setNotifyUrl("http://127.0.0.1:10880/test/callback/notify"); + + DaxPayResult execute = DaxPayKit.execute(param); + System.out.println(JsonUtil.toJsonStr(execute)); + } + + /** + * 支付宝web支付 + */ + @Test + public void aliPayWebPay() { + PayParam param = new PayParam(); + param.setClientIp("127.0.0.1"); + param.setBizOrderNo("SDK_"+ System.currentTimeMillis()); + param.setTitle("测试支付宝WEB支付"); + param.setDescription("这是支付宝WEB支付"); + param.setAmount(BigDecimal.valueOf(1.52)); + param.setChannel(ChannelEnum.ALI.getCode()); + param.setMethod(PayMethodEnum.WEB.getCode()); + param.setAttach("{回调参数}"); + param.setAllocation(false); + param.setReturnUrl("https://abc.com/returnurl"); + param.setNotifyUrl("http://127.0.0.1:10880/test/callback/notify"); + + DaxPayResult execute = DaxPayKit.execute(param); + System.out.println(JsonUtil.toJsonStr(execute)); + } + + /** + * 支付宝jsapi支付 + */ + @Test + public void aliPayJsApiPay() { + PayParam param = new PayParam(); + param.setClientIp("127.0.0.1"); + param.setBizOrderNo("SDK_"+ System.currentTimeMillis()); + param.setTitle("测试支付宝JsApi支付"); + param.setDescription("这是支付宝WEB支付"); + param.setAmount(BigDecimal.valueOf(1.52)); + param.setChannel(ChannelEnum.ALI.getCode()); + param.setMethod(PayMethodEnum.JSAPI.getCode()); + + AlipayParam alipayParam = new AlipayParam(); + alipayParam.setOpAppId("9021000135649359"); + alipayParam.setOpenId("06599D4kvsqTsdNkN1xG05ZACe29h4bm2hi78vsAEVnGCI2"); + param.setExtraParam(JsonUtil.toJsonStr(alipayParam)); + + param.setAttach("{回调参数}"); + param.setAllocation(false); + param.setReturnUrl("https://abc.com/returnurl"); + param.setNotifyUrl("http://127.0.0.1:10880/test/callback/notify"); + + DaxPayResult execute = DaxPayKit.execute(param); + System.out.println(JsonUtil.toJsonStr(execute)); + } + + /** + * 支付宝应用支付 + */ + @Test + public void aliPayAppPay() { + PayParam param = new PayParam(); + param.setClientIp("127.0.0.1"); + param.setBizOrderNo("SDK_"+ System.currentTimeMillis()); + param.setTitle("测试支付宝APP支付"); + param.setAmount(BigDecimal.valueOf(1.52)); + param.setChannel(ChannelEnum.ALI.getCode()); + param.setMethod(PayMethodEnum.APP.getCode()); + param.setAttach("{回调参数}"); + param.setAllocation(false); + param.setReturnUrl("https://abc.com/returnurl"); + param.setNotifyUrl("http://127.0.0.1:10880/test/callback/notify"); + + DaxPayResult execute = DaxPayKit.execute(param); + System.out.println(JsonUtil.toJsonStr(execute)); + } +} diff --git a/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/RefundOrderSyncTest.java b/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/RefundOrderSyncTest.java new file mode 100644 index 000000000..e58e6a717 --- /dev/null +++ b/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/RefundOrderSyncTest.java @@ -0,0 +1,41 @@ +package cn.daxpay.single.sdk.test.trade; + +import cn.daxpay.single.sdk.code.SignTypeEnum; +import cn.daxpay.single.sdk.net.DaxPayConfig; +import cn.daxpay.single.sdk.net.DaxPayKit; +import cn.daxpay.single.sdk.param.trade.refund.RefundSyncParam; +import cn.daxpay.single.sdk.response.DaxPayResult; +import cn.daxpay.single.sdk.model.trade.refund.RefundSyncModel; +import cn.daxpay.single.sdk.util.JsonUtil; +import org.junit.Before; +import org.junit.Test; + +/** + * 退款同步接口 + * @author xxm + * @since 2024/2/5 + */ +public class RefundOrderSyncTest { + + @Before + public void init() { + // 初始化支付配置 + DaxPayConfig config = DaxPayConfig.builder() + .serviceUrl("http://127.0.0.1:10880") + .signSecret("123456") + .signType(SignTypeEnum.HMAC_SHA256) + .build(); + DaxPayKit.initConfig(config); + } + + @Test + public void testPay() { + RefundSyncParam param = new RefundSyncParam(); + param.setRefundNo("DEVR24051020530263000002"); + param.setClientIp("127.0.0.1"); + DaxPayResult execute = DaxPayKit.execute(param); + System.out.println(JsonUtil.toJsonStr(execute)); + + } + +} diff --git a/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/RefundOrderTest.java b/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/RefundOrderTest.java new file mode 100644 index 000000000..913ece965 --- /dev/null +++ b/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/RefundOrderTest.java @@ -0,0 +1,54 @@ +package cn.daxpay.single.sdk.test.trade; + +import cn.daxpay.single.sdk.code.SignTypeEnum; +import cn.daxpay.single.sdk.net.DaxPayConfig; +import cn.daxpay.single.sdk.net.DaxPayKit; +import cn.daxpay.single.sdk.param.trade.refund.RefundParam; +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.daxpay.single.sdk.util.PaySignUtil; +import cn.hutool.core.util.RandomUtil; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigDecimal; + +/** + * 退款接口测试 + * 支持部分退款和全部退款, 部分退款的次数不要超过10次, 否则可能会出现不可知的错误 + * + * @author xxm + * @since 2024/2/5 + */ +public class RefundOrderTest { + + @Before + public void init() { + // 初始化支付配置 + DaxPayConfig config = DaxPayConfig.builder() + .serviceUrl("http://127.0.0.1:10880") + .signSecret("123456") + .signType(SignTypeEnum.HMAC_SHA256) + .appId("M8088873888246277") + .build(); + DaxPayKit.initConfig(config); + } + + /** + * 微信退款 + */ + @Test + public void refund(){ + RefundParam param = new RefundParam(); + param.setBizRefundNo("R" + RandomUtil.randomNumbers(5)); + param.setBizOrderNo("SDK_1721732511210"); + param.setAmount(BigDecimal.valueOf(0.01)); + param.setAttach("{回调参数}"); + param.setClientIp("127.0.0.1"); + + DaxPayResult execute = DaxPayKit.execute(param); + System.out.println(JsonUtil.toJsonStr(execute)); + System.out.println(PaySignUtil.verifyHmacSha256Sign(execute.getData(), "123456", execute.getSign())); + } +} diff --git a/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/TransferOrderTest.java b/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/TransferOrderTest.java new file mode 100644 index 000000000..450362711 --- /dev/null +++ b/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/trade/TransferOrderTest.java @@ -0,0 +1,78 @@ +package cn.daxpay.single.sdk.test.trade; + +import cn.daxpay.single.sdk.code.ChannelEnum; +import cn.daxpay.single.sdk.code.SignTypeEnum; +import cn.daxpay.single.sdk.code.TransferPayeeTypeEnum; +import cn.daxpay.single.sdk.net.DaxPayConfig; +import cn.daxpay.single.sdk.net.DaxPayKit; +import cn.daxpay.single.sdk.param.trade.transfer.TransferParam; +import cn.daxpay.single.sdk.response.DaxPayResult; +import cn.daxpay.single.sdk.model.trade.transfer.TransferModel; +import cn.daxpay.single.sdk.util.JsonUtil; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigDecimal; + +/** + * 转账测试 + * @author xxm + * @since 2024/6/20 + */ +public class TransferOrderTest { + + @Before + public void init() { + // 初始化支付配置 + DaxPayConfig config = DaxPayConfig.builder() + .serviceUrl("http://127.0.0.1:10880") + .signSecret("123456") + .signType(SignTypeEnum.HMAC_SHA256) + .appId("M8207639754663343") + .build(); + DaxPayKit.initConfig(config); + } + + + /** + * 发起转账操作(支付宝) + */ + @Test + public void aliTransfer() { + // 构建参数 + TransferParam param = new TransferParam(); + param.setBizTransferNo("T"+System.currentTimeMillis()); + param.setTitle("测试支付宝转账"); + param.setReason("我要转个账"); + param.setAmount(BigDecimal.valueOf(5)); + param.setChannel(ChannelEnum.ALI.getCode()); + param.setPayeeType(TransferPayeeTypeEnum.OPEN_ID.getCode()); + param.setClientIp("127.0.0.1"); + // 使用OpenId + param.setPayeeAccount("-G8AkkjjVhUl_VAf"); + // 发起请求 + DaxPayResult execute = DaxPayKit.execute(param); + System.out.println(JsonUtil.toJsonStr(execute)); + } + + /** + * 发起转账操作(微信) + */ + @Test + public void transfer() { + // 构建参数 + TransferParam param = new TransferParam(); + param.setBizTransferNo("T"+System.currentTimeMillis()); + param.setTitle("测试微信转账"); + param.setReason("我要转个账"); + param.setAmount(BigDecimal.valueOf(0.01)); + param.setChannel(ChannelEnum.WECHAT.getCode()); + param.setPayeeType(TransferPayeeTypeEnum.OPEN_ID.getCode()); + param.setClientIp("127.0.0.1"); + // 使用OpenId + param.setPayeeAccount(""); + // 发起请求 + DaxPayResult execute = DaxPayKit.execute(param); + System.out.println(JsonUtil.toJsonStr(execute)); + } +} diff --git a/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/util/PayParamSignTest.java b/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/util/PayParamSignTest.java new file mode 100644 index 000000000..54c46b5ee --- /dev/null +++ b/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/util/PayParamSignTest.java @@ -0,0 +1,71 @@ +package cn.daxpay.single.sdk.test.util; + +import cn.daxpay.single.sdk.param.channel.WechatPayParam; +import cn.daxpay.single.sdk.param.trade.pay.PayParam; +import cn.daxpay.single.sdk.util.PaySignUtil; +import lombok.extern.slf4j.Slf4j; +import org.junit.Test; + +import java.util.Map; + +/** + * 参数签名测试类 + * @author xxm + * @since 2024/2/7 + */ +@Slf4j +public class PayParamSignTest { + + /** + * 签名测试 + */ + @Test + public void sign(){ + + PayParam param = new PayParam(); + param.setClientIp("127.0.0.1"); + + param.setBizOrderNo("P0001"); + param.setTitle("测试接口支付"); + + Map map = PaySignUtil.toMap(param); + log.info("转换为有序MAP后的内容: {}",map); + String data = PaySignUtil.createLinkString(map); + log.info("将MAP拼接字符串, 并过滤掉特殊字符: {}",data); + String sign = "123456"; + data += "&sign="+sign; + data = data.toUpperCase(); + log.info("添加秘钥并转换为大写的字符串: {}",data); + log.info("MD5: {}",PaySignUtil.md5(data)); + log.info("HmacSHA256: {}",PaySignUtil.hmacSha256(data,sign)); + } + + /** + * 多层嵌套对象签名测试 + */ + @Test + public void sign2(){ + + PayParam param = new PayParam(); + param.setClientIp("127.0.0.1"); + + param.setBizOrderNo("P0002"); + param.setTitle("测试接口支付"); + WechatPayParam weChatPayParam = new WechatPayParam(); + weChatPayParam.setOpenId("6688812"); + weChatPayParam.setAuthCode("123456"); + param.setExtraParam(weChatPayParam.toJson()); + + Map map = PaySignUtil.toMap(param); + log.info("转换为有序MAP后的内容: {}",map); + String data = PaySignUtil.createLinkString(map).replaceAll("\\\"","").replaceAll("\"",""); + log.info("将MAP拼接字符串, 并过滤掉特殊字符: {}",data); + String sign = "123456"; + data += "&sign="+sign; + data = data.toUpperCase(); + log.info("添加秘钥并转换为大写的字符串: {}",data); + log.info("MD5: {}",PaySignUtil.md5(data)); + log.info("HmacSHA256: {}",PaySignUtil.hmacSha256(data,sign)); + } + +} diff --git a/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/util/SmSignTest.java b/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/util/SmSignTest.java new file mode 100644 index 000000000..f79f9acb3 --- /dev/null +++ b/daxpay-single-sdk/src/test/java/cn/daxpay/single/sdk/test/util/SmSignTest.java @@ -0,0 +1,18 @@ +package cn.daxpay.single.sdk.test.util; + +import cn.hutool.crypto.SmUtil; +import org.junit.Test; + +/** + * 国密签名测试 + * @author xxm + * @since 2024/6/29 + */ +public class SmSignTest { + + @Test + public void sign2(){ + String digestHex = SmUtil.sm3("aaaaa"); + System.out.println(digestHex); + } +}