Server API
Lobah 服务器提供了一些有用的 API,允许游戏与玩家进行更深入的互动。
注意:当开发者在 Lobah 平台上创建游戏时,他们会收到两条信息:appId 和 appKey。appKey 是敏感信息,应妥善保管。
服务端 API 包括用于玩家购买、奖励、消息发送等操作的服务器端 API 接口,提供给游戏服务器,以实现游戏与玩家的深度集成。
注意:为确保数据安全,生产环境中的服务端 API 只允许游戏服务器使用特定的 IP 地址访问。请在平台中配置游戏服务器的 IP 地址。
服务端 API 地址
Lobah 游戏的服务器 API 地址是:
https://game-gateway.lobah.net
认证
Lobah 服务器提供的 API 使用 HmacMD5 算法进行认证,以确保数据安全。因此,开发者的游戏服务器每次请求时都需要使用以下算法计算认证字符串:
macMD5 ( URLEncode ( "POST" + 请求路径 + Request parameters + 请求体 ), appKey )参与算法计算的元素如下:
参与算法计算的元素如下:
| 名称 | 内容 | 说明 | 示例值 |
|---|---|---|---|
| 请求路径 | 要访问的 API 路径。 | /1.0/open-gateway/game/send-message | |
| 请求参数 | 包含以下字段: | ||
| uid | 从客户端传递给游戏,表示游戏中当前活跃玩家的用户 ID。 | 1005008 | |
| access_token | 从客户端传递给游戏,用于用户身份验证。 | 4d0b364bcd2e9c6243b149e2e2a2c65a | |
| app_id | appId | 92 | |
| nonce | 随机字符串。 | 89e8379b | |
| ts | 当前时间戳。 | 1730970702 | |
| zone | 固定为 "SA"。 | SA | |
| 请求体 | 发送给 API 的具体数据。 | { "content": "hello world", "id_list": [ 1005008 ], "operator": "Test Game" } |
上面的示例数据将生成待加密的字符串内容如下:
POST/1.0/open-gateway/game/send-messageaccess_token=4d0b364bcd2e9c6243b149e2e2a2c65a&app_id=92&nonce=89e8379b&ts=1730970702&uid=1005008&zone=SA{ "content": "hello world", "id_list": [ 1005008 ], "operator": "Test Game" }待加密的字符串经过 URL 编码后,将得到以下内容:
POST%2F1.0%2Fopen-gateway%2Fgame%2Fsend-messageaccess_token%3D4d0b364bcd2e9c6243b149e2e2a2c65a%26app_id%3D92%26nonce%3D89e8379b%26ts%3D1730970702%26uid%3D1005008%26zone%3DSA%7B+%22content%22%3A+%22hello+world%22%2C+%22id_list%22%3A+%5B+1005008+%5D%2C+%22operator%22%3A+%22Test+Game%22+%7D使用 HmacMD5 计算出的认证字符串是:is:114921f6dd2c59477f34c76647249e3d.
当使用上述算法计算出的认证字符串进行 POST 请求时,非常重要 的是在请求参数的末尾附加&sig=authentication_string 因此,最终的请求 URL 将如下所示:
https://game-gateway.lobah.net/1.0/open-gateway/game/send-message?access_token=4d0b364bcd2e9c6243b149e2e2a2c65a&app_id=92&nonce=89e8379b&ts=1730970702&uid=1005008&zone=SA&sig=114921f6dd2c59477f34c76647249e3d认证测试
游戏服务器可以通过认证测试接口验证认证信息是否正确。
请求路径: /1.0/open-gateway/game/test
请求方法: POST
数据格式: JSON
请求体:
POST/1.0/open-gateway/game/send-messageaccess_token=4d0b364bcd2e9c6243b149e2e2a2c65a&app_id=92&nonce=89e8379b&ts=1730970702&uid=1005008&zone=SA{ "content": "hello world", "id_list": [ 1005008 ], "operator": "Test Game" }verify_status 有三个可能的值:
- EXPIRED : 用户的 access_token 已过期。
- LEGAL : 用户的 access_token 有效。
- ILLEGAL : 用户的 access_token 无效。 gender 将是 1 或 2,1 表示男性,2 表示女性。
如果 session_id 是一个空字符串,表示用户不在直播间。
请求示例 :
响应示例:
{
"app_id": 92,
"token": "4d0b364bcd2e9c6243b149e2e2a2c65a",
"uid": 1005008
}响应示例:
{
"verify_status":"LEGAL",
"user_id":1005008,
"avatar":"https://d1d7fyvslid3cf.cloudfront.net/images/2021/3/12/12/e7c6634011b84f5e9e30607b653babaf",
"user_name":"Grevfvv",
"user_coins":22514,
"level":15,
"gender": 1
}注意,在旧版文档中,
get-profile会返回session_id字段,该字段已弃用。请从游戏 URL 或游戏 SDK 中获取当前直播间的会话 ID。
向用户发送金币
游戏可以奖励玩家一定数量的金币,奖励金额从游戏可用的金币中支付。
请注意,游戏中可用于奖励的金币与玩家购买时的游戏收入是分开的。
请求路径: /1.0/open-gateway/game/reward
请求方法: POST
数据格式: JSON
请求体:
{
"app_id": appId,
"rewards": [
{
"amount": "奖励金额",
"reference_id": "游戏服务器生成的 ID,用于区分每个奖励记录",
"type": "coins",
"uid": User ID
}
],
"session_id": "直播间 ID"
}rewards 字段是一个数组,允许同时发放多组奖励。
session_id 是可选的。它可以是数字或字符串形式。最终以数字形式存储。
响应体:
{
"result":[
{
"reward_id":"奖励 ID",
"reference_id":"游戏服务器生成的 ID,用于区分每个奖励记录。",
"status": "结果状态",
"availableCoinsCredit": "可用于游戏奖励的金币总额"
}]
}result 数组对应于请求的 rewards 字段中指定的多个奖励的结果。开发者可以使用 reference_id 来筛选每个奖励的结果。
status 的可能值如下:
- 0: 成功
- 11: 被拒绝
- 12: 奖励金额为 0,未执行任何操作
- 13: 游戏金币不足
- 14: 无效的奖励类型
- 20: 其他错误
请求示例:
{
"app_id": 92, "rewards": [
{
"amount": 10,
"reference_id": "6a5aca7bfc66",
"type": "coins",
"uid": 1005008 }
],
"session_id": "1234567890"
}响应示例:
{
"result":[
{
"reward_id":"G92-1-R17309707032943514",
"reference_id":"6a5aca7bfc66",
"status":0,
"availableCoinsCredit": 10233
}
]
}玩家支付
游戏可以为玩家提供付费功能,例如购买道具或额外的尝试次数。
在使用购买功能之前,需要与 Lobah 游戏平台预先约定要购买的产品及其价格。玩家将使用 Lobah 金币进行购买结算。玩家拥有的金币余额可以通过Get User Prifile API 查看。
请求路径: /1.0/open-gateway/game/purchase
请求方法: POST
数据格式: JSON
请求体:
{
"app_id": "appId",
"product_id": "指定的产品 ID",
"reference_id": "由游戏服务器生成的用于标识此交易记录的 ID,此 ID 在所有交易中必须是唯一的",
"session_id": "直播间 ID",
"uid": "用户 ID"
}重要提示:由于
amount参数容易与其他 API 混淆,并考虑到使用购买 API 的习惯, 购买 API 中的amount参数已弃用 ,可以忽略。使用购买 API 时,玩家支付的金币数量由产品 ID 决定。
product_id 由 Lobah 和开发者约定。
session_id 是可选的。它可以是数字或字符串形式。最终以数字形式存储。
响应体:
{
"purchase_result_code": "结果码",
"balance": "游戏持有的余额",
"user_coins": "用户的金币余额",
"order_id": "交易 ID,用于退款"
}purchase_result_code 的结果如下:
- 0: 购买成功
- 10: appId 不正确
- 11: product_id 不正确
- 12: 用户金币不足
- 13: 重复或无效的
reference_id - 20: 其他错误
请求示例:
{
"app_id": 92,
"product_id": "GAME.SHOP.TEST.10COIN",
"reference_id": "29135edafa9d",
"session_id": "1234567890",
"uid": 1005008
}响应示例:
{
"purchase_result_code":0,
"balance":290,
"user_coins":22514,
"order_id":"G92-P17309707027364314"
}退款
购买操作后,可以对交易进行退款操作。退款后,购买时花费的金币将退还到玩家的账户。
请求路径: /1.0/open-gateway/game/refund
请求方法: POST
数据格式: JSON
请求体:
{
"app_id": "appId",
"order_id": "购买时返回的交易 ID"
}**响应体 **:
{
"result": "result code"
}result 的结果如下:
- 0: 退款成功
- 10: order_id 不正确
- 11: 被拒绝
- 20: 其他错误
请求示例:
{
"app_id": 92,
"order_id": "G92-P17309707027364314"
}响应示例:
{
"result":0
}顶级玩家
游戏服务器可以提供顶级玩家数据,在游戏的排行榜上显示来自 Lobah 平台的玩家。
请求路径: /1.0/open-gateway/game/top-players
请求方法: POST
数据格式: JSON
请求体:
{
"app_id": appId,
"rankings": [
{ “uid”: user ID, “score”: user score }
]
}用户分数按降序排名。
**响应体 **:
{
"ok": boolean
}当 ok 为 true 时,数据已成功写入;为 false 时,表示发生错误。
请求示例:
{
"app_id": 92,
"rankings": [
{ "uid": 1000064, "score": 98 },
{ "uid": 1000063, "score": 101 }
]
}响应示例:
{
"ok":true
}标记游戏状态
此 API 可以在房间的“正在玩”选项卡上显示游戏玩家信息。
请求路径: /1.0/open-gateway/game/mark-players
请求方法: POST
数据格式: JSON
请求体:
{
"app_id": appId,
"rankings": [
{ “uid”: user ID, “score”: user score, "session_id": room id }
]
}每次调用此接口都会覆盖之前的数据,以便于更新。
session_id 是玩家当前的房间 ID。如果设置了房间 ID,具有相同房间 ID 的玩家将显示在同一个房间中。如果未设置,则将显示所有玩家。
**响应体 **:
{
"ok": boolean
}当 ok 为 true 时,数据已成功写入;为 false 时,表示发生错误。
请求示例:
{
"app_id": 92,
"rankings": [
{ "uid": 1000064, "score": 98, "session_id": 1234456661 },
{ "uid": 1000063, "score": 101, "session_id": 1234456661 }
]
}响应示例:
{
"ok":true
}获取产品列表
此 API 可以获取可用的产品信息。
请求路径: /1.0/open-gateway/game/product-list
请求方法: POST
数据格式: JSON
请求体:
{
"app_id": appId
}**响应体 **:
{
"products":
[
{
"product_id": Product ID,
"coins": Product price,
"description": Product description
}
]
}所有可用的产品信息将在此处列出, product_id 用于购买 API。
请求示例:
{
"app_id": 92
}响应示例:
{
"products":
[
{"product_id":"GAME.SHOP.TEST.COIN12","coins":12,"description": ""},
{"product_id":"GAME.SHOP.TEST.COIN34","coins":34,"description": ""}
]
}交易
交易 API 是一组用于在游戏会话或阶段中为不同用户执行多个支付和奖励操作,然后进行一次性结算的 API。
1. 开始交易
请求路径: /1.0/open-gateway/game/transaction/start
请求方法: POST
数据格式: JSON
请求体:
{
"app_id": "appId",
"reference_id": "由游戏服务器生成的唯一 ID,用于区分此请求。"
}注意:
reference_id必须是唯一的;重复的reference_id值将导致调用失败。
**响应体 **:
{
"app_id": "appId",
"reference_id": "传入的 reference_id",
"transaction_id": "本次交易的 ID",
"result_code": "结果码"
}result_code 的值:
0: 交易成功启动。
10: 无效的
app_id。13: 无效或重复的
reference_id。20: 其他错误。
请求示例:
{
"app_id": 7,
"reference_id": "a2a8ab8cbd2b"
}响应示例:
{
"app_id": 7,
"reference_id": "a2a8ab8cbd2b",
"transaction_id": "TRX7-17434811375622102",
"result_code": 0
}2. 检查交易状态
请求路径: /1.0/open-gateway/game/transaction/status
请求方法: POST
数据格式: JSON
请求体:
{
"app_id": "appId",
"transaction_id": "This transaction's ID"
}**响应体 **:
{
"app_id": "appId",
"transaction_id": "本次交易的 ID",
"total_added_amount": "发送给用户的总金额",
"total_deducted_amount": "从用户处扣除的总金额",
"result_code": "结果码"
}result_code 的值:
- 0: 交易进行中
- 2: 交易已关闭
- 10: 无效的
app_id - 15: 不存在的
transaction_id - 20: 其他错误
请求示例:
{
"app_id": 7,
"reference_id": "a2a8ab8cbd2b"
}响应示例:
{
"app_id": 7,
"transaction_id": "TRX7-17434811375622102",
"total_added_amount": 0,
"total_deducted_amount": 0,
"result_code": 0
}3. 在交易中向用户发送金币
请求路径: /1.0/open-gateway/game/transaction/add
请求方法: POST
数据格式: JSON
请求体:
{
"app_id": "appId",
"transaction_id": "本次交易的 ID",
"reference_id": "由游戏服务器生成的唯一 ID,用于区分此请求。",
"amount": "要发送的金币数量",
"uid": "用户 ID",
"session_id": "用户所在的当前房间 ID"
}**响应体 **:
{
"app_id": "appId",
"transaction_id": "本次交易的 ID",
"reference_id": "传入的 reference_id",
"total_added_amount": "发送给用户的总金额",
"total_deducted_amount": "从用户处扣除的总金额",
"user_coins": "用户当前的金币余额",
"uid": "用户 ID",
"result_code": "结果码"
}result_code 的值:
- 0: 操作成功。
- 2: 交易已关闭; 此调用无效 。
- 10: 无效的
app_id。 - 13: 无效或重复的
reference_id。 - 15: 不存在的
transaction_id。 - 16: 发送的总金额超过扣除的总金额, 此调用无效 。
- 20: 其他错误。
请求示例:
{
"amount": 5,
"app_id": 7,
"transaction_id": "TRX7-17434811375622102",
"reference_id": "66e0702321da",
"session_id": 1733800215637628,
"uid": 1000064
}响应示例:
{
"app_id": 7,
"reference_id": "66e0702321da",
"transaction_id": "TRX7-17434811375622102",
"total_added_amount": 5,
"total_deducted_amount": 15,
"user_coins":6060,
"uid": 1000064,
"result_code": 0
}4. 在交易中从用户处扣除金币
请求路径: /1.0/open-gateway/game/transaction/deduct
请求方法: POST
数据格式: JSON
请求体:
{
"app_id": "appId",
"transaction_id": "本次交易的 ID",
"reference_id": "由游戏服务器生成的唯一 ID,用于区分此请求。",
"amount": "要扣除的金币数量",
"uid": "用户 ID",
"session_id": "用户所在的当前房间 ID"
}**响应体 **:
{
"app_id": "appId",
"transaction_id": "本次交易的 ID",
"reference_id": "传入的 reference_id",
"total_added_amount": "发送给用户的总金额",
"total_deducted_amount": "从用户处扣除的总金额",
"user_coins": "用户当前的金币余额",
"uid": "用户 ID",
"result_code": "结果码"
}result_code 的值:
- 0: 操作成功。
- 2: 交易已关闭, 此调用无效 。
- 10: 无效的
app_id。 - 12: 用户余额不足, 此调用无效 。
- 13: 无效或重复的
reference_id。 - 15: 不存在的
transaction_id。 - 20: 其他错误。
请求示例:
{
"amount": 15,
"app_id": 7,
"transaction_id": "TRX7-17434811375622102",
"reference_id": "08ec79b4c0dc",
"session_id": 1733800215637628,
"uid": 1000064
}响应示例:
{
"app_id": 7,
"reference_id": "08ec79b4c0dc",
"transaction_id": "TRX7-17434811375622102",
"total_added_amount": 0,
"total_deducted_amount": 15,
"user_coins":6060,
"uid": 1000064,
"result_code": 0
}5. 关闭交易
请求路径: /1.0/open-gateway/game/transaction/close
请求方法: POST
数据格式: JSON
请求体:
{
"app_id": "appId",
"transaction_id": "This transaction's ID"
}**响应体 **:
{
"app_id": "appId",
"transaction_id": "本次交易的 ID",
"total_added_amount": "发送给用户的总金额",
"total_deducted_amount": "从用户处扣除的总金额",
"result_code": "结果码"
}result_code 的值:
- 0: 操作成功。
- 2: 交易已关闭。
- 10: 无效的 app_id 。
- 20: 其他错误。
请求示例:
{
"app_id": 7,
"transaction_id": "TRX7-17434811375622102"
}响应示例:
{
"app_id": 7,
"transaction_id": "TRX7-17434811375622102",
"total_added_amount": 5,
"total_deducted_amount": 15,
"result_code": 0
}