4399 运营 SDK Harmony Next 客户端接入

本文档面向鸿蒙 Next 系统(HarmonyOS 5.0.0+)游戏开发,描述游戏怎样接入“4399游戏平台运营 SDK 鸿蒙 Next 版”。

1 隐私政策

如果您是开发者,在为用户提供服务前请阅读 《4399隐私保护政策》《4399鸿蒙联运SDK个人信息收集清单》
了解 SDK 对个人信息收集范围、处理目的以及权限使用情况。请您向用户提供服务时,告知用户并取得同意。

2 关于SDK

4399游戏平台运营 SDK 鸿蒙 Next 版(以下简称 SDK),为接入的游戏提供华为账号一键登录/4399 平台账户/手机号登录、防沉迷、游戏内购等功能。
SDK 在内部集成了鸿蒙系统提供的,联合登录、防沉迷、角色上报、应用内支付等游戏服务。

2.1 SDK内容

SDK 分为客户端与服务端两部分:

2.2 运行环境

游戏项目应符合Stage模型定义的规范,SDK 的开发和运行也是如此。SDK 的最低兼容版本为 15,编译目标版本为 20,即

{
  "targetSdkVersion": "6.0.0(20)",
  "compatibleSdkVersion": "5.0.3(15)"
}

3 接入准备

在正式接入 SDK 前,游戏要在运营的协助下,完成华为开发者后台和 4399 开发者后台的信息填写
完成后,游戏会得到两个参数:

4 引入依赖

假定游戏已经创建了鸿蒙 Next 项目,且游戏主模块是 entry,且其静态依赖存放目录为 libs

{
  "name": "entry",
  "dependencies": {
    "operate": "file:./libs/operate-1.0.0+36.har"
  }
}
{
  "products": [
    {
      "name": "default",
      "signingConfig": "default",
      "targetSdkVersion": "6.0.0(20)",
      "compatibleSdkVersion": "5.0.1(13)",
      "runtimeOS": "HarmonyOS",
      "buildOption": {
        "strictMode": {
          "useNormalizedOHMUrl": true
        }
      }
    }
  ]
}

5 接口调用

5.1 初始化(必接)

onWindowStageCreate(windowStage: window.WindowStage): void {
  windowStage.loadContent('pages/Index', (err) => {
    let mainWindow = windowStage.getMainWindowSync();
    let uiContext = mainWindow.getUIContext();

    // 游戏全屏,不显示系统状态栏等
    mainWindow.setWindowSystemBarEnable([]).catch()
    // 游戏方向,GAME_ORIENTATION 是 window.Orientation 中定义的值
    mainWindow.setPreferredOrientation(GAME_ORIENTATION).catch();
    // 初始化 SDK
    // GAME_KEY: 4399 平台的游戏 id,在运营协助完成游戏注册后,提供给游戏
    OperateCenter.init(uiContext, GAME_KEY).then((r: OperateResult<void>) => {
      // 初始化回调
      // OperateResult 字段特别是其中的 code,可查看“客户端接入文档#API 详情”
      // r.success ? "init success" : r.message
    });
  });
}

接口参数
主要的参数为游戏 game key 或游戏 id

参数名 类型 含义 说明
uiContext UIContext 页面上下文 UIContext 对象,在UIAbility 或页面组件中获取
gameKey number 游戏 id 游戏在 4399 平台的唯一标识

接口返回
SDK 的异步接口都是 Promise 化的,接口返回 OperateResult<T>T 为泛型字段,具体类型与接口有关
OperateResult中的标准字段 success, code, message 举例如下,详细情况参考下文”API 详情“ 部分

code 含义
0 成功,通用code
1 取消,通用code
2 处理中,通用code
3 失败,通用code
4 超时,通用code
5 中止,通用code
6 未初始化,通用code
7 SDK 内部状态异常,通用code
8 配置不全,通用code
9 未知错误,通用code

5.2 账号

5.2.1 登录(必接)

// 用户登录
// OperateResult 中的 ‘code, success, message’ 按统一标准定义,具体查看“客户端接入文档#API 详情”
// 若登录成功,将同时返回 User 对象
OperateCenter.login().then((r: OperateResult<User>) => {
  if (r.success) {
    // this.user = r.data;
  }
})

接口返回,参考下文”API 详情
OperateResult具体 code 可查看下文”API 详情“;登录成功通过 User 对象返回用户信息,具体字段描述如下

参数名 类型 含义 说明
uid string 官方账号标识 数字字符串,唯一,一般就是 4399 账号
name string 官方账号名称 字符串,一般就是 4399 账号
state string 账号登录状态 登录状态,用于用户登录状态校验

此时若游戏还需要对登录状态进一步校验,可以使用服务端相关接口,参考:登录状态接口校验

5.2.2 注册登出回调(必接)

// 注册全局登出回调
// 
// 华为游戏服务通知、防沉迷、账号互顶等都会引发 SDK 内部的登出
// SDK 在此回调接口通知游戏,游戏应更新角色状态,回到游戏登录界面
OperateCenter.addOnLogoutCallback(() => {
  // 游戏应回到自己的登录或者选服页面
});

5.2.3 登出

