跳到主要内容

Verification.Result

在验证尝试结果时发出。

字段

字段类型必需说明
eventTypestring始终为 "Verification.Result"
dataobject验证结果数据
data.idstring (UUID)唯一验证 ID
data.statusstring可以是 PASSFAIL
data.ageCategorystring估计的年龄类别。可以是 adultdigital-youthdigital-minor。仅在 statusPASSage 存在时存在
data.methodstring使用的验证方法。PASS 状态时始终存在。FAIL 状态时,仅在 failureReasonage-criteria-not-met 时存在
data.failureReasonstring验证失败的原因。statusFAIL 时始终存在。可以是 age-criteria-not-metmax-attempts-exceededfraudulent-activity-detected
data.ageobject年龄详细信息。当 age.lowage.high 都可用时存在。FAIL 状态时,仅在 failureReasonage-criteria-not-met 时存在
data.age.lownumber估计年龄的下限。对于硬年龄验证方法(如 ID 文档检查),这是确切年龄
data.age.highnumber估计年龄的上限。对于硬年龄验证方法(如 ID 文档检查),这是确切年龄
data.dobstring (YYYY-MM-DD)验证的出生日期。仅在验证方法提供时包含。如果方法可用,则始终包含

示例

{
"eventType": "Verification.Result",
"data": {
"id": "4e57301e-a4d1-498f-ac3f-f3d4de19abf6",
"status": "PASS",
"method": "id-document",
"age": {
"low": 43,
"high": 43
},
"dob": "1981-06-20"
}
}

验证事件合约

概述

此部分定义通过两种机制提供给您的验证状态的API合约:

  1. Webhook事件:验证完成时发送的Verification.Result Webhook事件
  2. API端点:用于轮询验证状态的GET /age-verification/get-status端点

此合约指定所有可能结果类型的字段存在规则、数据类型和解释指南。虽然两种机制提供类似的数据,但您必须注意状态值、字段存在和结构方面的重要差异。

DOM消息不是权威来源

验证结果也通过DOM消息传达给前端应用程序,用于UI控制目的。但是,只有webhook事件GET /age-verification/get-status端点响应应被视为集成逻辑的可靠、权威数据源。DOM消息仅用于前端应用程序状态管理,不应作为关键业务决策或数据持久化的基础。

数据结构

Webhook事件结构

Webhook事件包装在事件信封中:

{
"eventType": "Verification.Result",
"data": {
"id": "uuid",
"status": "PASS" | "FAIL",
"ageCategory": "adult" | "digital-youth" | "digital-minor" | null,
"method": "id-document" | "credit-card" | "self-confirmation" | "social-security-number" | "email-confirmation" | "age-estimation-scan" | null,
"age": {
"low": number,
"high": number
} | null,
"dob": "YYYY-MM-DD" | null,
"failureReason": string | null
}
}

API端点响应结构

GET /age-verification/get-status端点返回直接响应:

{
"id": "uuid",
"status": "PASS" | "FAIL" | "PENDING" | "IN_PROGRESS",
"ageCategory": "adult" | "digital-youth" | "digital-minor" | null,
"method": "id-document" | "credit-card" | "self-confirmation" | "social-security-number" | "email-confirmation" | "age-estimation-scan" | null,
"age": {
"low": number,
"high": number
} | null,
"dob": "YYYY-MM-DD" | null,
"failureReason": string | null
}

查询参数:

  • id (必需):验证 ID
  • includeDob (可选,默认:false):如果为 true,则在可用时包含 dob 字段

有关完整的端点文档,请参阅GET /age-verification/get-status

Webhook和API端点之间的主要差异

方面Webhook事件API端点
状态值PASSFAILPASSFAILPENDINGIN_PROGRESS
结构包装在 { eventType, data }直接响应对象
DOB字段如果可用则始终包含仅在设置了 includeDob=true 查询参数时包含
AgeCategory仅在状态为 PASS 时存在PASSFAIL 状态时都存在
Method仅在状态为 PASS 时存在PASSFAIL 状态时都存在
可用时间仅在验证完成时可以在任何时候轮询,包括验证期间

