高风险功能的年龄保证
某些司法管辖区中的某些权限在启用前需要经过验证的年龄。例如,巴西(BR)中的 loot-boxes-paid-cosmetic-only、loot-boxes-paid-gameplay-impacting、targeted-ads 和 profiling 需要 verifiedAgeThreshold 为 18。这些权限默认禁用,只能通过被认为已满足年龄要求的平台信号或专用年龄保证挑战(CHALLENGE_SESSION_UPGRADE_BY_AGE_ASSURANCE)来解锁。
本页帮助您做什么
使用本页了解以下内容:
- 为什么权限在玩家通过年龄门控后仍然禁用
POST /session/upgrade是否立即启用权限或返回挑战- 如何处理满足阈值但尚未验证年龄的玩家
- 如何在玩家最初声称的年龄低于阈值时进行恢复
已验证年龄阈值
verifiedAgeThreshold 意味着权限需要经过验证的年龄,而不仅仅是声称或推断的年龄。
目前,主要示例是:
- 巴西(
BR):loot-boxes-paid-cosmetic-only、loot-boxes-paid-gameplay-impacting、targeted-ads和profiling需要已验证年龄18;direct-marketing需要已验证年龄12
具有 verifiedAgeThreshold 的权限:
- 从不为
managedBy: GUARDIAN - 当玩家年龄足够但仍需验证时为
managedBy: PLAYER - 当玩家低于阈值时为
managedBy: PROHIBITED
这目前适用于上述列表中的巴西权限。随着更多司法管辖区添加已验证年龄要求,相同的权限模型适用。
权限状态逻辑
当权限具有 verifiedAgeThreshold 时,Permission 对象包含该字段:
{
"name": "loot-boxes-paid-gameplay-impacting",
"enabled": false,
"managedBy": "PLAYER",
"verifiedAgeThreshold": 18
}
| 玩家年龄与阈值的比较 | 年龄已验证? | managedBy | enabled |
|---|---|---|---|
| 低于阈值 | 不适用 | PROHIBITED | false |
| 达到或超过阈值 | 否 | PLAYER | false |
| 达到或超过阈值 | 是,通过已验证平台信号 | PLAYER | true |
| 达到或超过阈值 | 是,通过年龄保证 | PLAYER | true |
阈值权限从不为 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
相关请求字段:
| 字段 | 类型 | 描述 |
|---|---|---|
platformAgeSignal | PlatformAgeSignal | 可立即满足阈值的平台信号 |
options | object | 转发到年龄保证体验的选项 |
options.facialAgeEstimation.passIfOver | integer | 面部年龄估计应通过的最低年龄 |
options.facialAgeEstimation.failIfUnder | integer | 面部年龄估计应失败的最高年龄 |
options.redirectUrl | string | 挑战完成后的重定向目标 |
示例请求(已验证平台信号满足权限):
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 时:
- 令牌被解析和验证。
- 如果挑战已解决,玩家将被重定向到完成页面。
- 如果仍处于待处理状态,将显示包含 k-ID 年龄验证方法(如面部年龄估计或 ID 文件扫描)的验证 iframe。
- 完成后,结果会传回您的集成。
您可以通过三种方式接收该结果:
选项 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
可能的状态为 PASS、FAIL、PENDING 和 IN_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.id | POST /session/upgrade 返回的 challengeId |
data.status | PASS、FAIL 或 IN_PROGRESS |
data.sessionId | PASS 时存在:使用此值获取刷新的会话 |
Webhook 是服务器端处理的推荐方法,因为它们实时传递且不需要轮询。有关完整字段参考和状态生命周期,请参阅 Challenge.StateChange。
结果之后
PASS后,获取GET /session/get并使用刷新的权限。阈值权限现在应该已启用,会话应包含ageVerification。FAIL后,权限保持禁用。玩家可以稍后通过再次调用POST /session/upgrade重试。
年龄低于阈值的玩家的恢复流程
有时玩家输入的声称年龄低于高风险权限的阈值,最终得到 PROHIBITED 权限。在这种情况下,正常的 session/upgrade 流程无法解决问题,因为会话已经显示玩家对该功能而言年龄太小。
此恢复流程适用于:
- 玩家管理的会话
- 尚未关联审批者的监护人管理会话
当会话是监护人管理且已有关联审批者时,不适用此流程。
恢复步骤
- 引导玩家前往 AgeKit+ 的年龄申诉。 使用适当的
jurisdiction和criteria调用POST /age-verification/perform-age-appeal。在 iframe 或 webview 中展示返回的 URL 供玩家完成年龄验证。暂时不要使当前会话失效:如果申诉失败,玩家保留其现有会话,无需再次完成 VPC。 - 处理年龄申诉结果。 通过 DOM 事件、webhook 或
GET /age-verification/get-status监听结果。- 成功时: 申诉产生一个证明玩家已验证年龄的
verificationId。 - 失败时: 功能保持禁止。玩家保留其最初声称的年龄,现有会话被保留。
- 成功时: 申诉产生一个证明玩家已验证年龄的
- 使会话失效。 申诉成功后,在您这边丢弃
sessionId,让玩家重新开始。会话失效端点计划在未来版本中推出;目前,在客户端移除会话即可。 - 使用 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,后续具有相同或更低阈值的权限通常无需再次挑战即可满足