KYC · 客户准入
用于个人客户准入的异步工作流:注册客户、安全恢复或发起执行、查询状态与审核结果,并为每个等待节点提交数据。
流程概览
标准 KYC 工作流:
- 注册客户。
- 查询现有执行记录,以安全恢复流程并防止重复提交。
- 没有现有执行记录时,发起工作流。
- 查询状态,直到节点等待输入、案件进入人工审核或执行到达终止状态。
- 提交节点数据(OCR / 客户资料 / 活体检测 / OTP / 表单)。
- 工作流完成或转入人工审核。
1. 注册客户
Endpoint: workflow.applicant.register (POST).
{
"customerId": "C_abc123",
"email": "john@example.com"
}
At least one of customerId or email is required. This API is idempotent.
2. 恢复或发起工作流
2.1 查询现有执行记录
接口:workflow.apply.query(POST)。创建执行前应按 customerId 查询。这样可以防止重复提交,并在请求超时或未收到发起响应时恢复 executionId。
{ "customerId": "C_abc123" }
如返回现有执行记录,请保留其 executionId 并继续查询状态。如没有执行记录,则发起新的工作流。
2.2 发起工作流
接口:workflow.apply.submit(POST)。请求应使用 apiVersion=2.0.0。
{
"eventType": "KYC",
"source": "API",
"data": {
"customerId": "C_abc123",
"referenceId": "onboarding-uuid-001"
}
}
workflowId 为可选字段。当集成需要明确选择已发布的工作流时提供该字段。否则,WIDTH 会根据事件类型及租户配置匹配适用的已发布工作流。
响应包含创建的 executionId、sync 处理标识及响应 code。200 表示正常处理。403 表示额度不足;额度恢复前请勿重复创建执行。
3. 查询执行状态与审核结果
接口:workflow.execution.status(POST)。
{ "executionId": "exec-abc123def456" }
| 字段 | 说明 |
|---|---|
status | 当前工作流执行状态 |
caseNo | 此执行在 WIDTH 中创建的案件编号 |
caseStatus | 当前案件审核状态:UNASSIGNED、UNDER_REVIEW、RETURNED、OTHER_GROUP、APPROVED、REJECTED 或 CLOSED |
riskScore | 计算得出的风险评分(如适用) |
resolvedAt | 案件达到最终处理结果的时间 |
| 状态 | 含义 | Action |
|---|---|---|
RUNNING | Executing, no node waiting | Continue polling (2–5 sec) |
WAITING | Node waiting for input | Read currentNode, submit data |
COMPLETED | Workflow finished | Stop polling, read result |
FAILED | Execution failed | Stop polling, contact support |
TIMEOUT | Exceeded time limit | Stop polling, contact support |
CANCELLED | Execution cancelled | Stop polling |
caseStatus 为 UNASSIGNED、UNDER_REVIEW 或 RETURNED 时,将查询间隔放宽至 30–60 秒。执行达到终止状态后停止查询。4. 提交节点数据
When status is WAITING, dispatch on currentNode.nodeType:
nodeType | API | Purpose |
|---|---|---|
flow_action_identity_document | workflow.kyc.ocr | Upload ID, get OCR result |
flow_action_individual_particular | workflow.kyc.particular.data | Submit personal info |
flow_action_liveness_test | workflow.kyc.liveness.data | Submit liveness status |
flow_action_validate_email | workflow.kyc.otp.send/verify | Email OTP |
flow_action_validate_phone | workflow.kyc.otp.send/verify | Phone OTP |
flow_action_individual_required_document | workflow.kyc.required.doc | Supporting documents |
flow_action_individual_required_forms | workflow.kyc.required.form | Forms / questionnaires |
flow_action_screen_check | (automatic) | AML / sanctions screening |
身份证件(OCR)
Submit: workflow.kyc.ocr (POST). Poll for OCR results at workflow.kyc.ocr.data after 2–5 seconds — OCR usually completes in 5–15 seconds.
{
"provider": "WIDTH",
"frontImage": "s3://workflow-kyc/.../front.jpg",
"backImage": "s3://workflow-kyc/.../back.jpg",
"documentType": "INTERNATIONAL_PASSPORT",
"region": "SG",
"executionId": "exec-abc123def456",
"callbackKey": "kyc:ocr:exec-abc123def456:...",
"referenceId": "onboarding-uuid-001"
}
客户信息提交
Endpoint: workflow.kyc.particular.data.
{
"executionId": "exec-abc123def456",
"callbackKey": "kyc:particular:exec-abc123def456:...",
"referenceId": "onboarding-uuid-001",
"personData": "{\"name\":\"John Smith\",\"dateOfBirth\":\"1990-01-15\",\"nationality\":\"SG\",\"sex\":\"MALE\",\"countryOfResidence\":\"SG\",\"address\":\"123 Main St\"}"
}
personData is a JSON-encoded string, not a nested object. Call JSON.stringify() on the data before placing it in the request body.活体检测
Endpoint: workflow.kyc.liveness.data.
{
"provider": "SELF",
"status": "PASS",
"scores": "{\"qualityScore\":1.0,\"brightnessScore\":100,\"brightnessStatus\":\"normal\"}",
"images": "{\"faceFull\":\"s3://workflow-kyc/.../selfie.jpg\"}",
"executionId": "exec-abc123def456",
"callbackKey": "kyc:liveness:exec-abc123def456:...",
"referenceId": "onboarding-uuid-001"
}
邮箱 / 手机 OTP
Two steps: workflow.kyc.otp.send then workflow.kyc.otp.verify.
// send
{
"type": "email",
"identity": "john@example.com",
"executionId": "exec-abc123def456",
"callbackKey": "kyc:email:exec-abc123def456:...",
"referenceId": "onboarding-uuid-001"
}
// verify
{
"type": "email",
"identity": "john@example.com",
"code": "985024",
"executionId": "exec-abc123def456",
"callbackKey": "kyc:email:exec-abc123def456:...",
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"referenceId": "onboarding-uuid-001"
}
必需证件
Endpoint: workflow.kyc.required.doc. After all docs are uploaded, call workflow.kyc.required.doc.submit to advance.
{
"doc": "{\"front\":{\"url\":\"s3://workflow-kyc/.../bill.pdf\",\"filename\":\"bill.pdf\",\"content_type\":\"application/pdf\",\"size\":85618}}",
"isRequired": true,
"docType": "UTILITY_TELEPHONE_BILL",
"extraData": "{\"issueDate\":\"2026-03-01\"}",
"executionId": "exec-abc123def456",
"callbackKey": "kyc:required_doc:exec-abc123def456:...",
"referenceId": "onboarding-uuid-001"
}
必需表单
Endpoint: workflow.kyc.required.form.
{
"formId": "IndividualForm",
"formData": "{\"field_source_of_funds\":\"EMPLOYMENT\",\"field_annual_income\":\"50000-100000\"}",
"executionId": "exec-abc123def456",
"callbackKey": "kyc:required_form:exec-abc123def456:...",
"referenceId": "onboarding-uuid-001"
}