mcpField
D
didit-kyc-onboarding

didit-kyc-onboarding

github.com/didit-protocol安全29282 次安装2 周前更新
代码仓库

关于 didit-kyc-onboarding

用于通过 Didit 配置工作流、创建用户验证会话并获取审核结果的 KYC 接入技能,面向需要在注册流程中加入身份核验的开发者。

主要功能

  1. 01配置可复用的 KYC 工作流
  2. 02创建用户验证会话
  3. 03向用户提供验证 URL
  4. 04通过轮询或 Webhook 获取结果
  5. 05执行证件与自拍核验

适用场景

  1. 01在用户注册中加入身份验证
  2. 02向用户发送验证链接
  3. 03收集已完成核验的结果

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/didit-protocol/skills --skill didit-kyc-onboarding

安装后在 Claude Code 中输入/didit-kyc-onboarding确认已加载。

附带文件scripts/run_kyc.py

详细介绍

使用 Didit 进行 KYC

端到端的客户身份识别(KYC)验证。此技能会创建 KYC 工作流,生成一个会话 URL,供真实用户完成身份证件扫描 + 自拍 + 人脸匹配,并获取验证结果。

用户体验:

  1. 收到验证链接(或在你的应用中打开该链接)
  2. 扫描身份证件(护照、身份证、驾驶证、居留许可)
  3. 拍摄实时自拍照
  4. 将自拍照与证件照片进行匹配
  5. 获批、被拒或标记为待审核

**定价:**在一个工作流中,你只需为已完成的功能付费:身份证件验证(证件采集)$0.15、被动活体检测 $0.10、人脸匹配 $0.05;每个组织每月各有 500 次免费检查;主动活体检测(ACTIVE_3D 或 FLASHING)$0.15、NFC $0.15、AML 筛查 $0.20、电子邮件验证 $0.03、电话验证 $0.04 + 运营商费用。这些是截至 2026 年 11 月 1 日的标价,届时 Didit 将调整定价,每月 500 次免费检查将改为每月 $10 的免费额度。请查看 didit.me/pricing 了解当前价格。

API 参考:

相关技能:didit-sdk-integration(将会话嵌入 Web 或移动应用,而不是发送链接)、didit-case-management(审核 In Review 会话的队列)、didit-verification-management(Webhook、用户、账单)。


身份验证

每个请求都需要 x-api-key 标头。使用你在 Didit Business Console 的 Developers > API keys 下找到的应用 API 密钥,或者通过程序化方式创建账户和密钥(参见“开始使用”)。具有自定义访问权限的命名密钥需要 Workflows 写入权限才能创建工作流,需要 Sessions 写入权限才能创建会话(否则 url 和 session_token 会返回 null),需要 Decisions 读取权限来获取结果,以及 Media 读取权限来获取图片 URL 和 PDF 报告。

开始使用(还没有账户?)

如果你没有 Didit API 密钥,只需通过 2 次 API 调用即可创建:

  1. **注册:**使用 {"email": "[email protected]", "password": "MyStr0ng!Pass"} 调用 POST https://apx.didit.me/auth/v2/programmatic/register/
  2. 检查电子邮件,获取 6 位验证码
  3. **验证:**使用 {"email": "[email protected]", "code": "A3K9F2"} 调用 POST https://apx.didit.me/auth/v2/programmatic/verify-email/。密钥位于响应的 application.api_key 中。

**添加额度:**调用 GET /v3/billing/balance/ 进行查询,调用 POST /v3/billing/top-up/ 并传入 {"amount_in_dollars": 50} 获取 Stripe 结账链接。

如需了解完整的平台管理功能(工作流、会话、用户、账单),请参阅 didit-verification-management 技能。


快速开始:通过 3 次 API 调用完成 KYC

import requests, time

API_KEY = "your_api_key"
headers = {"x-api-key": API_KEY, "Content-Type": "application/json"}
BASE = "https://verification.didit.me/v3"
TERMINAL = {"Approved", "Declined", "In Review", "Expired", "Kyc Expired", "Abandoned"}

