最佳实践
准备工作
创建应用获取应用参数
在 TapTap 开发者中心 创建游戏应用,获取应用 Client ID、Client Token 等参数,用于初始化 SDK;

开通 TapTap 登录服务
合规认证服务依赖于 TapTap 登录服务,因此,厂商需要在 TapTap 开发者中心 > 你的游戏 > 游戏服务 > 应用配置 开启「TapTap 登录」;

配置应用包名和签名信息
Android 签名处填写 MD5 值,详情可参考:如何获取 MD5 值;

开通合规认证服务
找到 TapTap 开发者中心 > 你的游戏 > 游戏服务 > 基础服务 > 合规认证,根据游戏实际情况,选择「已有版号」或「暂无版号」方案,然后点击立即开通

若游戏选择的是「已有版号」方案则还需要完成中宣部实名认证系统的注册以及相应配置,具体的操作请参考 注册中宣部实名认证系统
可玩年龄限制
应用需要对用户年龄有额外限制时,可在 TapTap 开发者中心 > 你的游戏 > 游戏服务 > 合规认证 > 可玩年龄限制 中开启此功能,并配置所需的最低年龄要求
在后续的代码集成中,也需要处理相关的 1100 回调

代码接入
下面模拟一个小游戏来进行接入示例,该游戏主要包括两个场景:
- 登录场景 LoginScene: 用于初始化 SDK 、用户登录、切换账号、显示合规认证异常提示 UI 等
 - 游戏商店及设置场景 GameStoreAndSettignsScene: 用于展示充值页面、设置菜单等
 
另外,因合规认证模块在游戏整个生命周期中运行,所以通过全局的单例管理工具类 GameSDKManager 来处理 SDK 的初始化及回调。
完整示例代码可参考 TDS-Unity-Demo
导入 SDK 包体
- Unity
 
在游戏项目的 Packages/manifest.json 文件中添加以下依赖:
"dependencies":{
  "com.taptap.sdk.core":"https://github.com/taptap/tapsdk-unity-dist.git?path=/Core#4.8.2",
  "com.taptap.sdk.login":"https://github.com/taptap/tapsdk-unity-dist.git?path=/Login#4.8.2",
  "com.taptap.sdk.compliance":"https://github.com/taptap/tapsdk-unity-dist.git?path=/Compliance#4.8.2",
  "com.google.external-dependency-manager": "1.2.179",
  "com.github-glitchenzo.nugetforunity": "https://github.com/GlitchEnzo/NuGetForUnity.git?path=/src/NuGetForUnity"
}
在 Unity 顶部菜单中选择 Window > Package Manager 可查看已经安装在项目中的包。
初始化与设置回调
在 GameSDKManager 工具类中完成 SDK 的初始化及全局回调的设 置,示例如下:
- Unity
 
using System;
using TapSDK.Login;
using TapSDK.Compliance;
using TapSDK.Core;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// SDK 初始化及合规认证回调处理管理类
/// </summary>
public sealed class GameSDKManager
{
    // 游戏在 TapTap 开发者中心对应的 Client ID
    private readonly string clientId = "游戏的 Client ID";
    // 游戏在 TapTap 开发者中心对应的 Client Token
    private readonly string clientToken = "游戏的 Client Token";
    // 是否已初始化
    private readonly bool hasInit = false;
    
    // 是否已通过合规认证检查
    public bool hasCheckedCompliance { get; private set; }
    private static readonly Lazy<GameSDKManager> lazy
        = new Lazy<GameSDKManager>(() => new GameSDKManager());
    public static GameSDKManager Instance { get { return lazy.Value; } }
    private GameSDKManager() { }
    // 声明合规认证回调
    private readonly Action<int, string> ComplianceCallback = (code, errorMsg) =>
    {
        // 根据回调返回的参数 code 添加不同情况的处理
        switch (code)
        {
            case 500: // 玩家未受限制,可正常进入
                Instance.hasCheckedCompliance = true;
                // TODO: 显示开始游戏按钮      
                break;
            case 1000: // 防沉迷认证凭证无效时触发
            case 1001: // 当玩家触发时长限制时,点击了拦截窗口中「切换账号」按钮
            case 9002: // 实名认证过程中玩家关闭了实名窗口
                TapTapLogin.Instance.Logout(); // 如果游戏有其他账户系统,此时也应执行退出
                // TODO: 切换到登录页面 例如:SceneManager.LoadScene("Login");
                break;
            case 1100: // 当前用户因触发应用设置的年龄限制无法进入游戏
                // TODO: 游戏应自行绘制适龄限制提示,并引导玩家退出游戏
                break;
            case 1200: // 数据请求失败,应用信息错误或网络连接异常  
                // TODO: 引导玩家确认网络连接是否正常,并重新调用开始认证接口
                break;
            default:
                Debug.Log("其他可选回调");
                break;
        }
    };
    /// <summary>
    /// 初始化 TapSDK 并注册合规认证回调
    /// </summary>
    public void InitSDK()
    {
        if (!hasInit)
        {
            TapTapSdkOptions coreOptions = new TapTapSdkOptions
            {
                clientId = clientId,
                clientToken = clientToken
            };
            TapTapComplianceOption complianceOption = new TapTapComplianceOption
            {
                showSwitchAccount = false, // 是否显示切换账号按钮
                useAgeRange = true // 是否使用年龄段信息
            };
            // 创建其他选项数组
            TapTapSdkBaseOptions[] otherOptions = new TapTapSdkBaseOptions[]
            {
                complianceOption
            };
            TapTapSDK.Init(coreOptions, otherOptions);
            TapTapCompliance.RegisterComplianceCallback(ComplianceCallback);
        }
    }
    
