实名认证和防沉迷功能接入

按照国家新闻出版署《关于进一步严格管理切实防止未成年人沉迷网络游戏的通知》,各游戏出版运营企业均须在游戏内落实游戏实名认证和防沉迷新策略。依此 TDS 推出「防沉迷」功能,助力游戏厂商发展。

在使用 TDS 实名认证和防沉迷服务之前,游戏厂商需要完成一些前期准备工作。在 TapTap 开发者中心 创建游戏、开通游戏服务后,找到 游戏服务 > 生态服务 > 合规认证 根据游戏的情况在两种方案中选择一种,为游戏开通实名认证与防沉迷服务。

接下来将介绍该如何接入 TDS 推出的「实名认证和防沉迷」功能:

游戏实名认证

导入 SDK 包体

防沉迷 v3.7.1 之前,这种方式的前提是游戏需要接入 TapTap 登录功能,游戏可以选择通过基于内建账户系统接入 TapTap 登录,或者以单纯 TapTap 用户认证的方式接入 TapTap 登录。登录成功后需要将 TapSDK 返回的玩家属性用户唯一标识作为参数传递给防沉迷的接口,从而才可以开始 TapTap 快速认证。

防沉迷 v3.7.1 至 v3.22.0 版本,使用快速认证不再依赖 TapTap 登录 SDK。只需要开通 TapTap 登录功能、后台正确配置好应用的签名 MD5 值即可。

防沉迷自 v3.22.1 版本开始依赖于 TapTap 登录模块的包体,游戏需要导入 TapTap 登录包体并完成 TapTap 登录的初始化,游戏可以选择通过基于内建账户系统导入 TapTap 登录模块包体,或者以单纯 TapTap 用户认证的方式导入 TapTap 登录模块包体。

注意:游戏侧需要先完成 TapTap 登录模块的初始化,然后再进行如下代码所示的实名认证防沉迷 SDK 初始化。

初始化 SDK

逻辑上是先进行 SDK 初始化,然后调用以下的实名认证接口完成 TDS 的实名认证功能。建议将 SDK 的初始化靠前,初始化完成后再调用认证接口:AntiAddictionUIKit.StartupWithTapTap(isUserIdentifier); 建议初始化和认证接口直接保留微秒级的时间间隔,以确保 SDK 的初始化完成。

// 先初始化 TapTap 登录模块(单纯 TapTap 用户认证方式)
TapLogin.Init(string clientID); 


// 先初始化 TapTap 登录模块(基于内建账户方式)
var config =  new TapConfig.Builder()
    .ClientID("your_client_id") // 必须,开发者中心对应 Client ID
    .ClientToken("your_client_token") // 必须,开发者中心对应 Client Token
    .ServerURL("https://your_server_url") // 必须,开发者中心 > 你的游戏 > 游戏服务 > 基本信息 > 域名配置 > API
    .RegionType(RegionType.CN) // 非必须,CN 表示中国大陆,IO 表示其他国家或地区
    .ConfigBuilder();
TapBootstrap.Init(config);

// 注意:上述两种方式,请游戏侧根据实际需求采用上述两种方式的一种进行 TapTap 登录模块的初始化。

// 这部分代码只是初始化 SDK 并注册监听回调,认证的结果根据回调方法中 code 字段给出。需要说明的是:触发回调需要调用认证接口才行。
using TapTap.AntiAddiction;    
using TapTap.AntiAddiction.Model;    // 引入命名空间

AntiAddictionConfig config = new AntiAddictionConfig()
{
    gameId = "游戏的 Client ID",      // TapTap 开发者中心对应 Client ID
    showSwitchAccount = false,      // 是否显示切换账号按钮,根据游戏自身需求设置是否显示「切换账号」按钮
};         