# 1. Create a KYC workflow (one-time setup: reuse the workflow id for all users)
workflow = requests.post(f"{BASE}/workflows/", headers=headers, json={
    "workflow_label": "KYC Onboarding",
    "max_retry_attempts": 3,
    "features": [
        {"feature": "OCR"},
        {"feature": "LIVENESS", "config": {"face_liveness_method": "PASSIVE"}},
        {"feature": "FACE_MATCH", "config": {"face_match_score_decline_threshold": 50}},
    ],
}).json()
workflow_id = workflow["uuid"]

# 2. Create a session for a specific user
session = requests.post(f"{BASE}/session/", headers=headers, json={
    "workflow_id": workflow_id,
    "vendor_data": "user-abc-123",
    "callback": "https://yourapp.com/verification-done",
    "language": "en",
}).json()

print(f"Send user to: {session['url']}")
# User opens this URL, scans their ID, takes a selfie

# 3. Poll for the decision (or use webhooks)
while True:
    decision = requests.get(
        f"{BASE}/session/{session['session_id']}/decision/",
        headers={"x-api-key": API_KEY},
    ).json()
    status = decision["status"]
    if status in TERMINAL:
        break
    time.sleep(15)

print(f"Result: {status}")
if status == "Approved":
    id_data = decision["id_verifications"][0]
    print(f"Name: {id_data['first_name']} {id_data['last_name']}")
    print(f"DOB: {id_data['date_of_birth']}")
    print(f"Document: {id_data['document_type']} ({id_data['issuing_state']})")

第 1 步:创建 KYC 工作流

工作流定义了要运行哪些检查。每种用例创建一个工作流,并供所有用户重复使用。每个应用最多可创建 50 个工作流;每次调用都会创建一个新工作流。

POST https://verification.didit.me/v3/workflows/

**API 参考:**https://docs.didit.me/management-api/workflows/create

请求正文

请求正文仅接受以下键;任何其他键(包括 workflow_type)都会返回 400。

字段类型默认值描述
featuresarray必填按执行顺序排列的步骤:{"feature": "...", "config": {...}, "label": "..."}
workflow_labelstring"ID Verification"显示名称,最多 50 个字符
max_retry_attemptsinteger 0-103拒绝后允许重试的次数;0 表示首次拒绝后即停止
retry_window_daysinteger 1-365 or null7计算重试次数的滚动时间窗口;null = 计算所有历史记录
session_expiration_timeinteger 3600-2419200604800(7 天)未完成的会话过期前的秒数
face_liveness_max_attemptsinteger 1-33每个会话的活体检测提交次数
face_match_max_attemptsinteger 1-33每个会话的人脸匹配提交次数
is_defaultboolean-将其设为应用程序的默认工作流
statusdraft 或 publishedpublished省略时立即发布
is_white_label_enabledbooleanfalse应用你的白标自定义设置
is_desktop_allowedbooleanfalse允许在桌面浏览器中运行此流程
KYC 功能及其主要配置
feature配置备注
OCRdocuments_allowed、methods、duplicated_user_action、年龄和风险操作身份证件采集。将其放在第一步,以便后续步骤使用其数据
LIVENESSface_liveness_method:PASSIVE、ACTIVE_3D(3D 动作和闪光)或 FLASHING(3D 闪光)主动方式按 Active Liveness 计费($0.15)
FACE_MATCHface_match_score_decline_threshold、face_match_score_review_threshold(0-100)必须位于 OCR 之后
NFCallow_nfc_skip、skip_nfc_action、unverified_chip_action必须位于 OCR 之后;通过原生 iOS/Android SDK 读取芯片,在 Web 浏览器中会跳过
AMLaml_score_review_threshold、aml_score_approve_threshold需要在其前面配置 OCR
PHONE_VERIFICATION、EMAIL_VERIFICATION参见功能配置联系方式验证