// 用户登出
// OperateResult 中的 ‘code, success, message’ 按统一标准定义,具体查看“客户端接入文档#API 详情”
OperateCenter.logout().then((r: OperateResult<void>) => {
  // 注意:登出接口,有接口本身的回调,不论是否登出成功都返回结果;特别地,登出成功时,还会在全局登出回调中通知,
  //       游戏的登出逻辑,要注意下是否会重复,建议登出接口只提示失败
})

5.2.4 检查登录状态

let isLogin = OperateCenter.isLogin()

5.2.5 获取用户信息

let user: User = OperateCenter.getUser();

5.2.6 上报角色信息(非必接)

// 上报角色信息
// OperateResult 中的 ‘code, success, message’ 按统一标准定义,具体查看“客户端接入文档#API 详情”
OperateCenter.reportRole(role).then((r: OperateResult<void>) => {
  
})

接口参数
上报需要传入 Role 对象,具体字段含义如下,允许部分字段为空,但不可全部为空

参数名 类型 说明
roleId string 游戏角色ID
roleName string 角色名称
serverId string 角色所属区服ID
serverName string 角色所属区服名称

接口返回,参考”API 详情

5.3 游戏内购(必接)

游戏首先要注意,SDK 当前只支持消耗型商品的购买

在调用客户端接口前,需确认以下流程完成,否则无法测试:

完成上述流程后,调用客户端接口就可以进行发起充值到商品到账的完整测试
关于充值测试,更多内容参考”常见问题-怎样进行充值测试

// mark 为游戏的订单标识,游戏应通过自己的服务端生成唯一订单标识,此处是模拟生成
// let mark = genFromServerApi()

// 充值金额,如果一次购买多份,游戏要自行计算总价,此处用”单价 x 份数“方式计算
// 示例中通过华为应用内购接口,根据商品 id 查询商品信息,包括单价、币种等,再根据份数计算充值金额
// let money = product.microPrice * quantity / 1000000

// 游戏内购,需要订单信息 Order 对象
OperateCenter.iap({
  productId: product.id, // 商品 id,运营在华为开发者后台提交商品列表后获得
  mark,                  // 游戏订单标识,非空且唯一,支持字母、数字和字符 '-','_','|', 长度不可超过48个字符
  quantity,              // 购买的消耗性商品的份数
  money,                 // 总价,单位元,并非单价,游戏要自行用单价、份数等计算
  extras: {              // 透传参数,键值对
    "k1": "v1",
    "k2": 1,
    "k3": false
  } as Record<string, ValueType>
} as Order)
  // 充值回调
  // OperateResult 中的 ‘code, success, message’ 按统一标准定义,具体查看“客户端接入文档#API 详情”
  // 若下单成功,会在 Order 对象附上 4399 充值订单号,一起返回给游戏
  .then((r: OperateResult<Order>) => {
    if (r.success) {
      // 充值成功
    } else {
      // 充值失败    
    }
  })

接口参数

主要的参数为 Order 对象,此对象为游戏订单

参数名 类型 含义 说明
productId string 华为商品 id 商品在华为后台的唯一标识,运营配置后获得
money number 充值金额 非负数值,单位‘元’
mark string 游戏订单 非空且唯一,游戏对一笔订单的标识
支持字母、数字和字符 '-','_','
quantity number 商品份数 正整数,消耗型商品的份数
extras Record 透传参数 键值对,用于透传游戏附加在订单中的参数
orderId string 4399 充值订单号 4399 平台下单成功后,附加在接口返回的 Order 对象中

接口返回,参考下文”API 详情

6 API 详情

SDK 接口中的 OperateResult 对象中的 code 的所有情况:

code 含义
0 成功,通用code
1 取消,通用code
2 处理中,通用code
3 失败,通用code
4 超时,通用code
5 中止,通用code
6 未初始化,通用code
7 SDK 内部状态异常,通用code
8 配置不全,通用code
9 未知错误,通用code
21 登录配置获取失败
22 华为联合登录失败
23 华为联合登录结果异常
24 获取官方登录地址失败
25 官方登录后状态异常
26 重复登录
31 登出失败
41 当前环境不支持应用内购
42 根据商品 id 找不到对应商品信息
43 根据商品 id 查找信息失败
44 创建/处理华为订单失败
45 获取华为订单状态失败

7 常见问题

7.1 接入问题

7.1.1 SDK 有在线依赖吗

A:暂时没有(2025-10-10)


7.1.2 接入示例如何运行

A:鸿蒙平台应用无法提前配置签名,而签名、应用 id等是关联的,所以要游戏自行配置或替换为真实游戏参数
具体来说,要替换如下部分:

7.2 登录与防沉迷问题

7.2.1 华为账号登录与 4399 平台账号登录什么关系

A:二者集成在联合登录。若用户使用华为账号登录,会在后台关联一个 4399 uid,开发者调用 SDK 登录接口后获取的总是 4399 平台 uid


7.2.2 游戏需要处理防沉迷吗

A:不需要。SDK 集成了华为官方的防沉迷与 4399 平台的防沉迷,在必要的地方进行双重认证,游戏不需要额外处理

7.3 充值问题

7.3.1 怎样进行充值测试

A:先在沙盒环境,再在正式环境测试。不管哪种测试方式,都要在运营的帮助下进行。

充值测试注意事项


7.3.2 如何触发退款流程

A:满足下面条件


7.3.3 游戏如何处理退款流程

A:可在运营协助下完成