跳到主要内容

高风险功能的年龄保证

某些司法管辖区中的某些权限在启用前需要经过验证的年龄。例如,巴西(BR)中的 loot-boxes-paid-cosmetic-onlyloot-boxes-paid-gameplay-impactingtargeted-adsprofiling 需要 verifiedAgeThreshold 为 18。这些权限默认禁用,只能通过被认为已满足年龄要求的平台信号或专用年龄保证挑战(CHALLENGE_SESSION_UPGRADE_BY_AGE_ASSURANCE)来解锁。

本页帮助您做什么

使用本页了解以下内容:

  • 为什么权限在玩家通过年龄门控后仍然禁用
  • POST /session/upgrade 是否立即启用权限或返回挑战
  • 如何处理满足阈值但尚未验证年龄的玩家
  • 如何在玩家最初声称的年龄低于阈值时进行恢复

已验证年龄阈值

verifiedAgeThreshold 意味着权限需要经过验证的年龄,而不仅仅是声称或推断的年龄。

目前,主要示例是:

  • 巴西(BRloot-boxes-paid-cosmetic-onlyloot-boxes-paid-gameplay-impactingtargeted-adsprofiling 需要已验证年龄 18direct-marketing 需要已验证年龄 12

具有 verifiedAgeThreshold 的权限:

  • 从不为 managedBy: GUARDIAN
  • 当玩家年龄足够但仍需验证时为 managedBy: PLAYER
  • 当玩家低于阈值时为 managedBy: PROHIBITED
备注

这目前适用于上述列表中的巴西权限。随着更多司法管辖区添加已验证年龄要求,相同的权限模型适用。

权限状态逻辑

当权限具有 verifiedAgeThreshold 时,Permission 对象包含该字段:

{
"name": "loot-boxes-paid-gameplay-impacting",
"enabled": false,
"managedBy": "PLAYER",
"verifiedAgeThreshold": 18
}
玩家年龄与阈值的比较年龄已验证?managedByenabled
低于阈值不适用PROHIBITEDfalse
达到或超过阈值PLAYERfalse
达到或超过阈值是,通过已验证平台信号PLAYERtrue
达到或超过阈值是,通过年龄保证PLAYERtrue

阈值权限从不为 managedBy: GUARDIAN。监护人同意无法解锁它们。

会话中的 ageVerification

当已验证平台信号被处理或年龄保证挑战完成时,会话存储一个 ageVerification 对象:

{
"ageVerification": {
"verifiedAge": 18,
"platformName": "apple-ios",
"declarationType": "governmentIDChecked",
"verifiedAt": "2026-03-14T00:00:00Z"
}
}

此验证可重复使用。一旦存储在会话中,后续针对具有相同或更低阈值权限的 POST /session/upgrade 调用通常无需新的挑战即可满足。

会话升级流程

POST /session/upgrade 是决定玩家是否可以立即获得高风险权限或需要先验证的端点。

会话升级 API

相关请求字段:

字段类型描述
platformAgeSignalPlatformAgeSignal可立即满足阈值的平台信号
optionsobject转发到年龄保证体验的选项
options.facialAgeEstimation.passIfOverinteger面部年龄估计应通过的最低年龄
options.facialAgeEstimation.failIfUnderinteger面部年龄估计应失败的最高年龄
options.redirectUrlstring挑战完成后的重定向目标

示例请求(已验证平台信号满足权限):

POST /api/v1/session/upgrade

{
"sessionId": "608616da-4fd2-4742-82bf-ec1d4ffd8187",
"requestedPermissions": [
{ "name": "loot-boxes-paid-gameplay-impacting" }
],
"platformAgeSignal": {
"name": "apple-ios",
"ageLow": 18,
"ageHigh": 25,
"declarationType": "governmentIDChecked"
}
}
{
"session": {
"sessionId": "608616da-4fd2-4742-82bf-ec1d4ffd8187",
"permissions": [
{
"name": "loot-boxes-paid-gameplay-impacting",
"enabled": true,
"managedBy": "PLAYER",
"verifiedAgeThreshold": 18
}
],
"ageVerification": {
"verifiedAge": 18,
"platformName": "apple-ios",
"declarationType": "governmentIDChecked",
"verifiedAt": "2026-03-14T00:00:00Z"
}
}
}

示例请求(玩家满足阈值但仍需年龄保证):

POST /api/v1/session/upgrade

{
"sessionId": "608616da-4fd2-4742-82bf-ec1d4ffd8187",
"requestedPermissions": [
{ "name": "loot-boxes-paid-gameplay-impacting" }
],
"options": {
"redirectUrl": "https://mygame.com/callback"
}
}
{
"session": {
"sessionId": "608616da-4fd2-4742-82bf-ec1d4ffd8187",
"permissions": [
{
"name": "loot-boxes-paid-gameplay-impacting",
"enabled": false,
"managedBy": "PLAYER",
"verifiedAgeThreshold": 18
}
]
},
"challenge": {
"challengeId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"type": "CHALLENGE_SESSION_UPGRADE_BY_AGE_ASSURANCE",
"url": "https://family.k-id.com/session/upgrade/age-assurance?token=..."
}
}

示例结果(玩家低于阈值):

{
"session": {
"sessionId": "608616da-4fd2-4742-82bf-ec1d4ffd8187",
"permissions": [
{
"name": "loot-boxes-paid-gameplay-impacting",
"enabled": false,
"managedBy": "PROHIBITED",
"verifiedAgeThreshold": 18
}
]
}
}

在此情况下,不会返回挑战,因为玩家年龄不足以获得该权限。

关键行为:

  • 所有请求的权限必须全部具有 verifiedAgeThreshold,或全部没有
  • 如果玩家低于阈值,权限保持 PROHIBITED 且不会发出挑战
  • 已验证平台信号可以立即满足部分或全部请求的权限
  • 会话中现有的 ageVerification 也可以满足请求
  • 只有剩余未解决的权限才会转换为年龄保证挑战

处理挑战结果

挑战 URL 指向 https://family.k-id.com/session/upgrade/age-assurance?token=...

当玩家打开此 URL 时:

  1. 令牌被解析和验证。
  2. 如果挑战已解决,玩家将被重定向到完成页面。
  3. 如果仍处于待处理状态,将显示包含 k-ID 年龄验证方法(如面部年龄估计或 ID 文件扫描)的验证 iframe。
  4. 完成后,结果会传回您的集成。

您可以通过三种方式接收该结果:

选项 1:监听 postMessage

对于 iframe 或 webview 集成,Family Portal 会向父窗口发布 Challenge.StateChange 消息:

{
"eventType": "Challenge.StateChange",
"data": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"productId": "your-product-id",
"status": "PASS"
}
}
注意

