嵌入式流程
CDK 提供一个端到端小部件,在单个界面中处理完整的可验证父母同意 (VPC) 流程,在一个无缝体验中涵盖年龄门控、VPC、数据通知、权限和偏好设置。
什么是端到端小部件?
端到端小部件是一个全面的解决方案,在单个界面中处理完整的合规流程,在一个无缝体验中涵盖年龄门控、VPC、数据通知、权限和偏好设置。此小部件可以由父母在孩子的设备上或他们自己的设备上使用,为同意过程提供最大的灵活性。
生成小部件 URL
调用 /widget/generate-e2e-url API 创建处理完整 VPC 流程的端到端小部件 URL。这将返回一个唯一 URL,供用户完成年龄收集和父母同意过程。
请求示例
POST /api/v1/widget/generate-e2e-url
Content-Type: application/json
Authorization: Bearer your-api-key
{
"jurisdiction": "US-CA"
}配置标志
可选的 flags 参数允许您自定义要跳过的流程部分:
skipDataNotices:跳过数据通知和同意收集skipVerification:跳过验证步骤skipPermissions:跳过权限管理skipPreferences:跳过偏好设置
传递平台年龄信号(可选)
如果您的游戏已有来自平台的年龄数据(Apple iOS、Google Play、Xbox、Meta Horizon 或先前的 k-ID 验证),请将其作为 platformAgeSignal 包含在请求正文中。小部件会将该信号转发给底层的年龄门控检查,因此可以在已验证信号表明是成人时跳过年龄门控、无需额外验证步骤即可满足已验证年龄权限,并检测信号与玩家自报年龄之间的冲突。
POST /api/v1/widget/generate-e2e-url
Content-Type: application/json
Authorization: Bearer your-api-key
{
"jurisdiction": "US-CA",
"platformAgeSignal": {
"name": "apple-ios",
"ageLow": 18,
"ageHigh": 25,
"declarationType": "governmentIDChecked"
}
}有关支持的平台和字段形式,请参阅平台年龄信号。
响应示例
{
"id": "7854909b-9124-4bed-9282-24b44c4a3c97",
"url": "https://family.k-id.com/widget?token=eyJhbGciOiJFUzM4NCIs..."
}展示小部件 URL
小部件 URL 是一个托管的网页。请在适合您应用程序的环境中打开它:
- Web 应用:嵌入到 iframe 中(参见下方示例)、在弹出窗口中打开,或整页重定向。
- 移动应用:在系统浏览器组件(Android 上的 Custom Tabs,iOS 上的 ASWebAuthenticationSession)中打开小部件 URL,并传递
options.redirectUrl,以深度链接的形式将结果返回到您的应用。有关显示方法,请参阅移动应用快速入门指南。要获得最贴合品牌的体验,可以考虑改用自定义工作流原生构建年龄门控和同意 UX。 - 主机游戏(Switch、PlayStation、Xbox):主机浏览器通常受限或不存在。将小部件 URL 显示为二维码,让玩家在配对的移动设备上完成流程。由于移动设备的重定向无法返回到主机,请通过 webhook 加
/session/get轮询来接收结果。
小部件内可用的方法会自动适应司法管辖区要求,与托管环境无关。
Web 示例
<div id="vpc-container">
<iframe
id="vpc-widget"
src="WIDGET_URL"
width="100%"
height="600"
frameborder="0"
allow="camera;payment;publickey-credentials-get;publickey-credentials-create">
</iframe>
</div>对于移动环境,调用 /widget/generate-e2e-url 时传递 options.redirectUrl,并在应用中处理回调。端到端示例请参阅移动应用快速入门指南。
处理事件
DOM 事件可达的位置
下方的 JavaScript 事件(Widget.AgeGate.Result、Widget.AgeGate.Challenge、Widget.ExitReview)通过 postMessage 传递。要接收它们,宿主需要对小部件的 window 有一个活跃的 JavaScript 监听器。这包括 iframe 宿主、通过 window.open 打开的弹出窗口,以及带 JS 桥的移动端 WebView / WKWebView(参阅移动应用快速入门)。系统浏览器组件(ASWebAuthenticationSession、SFSafariViewController、Chrome Custom Tabs)和整页顶层重定向不暴露监听器,因此通过 redirectUrl 回调接收结果,并使用 /session/get 或 webhooks 在服务器端确认。
当年龄门控流程完成时,会创建会话以存储玩家的权限和年龄状态。每当流程需要挑战时都会创建挑战,用于可验证的家长同意,或在玩家申报的年龄足以跳过家长同意时用于 Automatic age assurance。
小部件发出您可以监听的 JavaScript 事件。请监听 Widget.AgeGate.Result 事件,其 data.status 表示流程如何结束:
PASS:玩家通过了年龄门控,并已创建会话。存在data.sessionId。FAIL:所需的挑战未通过(例如受信任的成人拒绝了家长同意,或玩家未完成 Automatic age assurance)。不会创建会话。PROHIBITED:玩家未达到该产品在此管辖区的最低年龄,无法继续。不会创建会话;data.age包含所输入的年龄。请阻止玩家继续。
如果流程中创建了挑战,事件还会包含 challengeId。有关挑战相关事件的详细信息,请参阅 Widget.AgeGate.Challenge。
关闭 UI
要确定何时关闭小部件 UI,请监听 Widget.ExitReview 事件。当用户单击"完成"按钮时会发出此事件,表示流程已完成,应关闭或隐藏 iframe。
window.addEventListener('message', (event) => {
if (!event.origin.endsWith('.k-id.com')) {
return;
}
const message = event.data;
if (message.eventType === 'Widget.AgeGate.Result') {
if (message.data.status === 'PASS') {
const sessionId = message.data.sessionId;
// 如果存在 challengeId,则表示流程中解决了一个挑战
// (例如家长同意或 Automatic age assurance)。
if (message.data.challengeId) {
console.log('Challenge resolved, session issued:', sessionId);
} else {
console.log('Session created (no challenge required):', sessionId);
}
grantAccess(sessionId);
} else if (message.data.status === 'FAIL') {
// 所需的挑战未通过(例如家长同意被拒绝,或
// Automatic age assurance 未完成)。无会话。
console.log('Age gate not passed');
restrictAccess();
} else if (message.data.status === 'PROHIBITED') {
// 玩家未达到该产品的最低年龄。
// 不会创建会话。阻止其继续。
console.log('Player below minimum age:', message.data.age);
restrictAccess();
}
}
// 如有需要,处理挑战相关事件
if (message.eventType === 'Widget.AgeGate.Challenge') {
if (message.data.status === 'FAIL') {
// 家长拒绝同意。限制访问
console.log('Consent denied');
restrictAccess();
}
}
if (message.eventType === 'Widget.ExitReview') {
// 当用户单击"完成"时关闭小部件 UI
closeWidget();
}
});通过重定向 URL 接收结果
系统浏览器组件(ASWebAuthenticationSession、SFSafariViewController、Chrome Custom Tabs)和整页顶层重定向无法暴露 DOM 监听器,因此改为通过 redirectUrl 回调接收年龄门控结果。在调用 /widget/generate-e2e-url 或 /widget/generate-age-gate-url 时传入 options.redirectUrl。该 URL 支持 http(s) 和带自定义协议方案的移动深度链接(例如 myapp://age-gate/return)。
当年龄门控流程完成时,k-ID 会将 Widget.AgeGate.Result 事件所携带的相同结果字段作为查询参数追加,并将玩家导航到您的 URL。重定向 URL 上的现有查询参数将被保留。
| 参数 | 说明 |
|---|---|
status | PASS、FAIL 或 PROHIBITED(见下文) |
sessionId | 新创建的会话。仅在 status 为 PASS 时存在。 |
challengeId | 流程中涉及的挑战(如果创建了)。 |
age | 玩家输入的年龄。当 status 为 PROHIBITED 时存在。 |
status 的值与 DOM 事件一致:
PASS:玩家通过了年龄门控,并已创建会话。使用sessionId授予访问权限。FAIL:所需的挑战未通过(例如家长同意被拒绝,或 Automatic age assurance 未完成)。不会创建会话。PROHIBITED:玩家未达到该产品在此管辖区的最低年龄。不会创建会话。请阻止玩家继续。
例如,未达到最低年龄的玩家将被导航到:
myapp://age-gate/return?status=PROHIBITED&age=8请将重定向查询参数视为 UX 提示,而非可信结果。在授予访问权限之前,请通过 Challenge.StateChange webhook 或 /session/get 在服务器端确认结果。
小部件处理的内容
小部件自动处理:
- 年龄收集:符合司法管辖区要求的年龄收集方法
- 数据通知:根据 Compliance Studio 中的产品配置接受的数据通知
- 权限:根据 Compliance Studio 中的产品配置管理的权限
- 父母同意挑战:如果确定用户是未成年人,则会创建挑战以供可信成人批准
- Automatic age assurance:如果产品在该司法管辖区启用了 Automatic age assurance,那些声明年龄足以跳过父母同意的玩家将被要求在小部件内证明所声明的年龄(面部年龄估计或 ID 文件),然后才能签发会话。
具体流程取决于司法管辖区和您在 Compliance Studio 中的产品配置。
启用 Automatic age assurance 后的会话创建时机
当 Automatic age assurance 在端到端小部件内触发时,会话是在玩家通过验证之后创建,而不是在年龄门控之后立即创建。流程完成后仍会触发 Widget.AgeGate.Result 事件,并在 PASS 时包含 sessionId。在该事件到达之前,请将流程视为正在进行中。
有关实施 VPC 的更多信息,请参阅 快速入门指南。