Unity IAP 为中国境外的开发者提供了一个在中国市场发布应用程序的方便渠道。本指南将介绍 Unity Channel SDK,并描述开发者将 IAP 内容发布到 Xiaomi Mi Game Center 平台的端到端过程。
将游戏发布到 Mi Game Center 的过程分为三个步骤: 1.通过 Unity Cloud Build 提交小米配置的游戏包。 2.在 Xiaomi-Unity Developer Portal 中,填写游戏的商店元数据。 3. Xiaomi facilitates your game’s submission for review by the Chinese government and subsequent publication.
Mi Game Center 是小米的官方 Android 应用商店。用户在此商店中可以搜索、浏览和使用安全支付方法购买小米平台的商品。有关更多信息,请访问 Unity 的小米合作伙伴站点。
Unity Channel 是 Unity IAP 的一个内部组件,通过简化用户登录、支付管理以及中国政府应用程序分发监管审批过程,帮助中国境外的开发者访问中国应用商店市场。
由于采用了 Unity Channel,Mi Pay(小米支付)的集成过程与 Google Play 及 iTunes 在以下方面存在不同:
本部分介绍通过 Unity Editor 使用 Unity IAP SDK 配置游戏的过程:
小米仅支持 Android 平台的发布。针对 Android 进行项目配置的过程分为 4 步。
1.下载并安装 Android 和 Java SDK。有关更多信息,请参阅有关 Android 开发入门 (Getting started with Android development) 的文档。 2.设置 SDK 文件路径目标。在 Unity Editor 中,选择 Edit > Preferences__,然后从左侧导航栏中选择 External Tools。向下滚动到 Android__ 部分,然后设置 SDK 和 JDK 字段以反映分别安装 Android 和 Java SDK 的文件路径(请参阅下面的图 1.1;请注意,可选择每个字段旁边的 Download 按钮直接进入每个 SDK 的下载网页)。 3.设置应用程序的 Package Name。小米要求应用程序的 Package Name 遵循“BuildName.mi”惯例。选择 Edit > Project Settings > Player 以打开 Player Settings 窗口。然后,选择 Android 选项卡(请参阅下图),并在 Other Settings > Identification 下设置 Package Name 字段(请参阅下面的图 1.2)。 4.将项目发布到 Android。在 Editor 中,选择 File > Build Settings__,然后从菜单中选择 Android。选择 Build__ 可测试 Unity 是否能找到 SDK 并编译项目。
在 Editor 的 Services 窗口中启用 Unity IAP(__Window__ > __Services__;请参阅有关设置 Unity IAP 的文档)。在提示导入 IAP 资源包时,务必选择 Import(请参阅下图)。从版本 1.13.0 起,Unity IAP 资源包中包含 Unity Channel 和小米 SDK。
如果希望在不采用应用内购 (IAP) 的情况下将应用程序发布到 Mi Game Center,请从 Build Settings 窗口 (File > Build Settings) 中安装小米 Unity Channel 独立 SDK,具体操作是从 Platform 菜单中选择 Android__,然后从出现的 Xiaomi Game Center__ 菜单选项中选择 Add。
Unity Channel 包含一个资源,该资源提供用于管理应用商店凭据和测试模式功能的 Editor 界面。导入 Unity IAP 资源包时,此 AppStoreSettings 资源会安装到 Assets/Plugins/UnityChannel/XiaomiSupport/Resources 中。此外还可在 Editor 中通过选择 Assets > Create > App Store Settings 来手动创建该资源。选择该资源并查看 Inspector 即可访问这一界面。
注意:__AppStoreSettings__ 资源仅在 Unity 5.6 以上版本中可用。
为了进行通信,Unity 和小米服务器都要求您提供游戏的唯一标识符。请注意,您可以在此处通过将项目 ID 粘贴到搜索字段来检索您的 Unity 客户端凭据。Unity 5.3 或 5.4 用户必须以这种方式检索和设置凭据,因为他们不能访问 AppStoreSettings 资源。上图中显示的设置如下所述:
1.Generate Unity Client 按钮可填充与项目关联的 Unity 凭据。
注意:生成、加载或更新 Unity 客户端凭据会将联网的请求发送到 Unity 的后端服务器。此操作的进度会显示在控制台日志中。
2.Client ID 和 Client Key 是通过 Unity IAP 与 Unity Channel 后端及小米后端进行通信的必需字段。Unity Channel 后端将会代理收据验证请求(有关更多信息,请参阅有关 Unity IAP 接收验证的文档,以及 Unity Channel SDK 文档的__收据验证和扩展__部分)。
3.Client RSA Public Key 是可选的安全层。使用该字段可接收服务器回调以进行客户端收据验证,或可与 Unity 服务器 API 集成。
注意:__Client Secret__ 是用于实施服务器端验证的另一个可选安全层。Client Secret 是随其他凭据一起自动生成的。随时从 AssetStoreSettings 资源中选择 Update Client Secret 即可刷新它。
4.为游戏服务器提供可选的 Callback URL 可接收购买交易数据。
5.在提交过程中,小米将分发 App ID、App Key 和 App Secret 凭据。在提交最终版本供发布之前,必须将这些凭据保存到应用商店设置 (App Store Settings) 中。
6.Test Mode 是测试应用程序购买流程和提交到小米的必选字段。
在集成过程的各个位置需要用到这些凭据和测试模式切换开关。请注意,应用商店设置数据会在服务器端更新,而不是保存到客户端。
如果已启用 Unity IAP 来导入小米资源包,则不需要采取任何操作。否则,请参阅有关设置 Unity IAP 的文档以启用该服务。
此外还可以通过 Unity Asset Store 安装最新的 Unity IAP 插件。
Unity IAP 中内置的小米客户端 SDK 取决于客户端中可用的商品元数据。因此,必须通过 Editor 的 IAP Catalog GUI (Window > Unity IAP > IAP Catalog) 来定义商品。
填充目录: IAP Catalog GUI 定义了商品及其在游戏客户端运行时的元数据。有关 Codeless IAP 的文档包含了有关通过 IAP Catalog 进行商品配置的信息。小米平台需要特别注意以下商品属性:
1.ID 是 Mi Game Center 需要的唯一标识符(字符串数据类型)。 2.Type 指示商品的耐用性。小米支持可消耗和非消耗商品类型。它不支持订阅商品类型。 3.Descriptions 部分控制着在 Mi Store 中使用的 Title 和 Description 文本。必须从 Locale 下拉菜单中选择 Simplified Chinese__(这是目前唯一支持的语言)。 4.Pay Configuration__ 控制着商品的价格。Unity Channel SDK 支持小米预定义的中国人民币定价等级,而非任意值。
有关商品属性及其参数的更多信息,请参阅有关定义商品的文档。
在 Editor 的 IAP Catalog 窗口中,通过选择 App Store Export > Xiaomi Mi Pay Catalog 来导出目录。
将 MiGameProductCatalog.prop 文件导出到所选的位置。将商品目录导入到 Xiaomi Developer Portal 上,具体操作是导航至项目的 IAP Configuration 选项卡,然后选择 __Import__(请参阅下面有关导入 IAP 商品目录的部分)。
导出 IAP Catalog 还会将 MiGameProductCatalog.prop 文件的副本写入到项目的 Assets/Plugins/Android/assets/ 目录(请参阅下图)。Unity IAP 在 IAP Catalog 编辑器中以及在运行时使用此文件。如果未通过 Xiaomi Developer Portal 显式导入任何目录文件,则此目录还会用作应用程序的默认商品目录。
Unity IAP 通常需要一个配置构建器(此构建器使用要为目标应用商店解析的 IAP Catalog 数据),随后需要 Unity IAP Initialize()
API(请参阅有关初始化 IAP 的文档)。
小米游戏在初始化 IAP 之前需要一个额外步骤,因为 Mi Game Center 要求应用程序在启动时通过登录 API 共享其凭据。
修改后的初始化过程变为:
1.初始化 Unity Channel 小米 API。
2.登录 Unity Channel 小米 API。
3.通过运行配置构建器实例正常初始化 Unity IAP,然后调用 Unity IAP initialize()
API。
应在游戏的运行时生命周期中尽早(最好在启动时)执行这些步骤。您可以在同一脚本中实现它们。
以下示例说明如何使用 Unity Channel SDK 修改初始化以便调用登录 API:
using AppStoreSupport;
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Purchasing;
using UnityEngine.Store;
// 在游戏启动时运行一次脚本。
public class UnityChannelSample : MonoBehaviour
{
// 小米登录需要一个登录监听器。
//通过实现 Unity Channel SDK 中包含的 ILoginListener 抽象类来创建一个登录监听器。
class SampleLoginListener : ILoginListener
{
public Action initializeIAP;
//步骤 1 成功;调用步骤 2
public void OnInitialized()
{
Debug.Log("Initialization succeeded.");
UnityEngine.Store.StoreService.Login(this); // 如果初始化成功,则启动小米登录
}
// 步骤 1 失败;显示错误消息和帮助
public void OnInitializeFailed(string message)
{
Debug.Log("Initialization failed.");
}
// 步骤 2 完成;调用步骤 3
public void OnLogin(UserInfo userInfo)
{
Debug.Log(string.Format("Login successful: userId {0}, userLoginToken {1}, channel {2}", userInfo.userId, userInfo.userLoginToken, userInfo.channel));
// 登录成功时,继续初始化 IAP
initializeIAP();
}
// 步骤 2 失败;显示错误消息和帮助
public void OnLoginFailed(string message)
{
Debug.Log("Login failed.");
}
}
}
注意:必须使用上述示例代码中的所有函数,这些函数涵盖了登录过程的所有可能步骤。但是,您可以选择每个函数内调用的操作。在该示例中,调试文本取代了调用的操作。该示例中的 OnLogin() 方法用于启动 Unity IAP 初始化函数。
接下来,使用登录监听器以及存储在 AppStoreSettings 资源中的应用程序凭据来初始化小米 API:
void Awake()
{
// 根据 SamleLoginListener 类创建一个登录监听器
SampleLoginListener loginListener = new SampleLoginListener();
// 将 initializeIAP 操作(来自 SampleLoginListener 类)关联到一个函数(在下一步中定义)
loginListener.initializeIAP = ConfigureIAP;
// 访问 AppStoreSettings 资源以使用存储的凭据生成 AppInfo。AppStoreSettings 类属于 AppStoreSupport 库的一部分。
AppStoreSettings appStoreSettings = Resources.Load<AppStoreSettings>("AppStoreSettings");
// 使用凭据和登录监听器来初始化小米
UnityEngine.Store.StoreService.Initialize(appStoreSettings.getAppInfo(), loginListener);
}
在加载项目的 AppStoreSettings 资源时,getAppInfo()
函数将返回用于 Mi Game Center 商店初始化过程的凭据数据。
最后,使用配置构建器为小米转换 IAP Catalog 中的商品数据,然后初始化 Unity IAP:
// 配置构建器需要一个商店监听器。
// 通过实现 IStoreListener 抽象类来创建一个商店监听器。
class StoreListener : IStoreListener
{
private IStoreController controller;
private IExtensionProvider extensions;
// 当 Unity IAP 准备好进行购买时调用。
public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
{
this.controller = controller;
this.extensions = extensions;
}
//请注意,如果互联网不可用,则不会调用此项;
// Unity IAP 会在互联网变为可用状态后尝试进行初始化。
public void OnInitializeFailed(InitializationFailureReason error)
{
}
//购买完成时或 Unity IAP 遇到不可恢复的初始化错误时调用;
// 可能在 OnInitialized() 之后的任何时间调用。
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e)
{
return PurchaseProcessingResult.Complete;
}
//购买失败时调用。
public void OnPurchaseFailed(Product i, PurchaseFailureReason p)
{
}
}
//运行配置构建器以定义商品
public void ConfigureIAP()
{
// 加载来自 IAP Catalog 中的商品
var module = StandardPurchasingModule.Instance();
var builder = ConfigurationBuilder.Instance(module);
var catalog = ProductCatalog.LoadDefaultCatalog();
// 对目录中的商品循环操作,将元数据提取到构建器
foreach (var product in catalog.allProducts)
{
if (product.allStoreIDs.Count > 0)
{
var ids = new IDs();
foreach (var storeID in product.allStoreIDs)
{
ids.Add(storeID.id, storeID.store);
}
builder.AddProduct(product.id, product.type, ids);
}
else
{
builder.AddProduct(product.id, product.type);
}
}
// 根据 StoreListener 类创建商店监听器
StoreListener storeListener = new StoreListener();
// 初始化 Unity IAP
UnityPurchasing.Initialize(storeListener, builder);
}
配置构建器引用商品 ID (Product IDs) 和商品类型 (Product Types) 来自动填充价格 (Price)、类型 (Type)、名称 (Title) 和描述 (Description) 元数据。它会使用 IAP Catalog 的 IAPProductCatalog.json 文件以及 Unity IAP 初始化过程中实例化的 builder
对象。
有关游戏内购买实现方法的信息,请参阅以下相关文档:
通过在 AppStoreSettings 资源界面中切换测试模式,在非小米 Android 设备上测试游戏的购买流程。Unity Channel 还提供了一个用于切换测试模式的 API:
AppInfo.debug = true;
Unity Channel 包装器包含 AppInfo
类,并将数据传递给小米 SDK。要将应用程序提交给小米,必须启用测试模式。测试模式也会出于测试目的而绕过信用卡要求。启用测试模式后,应编译项目并从 Android 设备启动生成的 APK 文件。
要测试实际购买情况,请将测试模式设置为 false 并在小米设备上进行测试。请注意,实际购买时要求具有 Xiaomi Mi Pay 帐户和适当的货币(如人民币)。
本部分介绍通过 Unity Editor 使用 Unity IAP SDK 提交游戏的过程:
1.设置 IAP 目标 2.测试 IAP 集成 3.注册应用程序 4.将游戏推送到 Xiaomi Portal
在 Unity Editor 中,通过选择 Window > Unity IAP > Android > Target Xiaomi Mi Game Pay 将 Unity IAP 目标设置为 Mi Game Pay。这样可以让小米成为游戏 APK 的下一次发布目标平台。此外还会创建配置文件以便在运行时通知 Unity IAP 使用 Xiaomi Mi Pay 原生计费 API。
在推送到小米之前,应对游戏进行试编译:在本地进行编译或者在 Unity Cloud Build 中将项目配置为 Android 编译目标后再进行编译(请参阅有关 Cloud Build 的文档)。
在 Editor 中通过 Unity Services 窗口启用 Cloud Build(请参阅有关 Cloud Build 实现的文档)。
使用以下两种方法之一将编译文件上传到项目的编译历史记录:
通过 Editor:
1.在 Cloud Build Services 窗口中,选择 Manage Target Builds > Add New Target。 2.在 TARGET SETUP 菜单中,将 PLATFORM 字段设置为 Android 并输入有用的 TARGET LABEL。然后,选择 Next: Save。 3.选择 __Start Cloud Build__,然后选择刚才创建的目标编译文件。
通过 Unity Cloud Build 开发者控制面板 (Developer Dashboard):
1.导航至项目的 Cloud Build History。 2.选择 __Upload__,然后选择在 Editor 中编译的 APK 文件。
使用以下两种方法之一将托管的编译文件推送到 Xiaomi Developer Portal:
通过 Editor:
在 Cloud Build Services 窗口中,根据编译历史记录时间轴找到所需的编译文件,然后选择 Push to Xiaomi。确认想要推送,然后确认操作完成。
通过 Unity Cloud Build 开发者控制面板 (Developer Dashboard):
1.导航至项目的 Cloud Build History。 2.选择 Download .APK file__,然后从下拉菜单中选择 Push to Xiaomi__。
您的 UDN 凭据可授权访问在 Xiaomi Unity Developer Portal 中上传的项目。首次登录时,必须先确认小米的条款和条件,然后再继续进入 Projects 列表。找到想要提交的项目。该项目的状态(下面突出显示处)最初显示为 Version1.0: Draft。选择剪贴板图标可查看项目全程状态变化的提交日志。选择状态链接可展开项目的元数据详细信息。
下图显示了详细信息:
本部分包含要在 Mi Game Center 显示的文本。
本部分包含在 Mi Game Center 显示的适用于手机和平板电脑设备的营销资源。请注意以下原则:
准备好后,请选择 Submit 以将游戏提交给小米供审查。项目的状态标识变为 In review。当项目处于审查状态时,无法编辑其详细信息。展开项目再选择 Cancel 即可取消审查并修改项目的详细信息。
您需要有 ISBN 出版许可证才能发布应用程序。小米为您通过中国国家新闻出版广电总局 (SAPPRFT) 的 ISBN 审批流程提供全面的支持。
小米不保证 SAPPRFT 会批准所有游戏(请参阅 SAPPRFT 提交指南)。为了满足应用商店和国家合规规则,您可能需要对游戏进行一些更改。
提交中国政府审批时,请注意以下提示:
在完成提交之前,请按照以下步骤确保小米拥有最新的 IAP 商品目录:
1.选择项目,然后从左侧导航栏中选择 IAP Configuration。 2.选择 Import。 3.导入您从项目中导出的 MiGameProductCatalog.prop 文件。 4.验证目录的内容,然后选择 Confirm。 5.随后将显示导入商品的列表。选择 Submit 即可提交该目录。
当小米表示批准时,项目状态将变为 Approved 并收到以下凭据:
在 AppStoreSettings 资源或初始化脚本中输入这些凭据值,然后将测试模式设置为 false
。创建新的游戏编译文件,然后像之前一样将此编译文件推送到小米。
小米通过电子邮件提供一份开发者合同。一旦您签订合同,小米便会推动政府审批程序。当游戏收到 ISBN 许可证并获准发布到 Mi Game Center 时,小米会通知您。
小米的内容审查过程通常需要 1–2 个工作日(除非小米建议更改游戏内容)。不过,政府审批程序和许可证分发过程可能需要 4–8 个月的时间。有关审查过程的更多信息,请参阅 Unity-Xiaomi 合作伙伴页面的常见问题解答 (FAQ) 部分。