状态类型

PASS

验证成功确定用户满足年龄标准。

可用性:

  • Webhook: ✅ 验证成功完成时发送
  • API端点: ✅ 验证完成且成功时返回

FAIL

验证确定用户不满足年龄标准,或验证过程因无法做出结论性年龄判定,或检测到欺骗行为而失败。这些情况会导致FAIL状态,并带有适当的 failureReason 值。

可用性:

  • Webhook: ✅ 验证失败完成时发送
  • API端点: ✅ 验证完成且失败时返回

状态:PENDING

验证请求已创建但尚未开始处理。

可用性:

  • Webhook: ❌ 从不发送(webhook仅在完成时触发)
  • API端点: ✅ 验证处于初始状态时返回

PENDING的API端点响应:

  • id (UUID) - 始终包含
  • status ("PENDING") - 始终包含
  • 所有其他字段都不存在

状态:IN_PROGRESS

验证当前正在处理中。

可用性:

  • Webhook: ❌ 从不发送(webhook仅在完成时触发)
  • API端点: ✅ 验证正在积极处理时返回

IN_PROGRESS的API端点响应:

  • id (UUID) - 始终包含
  • status ("IN_PROGRESS") - 始终包含
  • 所有其他字段都不存在

按状态分类的字段存在规则

Webhook事件

Webhook事件仅在验证完成时(状态为 PASSFAIL)发送。它们不包括中间状态,如 PENDINGIN_PROGRESS

状态:PASS

Webhook事件

始终包含:

  • id (UUID)
  • status ("PASS")
  • method (string) - 使用的验证方法

有时包含:

  • ageCategory (string) - 其中之一:adultdigital-youthdigital-minor(仅在 age 存在时存在)
  • age (object) - 包含 lowhigh 边界(仅在验证方法提供年龄信息时存在)
  • dob (string, YYYY-MM-DD格式) - 验证的出生日期,仅在验证方法提供时(有关特定方法,请参阅出生日期字段部分)。如果可用,则始终包含。

从不包含:

  • failureReason

API端点

始终包含:

  • id (UUID)
  • status ("PASS")
  • method (string) - 使用的验证方法(如果可用)

有时包含:

  • ageCategory (string) - 其中之一:adultdigital-youthdigital-minor(当年龄存在时)
  • age (object) - 包含 lowhigh 边界(当验证方法提供年龄信息时)

有时包含:

  • dob (string, YYYY-MM-DD格式) - 仅在设置了 includeDob=true 查询参数且验证方法提供时包含(有关特定方法,请参阅出生日期字段部分)

从不包含:

  • failureReason