配置中的操作可设为 DECLINE、REVIEW 或 NO_ACTION。其他功能(IP_ANALYSIS、PROOF_OF_ADDRESS、DATABASE_VALIDATION、QUESTIONNAIRE、AGE_ESTIMATION、DOCUMENT_AI)以及所有配置键,详见功能配置参考。

响应(201)

响应是完整的工作流配置(约 190 个字段)。主要字段:

{
  "uuid": "c3d4e5f6-7890-12cd-ef34-333333333333",
  "workflow_id": "c3d4e5f6-7890-12cd-ef34-333333333333",
  "workflow_label": "KYC Onboarding",
  "features": "OCR + LIVENESS + FACE_MATCH",
  "total_price": 0.3,
  "min_price": 0.3,
  "max_price": 0.3,
  "workflow_url": "https://verify.didit.me/u/w9TkPOx8RWG3UAz5ZRQGVQ",
  "max_retry_attempts": 3,
  "retry_window_days": 7,
  "session_expiration_time": 604800,
  "status": "published",
  "version": 1
}

保存 uuid(与 workflow_id 的值相同)。features 是由 " + " 拼接而成的字符串;价格是以美元计的 JSON 数字(按你的费率计算已启用功能的总和)。


第 2 步:为每位用户创建会话

每位用户都会获得自己的会话,其中包含唯一的验证 URL。

POST https://verification.didit.me/v3/session/

API 参考: https://docs.didit.me/sessions-api/create-session

关键参数
参数类型必填描述
workflow_iduuid是来自第 1 步
vendor_datastring建议填写您的用户 ID:用于按用户分组会话并支持重复检测。同一工作流版本中,如果存在 vendor_data 相同的未完成会话,系统会返回该会话,而不是新建会话
callbackurl建议填写验证后重定向到的地址。Didit 会将 verificationSessionId 和 status 作为查询参数附加
callback_methodstring否initiator、completer 或 both(跟随回调的设备)
languagestring否UI 语言(ISO 639-1)。省略时会自动检测
contact_detailsobject否email、send_notification_emails、email_lang、phone(E.164)
expected_detailsobject否first_name、last_name、date_of_birth(YYYY-MM-DD)、gender、nationality、id_country、identification_number、expected_document_types 等。不匹配会添加 *_MISMATCH_WITH_PROVIDED 警告
metadataany JSON否与会话一同存储,并在响应和 Webhook 中回传。接受任意 JSON 值;建议使用对象
响应(201)
{
  "session_id": "11111111-2222-3333-4444-555555555555",
  "session_number": 43762,
  "session_token": "3FaJ9wLqX2Mz",
  "url": "https://verify.didit.me/session/3FaJ9wLqX2Mz",
  "vendor_data": "user-abc-123",
  "metadata": null,
  "status": "Not Started",
  "workflow_id": "c3d4e5f6-7890-12cd-ef34-333333333333",
  "workflow_version": 1,
  "callback": "https://yourapp.com/verification-done"
}

将用户发送到 url(网页或移动端),或使用 SDK 嵌入会话(didit-sdk-integration 技能)。请将 session_token 视为机密:持有该令牌的任何人都可以完成验证。


第 3 步:获取判定结果

GET https://verification.didit.me/v3/session/{sessionId}/decision/

API 参考: https://docs.didit.me/sessions-api/retrieve-session

获取就绪状态的两种方式

方式 A:Webhook(生产环境推荐) 在 Business Console(Webhooks)中添加目标地址,或使用 POST /v3/webhook/destinations/(label、url、webhook_version: "v3"、subscribed_events: ["status.updated"])。Didit 会发送包含 session_id、status 的签名 POST;当状态为 Approved、Declined、In Review 或 Abandoned 时,还会发送完整的 decision。请验证签名(参见 didit-verification-management),并确保处理程序根据 event_id 实现幂等。