DOM postMessage 事件对于更新 UI 很有用,但不具有权威性。任何服务器端逻辑请使用 webhook 或轮询端点。

选项 2:轮询 GET /challenge/get-status

GET /api/v1/challenge/get-status?challengeId=a1b2c3d4-e5f6-7890-abcd-ef1234567890

可能的状态为 PASSFAILPENDINGIN_PROGRESS

选项 3:接收 Challenge.StateChange webhook

每当挑战状态变化时,k-ID 会向您配置的端点发布 Challenge.StateChange webhook 事件:

{
"eventType": "Challenge.StateChange",
"data": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"productId": 11472,
"status": "PASS",
"sessionId": "608616da-4fd2-4742-82bf-ec1d4ffd8187"
}
}
字段描述
data.idPOST /session/upgrade 返回的 challengeId
data.statusPASSFAILIN_PROGRESS
data.sessionIdPASS 时存在:使用此值获取刷新的会话

Webhook 是服务器端处理的推荐方法,因为它们实时传递且不需要轮询。有关完整字段参考和状态生命周期,请参阅 Challenge.StateChange

结果之后

  • PASS 后,获取 GET /session/get 并使用刷新的权限。阈值权限现在应该已启用,会话应包含 ageVerification
  • FAIL 后,权限保持禁用。玩家可以稍后通过再次调用 POST /session/upgrade 重试。

年龄低于阈值的玩家的恢复流程

有时玩家输入的声称年龄低于高风险权限的阈值,最终得到 PROHIBITED 权限。在这种情况下,正常的 session/upgrade 流程无法解决问题,因为会话已经显示玩家对该功能而言年龄太小。

此恢复流程适用于:

  • 玩家管理的会话
  • 尚未关联审批者的监护人管理会话

当会话是监护人管理且已有关联审批者时,适用此流程。

恢复步骤

  1. 引导玩家前往 AgeKit+ 的年龄申诉。 使用适当的 jurisdictioncriteria 调用 POST /age-verification/perform-age-appeal。在 iframe 或 webview 中展示返回的 URL 供玩家完成年龄验证。暂时不要使当前会话失效:如果申诉失败,玩家保留其现有会话,无需再次完成 VPC。
  2. 处理年龄申诉结果。 通过 DOM 事件、webhook 或 GET /age-verification/get-status 监听结果。
    • 成功时: 申诉产生一个证明玩家已验证年龄的 verificationId
    • 失败时: 功能保持禁止。玩家保留其最初声称的年龄,现有会话被保留。
  3. 使会话失效。 申诉成功后,在您这边丢弃 sessionId,让玩家重新开始。会话失效端点计划在未来版本中推出;目前,在客户端移除会话即可。
  4. 使用 k-ID 信号重新启动年龄门控流程。 将申诉中的 verificationId 作为 k-id 平台信号发送。
POST /api/v1/age-gate/check

{
"jurisdiction": "BR",
"platformAgeSignal": {
"name": "k-id",
"verificationId": "<verificationId from age appeal>"
}
}

k-ID 从 verificationId 解析已验证年龄。如果已验证年龄达到或超过 verifiedAgeThreshold,则创建会话时高风险权限已启用。

顺序权限升级

每个阈值权限独立跟踪:

  • 升级一个权限不会自动升级另一个
  • 每个权限仍需通过 POST /session/upgrade 请求
  • 一旦会话具有 ageVerification,后续具有相同或更低阈值的权限通常无需再次挑战即可满足