正版验证开发指南
从 TapSDK 4.7.1 版本开始支持使用 TapTap PC 端完成正版验证和使用 DLC 功能,使用前需接入启动校验,具体参考 TapTap PC 端集成 文档
正版验证适用于在 TapTap 上架的付费下载游戏。 游戏集成 TapSDK 的正版验证之后,当玩家启动游戏时(包含卸载后再次安装),SDK 会前往 TapTap 查询玩家是否已购买游戏:
- 如已购买,则可正常进入游戏。
- 如查询到未购买,在 Android 端将出现「游戏未激活,请前往 TapTap 购买此游戏」弹窗,玩家必须选择「打开 TapTap」购买之后才能游玩;在 PC 端调用启动校验时会返回失败
权限说明
- Unity
- Android Java
- Android Kotlin
该模块需要访问设备中已安装的 Tap 客户端信息,在 Android 11 且工程 targetVersion > 29 时需要
开发者在应用 AndroidManifest.xml 中添加如下配置:
<queries>
<package android:name="com.taptap" />
<package android:name="com.taptap.pad" />
<package android:name="com.taptap.global" />
</queries>
该模块将在应用中添加如下权限:
<uses-permission android:name="android.permission.REORDER_TASKS" />
该模块需要访问设备中已安装的 Tap 客户端信息,在 Android 11 且工程 targetVersion > 29 时需要
开发者在应用 AndroidManifest.xml 中添加如下配置:
<queries>
<package android:name="com.taptap" />
<package android:name="com.taptap.pad" />
<package android:name="com.taptap.global" />
</queries>
该模块将在应用中添加如下权限:
<uses-permission android:name="android.permission.REORDER_TASKS" />
SDK 获取
可以在 下载页 获得 TapSDK,添加以下依赖:
- Unity
- Android Java
- Android Kotlin
第一步:添加 SDK 所需的外部依赖
SDK 内部使用了部分第三方库,开发者接入时需先确保 SDK 外部依赖库已正常接入,具体设置如下:
- SDK 使用的 JSON 解析库为
Newtonsoft-json,如果当前工程已接入该依赖库,则不需额外处理,否则需在Packages/manifest.json添加如下依赖:
"com.unity.nuget.newtonsoft-json":"3.2.1"
- SDK 使用
com.google.external-dependency-manager管理 Android、iOS 依赖,如果当前工程已接入该依赖库,则不需额外处理,否则需在Packages/manifest.json添加如下依赖:
{
"dependencies": {
"com.google.external-dependency-manager": "1.2.179"
},
"scopedRegistries": [
{
"name": "package.openupm.com",
"url": "https://package.openupm.com",
"scopes": [
"com.google.external-dependency-manager"
]
}
]
}
第二步:添加 SDK 依赖
SDK 支持 Unity Package Manager 及本地文件导入两种集成方式,开发者根据需求选择其中一种即可,推荐使用远程依赖。
远程依赖
SDK 支持通过 NPMJS 及 GitHub 两种方式,开发者选择其中一种即可。
1. NPMJS 接入
在项目的 Packages/manifest.json 文件中添加以下依赖:
"dependencies":{
"com.taptap.sdk.core":"4.8.4",
"com.taptap.sdk.license":"4.8.4",
}
但需要注意的是,需在 Packages/manifest.json 中 dependencies 同级下声明 scopedRegistries:
"scopedRegistries":[
{
"name": "NPMJS",
"url": "https://registry.npmjs.org/",
"scopes": ["com.taptap"]
}
]
2. GitHub 接入
在项目的 Packages/manifest.json 文件中添加以下依赖:
"dependencies":{
"com.taptap.sdk.core":"https://github.com/taptap/tapsdk-unity-dist.git?path=/Core#4.8.4",
"com.taptap.sdk.license":"https://github.com/taptap/tapsdk-unity-dist.git?path=/License#4.8.4",
}
说明:自 4.7.2 起,Unity Packages 仓库已统一为大仓
tapsdk-unity-dist,所有包通过目录区分并使用?path=指定子目录、#指定版本标签。例如 Core 模块:"com.taptap.sdk.core": "https://github.com/taptap/tapsdk-unity-dist.git?path=/Core#4.7.2"
在 Unity 顶部菜单中选择 Window > Package Manager 可查看已经安装在项目中的包。
本地文件导入
- 在 下载页 下载下列模块对应
unitypackage文件,并在 Unity 项目中依次通过 Assets > Import Packages > Custom Packages 进行导入,包括:
TapSDK_Core.unitypackageTapSDK 基础库,必选。TapSDK_License.unitypackageTapTap 正版验证库,必选。
- 如果当前项目已集成
Newtonsoft.Json依赖,则忽略该步骤,否则在NuGet.orgNewtonsoft.Json 页面中通过点击右侧 「Download package」 下载库文件,并将下载的文件后缀从.nupkg修改为.zip,同时解压该文件并复制内部的Newtonsoft.Json.dll文件拷贝到工程Assets的Plugins目录下,另外为了避免导出 IL2CPP 平台时删除必要数据,需在Assets目录下创建link.xml文件(如果已有该文件,则添加如下内容),其内容如下:
<linker>
<assembly fullname="System.Core">
<type fullname="System.Linq.Expressions.Interpreter.LightLambda" preserve="all" />
</assembly>
</linker>
- 项目根目录的 build.gradle 添加仓库地址:
allprojects {
repositories {
google()
mavenCentral()
}
}
- app module 的 build.gradle 添加对应依赖:
dependencies {
implementation 'com.taptap.sdk:tap-core:4.8.4'
implementation 'com.taptap.sdk:tap-license:4.8.4'
}
- 项目根目录的 build.gradle 添加仓库地址:
allprojects {
repositories {
google()
mavenCentral()
}
}
- app module 的 build.gradle 添加对应依赖:
dependencies {
implementation 'com.taptap.sdk:tap-core:4.8.4'
implementation 'com.taptap.sdk:tap-license:4.8.4'
}
SDK 初始化
- Unity
- Android Java
- Android Kotlin
TapTapSdkOptions 详细参数见 入门指南#快速开始
using TapSDK.Core;
// 核心配置 详细参数见 [TapTapSDK]
TapTapSdkOptions coreOptions = new TapTapSdkOptions();
// TapSDK 初始化
TapTapSDK.Init(coreOptions);
TapTapSdkOptions 详细参数见 入门指南#快速开始
import com.taptap.sdk.core.TapTapRegion;
import com.taptap.sdk.core.TapTapSdk;
import com.taptap.sdk.core.TapTapSdkOptions;
/* 必选配置 */
// 开发者中心对应 Client ID
String clientId = "";
// 开发者中心对应 Client Token
String clientToken = "";
// 是否开启 log,建议 Debug 开启,Release 关闭,默认关闭 log
boolean enableLog = BuildConfig.DEBUG;
TapTapSdkOptions tapSdkOptions = new TapTapSdkOptions(
clientId, // 游戏 Client ID
clientToken, // 游戏 Client Token
TapTapRegion.CN // 游戏可玩区域: [TapTapRegion.CN]=国内 [TapTapRegion.GLOBAL]=海外
);
tapSdkOptions.setEnableLog(enableLog);
// 初始化 TapSDK
TapTapSdk.init(context, tapSdkOptions);
TapTapSdkOptions 详细参数见 入门指南#快速开始
import com.taptap.sdk.core.TapTapSdk
import com.taptap.sdk.core.TapTapSdkOptions
import com.taptap.sdk.core.TapTapRegion
import com.taptap.sdk.core.TapTapLanguage
TapTapSdk.init(
context = context,
sdkOptions = TapTapSdkOptions(
clientId = clientId,
clientToken = clientToken,
region = TapTapRegion.CN,
preferredLanguage = TapTapLanguage.ZH_HANS,
enableLog = false
)
)
正版验证
设置授权回调
可注册多个回调,
- Unity
- Android Java
- Android Kotlin
// 需要引入 `License` 库
using TapSDK.License;
// 默认情况下 SDK 会弹出不可由玩家手动取消的弹窗来避免未授权玩家进入游戏,如果需要回调来触发流程,请添加如下代码
TapTapLicense.RegisterLicenseCallBack(ITapLicenseCallback callback);
public interface ITapLicenseCallback
{
// 授权成功回调
void OnLicenseSuccess();
// 授权验证失败回调,仅当 PC 端用户完成退款时触发
void OnLicenseFailed();
}
import com.taptap.sdk.license.TapTapLicense;
import com.taptap.sdk.license.TapTapLicenseCallback;
// 默认情况下 SDK 会弹出不可由玩家手动取消的弹窗来避免未授权玩家进入游戏,如果需要回调来触发流程,请添加如下代码
TapTapLicense.registerLicenseCallback(new TapTapLicenseCallback() {
@Override
public void onLicenseSuccess() {
// 授权成功
}
});
import com.taptap.sdk.license.TapTapLicense
import com.taptap.sdk.license.TapTapLicenseCallback
// 默认情况下 SDK 会弹出不可由玩家手动取消的弹窗来避免未授权玩家进入游戏,如果需要回调来触发流程,请添加如下代码
TapTapLicense.registerLicenseCallback(object : TapTapLicenseCallback {
override fun onLicenseSuccess() {
// your code
}
})
检查是否购买游戏
在 Android 端 Check 方法中参数默认值为 false,表示为 SDK 首次触发以及在距离首次触发的第 5 天之后再一次会通过 TapTap 客户端来确认当前登录 用户是否购买游戏,如果使用 true 的话,则每次接口调用都会通过 TapTap 客户端来确认当前登录用户是否购买过游戏。
在 PC 端 Check 方法中参数无效,SDK 始终会通过 TapTap PC 端完成校验。
- Unity
- Android Java
- Android Kotlin
using TapSDK.License;
// 普通检查
TapTapLicense.CheckLicense();
// 强制检查
TapTapLicense.CheckLicense(true);
import com.taptap.sdk.license.TapTapLicense;
// 普通检查
TapTapLicense.checkLicense(activity);
// 强制检查
TapTapLicense.checkLicense(activity, true);
import com.taptap.sdk.license.TapTapLicense
// forceCheck参数可不传,默认为false
TapTapLicense.checkLicense(activity: Activity, forceCheck: Boolean)
Android 11 及更高版本的适配
Android 11(API level 30)之后加强了隐私保护策略,引入了大量变更和限制,其中一个重要变更——软件包可见性,将会导致第三方应用无法拉起 TapTap 客户端,从而影响 TapTap 相关功能的正常使用,包括但不限于更新唤起 TapTap、购买验证等功能。
如果没有完成适配,Android 版本为 11 及更高版本的客户端打开游戏会提示「本游戏需要最新版 TapTap 服务支持」,无法正常进入游戏。异常呈现如下图所示:

