XMDT 服务器集成
你的服务器只需要发起一次调用。它从不携带或接收玩家的姓名、出生日期、手机号码或 OTP 验证码。
| 环境 | Base URL |
|---|---|
| Dev | https://api-xmdt.dev.alogame.vn |
| Prod | https://api-xmdt.alogame.vn |
两者都已上线。secret_key 按环境区分——dev 生成的 key 无法用于 prod,反之亦然。参见下方获取 secret。
| 调用 | 何时调用 | 为什么 |
|---|---|---|
POST /xmdt/session | 每当你的客户端需要打开 XMDT 界面时,以及任何你需要确认玩家是否已完成验证的时刻 | 为 SDK 生成一个短期有效的 token —— 你的 HMAC secret 永远不会到达设备端。它的响应还带有 xmdtCompleted,该字段直接来自 Alogame、从不经玩家设备转发——这就是你可以信任的答案。 |
获取 secret
联系你的 Alogame 运营对接人,为你的 gameId 开通 XMDT。你会仅一次收到一个 secret_key,就在它被生成的那一刻——之后无法再次获取,所以请立即存入你自己的密钥管理系统,不要写进最终会被提交到版本控制里的配置文件。
dev 和 prod 分别单独开通,各自有自己的 secret_key——如果需要先在 dev 测试再切换正式版本到 prod,请明确同时申请两个环境的 secret。
请求签名
以下调用使用的签名方案,比 Alogame 的支付接口更简单:没有时间戳,没有重放窗口,不需要字段排序。
X-Signature: HMAC-SHA256(secret_key, raw_request_body),十六进制小写
被签名的内容是发送时原始的 JSON body 字节——不是重新序列化或排过序的版本。
如果你的框架先解析了 JSON,再对重新序列化后的结果签名,键的顺序、空格、数字格式都可能与你实际发送的内容不同,签名就会不匹配。请在 JSON 解析器读取之前先捕获原始 body(参见支付 API 认证指南——目前仅有英文版——中各语言的正确做法示例;原理相同,只是签名公式不同)。
const crypto = require("crypto");
function signXmdtBody(rawBody, secret) {
return crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
}
import hmac, hashlib
def sign_xmdt_body(raw_body: bytes, secret: str) -> str:
return hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
function signXmdtBody(string $rawBody, string $secret): string {
return hash_hmac('sha256', $rawBody, $secret);
}
将其作为 X-Signature 头发送,Content-Type: application/json,用于下面的调用。没有单独的 service-id 头——请求体里的 gameId 就是校验依据。
POST /xmdt/session —— 生成 session token
在你的客户端即将打开 XMDT 界面时调用(AlogameKycSdk.show())。
请求
{
"gameId": "your_game_id",
"username": "player_account_name",
"serverId": "server_01",
"roleId": "character_123"
}
| 字段 | 是否必填 | 说明 |
|---|---|---|
gameId | 是 | 你注册时使用的游戏代码 |
username | 是 | 你自己稳定的单个玩家标识——是这个而不是设备 ID,把玩家和其 XMDT 记录关联起来 |
serverId | 否 | 如果此时你的游戏还没有选服步骤,可省略 |
roleId | 否 | 如果玩家还没有选择角色,可省略 |
BODY='{"gameId":"your_game_id","username":"player_account_name"}'
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SECRET" | sed 's/^.* //')
curl -X POST https://api-xmdt.dev.alogame.vn/xmdt/session \
-H "Content-Type: application/json" \
-H "X-Signature: $SIG" \
-d "$BODY"
响应
{
"sessionToken": "opaque-token-hand-this-to-your-client",
"expiresAt": "2026-08-07T12:15:00Z",
"xmdtRequired": true,
"xmdtCompleted": false
}
| 字段 | 含义 |
|---|---|
sessionToken | 直接转交给你的客户端——这是 AlogameKycSdk.setGameRole() 所需要的。有效期 15 分钟。 |
xmdtRequired | SDK 表单是否显示关闭按钮。由 Alogame 运营按游戏配置,你不需要在每次调用时单独设置。 |
xmdtCompleted | 该玩家已经拥有完整的 XMDT 记录——如果你想避免打开一个无意义的空界面,客户端可以完全跳过调用 show()。 |
该 token 仅供 collect 步骤单次使用,15 分钟后失效——每次调用 show() 都应生成一个新 token,不要缓存后跨多个 session 复用。
把这个调用当作权威校验
不要仅凭 SDK 的 onResult 回调就放行任何操作——那个回调来自玩家设备,被修改过的客户端可以在从未真正验证的情况下上报成功。在你真正需要信任这个答案的那一刻(例如让玩家进入一场对局之前),再次调用同一个接口,并从响应中读取 xmdtCompleted。这里没有单独的状态查询接口:该字段之所以权威,是因为它经由同一个已签名的服务器对服务器调用,直接来自 Alogame——从未经玩家设备转发。
请在你这边缓存 true 的结果,而不是每次登录都重新 mint——已完成的记录不会再变回未完成,而且 mint 本身按玩家做了速率限制(见下方"错误"部分)。
错误
| HTTP | code | 含义 |
|---|---|---|
| 400 | invalid_request | JSON 格式错误,或缺少 gameId/username |
| 401 | missing_headers | 未发送 X-Signature 头 |
| 401 | invalid_signature | 签名不匹配——检查你签名的是否是原始 body |
| 403 | unknown_service | gameId 未注册或已被停用 |
| 409 | xmdt_disabled | 你的 gameId 尚未开通 XMDT——联系运营 |
| 409 | email_required_unsupported | 你的游戏配置了此 SDK 流程不支持的邮箱验证要求——联系运营 |
| 429 | rate_limited | 该玩家/IP 在短时间内发起了过多 mint 请求——请退避后重试,不会告知具体触发了哪个限制 |
| 500 | internal_error | 采用退避策略重试 |
所有错误响应都是同样的结构:{"code": "...", "message": "..."}。