您需要了解的内容
  • 将PASS状态视为成功的验证
  • ageCategory 字段存在时,使用它来确定用户权限和访问级别
  • ageCategory 存在时,不要仅依赖 age.lowage.high 进行访问控制,而是使用 ageCategory
  • 如果提供了 dob,可以使用它,但不要假设它始终可用
  • 对于API端点:如果需要DOB数据,请在查询参数中设置 includeDob=true(请参阅GET /age-verification/get-status

状态:FAIL

Webhook事件

始终包含:

  • id (UUID)
  • status ("FAIL")
  • failureReason (string) - 失败原因

有时包含:

  • method (string) - 仅在失败不是由于 max-attempts-exceededfraudulent-activity-detected 导致时存在
  • age (object) - 仅在 failureReasonage-criteria-not-met 时存在
  • dob (string) - 仅在验证方法提供时存在(有关特定方法,请参阅出生日期字段部分)。如果可用,则始终包含。

从不包含:

  • ageCategory - Webhook事件仅在状态为 PASS 时包含 ageCategory

API端点

始终包含:

  • id (UUID)
  • status ("FAIL")
  • failureReason (string) - 失败原因

有时包含:

  • method (string) - 仅在失败是由于 age-criteria-not-met 导致时存在
  • age (object) - 仅在 failureReasonage-criteria-not-met 时存在
  • ageCategory (string) - 仅在 age 存在时存在
  • dob (string) - 仅在设置了 includeDob=true 查询参数且验证方法提供时包含(有关特定方法,请参阅出生日期字段部分)

从不包含:

  • age 不存在时的 ageCategory
您需要了解的内容
  • FAIL 状态视为不成功的验证,不要授予访问权限或权限
  • 始终检查 failureReason 以了解验证失败的原因
  • 不要假设FAIL状态存在 age 字段,它们可能不可用
  • 如果 FAIL 结果中存在 age,可以将其用于日志记录或分析,但不要将其用于访问控制决策
  • 处理 methodage 不存在的情况,这表示系统级失败,而不是年龄确定失败
  • 对于Webhook事件:FAIL 状态不会存在 ageCategory,因此不要尝试使用它
  • 对于API端点:即使 FAIL 状态存在 ageCategory,也不要将其用于访问控制决策

常见失败原因:

  • age-criteria-not-met - 用户的验证年龄不满足所需阈值
  • max-attempts-exceeded - 用户已用尽所有可用的验证尝试(这是用户在失败或不明确的年龄确定后用尽重试时的最终失败原因)
  • fraudulent-activity-detected - 系统检测到可疑或欺诈行为

年龄字段填充规则

age 对象存在时

age 对象包含两个字段:

  • low (number):年龄估计的下限,或硬验证方法(例如ID文档)的确切年龄
  • high (number):年龄估计的上限,或硬验证方法的确切年龄,或如果仅知道最小年龄则为150

age 存在的条件:

  • 验证方法提供了年龄信息
  • 对于FAIL状态:failureReasonage-criteria-not-met
您需要了解的内容
  • 在访问 age 对象之前,始终检查 age.lowage.high 是否存在
  • 不要假设 age.low === age.high 意味着您有确切年龄,可能是,但这取决于验证方法
  • status 不是PASS时,不要将 age 字段用于访问控制
  • 对于PASS状态,在做出访问决策时,优先使用 ageCategory 而不是原始 age

ageCategory 存在时

ageCategory 字段是从年龄和管辖区信息派生的。

值:

  • adult - 用户被分类为成人
  • digital-youth - 用户被分类为数字青年(年龄受限但不是未成年人)
  • digital-minor - 用户被分类为数字未成年人

ageCategory 存在的条件:

  • age 对象存在
  • 从年龄和管辖区成功计算了年龄类别
  • 对于FAIL状态:failureReasonage-criteria-not-met
您需要了解的内容
  • 当状态为PASS且 ageCategory 存在时,将 ageCategory 用于访问控制决策
  • 不要假设 ageCategory 始终存在,即使 age 存在
  • 处理 age 存在但 ageCategory 不存在的情况
  • 对于FAIL状态,即使存在 ageCategory,也不要将其用于访问控制决策

ageageCategory 不存在时

条件:

  • 验证以 max-attempts-exceededfailureReason 失败 - 未进行年龄确定
  • 验证以 fraudulent-activity-detectedfailureReason 失败 - 出于安全原因,年龄数据被排除
  • 验证方法未提供年龄信息
您需要了解的内容
  • 不要假设年龄信息始终可用,优雅地处理缺失的年龄字段
  • age 不存在时,不要尝试从其他字段推断年龄
  • 对于没有年龄字段的FAIL状态,依赖 failureReason 来了解出了什么问题

出生日期字段

格式: YYYY-MM-DD (ISO 8601日期格式)

存在时: dob 字段仅在验证方法提供验证的出生日期时包含。对于仅提供年龄估计或年龄范围的方法,不包含此字段。考虑到验证方法和管辖区的各种组合,您不应执行验证或对 dob 何时必须存在抱有期望。该字段在验证方法可用时提供,但不能保证在所有场景中都存在。

可以提供 dob 的方法:

  • id-document - 当ID文档包含可读的出生日期信息时
  • credit-card - 当信用卡验证提供出生日期时(并非所有信用卡验证都包含DOB)
  • social-security-number - 当SSN验证提供出生日期时
  • privy - 始终提供(印度尼西亚身份验证)
  • korean-real-name - 始终提供(通过Inicis进行的韩国实名验证)
  • age-attestation - 当证明包含出生日期信息时
  • singpass - 始终提供(新加坡国民身份验证)

从不提供 dob 的方法:

  • age-estimation-scan - 仅提供年龄范围,不提供验证的DOB
  • email-confirmation - 仅提供年龄估计,不提供验证的DOB
  • email-estimation - 仅提供年龄估计,不提供验证的DOB
  • self-confirmation - 没有可用的验证DOB

状态条件:

  • 当方法提供时,在PASS状态时存在
  • 当方法在确定用户不满足年龄标准之前提供时,在FAIL状态时存在
您需要了解的内容
  • 不要假设 dob 始终存在,即使对于PASS状态
  • 如果 dob 存在,请验证其格式为 YYYY-MM-DD
  • 可以将 dob 用于额外验证或日志记录,但不要将其作为确定年龄的主要方式

方法字段

存在时:

  • PASS状态时始终存在
  • FAIL状态时,当 failureReasonage-criteria-not-met 时存在

可能的值:

  • id-document - 政府签发的ID文档验证(可以包含DOB)
  • credit-card - 信用卡验证(可以包含DOB)
  • self-confirmation - 自我声明的年龄确认(无DOB)
  • age-estimation-scan - 通过文档扫描进行年龄估计(无DOB,仅年龄范围)
  • social-security-number - 基于SSN的验证(可以包含DOB)
  • email-confirmation - 基于电子邮件的年龄验证(无DOB,仅年龄估计)
  • email-estimation - 基于电子邮件的年龄估计(无DOB,仅年龄估计)
  • privy - 印度尼西亚身份验证(始终包含DOB)
  • korean-real-name - 通过Inicis进行的韩国实名验证(始终包含DOB)
  • age-attestation - 通过k-ID进行的年龄证明(可以包含DOB)
  • singpass - 新加坡国民身份验证(始终包含DOB)
  • connect-id - 澳大利亚ConnectID验证
您需要了解的内容
  • 可以将 method 用于分析或日志记录目的
  • 不要将 method 用于访问控制决策

失败原因值

常见的 failureReason 值:

  • age-criteria-not-met - 用户的验证年龄不满足所需阈值
  • max-attempts-exceeded - 用户已用尽所有可用的验证尝试
  • fraudulent-activity-detected - 系统检测到可疑或欺诈行为
您需要了解的内容
  • 优雅地处理未知的 failureReason 值,如果看到意外值,不要中断
  • 不要仅基于 failureReason 做出访问决策,始终考虑 status 字段
  • 建议记录 failureReason 用于调试和分析目的

完整字段矩阵

Webhook事件

字段PASSFAIL
idalwaysalways
statusalwaysalways
methodalwayssometimes¹
ageCategorysometimes²never
agesometimes²sometimes³
dobsometimes⁴sometimes⁴
failureReasonneveralways

¹ 除非 failureReasonmax-attempts-exceededfraudulent-activity-detected,否则存在
² 仅当 age.lowage.high 都可用时存在
³ 仅当 age.lowage.high 都可用且 failureReason 不是 max-attempts-exceededfraudulent-activity-detected 时存在
⁴ 如果验证方法可用,则始终包含

API端点

字段PENDINGIN_PROGRESSPASSFAIL
idalwaysalwaysalwaysalways
statusalwaysalwaysalwaysalways
methodneverneversometimes²sometimes¹
ageCategoryneverneversometimes²sometimes²
ageneverneversometimes²sometimes³
dobneverneversometimes⁴sometimes⁴
failureReasonneverneverneveralways

¹ 除非 failureReasonmax-attempts-exceededfraudulent-activity-detected,否则存在
² 仅当 age.lowage.high 都可用时存在
³ 仅当 age.lowage.high 都可用且 failureReason 不是 max-attempts-exceededfraudulent-activity-detected 时存在
⁴ 仅在设置了 includeDob=true 查询参数且验证方法可用时包含

示例负载

Webhook事件示例

包含年龄信息的 PASS 状态

{
"eventType": "Verification.Result",
"data": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"status": "PASS",
"method": "id-document",
"ageCategory": "adult",
"age": {
"low": 25,
"high": 25
},
"dob": "1998-05-15"
}
}

