跳到主要内容
版本:v3

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

提示

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

信息

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

环境要求

  • Unity 2019.4 或更高版本
  • iOS 11 或更高版本,Xcode 版本 14.1 或更高版本
  • Android 5.0(API level 21)或更高版本

集成前准备

  1. 参考 准备工作 创建应用、开启应用配置。
  2. 参考实名认证和防沉迷功能介绍中准备工作开通防沉迷服务。

SDK 配置

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

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

方法一:使用 Unity Package Manager

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

"dependencies":{
"com.tapsdk.antiaddiction":"https://github.com/taptap/TapAntiAddiction-Unity.git#3.23.0",
"com.taptap.tds.login":"https://github.com/TapTap/TapLogin-Unity.git#3.23.0",
"com.taptap.tds.common":"https://github.com/TapTap/TapCommon-Unity.git#3.23.0",
"com.taptap.tds.bootstrap":"https://github.com/TapTap/TapBootstrap-Unity.git#3.23.0", // 可选
"com.leancloud.realtime": "https://github.com/leancloud/csharp-sdk-upm.git#realtime-1.0.2",
"com.leancloud.storage": "https://github.com/leancloud/csharp-sdk-upm.git#storage-1.0.2",
}

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

方法二:手动导入

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

  • TapSDK-UnityPackage.zip 解压后,导入其中的 TapTap_Common_3.23.0.unitypackageTapTap_AntiAddiction_3.23.0.unitypackage以及TapTap_Login_3.23.0.unitypackage

iOS 平台配置:

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

查看 Unity 输出的 Xcode 工程详情配置
  1. 请确保设置 Xcode - General - Frameworks, Libraries, and Embedded Content 中的 AntiAddictionService.frameworkAntiAddictionUI.frameworkDo Not Embed

  1. 如果编译报错找不到头文件或者模块,请确保 Xcode - Build Settings - Framework Search Paths 中的路径以保证 Xcode 正常编译。

  1. 确保 Xcode 工程的 Build SettingsSwift Compile Language / Swift Language VersionSwift5

  1. 添加依赖库 libz.tbdlibc++.tbd

  1. 开始代码接入。

  2. AntiAddiction-Unity/Assets/Plugins/iOS/Resource/AntiAdictionResources.bundle 拷贝到 Unity 导出的 Xcode 工程目录下(如果 Unity 项目没有正确导入 AntiAddictionResources.bundle)。假设你的 Unity 项目名称为 AntiDemo,则默认导出 Xcode 工程名为 antidemoxcode,需要将 AntiAdictionResources.bundle 拷贝到 antidemoxcode 目录里。拷贝成功后在项目的 Build Phases > Copy Bundle Resources 里添加拷贝的 AntiAdictionResources.bundle

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

初始化

因为防沉迷模块依赖于 TapLogin 模块,所以在防沉迷模块初始化前必须把 TapLogin 模块初始化了。如果使用了 TapBootstrap 模块(推荐),那么可以通过 TapBootstrap 模块的初始化来初始化 TapLogin 模块。

初始化防沉迷 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 上的年龄段信息完成实名。(如果用户使用的是 TapTap 登录,那么将会默认使用 TapTap 快速认证)
  2. 不使用 TapTap 快速认证(即弹出「TapTap 快速认证」授权框后,点击「不使用」按钮),玩家在 SDK 提供的界面中手动输入身份证号等实名信息。

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

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

TapTap 快速认证

信息

快速认证需要玩家在已登录状态下授权游戏使用其在 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.StartupWithTapTap(userIdentifier);

注意: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();

测试模式设置

测试账号的使用强依赖于 TapTap 登录功能,需要游戏先实现 TapTap 登录功能。使用提供的测试账号以邮箱方式登录 TapTap,游戏启动后触发 TapTap 登录,登录成功后会在成功的回调中得到当前测试账号对应的 unionidunionid 获取方式可以参考获取用户信息的内容。

开启测试模式的接口需要在 SDK 的 init 初始化接口之后,startupwithtaptap 接口之前调用。在 startupwithtaptap 传入的 玩家唯一标识 userIdentifier 必须为测试账号对应的 TapTap 登录后返回的 unionid

AntiAddictionUIKit.SetTestEnvironment(enable)

使用该接口需要在控制台开启「切换为测试模式」,可以针对某个账号进行一些设置,正式打包上线的应用应该需要去掉这个接口。

获取剩余时长

获取玩家当前剩余时长:

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":"请输入正确的金额格式"
}
}