最佳实践
准备工作
创建应用获取应用参数
在 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/TapSDKCore-Unity.git#4.3.10",
"com.taptap.sdk.login":"https://github.com/taptap/TapSDKLogin-Unity.git#4.3.10",
"com.taptap.sdk.compliance":"https://github.com/taptap/TapSDKCompliance-Unity.git#4.3.10",
"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.uniontId;
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: 处理参数或网络异常后重试
}
);