对此提供如下两种适配方案:
方案一:
编译时将 targetSdkVersion 改为 29(目前设置成 >= 30 会触发该问题)。
方案二:
-
将 gradle build tools 改为 4.1.0+:
classpath 'com.android.tools.build:gradle:4.1.0' -
在 AndroidManifest.xml 里添加
<queries>标签中的内容:<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="string">
<application
. . .
</application>
<!--添加如下 queries 标签的内容,直接在 manifest 标签下-->
<queries>
<package android:name="com.taptap" />
<package android:name="com.taptap.pad" />
<package android:name="com.taptap.global" />
</queries>
</manifest>
DLC
请确保:
- DLC 商品已正确创建并审核通过,否则 DLC 查询和购买不会成功。DLC 商品配置事项详见 DLC 商品文档。
- 商店资料(路径:商店 - 游戏资料 - 商店资料)中填写 APK 包名并处于已上线状态。
设置查询和购买回调
DLC 回调包含查询回调和购买回调。
- Unity
- Android Java
- Android Kotlin
using TapSDK.License;
public class MyTapDLCCallback:ITapDlcCallback
{
public void OnQueryCallBack(TapLicenseQueryCode code, Dictionary<string, object> queryList)
{
// 查询回调
}
public void OnOrderCallBack(string sku, TapLicensePurchasedCode status)
{
// 购买回调
// 在 Android 端当用户购买成功/失败时触发
// 在 PC 端当用户在 TapTap PC 端完成商品购买或退款时触发
}
}
TapTapLicense.RegisterDLCCallback(new MyTapDLCCallback());
import com.taptap.sdk.license.TapTapDLCCallback;
import com.taptap.sdk.license.TapTapLicense;
TapTapLicense.registerDLCCallback(new TapTapDLCCallback() {
@Override
public void onQueryResult(int resultCode, @Nullable HashMap<String, Integer> resultList) {
// 查询回调
}
@Override
public void onPurchaseResult(@NonNull String skuId, int status) {
// 购买回调
}
});
import com.taptap.sdk.license.TapTapLicense
import com.taptap.sdk.license.TapTapDLCCallback
TapTapLicense.registerDLCCallback(object : TapTapDLCCallback {
override fun onQueryResult(resultCode: Int, resultList: HashMap<String, Int>?) {
// 查询回调
}
override fun onPurchaseResult(skuId: String, status: Int) {
// 购买回调
}
})
Android 端:购买回调仅在主动调用购买商品接口时触发
PC 端:任何在 TapTap 客户端完成支付或退款操作均会触发购买回调,与是否调用购买商品接口无关。
回调参数说明
查询回调中参数 TapLicenseQueryCode 表示查询结果, 取值范围如下:
| 回调 | 回调值 | 说明 |
|---|---|---|
| QUERY_RESULT_OK | 0 | 查询成功 |
| QUERY_RESULT_NOT_INSTALL_TAPTAP | 1 | 检查测试机未安装 TapTap 客户端,仅 Android 端返回 |
| QUERY_RESULT_ERR | 2 | 查询失败 |
| ERROR_CODE_UNDEFINED | 80000 | 未知错误 |
当查询成功时,参数 queryList 为键值对类型的具体数据,其中 key 为查询的商品 skuid,value 表示该商品的购买状态:0 表示未购买,1 表示已购买。
购买回调中参数 sku 为购买的商品 skuid,参数 TapLicensePurchaseCode 为购买结果,取值范围如下:
| 回调 | 回调值 | 说明 |
|---|---|---|
| DLC_NOT_PURCHASED | 0 | 未完成支付 |
| DLC_PURCHASED | 1 | 支付成功 |
| DLC_RETURN_ERROR | -1 | 支付异常 |
查询购买状态
通过商品 skuId 数组批量查询多个商品购买状态,结果通过查询回调返回。
- Unity
- Android Java
- Android Kotlin
TapTapLicense.QueryDLC(string[] skuIds);
import com.taptap.sdk.license.TapTapLicense;
List<String> skuList = new ArrayList<>();
skuList.add("skuId1");
skuList.add("skuId2");
TapTapLicense.queryDLC(activity, skuList);
import com.taptap.sdk.license.TapTapLicense
TapTapLicense.queryDLC(activity: Activity, skuIds: List<String>)
购买商品
通过商品 skuId 发起购买,结果通过购买回调返回。
- Unity
- Android Java
- Android Kotlin
TapTapLicense.PurchaseDLC(string skuId);
import com.taptap.sdk.license.TapTapLicense;
TapTapLicense.purchaseDLC(activity, "skuId");
import com.taptap.sdk.license.TapTapLicense
TapTapLicense.purchaseDLC(activity: Activity, skuId: String)
skuId
请前往 DLC 商品 查看如何创建 DLC 商品并获得 skuid。
如何测试
完成 SDK 接入后,买断制游戏白名单中的用户即可自测。详细自测流程参考接入与自测