跳到主要内容
版本:v3

实名认证和防沉迷开发指南

提示

使用 TDS 实名认证和防沉迷服务之前,需要在 开发者中心后台 > 游戏服务 > 生态服务 > 合规认证 处开通服务,可选择「已有版号」或「暂无版号」方案。

信息

推荐阅读博客:实名认证和防沉迷功能接入,加深对实名认证和防沉迷功能的理解。

SDK 配置

可以在 下载页 获得 TapSDK,引入防沉迷模块。

Unity 模块,移动端通过引入 iOS 和 Android 模块后增加桥接文件打包出的 .unitypackage,方便以 Unity 开发的游戏直接引入。其他引擎/平台的游戏可以通过 iOS/Android 原生的方式接入,详见 iOS/Android 接入文档。PC(Windows、Mac、Unity Editor)下已经直接通过 Unity Native 的方式实现不需要增加桥接文件。

Unity 开发环境要求:Unity 2019.4 或更高版本

支持版本:

  • Android:最低支持 5.0
  • iOS:最低支持 iOS 10.0
  • Windows 以及 Mac 均已支持

SDK 可以通过 Unity Package Manager 导入或手动导入,二者任选其一。请根据项目需要选择。

方法一:使用 Unity Package Manager

在项目的 Packages/manifest.json 文件中添加以下依赖:

"dependencies":{
"com.tapsdk.antiaddiction":"https://github.com/taptap/TapAntiAddiction-Unity.git#3.18.3",
"com.leancloud.storage": "https://github.com/leancloud/csharp-sdk-upm.git#storage-1.0.2",
"com.taptap.tds.common":"https://github.com/TapTap/TapCommon-Unity.git#3.18.3",
}

在 Unity 顶部菜单中选择 Window > Package Manager 可查看已经安装在项目中的包。

方法二:手动导入

下载页 找到 TapSDK Unity 和 LeanCloud C# SDK 下载地址,分别下载 TapSDK-UnityPackage.zip 和 LeanCloud-SDK-Storage-Unity.zip。

  • TapSDK-UnityPackage.zip 解压后,导入其中的 TapTap_Common_3.18.3.unitypackageTapTap_AntiAddiction_3.18.3.unitypackage

iOS 平台配置:

使用 Xcode 13.0 beta 5 编译,检查 Unity 输出的 Xcode 工程:

  1. 请确保设置 Xcode - General - Frameworks, Libraries, and Embedded Content 中的 AntiAddictionService.frameworkAntiAddictionUI.frameworkDo Not Embed
  2. 如果编译报错找不到头文件或者模块,请确保 Xcode - Build Settings - Framework Search Paths 中的路径以保证 Xcode 正常编译。
  3. 确保 Xcode 工程的 Build SettingsSwift Compile Language / Swift Language VersionSwift5
  4. 添加依赖库 libz.tbdlibc++.tbd
  5. 开始代码接入。
  6. AntiAddiction-Unity/Assets/Plugins/iOS/Resource/AntiAdictionResources.bundle 拷贝到游戏项目下(如果 Unity 项目没有正确导入 AntiAddictionResources.bundle)。

防沉迷 SDK 需要联网和发送请求数据的权限,请开发者注意在项目中声明相应权限。

初始化

初始化防沉迷 UI 模块,设置启动防沉迷功能的配置,注册防沉迷的消息监听。请注意,触发回调需要调用防沉迷认证接口。

using TapTap.AntiAddiction;
using TapTap.AntiAddiction.Model;

AntiAddictionConfig config = new AntiAddictionConfig()
{
gameId = "your_client_id", // TapTap 开发者中心对应 Client ID
showSwitchAccount = false, // 是否显示切换账号按钮
};

Action<int, string> callback = (code, errorMsg) => {
// code == 500; // 登录成功
// code == 1000; // 用户登出
// code == 1001; // 切换账号
// code == 1030; // 用户当前无法进行游戏
// code == 1050; // 时长限制
// code == 9002; // 实名过程中点击了关闭实名窗
UnityEngine.Debug.LogFormat($"code: {code} error Message: {errorMsg}");
};