    /// <summary>
    /// 开始合规认证检查
    /// </summary>
    /// <param name="userIdentifier">用户唯一标识</param>
    public void StartCheckCompliance(string userIdentifier)
    {
        hasCheckedCompliance = false;
        TapTapCompliance.Startup(userIdentifier);
    }
}
TapTap 登录 & 开始实名认证
登录场景为游戏的第一个场景,在该脚本中需调用 GameSDKManager 中初始化接口,并实现 Tap 登录、开始合规认证,示例如下:
TapTap 登录按钮素材需要使用官方提供的登录按钮素材;
- Unity
 
using UnityEngine;
using System;
using TapSDK.Login;
using TapSDK.Compliance;
using System.Collections.Generic;
/// <summary>
/// 登录场景
/// </summary>
public class LoginScene : MonoBehaviour
{
    /// <summary>
    /// 初始化 SDK 并判断本地是否已登录,已登录时开始合规认证检查,否则显示登录按钮
    /// </summary>
    async void Start()
    {
        // 初始化 SDK
        GameSDKManager.Instance.InitSDK();
        TapTapAccount account = null;
        try
        {
            // 检查本地是否已存在 account 信息
           account = await TapTapLogin.Instance.GetCurrentTapAccount();
        }
        catch (Exception e)
        {
            Debug.Log("本地无有效用户信息");
        }
        if (account == null)
        {
            // TODO: 显示登录按钮
        }
        else
        {
            // 如果当前还未通过合规认证检查,开始认证
            if (!GameSDKManager.Instance.hasCheckedCompliance)
            {
                // 开始合规认证检查
                StartCheckCompliance();
            }
        }
    }
    /// <summary>
    /// 登录按钮点击后执行 Tap 登录
    /// </summary>
    public async void OnTapLoginButtonClick()
    {
        try
        {
            List<string> scopes = new List<string>
            {
                TapTapLogin.TAP_LOGIN_SCOPE_PUBLIC_PROFILE
            };
            // 发起 Tap 登录并获取用户信息
            var account = await TapTapLogin.Instance.LoginWithScopes(scopes.ToArray());
            // 开始合规认证检查
            StartCheckCompliance();
        }
        catch (Exception e)
        {
            // 登录取消或错误,提示用户重新登录
            Debug.Log("用户登录取消或错误");
        }
    }
    /// <summary>
    /// 开启合规认证检查
    /// </summary>
    public async void StartCheckCompliance()
    {
        // 获取当前已登录用户的 account 信息
        TapTapAccount account = null;
        try
        {
            account = await TapTapLogin.Instance.GetCurrentTapAccount();
        }
        catch (Exception exception)
        {
            Debug.Log($"获取用户信息出现异常:{exception}");
        }
        if (account == null)
        {
            // 无法获取用户信息时,登出并显示登录按钮
            TapTapLogin.Instance.Logout();
            // TODO: 显示登录按钮
            return;
        }
        // 使用当前 Tap 用户的 unionid 作为用户标识进行合规认证检查
        string userIdentifier = account.unionId;
        GameSDKManager.Instance.StartCheckCompliance(userIdentifier);
    }
}
限制未成年人消费额度
每次充值之前,游戏侧请 务必 调用 CheckPaymentLimit 接口进行判断,检验当前玩家的充值行为是否被限制。充值金额的单位为分。
- Unity
 
using TapSDK.Compliance;
// 100 表示 100 分,即 1 元
long amount = 100;
TapTapCompliance.CheckPaymentLimit(amount, (result) =>
    {
        // 获取检查状态
        int status = result.status;
        
        // 当前充值不受限
        if (status == 1)
        {
            // TODO: 进行后续充值流程,充值完成后调用上报充值金额接口
        }
        else
        {
            // 本次充值触发合 规限制,游戏侧需停止后续充值流程
        }
    },
    (exception) =>
    {
        // TODO: 处理参数或网络异常后重试
    }
);
充值成功后,游戏侧请 务必 调用 SubmitPayment 接口上报玩家充值金额。上报充值金额时,传入的充值金额的单位同样为分。
- Unity
 
using TapSDK.Compliance;
// 100 表示 100 分,即 1 元
long amount = 100;
TapTapCompliance.SubmitPayment(amount, () =>
    {
        // 提交成功
    }, (exception) =>
    {
        // TODO: 处理参数或网络异常后重试
    }
);