聚合渠道SDK-Harmony(ArkTS)

1 文档修订记录

文档版本 文档更新日期 文档更新内容
3.3.55 2024.04.28 鸿蒙SDK1.0

2 接入准备

支持 devEco Studio 接入

2.1 导入SDK

工程目录下新建libs文件夹,将平台提供的 .har文件 到工程的 libs 目录中

2.2 配置 oh-package.json5

打开工程的 oh-package.json5

  • 拷贝以下代码到 devDependencies 字段下。
   "@ohos/FYCore": "file:./lib/FYCore.har",
   "@ohos/FYCombine": "file:./lib/FYCombine.har",
   "@ohos/FYThird": "file:./lib/FYThird.har"

图片

然后clean项目

2.3 添加SDK配置

1.将平台提供的fyconfig.json文件,拷贝到工程目录AppScope/
resources/base/element目录下
图片

2.4 配置鸿蒙登录参数

1、登录AppGallery Connect平台,在“我的项目”中选择目标应用,获取“项目设置 > 常规 > 应用”的APP ID和Client ID。
图片

2、在工程中entry模块的module.json5文件中,新增metadata并配置 client_id 和 app_id:

  "metadata": [ // 配置如下信息
    {
      "name": "client_id",
      "value": "xxxxxx"  //配置为前面步骤中获取的Client ID
    },
    {
      "name": "app_id",
      "value": "xxxxxx"  //配置为为前面步骤中获取的APP ID
    }
  ];

图片

2.5 添加权限

在工程中entry模块的module.json5文件中,新增网络权限配置:

"requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      }
    ]

图片

2.6 添加类引用

如果ets文件添加类引用

import { FYAPP, FYCombineInitInfo, FYCombinePayInfo, FYResponse } from '@ohos/FYCore';
import { FYCombine } from '@ohos/FYCombine'
import {  emitter } from '@kit.BasicServicesKit';

如果ts文件添加类引用

import { FYAPP, FYCombineInitInfo, FYCombinePayInfo, FYResponse } from '@ohos/FYCore';
import { FYCombine } from '@ohos/FYCombine/exportTs'
import {  emitter } from '@kit.BasicServicesKit';

3 界面跳转标准规范

为了您能快速接入,并避免大多数对接问题,请按照标准规范来对接。

3.1 登录流程

登录流程

3.2 首屏-切换账号流程

首屏-切换账号流程

3.3 游戏中-切换账号流程

游戏中-切换账号流程

4 客户端接口

接口接入的要诀?

  • 必接接口一定要接入,选接接口根据需要接入

  • 必传参数一定要传,能传的参数尽量都传

  • 所有的生命周期接口一定要接入

4.1 初始化(必接)

1.说明

  • 游戏需要在刚启动游戏的时候调用

  • 初始化接口init应该在游戏主界面加载后第一时间调用,一般在EntryAbility的onWindowStageCreate生命周期函数中调用:

2.调用

 FYAPP.getInstance().init(context)
 FYAPP.getInstance().setContext(context);

 let  initInfo :FYCombineInitInfo = new FYCombineInitInfo();
 initInfo.gameVersion="xxx";

 FYCombine.getInstance().doInit(context, initInfo).then((response) => {

      // 初始化回调
      // 游戏应在确保收到此回调后才能调用聚合渠道模块的其他接口
      // 游戏不需管是否初始化成功,只要关心有没有收到初始化回调即可,也不需要重新调用初始化,SDK内部自己会处理初始化失败的情况
      //
      // TODO: 初始化完成
      let status = response.status; // 初始化状态 成功 status:0
      let message = response.message;// 返回信息
      //游戏有用到聚合 SDK 的一些配置参数,可以从此处获取。

      //设备 ID,此 ID 为 SDK 生成的标识设备的唯一 ID
      let deviceId = response.getDataValue("device_id");
      //APP ID
      let appId = response.getDataValue("app_id");
      //通行证标识,用来标明该渠道用什么通行证进行登录,如果游戏要对不同通行证做差异化处理时,可以使用此标识作为区分
      let passportCode = response.getDataValue("passport_code");
      //获取渠道ID,如果游戏要对渠道做差异化处理时,可以使用此ID作为区分;渠道ID列表,请查看星云平台->对接中心->渠道打包->渠道配置;
      let channelId = response.getDataValue("channel_id");
      // 支付标识,用来标明该渠道用什么支付方式,一般和通行证代号一致,有一些特殊的渠道登录和支付不一致,例如:苹果渠道,登录是飞鱼通行证(feiyu3),支付则是苹果支付(apple),
      let paymentCode = response.getDataValue("payment_code");

    }).catch((err: FYResponse) => {
        // 返回失败信息
        let str = JSON.stringify(err.toJson());
    });

