KYC Magic Link
独立区域合同
此用例不使用 Unico 的 POST /v1/process 端点,也不使用 API/TCA 合同。集成对象为 Trully.ai(主机 api.trully.ai),通过 x-api-key 进行身份验证(而非 Bearer JWT),并使用专有响应模式。对于其他国家,请使用 Onboarding(全球)。
此用例解决的问题
KYC Magic Link 解决了在墨西哥执行身份识别流程的挑战,负责收集国家身份证件(INE)和面部生物特征。通过 Unico 托管的旅程,您可以借助自己的渠道(WhatsApp、短信、电子邮件)发送的链接,消除前端开发摩擦。
在以下情况下使用此用例:
- 您在墨西哥运营,且使用的身份证件为 INE(必须)。
在以下情况下请勿使用此用例:
- 用户不在墨西哥或使用其他证件 → 请查看其他入驻用例。
涉及的能力
在单个流程中执行的管道:
| 能力 | 是否必需 | 在流程中的作用 |
|---|---|---|
| Document Capture | 必需 | 采集 INE 证件图像。此用例中不支持文件复用——每个会话都需要重新采集。 |
| Liveness | 必需 | 活体检测——锚定流程的必要自拍。 |
| Risk Fraud Classification | 必需 | 交叉参考行为信号,标记与 CPF 相关的欺诈风险。 |
| Identity Verification | 可选(如已签约) | 使用 Unico 的身份库和附加信号,验证交易人脸是否属于所提供政府标识符的持有人。 |
前提条件
- API 密钥 — 由 Unico 的 Onboarding 项目经理提供。在
x-api-key请求头中发送。 - 公开 HTTPS 端点,用于接收 webhook(可选,但建议配置)。
- CORS 配置 — 在接收 webhook 的服务器上允许来源
https://verification.unico.app(生产环境)和https://verification.uat.unico.app(沙盒环境)。
分步实现
与其他用例不同,Magic Link 没有 flow 字段——集成直接与 Trully API 对接。该端点创建一个唯一的验证链接,您通过自有渠道分发给用户。
1. 创建 Magic Link
端点: POST https://sandbox.trully.ai/v2/magic-link
请求头:
| 请求头 | 必需 | 描述 |
|---|---|---|
x-api-key | 是 | 由 Unico Onboarding 项目经理提供的 API 密钥。 |
Content-Type | 是 | application/json |
请求体(application/json):
| 字段 | 类型 | 必需 | 描述 |
|---|---|---|---|
external_id | string | 否 | 请求的外部标识符,用于追踪和参考。 |
metadata | object | 否 | 配置参数容器。 |
metadata.phone | string | 否 | 用户的国际格式电话号码(例如 521234567890)。 |
metadata.redirect_url | string | 否 | KYC 流程完成后重定向用户的 URL。 |
metadata.webhook_url | string | 否 | KYC 流程完成后发送数据的 URL。此 webhook 将在客户端调用。出于安全原因,端点应使用 HTTPS。组件将等待一分钟等待您的 webhook 服务器响应——之 后将中断通信。流程不会受到 webhook 通信的任何影响。请确保在生产和沙盒环境中分别在 CORS 配置中允许 https://verification.unico.app 和 https://verification.uat.unico.app。 |
metadata.track_webhook_url | string | 否 | 发送用户处理的每个 KYC 步骤的 URL(参见下方 webhook 事件)。此 webhook 将在客户端调用。出于安全原因,端点应使用 HTTPS。组件将等待一分钟等待您的 webhook 服务器响应——之后将中断通信。流程不会受到 webhook 通信的任何影响。请确保在生产和沙盒环境中分别在 CORS 配置中允许 https://verification.unico.app 和 https://verification.uat.unico.app。 |
data.step 的可能值(发送至 track_webhook_url):
| 步骤 | 描述 |
|---|---|
form_start | 用户正在扫描证件。 |
form_document_front | 用户已采集 INE 正面。 |
form_document_back | 用户已采集 INE 背面。 |
form_document | 流程目前处于自拍步骤。 |
form_selfie | 用户已到达操作的最后步骤。 |
form_decision_maker | 操作返回系统响应。 |
示例请求:
curl -X POST https://sandbox.trully.ai/v2/magic-link \
-H "x-api-key: $TRULLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"external_id": "user-mx-12345",
"metadata": {
"phone": "521234567890",
"redirect_url": "https://app.client.com.mx/kyc-done",
"webhook_url": "https://app.client.com.mx/webhook/result",
"track_webhook_url": "https://app.client.com.mx/webhook/track"
}
}'
2. 接收令牌和链接 URL
响应字段:
| 字段 | 类型 | 描述 |
|---|---|---|
data.external_id | string(可为空) | 请求的外部标识符,用于追踪和参考。 |
data.created_on | string(日期时间) | Magic Link 的创建日期。 |
data.is_active | boolean | 若为 true,则 Magic Link 处于激活状态。 |
data.token | string | Magic Link 的令牌,用于将 KYC 流程与 Magic Link 关联。 |
data.magic_link_url | string(URI) | 用于启动 KYC 流程的 Magic URL 链接。 |
data.metadata.redirect_url | string(可为空) | KYC 流程完成后重定向用户的 URL。 |
data.metadata.webhook_url | string(可为空) | KYC 流程完成后发送数据的 URL。此 webhook 将在客户端调用。 |
data.metadata.track_webhook_url | string(可为空) | 发送用户处理的每个 KYC 步骤的 URL。此 webhook 将在客户端调用。 |
data.version | string | Magic Link 的版本。 |
version | string | 处理请求的 API 版本,用于追踪变更和兼容性。 |
status | string | 响应状态的文本表示,指示操作成功或失败。 |
status_code | integer | 响应的 HTTP 状态码,提供请求结果的标准化指示。 |
request_date | string(日期时间) | 请求的日期和时间,ISO 8601 格式。 |
request.metadata.redirect_url | string(可为空) | KYC 流程完成后重定向用户的 URL(请求回显)。 |
request.metadata.webhook_url | string(可为空) | 完成后发送 KYC 流程数据的 URL(请求回显)。 |
request.metadata.track_webhook_url | string(可为空) | 发送用户处理的每个 KYC 步骤的 URL(请求回显)。 |
示例响应:
{
"data": {
"external_id": null,
"created_on": "2025-07-28T18:11:54.430048399Z",
"is_active": true,
"token": "3f6dbcc1-49ba-4935-be90-dd8dd59b5530",
"magic_link_url": "https://verification.uat.unico.app/link/v2/3f6dbcc1-49ba-4935-be90-dd8dd59b5530",
"metadata": {
"redirect_url": null,
"webhook_url": null,
"track_webhook_url": null
},
"version": "v2"
},
"version": "v1.4.2",
"status": "ok",
"status_code": 200,
"request_date": "2025-07-28T18:11:54+0000",
"request": {
"metadata": {
"redirect_url": null,
"webhook_url": null,
"track_webhook_url": null
}
}
}
错误响应 — POST /v2/magic-link
| 代码 | 消息 | 描述 |
|---|---|---|
400 Bad Request | data provided in the field is invalid | 请求 payload 中的数据结构或字段值无效。检查必需字段 和格式。 |
403 Forbidden | Forbidden | API 密钥缺失、已过期或无权限。请验证 x-api-key 请求头。 |
500 Internal Server Error | internal server error | 服务器端处理失败。使用指数退避进行重试。如果持续出现,请联系支持团队。 |
400 响应示例:
{
"data": {
"error": "data provided in the field is invalid"
},
"version": "v1.4.2",
"status": "bad request",
"status_code": 400,
"request_date": "2025-07-28T20:22:29+0000",
"request": {
"metadata": null
}
}
3. 将 magic_link_url 分发给用户
通过 WhatsApp、短信、电子邮件发送或嵌入页面。用户在自己的设备上访问链接并完成托管旅程。
4. 接收结果
- 通过 GET 轮询(必需)— 定期调用
GET /v2/history/request?magic_link_token={token},直到unico.result有值为止。参见下方的通过 GET 轮询。 - Webhook(可选)— 与您的 Onboarding PM 配置以自动接收事件。参见下方的 Webhook。
通过 GET 轮询
端点: GET https://sandbox.trully.ai/v2/history/request
查询参数:
| 参数 | 类型 | 必需 | 描述 |
|---|---|---|---|
magic_link_token | string | 是 | 创建 Magic Link 时返回的令牌。 |
请求头:
| 请求头 | 必需 | 描述 |
|---|---|---|
x-api-key | 是 | 由 Unico Onboarding 项目经理提供的 API 密钥。 |
示例请求:
curl "https://sandbox.trully.ai/v2/history/request?magic_link_token=$TOKEN" \
-H "x-api-key: $TRULLY_API_KEY"
示例响应:
{
"data": {
"images": {
"document_image": "/9j/4ASu7bmV[...]fyPjOKfgif//Z",
"document_image_back": "/9j/4ASu7bmV[...]fyPjOKfgif//Z",
"selfie": "/9j/4ASu7bmV[...]fyPjOKfgif//Z"
},
"response": {
"curp": {
"age": 58,
"curp": "GOCJ850627HDFRRL09",
"date_of_birth": "14/11/1956",
"deceased": false,
"gender": "M",
"government_name": "LUKE SKYWALKER",
"government_valid": true,
"is_mexican": true,
"name_to_CURP_valid": true,
"state_iso": "MX-NLE",
"state_of_birth": "Nuevo León"
},
"document": {
"back": {
"cic": "237457894",
"citizen_id": "237457894",
"mrz": "IDMEX999999999999<9 VADER<SKYWALKER<<LUKE"
},
"details": {
"detected": true,
"document_id": 229928,
"forensics": { "is_valid": "no" }
},
"front": {
"face_analysis": {
"face_id": 237437,
"face_id_v2": 199068,
"first_seen": "12/22/2022, 18:54:09",
"inquiry_date": "07/28/2025, 20:53:12",
"last_seen": "07/28/2025, 18:47:46",
"last_seen_by_your_company": "07/24/2025, 21:38:21",
"match": true,
"match_fraud_flag": true,
"seen_by_your_company": true,
"seen_different_companies": 46,
"times_seen_by_your_company": 3,
"times_seen_last_month": 111,
"unique_face_id_v2": 126880,
"warnings": {
"external_id": "User found in the company with other external_ids: ['abc-123']"
}
},
"information": {
"address": { "text": "DOMICILIO/ADDRESS, HARLINGEN, TX 78552", "valid": false },
"birthdate": { "text": "14/11/1956", "valid": true },
"complete_name": { "text": "LUKE SKYWALKER", "valid": true },
"curp": { "text": "GOCJ850627HDFRRL09", "valid": true },
"electoral_key": { "text": "GRCRSN82031007M500", "valid": true },
"last_name": { "text": "SKYWALKER", "valid": true },
"mother_last_name": { "text": "ORGANA", "valid": true },
"name": { "text": "LUKE", "valid": true },
"registration_year": { "text": "1998", "valid": true },
"sex": { "text": "H", "valid": true },
"valid_thru": { "text": "2027", "valid": true }
}
}
},
"face_match": false,
"label": null,
"reason": null,
"request_id": "d1kxp9ah8f0s71uv9zx0",
"selfie": {
"face_id": 237436,
"face_id_v2": 4378,
"first_seen": "02/05/2025, 02:36:19",
"first_seen_image": true,
"inquiry_date": "07/28/2025, 20:52:49",
"last_seen": "07/28/2025, 20:52:51",
"last_seen_by_your_company": "07/23/2025, 18:14:27",
"match": true,
"match_fraud_flag": true,
"seen_by_your_company": true,
"seen_different_companies": 2,
"times_seen_by_your_company": 2,
"times_seen_last_month": 7,
"unique_face_id_v2": 494,
"warnings": {}
},
"unico": {
"process_id": "d333dfac-9ddb-4066-8e2c-44eaf4c86b4a",
"result": "PROCESS_RESULT_LIVE"
}
},
"user_id": ""
},
"request_date": "2025-07-28T20:53:38",
"status": "Request fulfilled, document follows",
"status_code": 200,
"version": "v3.6.0"
}
响应字段:
根级别:
| 字段 | 类型 | 描述 |
|---|---|---|
status | string | 响应状态的文本表示。 |
status_code | integer | HTTP 状态码。 |
request_date | string(日期时间) | 请求的日期和时间。 |
version | string | 处理请求的 API 版本。 |
data.user_id | string | 原始请求中设置的用户 ID。 |
data.images — Base64 编码的采集图像:
| 字段 | 类型 |
|---|