AntiAddictionUIKit.Init(config, callback);
// 如果是 PC 平台还需要额外设置一下 gameId
TapTap.AntiAddiction.TapTapAntiAddictionManager.AntiAddictionConfig.gameId = "your_client_id"

参数说明

  • config 是防沉迷功能的配置,包括如下参数:
    • gameId 游戏的 Client ID,可以在控制台查看(开发者中心 > 你的游戏 > 游戏服务 > 应用配置)。
    • showSwitchAccount 是否显示切换账号按钮。如果游戏没有切换账号功能,可以在初始化阶段配置隐藏切换账号按钮;如果游戏选择显示切换账号按钮(如下图所示),玩家点击之后会触发 1001 回调,游戏可根据这个回调 code 做相应处理。
  • callback 是防沉迷的在各种情况下,通知用户的回调接口,包含参数如下:
    • code 不同情况下的回调类型,详情可以参考下面的回调类型
    • errorMsg 在执行不同业务时,发生错误时的错误消息。

切换账号界面

回调类型

回调 code回调类型触发逻辑
500LOGIN_SUCCESS玩家登录后判断当前玩家可以进行游戏
1000EXITED退出账号
1001SWITCH_ACCOUNT点击切换账号按钮
1030PERIOD_RESTRICT未成年玩家当前无法进行游戏
1050DURATION_LIMIT时长限制
9002REAL_NAME_STOP实名过程中点击了关闭实名窗

防沉迷认证

SDK 支持两种防沉迷认证方式:

  1. 使用 TapTap 快速认证,可令玩家授权游戏使用 TapTap 上的年龄段信息完成实名。
  2. 不使用 TapTap 快速认证,玩家在 SDK 提供的界面中手动输入身份证号等实名信息。

TDS 云端会根据实名信息判断玩家是否可以进行游戏,并将相关信息上报至中宣部防沉迷实名认证系统。

我们推荐使用第一种方式,对于玩家而言,不需要手动输入信息,可以快速完成认证、进入游戏,体验更佳。

TapTap 快速认证

信息

防沉迷 v3.7.1 开始,使用快速认证不再依赖 TapTap 登录 SDK,但快速认证需要玩家在已登录状态下授权游戏使用其在 TapTap 上的年龄段信息完成实名,请确保完成了以下工作

  • 在开发者中心手动开通 TapTap 登录功能。操作位置在 游戏 > 游戏服务 > 应用配置 页面,找到 TapTap 登录服务,点击「立即开通」按钮。若此项未完成,快速认证时玩家会遇到「应用未开通 TapTap 登录服务」提醒。
  • 在开发者中心配置签名证书。若此项未完成,快速认证拉起 TapTap 客户端会提示「授权失败」。
  • 在开发者中心添加测试用户,或者点击「开放全量用户」按钮。若此项未完成,快速认证时玩家会遇到「抱歉,该游戏 / 应用暂未开放」提醒。

传入玩家唯一标识 userIdentifier 及 是否是 Tap 用户参数时,即可开始 TapTap 快速认证。SDK 会拉起 TapTap 开始快速认证,如果 SDK 检测到玩家设备中未安装 TapTap 客户端,则会打开 WebView,玩家可授权游戏使用其在 TapTap 上的年龄段信息来完成游戏内的实名流程。

其中的玩家唯一标识 userIdentifier,如果接入 TDS 内建账户系统,可以用玩家的 objectId;如果使用单纯 TapTap 用户认证则可以用 openidunionid

对于是否是 Tap 用户,游戏可根据当前玩家选择的登录方式进行设置,即选择 Tap 登录方式的设置为 true, 其他类型设置为 false

// 注意唯一标识参数值长度不能超过 64 字符
string userIdentifier = "玩家的唯一标识";
AntiAddictionUIKit.Startup(userIdentifier, true);

注意:Unity 项目如果没有接入登录模块,则项目导出的 Xcode 工程打包 iOS 时需要配置 URLSchema

查看 Xcode 工程如何配置 URLSchema

打开 info.plist,添加如下配置(请替换 clientID 为你在控制台获取的 Client ID):