3.参数

参数名 说明 是否必传
context UIAbilityContext
gameVersion 游戏版本号

4.2 登录(必接)

1.说明

  • 启动完游戏显示首页时调用。

  • 玩家点击游戏界面的「进入游戏」时,需要判断是否有登录成功,如有则可以进入游戏;否则再次调用登录接口,让玩家重新登录,直到登录成功。

2.调用

 FYCombine.getInstance().doLogin(context).then((response) => {

            if (response.status == FYResponse.SUCCESS) {
             // 游戏维度唯一用户ID
              let openId = response.getDataValue("open_id");
              // 登录校验码,有效时间 7天,请在有效时间内完成校验,如超出时间需重新调用登录接口获取新校验
              let token = response.getDataValue("token");
              // 第三方用户ID
              let userId = response.getDataValue("user_id");
              // 全渠道唯一用户ID
              let unionId = response.getDataValue("union_id");
              // 渠道ID
              let channelId = response.getDataValue("channel_id");
              // 身份证生日,格式:"1991-12-31"(有可能空)
              let identityBirthday = response.getDataValue("identity_birthday");
              // 身份证年龄(有可能空)
              let identityAge = response.getDataValue("identity_age");
              // 支付标识
              let paymentCode = response.getDataValue("payment_code");
              // 通行证标识
              let passportCode = response.getDataValue("passport_code");
              // TODO: 登录成功
              // TODO: 请求游戏服务端验证登录
            }

          }).catch((err: FYResponse) => {
           if (err.status == FYResponse.LOGIN_CANCEL) {
              // TODO: 登录取消
            } else {
              // TODO: 登录失败
            }
          });

3.参数

参数名 说明 是否必传
context UIAbilityContext

4.3 切换账号(必接)

1.说明

  • 在需要切换用户时调用,该接口会弹出登录窗口,让用户重新登录。

  • 与「用户登录」接口不同的是,登录接口非首次登录会自动登录,而此接口必定会弹出登录窗口。

2.调用

 FYCombine.getInstance().doSwitchAccount(context).then((response) => {

            if (response.status == FYResponse.SUCCESS) {
            // 游戏维度唯一用户ID
              let openId = response.getDataValue("open_id");
              // 登录校验码,有效时间 7天,请在有效时间内完成校验,如超出时间需重新调用登录接口获取新校验码
              let token = response.getDataValue("token");
              // 第三方用户ID
              let userId = response.getDataValue("user_id");
              // 全渠道唯一用户ID
              let unionId = response.getDataValue("union_id");
              // 渠道ID
              let channelId = response.getDataValue("channel_id");
              // 身份证生日,格式:"1991-12-31"(有可能空)
              let identityBirthday = response.getDataValue("identity_birthday");
              // 身份证年龄(有可能空)
              let identityAge = response.getDataValue("identity_age");
              // 支付标识
              let paymentCode = response.getDataValue("payment_code");
              // 通行证标识
              let passportCode = response.getDataValue("passport_code");
              // TODO: 登录成功
              // TODO: 请求游戏服务端验证登录

            }

          }).catch((err: FYResponse) => {
            if (err.status == FYResponse.LOGIN_CANCEL) {
              // TODO: 登录取消
            } else {
              // TODO: 登录失败
            }

          });

3.参数

参数名 说明 是否必传
context UIAbilityContext

4.4 支付(选接)

