跳轉到主要內容

KYC · 客戶准入

用於個人客戶准入的非同步工作流:註冊客戶、安全恢復或發起執行、查詢狀態與審核結果,並為每個等待節點提交資料。

流程概覽

標準 KYC 工作流:

  1. 註冊客戶。
  2. 查詢現有執行記錄,以安全恢復流程並防止重複提交。
  3. 沒有現有執行記錄時,發起工作流。
  4. 查詢狀態,直到節點等待輸入、案件進入人工審核或執行到達終止狀態。
  5. 提交節點資料(OCR / 客戶資料 / 活體檢測 / OTP / 表單)。
  6. 工作流完成或轉入人工審核。

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 會根據事件類型及租戶設定匹配適用的已發佈工作流。

回應包含建立的 executionIdsync 處理標識及回應 code200 表示正常處理。403 表示額度不足;額度恢復前請勿重複建立執行。

3. 查詢執行狀態與審核結果

端點:workflow.execution.status(POST)。

{ "executionId": "exec-abc123def456" }
欄位說明
status目前工作流執行狀態
caseNo此執行在 WIDTH 中建立的案件編號
caseStatus目前案件審核狀態:UNASSIGNEDUNDER_REVIEWRETURNEDOTHER_GROUPAPPROVEDREJECTEDCLOSED
riskScore計算得出的風險評分(如適用)
resolvedAt案件達到最終處理結果的時間
狀態含義Action
RUNNINGExecuting, no node waitingContinue polling (2–5 sec)
WAITINGNode waiting for inputRead currentNode, submit data
COMPLETEDWorkflow finishedStop polling, read result
FAILEDExecution failedStop polling, contact support
TIMEOUTExceeded time limitStop polling, contact support
CANCELLEDExecution cancelledStop polling
人工審核屬於正常工作流狀態,並非 API 失敗。自動處理期間每 3–5 秒查詢一次。當 caseStatusUNASSIGNEDUNDER_REVIEWRETURNED 時,將查詢間隔放寬至 30–60 秒。執行達到終止狀態後停止查詢。

4. 提交節點資料

When status is WAITING, dispatch on currentNode.nodeType:

nodeTypeAPIPurpose
flow_action_identity_documentworkflow.kyc.ocrUpload ID, get OCR result
flow_action_individual_particularworkflow.kyc.particular.dataSubmit personal info
flow_action_liveness_testworkflow.kyc.liveness.dataSubmit liveness status
flow_action_validate_emailworkflow.kyc.otp.send/verifyEmail OTP
flow_action_validate_phoneworkflow.kyc.otp.send/verifyPhone OTP
flow_action_individual_required_documentworkflow.kyc.required.docSupporting documents
flow_action_individual_required_formsworkflow.kyc.required.formForms / 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"
}