<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>taptap</string>
<key>CFBundleURLSchemes</key>
<array>
<!-- 这里注意下,中括号需要去掉,最终是 Client ID 前拼接上 `tt` 的形式,例如:ttFwFdCxxxxxxxQDQwQN -->
<string>tt[clientID]</string>
</array>
</dict>
</array>

<key>LSApplicationQueriesSchemes</key>
<array>
<string>tapiosdk</string>
<string>tapsdk</string>
</array>

登出

玩家在游戏内退出账号时调用,重置防沉迷状态。

AntiAddictionUIKit.Exit();

获取玩家年龄段

调用该接口可获取玩家所处年龄段:

int ageRange = AntiAddictionUIKit.AgeRange;

上例中的 ageRange 是一个整数,表示玩家所处年龄段的下限(最低年龄)。 特别地,-1 表示「未知」,说明该用户还未实名。

类型数值含义
-1未知
00 到 7 岁
88 到 15 岁
1616 到 17 岁
18成年玩家

获取剩余时长(单位:秒)

获取玩家当前剩余时长:

int remainingTimeInSeconds = AntiAddictionUIKit.RemainingTime;

获取剩余时长(单位:分钟)

获取玩家当前剩余时长:

int remainingTimeInMinutes = AntiAddictionUIKit.RemainingTimeInMinutes;

检查消费上限

根据年龄段的不同,未成年玩家的消费金额有不同的上限。 如果启用消费限制功能,开发者需要在未成年玩家消费前检查是否受限,并在成功消费后上报消费金额。

游戏在收到玩家的付费请求后,调用以下接口当前玩家的付费行为是否被限制:

long amount = 100;
AntiAddictionUIKit.CheckPayLimit(amount,
(result) => {
// status 为 1 时可以支付
int status = result.status;
if (status == 1) {
// 可以进行支付
}
},
(exception) => {
// 处理异常
}
);

消费金额的单位为分。

检查消费上限需要游戏事先上报未成年玩家的消费金额。 建议开发者在服务端上报,服务端上报方式参见 相关 REST API 用法说明。 开发者也可以调用 SDK 提供的接口,当未成年玩家消费成功后,在客户端上报消费金额,在客户端上报的可靠性低于在服务端上报,主要适用于无服务端的单机游戏。

long amount = 100;
AntiAddictionUIKit.SubmitPayResult(amount,
() => {
// 成功
}, (exception) => {
// 处理异常
}
);

上报消费金额时,传入的消费金额的单位同样为分。

上报游戏时长

已登录的玩家,开始游戏时调用此接口,之后 SDK 会自动轮询上报游戏时长。

AntiAddictionUIKit.EnterGame();

相应地,已登录的玩家,停止游戏时调用此接口,之后 SDK 停止轮询上报时长。

AntiAddictionUIKit.LeaveGame();

REST API

请求格式

REST API 请求的主体为 JSON 格式,HTTP header 的 Content-Type 需要设置为 application/json

请求通过 Authorization TOKEN HTTP 头进行鉴权。 开发者需要在客户端通过 SDK 接口获取 TOKEN 后传给服务端,然后在服务端凭借此 TOKEN 调用防沉迷服务的 REST API。

API Base 为 https://tds-tapsdk.cn.tapapis.com

获取鉴权 Token

string token = AntiAddictionUIKit.CurrentToken;

鉴权 Token 永久有效。

检查玩家当前能否游戏

curl -X POST \
-H "Content-Type: application/json" \
-H 'Authorization: {{token}}' \
https://tds-tapsdk.cn.tapapis.com/anti-addiction/v1/clients/{{clientId}}/users/{{userIdentifier}}/playable

其中:

  • {{token}} 需替换为客户端获取的鉴权 token
  • {{clientId}} 需替换为 开发者中心后台游戏服务 > 应用配置 中的 Client ID。
  • {{userIdentifier}} 需替换为游戏在调用 防沉迷认证 时使用的玩家唯一标识

以下情况的响应状态码均为 200:

// 实名认证失败
{
"success": true,
"data": {
"status": 2,
"anti_addiction_token": "",
"age_limit": 18,
"has_auth_record": false
}
}

// 成年玩家
{
"success":true,
"data":{
"code":200,
"can_play":true,
"message":"游戏时间不受限制",
"remain_time":60,
"cost_time":0,
"restrict_type":0,
"title":"健康游戏提示",
"description":"当前为成年人账号"
}
}

// 未成年玩家,当前可以游戏
{
"success":true,
"data":{
"code":200,
"can_play":true,
"message":"游戏允许时间",
"remain_time": {{remainTime}},
"cost_time": {{costtime}},
"restrict_type":1,
"title":"健康游戏提示","description":"你当前为未成年账号,已被纳入防沉迷系统。根据国家相关规定,周五、周六、周日及法定节假日 20 点 - 21 点之外为健康保护时段。你今日游戏时间还剩余${remainTime}分钟,请注意适当休息。"
}
}

// 未成年玩家,当前不可游戏
{
"success":true,
"data":{
"code":200,
"can_play":false,
"message":"游戏时间耗尽",
"remain_time": 0,
"cost_time": 60,
"restrict_type":1,
"title":"健康游戏提示",
"description":"你当前为未成年账号,已被纳入防沉迷系统。根据国家相关规定,周五、周六、周日及法定节假日 20 点 - 21 点之外为健康保护时段。当前时间段无法游玩,请合理安排时间。"
}
}

Token 解析错误会返回 401 错误:

{
"success":false,
"data":{
"code":16,
"error":"实名认证失败",
"error_description":"未实名用户不能进入游戏",
"msg":"该账号没有通过实名认证"
}
}

检查玩家消费是否受限

充值金额以分为单位,比如检查玩家是否可以消费 1 元(100 分):

curl -X POST \
-H "Content-Type: application/json" \
-H 'Authorization: {{token}}' \
-d '{"amount": 100}' \
https://tds-tapsdk.cn.tapapis.com/anti-addiction/v1/clients/{{clientId}}/users/{{userIdentifier}}/payable

消费受限和不受限时响应的状态码都是 200:

// 受限
{
"success":true,
"data":{
"code":200,
"status":false,
"message":"限额提示",
"title":"健康消费提示",
"description":"允许充值根据国家相关规定,未满8周岁:不提供付费服务;8-16周岁以下:单笔付费不超过50元,每月累计不超过200元;16-18周岁以下:单笔付费不超过100元,每月累计不超过400元。"
}
}

// 允许
{
"success":true,
"data":{
"code":200,
"status":true,
"message":"限额提示",
"title":"健康消费提示",
"description":"允许充值根据国家相关规定,未满8周岁:不提供付费服务;8-16周岁以下:单笔付费不超过50元,每月累计不超过200元;16-18周岁以下:单笔付费不超过100元,每月累计不超过400元。"
}
}

金额格式异常时返回 400 错误:

{
"success":false,
"data":{
"code":3,
"error":"上传金额不正确",
"error_description":"金额大于等于0并小于100_000_000_000","msg":"请输入正确的金额格式"
}
}

实名认证失败(包括 Token 解析错误)时返回 401 错误:

{
"success":false,
"data":{
"code":16,
"error":"实名认证失败",
"error_description":"未实名用户不能进入游戏",
"msg":"该账号没有通过实名认证"
}
}

上报消费金额

玩家充值 1 元(100 分),提交消费金额:

curl -X POST \
-H "Content-Type: application/json" \
-H 'Authorization: {{token}}' \
-d '{"amount": 100}' \
https://tds-tapsdk.cn.tapapis.com/anti-addiction/v1/clients/{{clientId}}/users/{userIdentifier}/payments

上报成功时响应的状态码为 200,返回结果:

{
"success":true,
"data":{"message":"上传金额成功"}
}

金额格式异常时返回 400 错误:

{
"success":false,
"data":{
"code":3,
"error":"上传金额不正确",
"error_description":"金额大于等于0并小于100_000_000_000","msg":"请输入正确的金额格式"
}
}

常见问题

如何开通实名认证与防沉迷服务