1.说明

  • 调用此接口将拉起支付界面

  • 建议游戏制定的商品标识格式为:com.feiyu.app_id.xxxx,以保证商品 id 的唯一性

  • 打开"星云平台->对接中心->SDK对接->SDK列表->基础接入参数->游戏支付回调地址",配置游戏服务端的支付回调地址,支付完成后会通过此地址回调支付结果
    图片

  • 客户端的支付回调不能作为支付成功的依据,不能在此处发放道具。判断支付是否成功要根据服务端的支付回调。具体的服务端回调请看服务端接入文档

  • 客户端的支付回调只可以用来控制游戏界面显示,例如loading框的关闭、遮罩层的关闭

  • 商品ID需要配置到华为后台,才能拉起支付

2.调用

let payInfo: FYCombinePayInfo = new FYCombinePayInfo();
payInfo.playerId = "role_id_001";
payInfo.playerName = "role_name_001";
payInfo.playerLevel = "1";
payInfo.serverId = "1";
payInfo.serverName = "server_name_001";
payInfo.goodsId = "com.feiyu.20001.store1";
payInfo.goodsName = "测试商品1";
payInfo.vipLevel = "1";
payInfo.payAmount = "100";
payInfo.gameOrderId = "";
payInfo.notifyExt = "extra";
payInfo.paySignType = "md5";
payInfo.notifyURL = "";

FYCombine.getInstance().doPay(context, payInfo).then((response => {
            // 支付回调
            // 此回调不能作为支付成功的依据,故游戏不能在此处发放道具,游戏需要根据服务端的支付回调作为支付是否成功的依据,具体的服务端回调请看「服务端接入文档」https://help.737.com/archives/docs/detail/channel_combine/sdk/server
            // 此回调只可以用来控制游戏界面显示,例如 loading 框的关闭、遮罩层的关闭
            // 支付成功
            if (response.status == FYResponse.SUCCESS) {
            // 星云订单号
              let orderId = response.getDataValue("order_id");
              // 游戏订单号
              let gameOrderId = response.getDataValue("game_order_id");
            }
          })).catch((err: FYResponse) => {
            if (err.status == FYResponse.PAY_CANCEL) {
              //支付取消
              // 星云订单号
              let orderId = err.getDataValue("order_id");
              // 游戏订单号
              let gameOrderId = err.getDataValue("game_order_id");
            } else if (err.status == FYResponse.PAY_UNKNOWN) {
              //支付状态未知
              // 第三方渠道没有给明确的客户端支付状态,建议游戏提示“如若购买成功,稍后即到账”类似的不是很明确的提示。
              // 星云订单号
              let orderId = err.getDataValue("order_id");
              // 游戏订单号
              let gameOrderId = err.getDataValue("game_order_id");
            } else {
              //支付状态失败
              // 星云订单号
              let orderId = err.getDataValue("order_id");
              // 游戏订单号
              let gameOrderId = err.getDataValue("game_order_id");
            }
          })

3.参数

参数名 说明 是否必传
context UIAbilityContext
playerId 角色id。对应服务端支付回调的player_id参数
playerName 角色名
playerLevel 角色等级,数字格式
serverId 区服id,数字格式。对应服务端支付回调的server_id参数
serverName 区服名称
goodsId 商品标识,规范格式:com.feiyu.app_id.xxxx,例: com.feiyu.20001.store1 。对应服务端支付回调的goods_id参数
goodsName 商品名称
payAmount 支付金额,单位:分 (海外游戏传美分),数字格式。对应服务端支付回调的total_amount参数
gameOrderId 游戏订单号,由游戏生成并管理,服务端支付验证的时候会用到。对应服务端支付回调的out_trade_no参数
notifyExt 额外参数,游戏的透传参数可通过此参数传递,支付完成后平台服务端会回调此参数给游戏服务端。对应服务端支付回调的notify_ext参数
vipLevel vip等级,数字格式,如果游戏没有vip等级则传"0"
paySignType 签名类型,游戏服务器接收回调通知签名方式,需要游戏传递:md5/rsa
notifyURL 1.通过该值能在客户端动态传递服务端支付回调地址;2.若您在客户端传递了该地址,则支付完成后会通过此地址回调支付结果;3.若您同时也在星云后台配置了支付回调地址,会优先回调客户端传递的地址;4.需要先配置支付回调可信域名,请前往"星云后台->对接中心->回调配置->支付回调可信域名"进行配置,否则无法回调成功;5.若您在客户端传递了该地址,在游戏包体发布之前,建议您仔细检查该参数是否配置正确,以防止包体发布后支付出现问题