包含年龄信息的 FAIL 状态

{
"eventType": "Verification.Result",
"data": {
"id": "123e4567-e89b-12d3-a456-426614174001",
"status": "FAIL",
"method": "age-estimation-scan",
"failureReason": "age-criteria-not-met",
"age": {
"low": 16,
"high": 17
}
}
}

不包含年龄信息的 FAIL 状态

{
"eventType": "Verification.Result",
"data": {
"id": "123e4567-e89b-12d3-a456-426614174002",
"status": "FAIL",
"failureReason": "max-attempts-exceeded"
}
}

API端点响应示例

PENDING 状态

{
"id": "123e4567-e89b-12d3-a456-426614174003",
"status": "PENDING"
}

IN_PROGRESS 状态

{
"id": "123e4567-e89b-12d3-a456-426614174004",
"status": "IN_PROGRESS"
}

包含年龄信息的 PASS 状态(无DOB)

{
"id": "123e4567-e89b-12d3-a456-426614174000",
"status": "PASS",
"method": "id-document",
"ageCategory": "adult",
"age": {
"low": 25,
"high": 25
}
}

包含DOB的 PASS 状态(includeDob = true

{
"id": "123e4567-e89b-12d3-a456-426614174000",
"status": "PASS",
"method": "id-document",
"ageCategory": "adult",
"age": {
"low": 25,
"high": 25
},
"dob": "1998-05-15"
}

包含年龄信息的 FAIL 状态

{
"id": "123e4567-e89b-12d3-a456-426614174001",
"status": "FAIL",
"method": "age-estimation-scan",
"failureReason": "age-criteria-not-met",
"age": {
"low": 16,
"high": 17
},
"ageCategory": "digital-minor"
}

不包含年龄信息的 FAIL 状态

{
"id": "123e4567-e89b-12d3-a456-426614174002",
"status": "FAIL",
"failureReason": "max-attempts-exceeded"
}

实现检查清单

Webhook事件

  • 处理两种状态类型:PASS和FAIL(webhook从不发送PENDING或IN_PROGRESS)
  • 在访问 age.lowage.high 之前检查 age 对象是否存在
  • 当状态为PASS且 ageCategory 存在时,将 ageCategory 用于访问控制
  • 不要将 ageCategory 用于FAIL状态(webhook事件中不会存在)
  • 处理 method 不存在的情况(系统级失败)
  • 处理 ageageCategory 不存在的情况(某些失败场景)
  • 如果存在,验证 dob 格式(YYYY-MM-DD)
  • 记录 failureReason 用于调试
  • 不要为FAIL状态授予访问权限
  • 优雅地处理未知的 failureReason

API端点

  • 处理所有状态类型:PENDING、IN_PROGRESS、PASS和FAIL
  • 对于PENDING和IN_PROGRESS状态,仅期望 idstatus 字段
  • 如果需要DOB数据,设置 includeDob=true 查询参数(请参阅GET /age-verification/get-status
  • 在访问 age.lowage.high 之前检查 age 对象是否存在
  • 当状态为PASS且 ageCategory 存在时,将 ageCategory 用于访问控制
  • 当状态为FAIL时,即使存在,也不要将 ageCategory 用于访问控制
  • 处理 method 不存在的情况(系统级失败)
  • 处理 ageageCategory 不存在的情况(某些失败场景)
  • 如果存在,验证 dob 格式(YYYY-MM-DD)
  • 记录 failureReason 用于调试
  • 不要为FAIL状态授予访问权限
  • 优雅地处理未知的 failureReason
  • 为PENDING和IN_PROGRESS状态实现适当的轮询策略

实现说明

AgeCategory行为

ageCategory 字段在Webhook事件中仅在状态为PASS时包含。这确保年龄类别信息仅在验证成功时提供。请注意,API端点可以在某些情况下为FAIL状态包含 ageCategory,但您不应将其用于访问控制决策。

版本历史

  • 2024-12-05: 初始API合约文档