方式 B:轮询 每隔 10 到 30 秒轮询一次 GET /v3/session/{sessionId}/decision/。遇到终态时停止:Approved、Declined、In Review、Expired、Kyc Expired 或 Abandoned。人工审核后,In Review 状态仍可能变化,因此请保留 Webhook。

判定响应字段

每个功能都有各自的数组,其中包含各自的 status、node_id 和 warnings。顶层没有 warnings 键。

{
  "session_id": "11111111-2222-3333-4444-555555555555",
  "session_number": 43762,
  "status": "Approved",
  "workflow_id": "c3d4e5f6-7890-12cd-ef34-333333333333",
  "features": ["ID_VERIFICATION", "LIVENESS", "FACE_MATCH"],
  "vendor_data": "user-abc-123",
  "metadata": null,
  "id_verifications": [{
    "node_id": "ocr",
    "verification_method": "document",
    "status": "Approved",
    "document_type": "Passport",
    "document_number": "ABC123456",
    "issuing_state": "USA",
    "issuing_state_name": "United States",
    "first_name": "Alex",
    "last_name": "Sample",
    "full_name": "Alex Sample",
    "date_of_birth": "1990-01-15",
    "age": 36,
    "expiration_date": "2030-06-01",
    "gender": "M",
    "nationality": "USA",
    "mrz": {"surname": "SAMPLE", "name": "ALEX", "document_type": "P", "document_number": "ABC123456", "birth_date": "900115", "expiry_date": "300601", "sex": "M"},
    "portrait_image": "https://<media-host>/...",
    "warnings": []
  }],
  "liveness_checks": [{
    "node_id": "liveness",
    "status": "Approved",
    "method": "PASSIVE",
    "score": 92.5,
    "warnings": []
  }],
  "face_matches": [{
    "node_id": "face_match",
    "status": "Approved",
    "score": 97.3,
    "warnings": []
  }],
  "aml_screenings": [],
  "created_at": "2026-05-17T10:30:00Z"
}

字段说明:

  • document_type 是显示名称:Passport、Identity Card、Driver's License、Residence Permit 等。
  • issuing_state 和 nationality 使用 ISO 3166-1 alpha-3。日期格式为 YYYY-MM-DD;MRZ 日期为原始的 YYMMDD。mrz 是一个对象;未读取到 MRZ 时为 null。
  • 功能状态(Approved、Declined、In Review、Not Finished 等)与会话 status 相互独立。
  • id_verifications 中的 verification_method 为 document、id_lookup 或 wallet。
  • 警告:{feature, risk, additional_data, log_type, short_description, long_description, node_id}。请参阅 didit-id-document-verification 技能和 https://docs.didit.me/core-technology/id-verification/warnings-id-verification。
会话状态
状态含义操作
Not Started会话已创建,但尚未打开链接等待或提醒用户
In Progress用户正在完成步骤等待
Awaiting User企业(KYB)会话正在等待相关人员完成 KYC 会话等待
Resubmitted已要求用户重新完成特定步骤等待新结果
Approved所有检查均已通过用户已验证
Declined一项或多项检查未通过查看每项功能的 warnings
In Review需要人工审核在控制台中审核,或通过 API 决定(见下文)
Expired会话在完成前已过期(默认为 7 天,session_expiration_time)创建新会话
Abandoned用户已开始,但未在规定时间内完成创建新会话
Kyc Expired先前已批准的会话已超过其 KYC 过期政策规定的期限重新验证用户

这些值是精确区分大小写的字符串(Kyc Expired 中只有 K 是大写)。


可选:决策后的操作

手动批准或拒绝
PATCH https://verification.didit.me/v3/session/{sessionId}/update-status/

API 参考: https://docs.didit.me/sessions-api/update-status

会话必须处于 Approved、Declined、In Review、Kyc Expired、Abandoned 或 Resubmitted 状态,且新状态必须与当前状态不同(否则返回 400)。