Action<int, string> callback = (code, errorMsg) => {
    
    UnityEngine.Debug.LogFormat($"code: {code} error Message: {errorMsg}");

    // 根据 code 不同提示玩家不同信息,详见下面的说明
    if (code == 500)
    {
        // 该玩家可以正常进入游戏;如果需要上报时长,调用如下接口开始计时
        AntiAddictionUIKit.EnterGame();

    }
    if (code == 1000)
    {
        // 退出账号,当调用 AntiAddictionUIKit.Logout() 接口时触发
        // 玩家在游戏内退出账号时调用该接口,重置防沉迷状态。
    }
    if (code == 1001)
    {
        // 点击切换账号按钮(v1.0.2 新增)
        // 说明玩家在实名认证过程中,点击了「切换账号」按钮,点击切换账号按钮会触发该回调,同时实名认证的弹窗会被销毁,
        // 逻辑上需要游戏重新触发实名认证,正确引导玩家完成实名认证
    }
    if (code == 1030)
    {
        // 该回调状态不需要游戏做额外的处理
        // 说明玩家是未成年,而该未成年玩家此时是不被允许进行游戏的,逻辑上不要进行游戏主界面的跳转,
        // 这种状态,SDK 内部封装的弹窗会被触发,玩家只能选择「切换账号」(前提是显示切换账号按钮 bool showSwitchAccount = true)或者「退出游戏」
    }
    if (code == 1050)
    {
        // 开始游戏时调用 AntiAddictionUIKit.EnterGame(); 接口,停止游戏时调用 AntiAddictionUIKit.LeaveGame(); 接口
        // 说明玩家是未成年,该未成年玩家此时是可以允许进行游戏的,需要额外说明,这种状态开发者不需要关注,也不要做什么逻辑上的处理。
        // 该玩家如果持续游戏时间达到当天上限,SDK 内部会做处理,给出弹窗,玩家只能选择退出游戏
    }
    
    if (code == 9002)
    {
        // 实名认证过程中玩家点击了关闭实名窗,说明玩家并没有完成实名认证,是不可以进入游戏的。
        // 逻辑上需要继续触发实名认证,正确引导玩家完成实名认证
    }
    
};

AntiAddictionUIKit.Init(config, callback);

实名认证

具体的代码示范如下:

string userIdentifier = "玩家的唯一标识";
// 玩家唯一标识 userIdentifier 详细说明:
// 1、如果接入 TDS 内建账户系统,建议使用 SDK 返回的 objectId 字段;
// 2、如果使用单纯 TapTap 用户认证则可以用 openid 或 unionid
// 3、针对非 TapTap 登录的方式,游戏侧有自己的用户系统则 userIdentifier 赋值为游戏侧用户系统的用户唯一标识。
// 总之,玩家唯一标识 userIdentifier 的赋值要符合不同的玩家,设置的用户唯一标识不同即可。
AntiAddictionUIKit.StartupWithTapTap(isUserIdentifier);

TDS 的实名认证依据游戏侧采取的不同登录方式而呈现出不同的效果,主要分为 TapTap 登录和非 TapTap 登录两种模式:

  • TapTap 登录方式实现快速认证 游戏采用的登录方式为 TapTap 登录,则游戏在 TapTap 登录后,调用 StartupWithTapTap 接口会直接采用玩家在 Tap 社区客户端已经通过 TapTap 客户端实名过的信息来完成实名认证(静默实名认证授权),该方式省却了玩家在游戏中再次授权 TapTap 实名认证和输入身份信息来进行实名认证,让整个实名认证流程变得更为简洁。此方式基于 TapTap 的 access token,SDK 会自动获取 access token。 如果自动获取失败,那么会显示手动输入实名信息的用户界面。

  • 非 TapTap 登录方式的实名认证 游戏采用非 TapTap 登录方式,调用 StartupWithTapTap 接口会看到如下的弹窗:

该弹窗有对应两个按钮「不使用」和「使用」,这个时候玩家点击「使用」按钮,就会唤起 TapTap 客户端实名认证授权,即使用玩家在 Tap 社区客户端已经通过 TapTap 客户端实名过的信息来完成实名认证。如果玩家点击「不使用」按钮,则会弹出手动输入实名信息的弹窗,玩家通过手动输入身份信息来完成实名认证,具体的弹窗如下图所示的「游戏实名认证」窗口。

手动输入实名信息会触发上述的「游戏实名认证」弹窗,玩家输入姓名、身份证号后如果认证失败,会提示「认证未通过,请提交真实信息」,如果乱填写身份证号,则会提示「身份证号码非法」。这些也不需要开发者关心,认证失败时,「游戏实名认证」窗口是不会关闭的,除非玩家点击右上角的 x 按钮主动关闭。这些都是 SDK 内部封装好的,开发者重点需要关心的是文档中给出的回调类型,这个很重要。比如实名认证过程中,玩家点击了右上角的 x 按钮,则会触发 code 为 9002 的回调,该回调告知开发者玩家的动作,表示玩家并没有完成实名认证,开发者对此应该做相应的逻辑处理。