可以在 开发者中心后台 > 游戏服务 > 生态服务 > 合规认证 处自助开通服务。目前提供两种方案,游戏开通时选择其中一种:

  • 有版号。完成控制台提示的前置条件,点击开通,然后配置好中宣部参数
    • 将中宣部系统后台的游戏备案识别码、应用标识、应用密钥填写到 TapTap 开发者中心后台对应处。
    • 将 TapTap 开发者中心后台显示的 IP 白名单地址复制、填写到中宣部系统后台。
  • 暂无版号。无版号游戏无法配置中宣部参数,可直接选择开通,等游戏有了版号,可以配置中宣部参数并切换到有版号方案。切换后客户端代码不受影响,不需要修改。

SDK 自带哪些用户界面(UI)

实名认证和防沉迷 SDK 提供的用户界面主要在防沉迷授权阶段,可参考功能介绍文档中的界面预览。

授权失败

在实名认证时使用 TapTap 快速认证服务提示「授权失败」,请至后台配置签名证书

未查询到实名认证配置

实名认证时使用手动输入实名信息服务提示「未查询到实名认证配置」,原因是未开启实名认证服务,需要在 开发者中心后台 > 游戏服务 > 生态服务 > 合规认证 处自助开通服务。

userIdentifier is empty

调用认证接口时需要传入的玩家唯一标识 userIdentifier 参数值为空,建议开发者对此做非空判断。

未弹出实名认证窗口/未收到回调

这种情况一般是仅调用了初始化防沉迷 UI 模块代码,也就是说只完成了 SDK 的初始化,同时注册防沉迷的消息监听。

触发实名认证弹窗必须调用 认证接口,之后才会收到回调。

重复认证

我们预期同一个玩家认证过一次之后不再触发弹窗,防沉迷服务直接使用第一次认证的结果,这样用户体验更好。

如果出现重复认证,可以按照以下思路排查:

  • 首先确认游戏使用的 玩家唯一标识 userIdentifier 符合要求。如果同一个玩家用的 userIdentifier 会发生改变,在防沉迷服务中会被视为不同用户,导致重复认证。这个时候需要游戏传入合适的 userIdentifier,建议接入 TDS 内建账户系统,用 objectId 作为玩家唯一标识;或者使用单纯 TapTap 用户认证,传入 openidunionid 作为玩家唯一标识。
  • 如果是有版号游戏,请确认在 开发者中心后台游戏服务 > 生态服务 > 合规认证 处填写的参数无误。如果参数有问题,请求中宣部接口会失败,导致重复认证。请检查以下参数配置:
    • IP 白名单地址全部填入中宣部系统后台。
    • 游戏备案识别码、应用标识和中宣部后台保持一致。
    • 应用密钥在有效期内(有效期为半年,注意在失效前更新)。

注意事项

玩家唯一标识 userIdentifier 参数说明

第一次认证会触发实名认证弹窗,让玩家授权游戏获取 TapTap 实名信息或输入身份信息,认证通过后,后面每一次以同样的 userIdentifier 调用认证接口都会直接拿到第一次认证的结果,不再触发弹窗。

因此,同一个用户的唯一标识应该要保证唯一性。

测试实名认证环境

无论是 Android 还是 iOS 项目,不支持在 Unity Editor 环境里调试,请对应打包到真实设备或者移动端的模拟器中进行测试实名认证防沉迷的相关功能。

更新日志

3.18.3

内容变更:

  1. 修复 Unity 接入时 iOS 无回调问题

3.18.2

内容变更:

  1. 修复提示窗口 UI 错位问题
  2. 修复 iOS 部分情况下进入宵禁未弹出提示异常

接口变更

新增接口

防沉迷开始认证接口添加 isTapUser 参数,当登录方式为 Tap 登录时设置为 true, 其他方式设置为 false

// 注意唯一标识参数值长度不能超过 64 字符
string userIdentifier = "玩家的唯一标识";
// Deprecated in 3.18.2 Added in 3.15.0
// AntiAddictionUIKit.Startup(userIdentifier);
AntiAddictionUIKit.Startup(userIdentifier, true);