requests.patch(f"{BASE}/session/{session_id}/update-status/",
    headers=headers,
    json={"new_status": "Approved", "comment": "Manual review passed"})
要求重新提交

如果证件照片模糊,可要求用户仅重新完成该步骤。从决策中获取 node_id:通过此 API 创建的工作流使用 ocr、liveness、face_match 等 ID;通过控制台创建的工作流使用 feature_ocr 等 ID。

decision = requests.get(f"{BASE}/session/{session_id}/decision/", headers=headers).json()
ocr_node = decision["id_verifications"][0]["node_id"]

requests.patch(f"{BASE}/session/{session_id}/update-status/",
    headers=headers,
    json={
        "new_status": "Resubmitted",
        "nodes_to_resubmit": [{"node_id": ocr_node, "feature": "OCR"}],
        "send_email": True,
        "email_address": "[email protected]",
    })

省略 nodes_to_resubmit,即可重新提交所有已尝试且状态为 Declined、In Review、Not Finished 或 Expired 的步骤(NFC 和 IP 分析不会自动选中)。这些步骤采集的数据将被删除,过期时间窗口将重新开始,原验证 URL 也将恢复可用。

屏蔽欺诈用户

通过 Lists API 将会话中的人脸或证件添加到系统屏蔽列表(每个应用针对每种条目类型都有一个屏蔽列表):

lists = requests.get(f"{BASE}/lists/", headers=headers,
                     params={"list_type": "blocklist", "entry_type": "face"}).json()
list_uuid = lists["results"][0]["uuid"]
requests.post(f"{BASE}/lists/{list_uuid}/entries/",
    headers=headers,
    json={"reference_session_id": session_id})

API 参考: https://docs.didit.me/management-api/lists/create-entry

生成 PDF 报告

适用于状态为 Approved、Declined、In Review 或 Kyc Expired 的会话。返回 application/pdf 字节数据。

response = requests.get(f"{BASE}/session/{session_id}/generate-pdf/",
    headers={"x-api-key": API_KEY})
with open("report.pdf", "wb") as f:
    f.write(response.content)

API 参考: https://docs.didit.me/sessions-api/generate-pdf

错误响应
代码含义操作
400请求无效查看响应正文中的字段错误
401API 密钥已过期轮换密钥,或在 Developers > API keys 中创建新密钥
403API 密钥缺失、错误或已撤销;受限密钥无权访问此端点;请求来自密钥 IP 允许列表之外;或额度不足查看 detail 或 error 中的消息:修复 x-api-key 请求头或密钥权限,或充值
404未找到会话(或该会话不属于受限密钥的工作流)检查 sessionId
429超出速率限制:每个密钥每分钟 300 个 POST/PATCH/DELETE 请求和 600 个 GET 请求等待 Retry-After 指定的秒数,然后重试

KYC 工作流变体

KYC + AML 筛查
requests.post(f"{BASE}/workflows/", headers=headers, json={
    "workflow_label": "KYC + AML",
    "features": [
        {"feature": "OCR"},
        {"feature": "LIVENESS", "config": {"face_liveness_method": "PASSIVE"}},
        {"feature": "FACE_MATCH"},
        {"feature": "AML"},
    ],
})
KYC + 电话 + 电子邮件
requests.post(f"{BASE}/workflows/", headers=headers, json={
    "workflow_label": "KYC + Contact",
    "features": [
        {"feature": "OCR"},
        {"feature": "LIVENESS", "config": {"face_liveness_method": "PASSIVE"}},
        {"feature": "FACE_MATCH"},
        {"feature": "PHONE_VERIFICATION"},
        {"feature": "EMAIL_VERIFICATION"},
    ],
})
KYC + NFC(芯片读取)

为带芯片的护照和电子身份证提供最高级别的保障。需要使用原生 iOS/Android SDK;网页流程会跳过 NFC。