4.5 用户中心(必接)

1.说明

  • 需在游戏内的设置界面,放置一个「用户中心」按钮,点击按钮调用此接口

  • 调用此接口将弹出用户中心界面

2.调用

FYCombine.getInstance().doUserCenter(context)

3.参数

参数名 说明 是否必传
context UIAbilityContext

4.6 登出回调(必接)

1.说明

  • 点击用户中心里面切换账号按钮主动触发
  • 游戏在此处判断是否在游戏内,如果在游戏内则退出到登录首页
  • 初始化后设置回调监听

2.调用

let innerEvent: emitter.InnerEvent = {eventId:FYResponse.LOGIN_OUT};
 // 收到eventId为FYResponse.LOGIN_OUT的事件后执行回调函数
 emitter.on(innerEvent, (data) => {
 //退出到游戏首页
 });          

3.参数

参数名 说明 是否必传
context UIAbilityContext

4.7 登出(选接)

1.说明

  • 登出 SDK,并回调登出回调给游戏。

2.调用

FYCombine.getInstance().doLogout(context).then((response=>{
   // TODO: 登出成功
 }));

3.参数

参数名 说明 是否必传
context UIAbilityContext

4.8 退出游戏(选接)

1.说明

  • 当用户按手机返回键,意图退出应用时调用。

2.调用

FYCombine.getInstance().doExitGame(context).then((response=>{
     // TODO: 关闭应用

  })).catch((err: FYResponse) => {
     // TODO: 弹出游戏自定义的退出框

   })

3.参数

参数名 说明 是否必传
context UIAbilityContext

4.9 第三方收集信息(选接)

1.说明

  • 用于收集第三方SDK收集游戏数据。
  • 如果有出"鸿蒙"渠道,请对接此接口,否则上架渠道会被拒。

2.调用

let info = new Map<string, string> ();
info.set("method","xxx"); //method (进入区服:enterServer,创建角色:createRole ,角色升级:levelUp) 
info.set("playerId","xxx");//角色ID
info.set("playerName","xxx");//角色名称
info.set("playerLevel","xxx");//角色等级
info.set("serverId","xxx");//区服ID
info.set("serverName","xxx");//区服名称
info.set("playerTime","123456");//角色创建时间,必须取服务端时间,必须为时间戳
FYCombine.getInstance().doCollectInfo(context,info);

3.参数

参数名 说明 是否必传
context UIAbilityContext
infoDict 要收集的信息,key 和 value 根据第三方SDK 需求决定

5 F&Q

5.1 切换账号的流程是怎样的?

常规的流程:点击用户中心的切换账号 -> 接收到退出回调(logoutCallback) -> 退出到登录首屏 -> 调出登录窗口 -> 登录另一个账号 -> 点击进入游戏 -> 游戏中

非常规的流程:点击用户中心的切换账号 -> 弹出登录窗口 -> 登录另一个账号 -> 接收到登录回调(loginCallback) -> 检测 open_id 变了 -> 退出到登录首屏 -> 检测已有账号登录 -> 点击进入游戏 -> 游戏中

非常规的流程会出现在某些渠道(比如 4399),没有退出回调,直接呼出登录窗口。那这时候就需要检查 open_id 是否改变,来让游戏重新回到登录首屏。

也就是说,以上这 2 个流程,游戏都要有。

5.2 渠道ID(channel_id)和通行证标识(passport_code)有啥区别?

  • 一种通行证标识,可以对应多个渠道ID,渠道ID的颗粒度是最低的。游戏对渠道做区分,通常用渠道ID 即可,这个是最保险的方法。如果只想粗颗粒度的区分不同类型的渠道,则用通行证标识。

  • 具体渠道ID的值,可以查看星云后台的 对接中心-渠道打包-渠道配置 。

  • 具体通行证标识,可以查看渠道版本信息

6 Unity 游戏对接

如果您的游戏是 Unity 引擎开发的,我们有提供专门给 Unity 工程对接的桥接代码,以方便 Unity 游戏快速接入。请点击以下链接跳转到相应的文档:

聚合渠道SDK-Unity&Harmony