diff --git a/daxpay-payment/daxpay-payment-common/pom.xml b/daxpay-payment/daxpay-payment-common/pom.xml
index b97e83d4f..19734dedd 100644
--- a/daxpay-payment/daxpay-payment-common/pom.xml
+++ b/daxpay-payment/daxpay-payment-common/pom.xml
@@ -110,6 +110,12 @@
capability-alipay
${project.version}
+
+
+ cn.daxpay.open
+ capability-douyin
+ ${project.version}
+
cn.daxpay.open
diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/core/assist/PlatformAuthService.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/core/assist/PlatformAuthService.java
index a628045c7..af1bad34d 100644
--- a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/core/assist/PlatformAuthService.java
+++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/core/assist/PlatformAuthService.java
@@ -6,6 +6,8 @@ import cn.daxpay.open.payment.unipay.result.assist.AuthUrlResult;
import cn.daxpay.open.platform.capability.alipay.auth.config.AlipayAuthConfig;
import cn.daxpay.open.platform.capability.alipay.auth.result.AlipayAuthResult;
import cn.daxpay.open.platform.capability.alipay.auth.service.AlipayAuthCapability;
+import cn.daxpay.open.platform.capability.douyin.auth.result.DouyinAuthResult;
+import cn.daxpay.open.platform.capability.douyin.auth.service.DouyinH5AuthService;
import cn.daxpay.open.platform.capability.wechat.auth.result.WechatAuthResult;
import cn.daxpay.open.platform.capability.wechat.auth.result.WechatAuthUrlResult;
import cn.daxpay.open.platform.capability.wechat.auth.service.WechatMpAuthService;
@@ -133,7 +135,7 @@ public class PlatformAuthService {
/// 生成抖音 H5 静默授权链接(平台级, 无商户上下文, 仅调试)
///
- /// 读取平台级 [PlatformDouyinH5AuthConfig], 调用 [DouyinH5AuthService] 构造 silent_auth 链接,
+ /// 读取平台级 [PlatformDouyinH5AuthConfig], 调用 capability-douyin [DouyinH5AuthService] 构造 silent_auth 链接,
/// 回调指向固定的 `/auth/douyin`(抖音要求 redirect_uri 与平台配置完全一致, 不支持 path 段或 query 参数)。
/// 会话标识 authToken 通过 state 参数透传, 回调后从 state 恢复会话。
/// session 标记 `source=platform_douyin`, 认证分发层据此走平台级抖音换票分支([authDouyin])。
@@ -222,7 +224,7 @@ public class PlatformAuthService {
config.getClientKey(), config.getClientSecret(), param.getAuthCode());
if (StrUtil.isBlank(data.getOpenId())) {
// 抖音: 获取用户标识失败
- throw new BizInfoException(CommonErrorCode.SYSTEM_ERROR, "error.social.douyinAuthFailed", "openId is blank");
+ throw new BizInfoException(CommonErrorCode.SYSTEM_ERROR, "error.douyin.authFailed", "openId is blank");
}
AuthResult authResult = new AuthResult()
.setOpenId(data.getOpenId())
diff --git a/daxpay-platform/daxpay-platform-capability/capability-douyin/pom.xml b/daxpay-platform/daxpay-platform-capability/capability-douyin/pom.xml
new file mode 100644
index 000000000..ec9cc4f1d
--- /dev/null
+++ b/daxpay-platform/daxpay-platform-capability/capability-douyin/pom.xml
@@ -0,0 +1,40 @@
+
+
+ 4.0.0
+
+ cn.daxpay.open
+ daxpay-platform-capability
+ 4.0.0-SNAPSHOT
+
+
+ capability-douyin
+ 抖音开放平台 H5 认证能力模块
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ cn.daxpay.open
+ daxpay-platform-core
+ ${project.version}
+
+
+
+ cn.hutool
+ hutool-http
+ ${hutool.version}
+
+
+
+ cn.hutool
+ hutool-json
+ ${hutool.version}
+
+
+
diff --git a/daxpay-platform/daxpay-platform-capability/capability-douyin/src/main/java/cn/daxpay/open/platform/capability/douyin/DouyinAutoConfiguration.java b/daxpay-platform/daxpay-platform-capability/capability-douyin/src/main/java/cn/daxpay/open/platform/capability/douyin/DouyinAutoConfiguration.java
new file mode 100644
index 000000000..0a56ea021
--- /dev/null
+++ b/daxpay-platform/daxpay-platform-capability/capability-douyin/src/main/java/cn/daxpay/open/platform/capability/douyin/DouyinAutoConfiguration.java
@@ -0,0 +1,16 @@
+package cn.daxpay.open.platform.capability.douyin;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.context.annotation.ComponentScan;
+
+/// # 抖音开放平台能力模块自动配置
+///
+/// 装配抖音 H5 静默授权服务([DouyinH5AuthService], HTTP 直连无官方 SDK),
+/// 供 payment 模块(平台级调试认证)等调用方使用, 不耦合配置存储。
+///
+@Slf4j
+@AutoConfiguration
+@ComponentScan
+public class DouyinAutoConfiguration {
+}
diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/core/assist/DouyinAuthResult.java b/daxpay-platform/daxpay-platform-capability/capability-douyin/src/main/java/cn/daxpay/open/platform/capability/douyin/auth/result/DouyinAuthResult.java
similarity index 86%
rename from daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/core/assist/DouyinAuthResult.java
rename to daxpay-platform/daxpay-platform-capability/capability-douyin/src/main/java/cn/daxpay/open/platform/capability/douyin/auth/result/DouyinAuthResult.java
index 9dcc95189..bb88df3ac 100644
--- a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/core/assist/DouyinAuthResult.java
+++ b/daxpay-platform/daxpay-platform-capability/capability-douyin/src/main/java/cn/daxpay/open/platform/capability/douyin/auth/result/DouyinAuthResult.java
@@ -1,4 +1,4 @@
-package cn.daxpay.open.payment.core.assist;
+package cn.daxpay.open.platform.capability.douyin.auth.result;
import lombok.Data;
import lombok.experimental.Accessors;
diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/core/assist/DouyinH5AuthService.java b/daxpay-platform/daxpay-platform-capability/capability-douyin/src/main/java/cn/daxpay/open/platform/capability/douyin/auth/service/DouyinH5AuthService.java
similarity index 84%
rename from daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/core/assist/DouyinH5AuthService.java
rename to daxpay-platform/daxpay-platform-capability/capability-douyin/src/main/java/cn/daxpay/open/platform/capability/douyin/auth/service/DouyinH5AuthService.java
index c3d7a22e9..fe8055f68 100644
--- a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/core/assist/DouyinH5AuthService.java
+++ b/daxpay-platform/daxpay-platform-capability/capability-douyin/src/main/java/cn/daxpay/open/platform/capability/douyin/auth/service/DouyinH5AuthService.java
@@ -1,7 +1,7 @@
-package cn.daxpay.open.payment.core.assist;
+package cn.daxpay.open.platform.capability.douyin.auth.service;
-import cn.daxpay.open.platform.core.code.CommonErrorCode;
-import cn.daxpay.open.platform.core.exception.BizInfoException;
+import cn.daxpay.open.platform.capability.douyin.auth.result.DouyinAuthResult;
+import cn.daxpay.open.platform.core.exception.operation.OperationFailException;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpRequest;
@@ -21,8 +21,9 @@ import org.springframework.stereotype.Service;
/// 与微信公众号 SDK([WechatMpAuthService]) 不同, 抖音 H5 静默授权仅需简单 HTTP 调用,
/// 不依赖第三方 SDK, 直接使用 Hutool HttpUtil 完成。
///
-/// 配置来源: 平台级 [cn.daxpay.open.platform.system.entity.config.platform.auth.PlatformDouyinH5AuthConfig]
-/// (clientKey / clientSecret)。
+/// ## 能力边界
+/// - 生成静默授权链接 / authCode 换 openId(HTTP 直连, 无官方 SDK)
+/// - 不做配置存储 / state / queryCode 缓存(由调用方自行管理)
///
/// 参考文档: https://developer.open-douyin.com/docs/resource/zh-CN/dop/ability/opensdk/user-authorization/get-login-openid
@Slf4j
@@ -41,7 +42,7 @@ public class DouyinH5AuthService {
/// 构造抖音静默授权链接
///
/// 抖音 silent_auth 不支持在 redirect_uri 中携带 query 参数,
- /// authToken 通过 path 段传递(`/auth/douyin/{authToken}`), state 用于 CSRF 校验。
+ /// authToken 通过 path 段或 state 传递, state 用于 CSRF 校验。
///
/// @param clientKey 抖音开放平台 Client Key
/// @param redirectUri 授权回调地址(不含 query 参数)
@@ -82,20 +83,20 @@ public class DouyinH5AuthService {
JSONObject data = object.getJSONObject("data");
if (data == null) {
// 抖音: 换取用户标识失败: {0}
- throw new BizInfoException(CommonErrorCode.SYSTEM_ERROR, "error.social.douyinAuthFailed",
+ throw new OperationFailException("error.douyin.authFailed",
object.getStr("message", body));
}
// error_code 非 0 表示业务错误
int errorCode = data.getInt("error_code", -1);
if (errorCode != 0) {
// 抖音: 换取用户标识失败: {0}
- throw new BizInfoException(CommonErrorCode.SYSTEM_ERROR, "error.social.douyinAuthFailed",
+ throw new OperationFailException("error.douyin.authFailed",
data.getStr("description", "error_code=" + errorCode));
}
String openId = data.getStr("open_id");
if (StrUtil.isBlank(openId)) {
// 抖音: 获取用户标识失败
- throw new BizInfoException(CommonErrorCode.SYSTEM_ERROR, "error.social.douyinAuthFailed", "openId is blank");
+ throw new OperationFailException("error.douyin.authFailed", "openId is blank");
}
return new DouyinAuthResult()
.setOpenId(openId)
diff --git a/daxpay-platform/daxpay-platform-capability/capability-douyin/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/daxpay-platform/daxpay-platform-capability/capability-douyin/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
new file mode 100644
index 000000000..6ea279762
--- /dev/null
+++ b/daxpay-platform/daxpay-platform-capability/capability-douyin/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -0,0 +1 @@
+cn.daxpay.open.platform.capability.douyin.DouyinAutoConfiguration
diff --git a/daxpay-platform/daxpay-platform-capability/capability-douyin/src/main/resources/i18n/en-US/error/douyin.json b/daxpay-platform/daxpay-platform-capability/capability-douyin/src/main/resources/i18n/en-US/error/douyin.json
new file mode 100644
index 000000000..5806927f5
--- /dev/null
+++ b/daxpay-platform/daxpay-platform-capability/capability-douyin/src/main/resources/i18n/en-US/error/douyin.json
@@ -0,0 +1,3 @@
+{
+ "authFailed": "Douyin: failed to get user identifier: {0}"
+}
diff --git a/daxpay-platform/daxpay-platform-capability/capability-douyin/src/main/resources/i18n/zh-CN/error/douyin.json b/daxpay-platform/daxpay-platform-capability/capability-douyin/src/main/resources/i18n/zh-CN/error/douyin.json
new file mode 100644
index 000000000..2afcba85b
--- /dev/null
+++ b/daxpay-platform/daxpay-platform-capability/capability-douyin/src/main/resources/i18n/zh-CN/error/douyin.json
@@ -0,0 +1,3 @@
+{
+ "authFailed": "抖音: 获取用户标识失败: {0}"
+}
diff --git a/daxpay-platform/daxpay-platform-capability/capability-social/src/main/resources/i18n/en-US/error/social.json b/daxpay-platform/daxpay-platform-capability/capability-social/src/main/resources/i18n/en-US/error/social.json
index d608a4682..d2116ddae 100644
--- a/daxpay-platform/daxpay-platform-capability/capability-social/src/main/resources/i18n/en-US/error/social.json
+++ b/daxpay-platform/daxpay-platform-capability/capability-social/src/main/resources/i18n/en-US/error/social.json
@@ -7,7 +7,6 @@
"alipayNotConfigured": "Platform-level Alipay configuration is incomplete, please configure it in 'Third-party Platform Management' first",
"wechatMpNotConfigured": "Platform-level WeChat Official Account configuration is incomplete, please configure it in 'Third-party Platform Management' first",
"douyinH5NotConfigured": "Platform-level Douyin H5 app configuration is incomplete, please configure it in 'Third-party Platform Management' first",
- "douyinAuthFailed": "Douyin: failed to get user identifier: {0}",
"weCom": {
"notCorpMember": "Not a member of this enterprise, login is not supported"
},
diff --git a/daxpay-platform/daxpay-platform-capability/capability-social/src/main/resources/i18n/zh-CN/error/social.json b/daxpay-platform/daxpay-platform-capability/capability-social/src/main/resources/i18n/zh-CN/error/social.json
index dda3dccce..91ae5bbc4 100644
--- a/daxpay-platform/daxpay-platform-capability/capability-social/src/main/resources/i18n/zh-CN/error/social.json
+++ b/daxpay-platform/daxpay-platform-capability/capability-social/src/main/resources/i18n/zh-CN/error/social.json
@@ -7,7 +7,6 @@
"alipayNotConfigured": "平台级支付宝配置不完整,请先在「三方平台管理」中配置",
"wechatMpNotConfigured": "平台级微信公众号配置不完整,请先在「三方平台管理」中配置",
"douyinH5NotConfigured": "平台级抖音 H5 应用配置不完整,请先在「三方平台管理」中配置",
- "douyinAuthFailed": "抖音: 获取用户标识失败: {0}",
"weCom": {
"notCorpMember": "非本企业成员,不支持登录"
},
diff --git a/daxpay-platform/daxpay-platform-capability/pom.xml b/daxpay-platform/daxpay-platform-capability/pom.xml
index f32f0c965..e4c92e81f 100644
--- a/daxpay-platform/daxpay-platform-capability/pom.xml
+++ b/daxpay-platform/daxpay-platform-capability/pom.xml
@@ -17,6 +17,7 @@
capability-wechat
capability-social
capability-alipay
+ capability-douyin
4.0.0