requests.post(f"{BASE}/workflows/", headers=headers, json={
    "workflow_label": "KYC + NFC",
    "features": [
        {"feature": "OCR"},
        {"feature": "NFC"},
        {"feature": "LIVENESS", "config": {"face_liveness_method": "PASSIVE"}},
        {"feature": "FACE_MATCH"},
    ],
})
更严格的活体检测和会话设置
requests.post(f"{BASE}/workflows/", headers=headers, json={
    "workflow_label": "KYC High Assurance",
    "max_retry_attempts": 1,
    "retry_window_days": 30,
    "session_expiration_time": 86400,
    "face_liveness_max_attempts": 2,
    "features": [
        {"feature": "OCR"},
        {"feature": "LIVENESS", "config": {"face_liveness_method": "FLASHING"}},
        {"feature": "FACE_MATCH", "config": {"face_match_score_decline_threshold": 60}},
    ],
})
各国家的非文档查询与数字 ID 钱包

OCR 功能的 config.methods 按 ISO 3166-1 alpha-3 国家代码选择用户可使用的 ID Verification 方法:文档采集、查询政府登记册或其他权威来源(用户输入其国家 ID 号码),以及数字 ID 钱包。未指定的国家仍仅支持文档采集。每种方法和钱包都必须在该国家的能力目录(控制台 Countries 标签页)中标记为可用,否则整个保存操作都会被拒绝。

requests.post(f"{BASE}/workflows/", headers=headers, json={
    "workflow_label": "KYC with lookup",
    "features": [
        {"feature": "OCR", "config": {"methods": {
            "ZAF": {
                "document": {"enabled": True},
                "id_lookup": {"enabled": True, "max_attempts": 2,
                              "on_no_match": "fallback_to_document"},
            },
        }}},
        {"feature": "LIVENESS", "config": {"face_liveness_method": "PASSIVE"}},
        {"feature": "FACE_MATCH"},
    ],
})
键默认值取值
<ISO3>.document.enabledtrue接受拍摄的文档
<ISO3>.id_lookup.enabledfalse提供查询选项
<ISO3>.id_lookup.max_attempts1已回答查询次数,范围为 1 到 5
<ISO3>.id_lookup.skip_liveness_and_face_matchtrue若来源返回了肖像且肖像与自拍照匹配,则跳过后续活体检测/人脸匹配
<ISO3>.id_lookup.on_partial_match / on_no_match / on_provider_errorfallback_to_document或 decline
<ISO3>.wallet.enabledfalse提供钱包登录选项
<ISO3>.wallet.providers[]该国家接受的目录钱包 ID,例如 ["mitid"](接受列表,不是排序列表)
<ISO3>.wallet.on_failurefallback_to_document或 decline

查询按国家计费,钱包按完成的验证次数计费,不包含在 500 次免费文档检查中。请参阅 https://docs.didit.me/core-technology/id-verification/non-doc-lookup 和 https://docs.didit.me/core-technology/id-verification/digital-id-wallets。


实用脚本

run_kyc.py:通过命令行完成完整的 KYC 设置
# Requires: pip install requests
export DIDIT_API_KEY="your_api_key"

# Create a KYC workflow (one-time)
python scripts/run_kyc.py setup --label "My KYC" --liveness --face-match
python scripts/run_kyc.py setup --label "KYC + AML" --aml --liveness-method FLASHING

# Create a session for a user
python scripts/run_kyc.py session --workflow-id <uuid> --vendor-data user-123

# Get the decision (or poll until a terminal status)
python scripts/run_kyc.py decision <session_id>
python scripts/run_kyc.py decision <session_id> --poll --interval 15

# Full flow: create workflow + session in one command
python scripts/run_kyc.py full --vendor-data user-123 --callback https://myapp.com/done

也可以将其导入:

from scripts.run_kyc import setup_kyc_workflow, create_kyc_session, get_decision, poll_decision

评论

支持 Markdown