再次针对 StartupWithTapTap 接口的userIdentifier:玩家的唯一标识参数做个说明。如果第一次认证后,紧接着进行第二次认证,userIdentifier 值没有改变的话,TapTap 服务端会根据该 userIdentifier 上次的认证结果结合当前时间段直接返回认证结果。所以,不同的玩家,这里的唯一标识应该要保持不同。

有的开发者可能会将该参数赋值为获取到的设备唯一标识,但是真的不太建议这样操作,因为安卓碎片化较为严重,玩家不同意获取设备信息权限等因素可能导致获取到的设备唯一标识为空,从而导致 userIdentifier 为空。如果代码不够健壮,非空判定比较少,结果就会是无法正常使用实名认证功能。当 userIdentifier 为空时调用实名认证接口会弹出 "userIdentifier is empty" 的提示窗。

无版号游戏没有开通实名认证防沉迷服务是无法使用 TDS 的实名认证防沉迷功能的。没有开通服务的游戏接入实名认证防沉迷,当调用实名认证接口时会给出相对应的提示:「未查询到实名认证配置」

上报游戏时长:

如果启用时长限制功能,需要上报游戏时长。已登录的玩家,开始游戏时调用此接口,之后 SDK 会自动轮询上报游戏时长。

AntiAddictionUIKit.EnterGame();

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

AntiAddictionUIKit.LeaveGame();

防沉迷策略

仅允许未成年人在周五、周六、周日和法定节假日的 20:00 至 21:00 进行游戏。非允许游戏时间段内,SDK 封装的相应逻辑会被触发,弹出提示框提醒未成年无法继续游戏。此时的未成年玩家最多有两种选择:「退出游戏」或者「切换账号」。

如果初始化 SDK 时设置的一个参数 showSwitchAccount 为 false(表示不显示「切换账号」按钮),那此时的未成年玩家只能选择「退出游戏」了。

// 是否显示切换账号按钮
bool showSwitchAccount = false;

检查消费上限

根据年龄段的不同,未成年玩家的消费金额有不同的上限。 如果要启用消费限制功能,开发者只需要在未成年玩家消费前检查是否受限。如果游戏没有消费则可以忽略这部分说明。

游戏在收到玩家的付费请求后,调用以下接口检验当前玩家的付费行为是否被限制,游戏侧请 务必 在未成年玩家每次充值之前调用如下接口进行判断。

long amount = 100;    // 100 表示 100 分,即 1 元
AntiAddictionUIKit.CheckPayLimit(amount,
    (result) => {
        // status 为 1 时可以支付
        int status = result.status;
        if (status == 1) {
            // 可以进行支付
        } else {
          // 说明玩家当前的这一笔消费不可以再继续了,如果继续就超过了限制,游戏侧则要拦截这笔消费。
        }
    },
    (exception) => {
        // 处理异常
    }
);

消费金额的单位为分。

Checklist

游戏侧接入 TDS 实名认证防沉迷功能,开发者需要测试实名认证防沉迷流程是否正常,检查并知晓以下事项:

  • 游戏侧正确导入 TDS 实名认证防沉迷所需的包体。(知晓:防沉迷自 v3.22.1 版本开始依赖于 TapTap 登录模块的包体)

  • SDK 的正确初始化,gameId 参数为 Tap Client ID,游戏侧根据需求决定是否显示「切换账号」按钮,若显示「切换账号」按钮请务必处理好这块的逻辑。(不要忘记初始化 TapTap 登录模块)

  • 充分了解实名认证防沉迷的各个回调方法所对应的含义,游戏侧对此做出相应的逻辑处理。

  • 充分了解实名认证 AntiAddictionUIKit.StartupWithTapTap(userIdentifier) 接口的 userIdentifier 参数含义。

  • SDK 的初始化 AntiAddictionUIKit.Init 和实名认证接口 AntiAddictionUIKit.StartupWithTapTap 保留毫秒级的间隔,以确保 SDK 完成初始化。

  • 游戏在收到未成年玩家付费请求后请务必先检查当前这笔消费是否已达上限,达到上限则拦截当前这笔消费。

服务支持

对此有任何问题,非常欢迎通过开发者中心后台提工单咨询。