免费
适用于构建、测试和您的首批用户。
- 每月500次完整KYC验证
- 身份、活体、人脸匹配、设备和IP验证
- 200+欺诈信号、黑名单、重复项检测
- Didit网络内可复用KYC
- 工作流构建器、案件管理、SDK
- AI 支持 控制台内 AI 助手、文档和社区支持。
全球2,000多家组织信赖。
可用性来自生产方法目录,而非此页面。钱包一旦可在您的工作流中接受,便会在此处亮起。不承诺任何发布日期。
即将推出
目录中的每个钱包都列出了其官方标志、运营国家/地区及其发行机构。目前均未上线生产环境:启动开关已关闭,因此每个都显示“即将推出”,在开关打开之前无法在工作流中启用。
一旦上线,勾选您在每个国家/地区接受的钱包。选择取消或失败的登录是回退到文档捕获还是拒绝。无需代码。
直接来自方法目录
目录中
覆盖国家/地区
eIDAS 高级
无需任何排序控制
勾选即完成配置。用户从您接受的列表中选择,屏幕上的顺序不具任何意义。每个钱包在上线前都保持其目录状态。
终端用户所见
MitID · Danish Agency for Digital Government
仅限管理员界面
终端用户永远不会看到保障标签、来源名称或价格。您的审核人员可以看到所有这三项。
至少有一个钱包的国家
国家
EUDI 钱包覆盖
覆盖范围按国家/地区遵循目录。此处显示国旗表示该国家/地区列出了钱包,而非已上线。
$ curl -X POST https://verification.didit.me/v3/session/ \
-H "x-api-key: <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"workflow_id": "wf_wallets",
"vendor_data": "user_42"
}'{ "url": "https://verify.didit.me/..." }const crypto = require("crypto");
// X-Signature-V2 signs canonical JSON: keys sorted as strings, compact,
// Unicode preserved. Emit the sorted entries directly - rebuilding an object
// would reorder integer-like keys ("10", "2"). Never hash req.rawBody.
const canonical = (v) =>
Array.isArray(v) ? "[" + v.map(canonical).join(",") + "]"
: v && typeof v === "object"
? "{" + Object.keys(v).sort()
.map((k) => JSON.stringify(k) + ":" + canonical(v[k])).join(",") + "}"
: JSON.stringify(v);
app.post("/webhooks/didit", express.json(), (req, res) => {
// Freshness: the signed body timestamp (refreshed on retry) must be recent
// and X-Timestamp must agree - the header alone is unsigned and replayable.
const ts = Number(req.body?.timestamp);
if (!ts || String(ts) !== req.headers["x-timestamp"] ||
Math.abs(Date.now() / 1000 - ts) > 300) return res.sendStatus(401);
const expected = crypto.createHmac("sha256", SECRET)
.update(canonical(req.body), "utf8").digest("hex");
const sig = String(req.headers["x-signature-v2"] ?? "");
const valid = sig.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
if (!valid) return res.sendStatus(401);
const { status, decision } = req.body;
// One entry per ID Verification node; pick yours by node_id when you run several.
const [idv] = decision?.id_verifications ?? [];
// idv.verification_method: "document" | "id_lookup" | "wallet"
res.sendStatus(200);
});{ "verification_method": "wallet", "assurance": "cryptographic" }# Didit digital ID wallets — integrate in 5 minutes
You are adding digital ID wallet sign-in to my_stack. The user signs in with a
government or bank digital identity and the wallet returns signed attributes.
Every URL, header, and enum value below is canonical — do not paraphrase or
"improve" them.
## 1. Provision an account
- Sign up: https://business.didit.me (no credit card required).
- Grab the API key for your application from the console.
## 2. Read the methods catalog first
Wallet availability is server-driven per country. Never hard-code a wallet list.
The catalog is not a public REST endpoint. Read it one of two ways:
- Business Console (signed in): your application -> ID Verification ->
Countries tab. https://docs.didit.me/console/id-verification-methods
- Didit MCP server tool didit_workflow_get_id_verification_methods_catalog,
authenticated with the same x-api-key; pass country (ISO 3166-1 alpha-3)
to narrow it to one country. https://docs.didit.me/integration/mcp/tools
- Public mirror of the coverage table (no auth, read-only):
https://docs.didit.me/core-technology/id-verification/verification-methods#coverage
The catalog gives you, per wallet id: the display name, the countries it
covers, the issuing authority, the level of assurance, the availability state,
and the attributes it returns. As of this prompt every wallet is coming soon:
the launch switch is off in production, so the catalog will not let you accept
one yet. Build against the catalog and re-read it; do not hard-code a date.
## 3. Create a workflow with the ID Verification (OCR) feature
POST https://verification.didit.me/v3/workflows/
-H "x-api-key: <your-api-key>"
-H "Content-Type: application/json"
The ID Verification feature's enum value is OCR (UPPERCASE — strict enum;
there is no ID_VERIFICATION alias and the API rejects it). Wallets are its
wallet method, accepted per country under config.methods on that same
feature entry, in the same request. Keys are ISO 3166-1 alpha-3.
{
"workflow_label": "Wallet onboarding",
"features": [
{
"feature": "OCR",
"config": {
"methods": {
"DNK": {
"document": { "enabled": true },
"wallet": {
"enabled": true,
"providers": ["mitid"],
"on_failure": "fallback_to_document"
}
},
"NOR": {
"document": { "enabled": true },
"wallet": {
"enabled": true,
"providers": ["bankid_no", "vipps"],
"on_failure": "fallback_to_document"
}
}
}
}
}
]
}
Response: the workflow uuid — use it as workflow_id in step 4.
Rules that the API enforces:
- providers is an accept-list, not a ranking. Order carries no meaning and
the end user picks
- on_failure is either fallback_to_document or decline. It covers all three
cases: no wallet, cancelled, sign-in failed
- a wallet id the catalog does not mark available for that country is
rejected, and the rejection fails the whole save — including any lookup
configuration next to it. While every wallet is coming soon, keep
wallet.enabled false (or omit the wallet block) so the save succeeds
- unknown wallet ids already saved on a workflow are preserved untouched, so
a config written by a newer console version is never silently dropped
- a country with no method enabled is rejected at publish time
## 4. Create a session
POST https://verification.didit.me/v3/session/
-H "x-api-key: <your-api-key>"
-H "Content-Type: application/json"
-d '{ "workflow_id": "<id from step 3>", "vendor_data": "<your user id>" }'
Response: 201 with url (the hosted verification link), session_token and
session_id. Redirect the user to url, or open it in the SDK. The field is
named url — there is no session_url and no verification_url. Didit
shows the accepted wallets for the user's country with their brand marks,
hands off to the wallet, and waits for the signed assertion to come back.
## 5. Webhooks
Register a destination (console -> API & Webhooks, or
POST https://verification.didit.me/v3/webhook/destinations/ with
webhook_version "v3" and subscribed_events ["status.updated"]) and store the
secret_shared_key it returns. Verify every delivery:
Header: X-Signature-V2 (NOT X-Signature, NOT X-Signature-Simple)
Algorithm: HMAC-SHA256, hex digest, over the CANONICAL JSON of the payload:
parse the body, sort keys recursively, serialise compact with
Unicode preserved and whole-valued floats as integers. Do NOT
hash the raw request bytes — that is the v1 X-Signature
algorithm and fails for V2 whenever whitespace or key order
differs from the canonical form.
Freshness: the signed body field timestamp is the dispatch time (Unix
seconds, refreshed on every retry). Reject when
abs(now - timestamp) > 300 seconds, and reject when the
X-Timestamp header does not equal it. The header is not
covered by the signature, so it must never be the only replay
check: a captured delivery replays with just that header
refreshed.
Compare: constant-time (crypto.timingSafeEqual)
Reference handler (Express) — use it as written:
const crypto = require("crypto");
// X-Signature-V2 signs canonical JSON: keys sorted as strings, compact,
// Unicode preserved. Emit the sorted entries directly - rebuilding an object
// would reorder integer-like keys ("10", "2"). Never hash req.rawBody.
const canonical = (v) =>
Array.isArray(v) ? "[" + v.map(canonical).join(",") + "]"
: v && typeof v === "object"
? "{" + Object.keys(v).sort()
.map((k) => JSON.stringify(k) + ":" + canonical(v[k])).join(",") + "}"
: JSON.stringify(v);
app.post("/webhooks/didit", express.json(), (req, res) => {
// Freshness: the signed body timestamp (refreshed on retry) must be recent
// and X-Timestamp must agree - the header alone is unsigned and replayable.
const ts = Number(req.body?.timestamp);
if (!ts || String(ts) !== req.headers["x-timestamp"] ||
Math.abs(Date.now() / 1000 - ts) > 300) return res.sendStatus(401);
const expected = crypto.createHmac("sha256", SECRET)
.update(canonical(req.body), "utf8").digest("hex");
const sig = String(req.headers["x-signature-v2"] ?? "");
const valid = sig.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
if (!valid) return res.sendStatus(401);
const { status, decision } = req.body;
// One entry per ID Verification node; pick yours by node_id when you run several.
const [idv] = decision?.id_verifications ?? [];
// idv.verification_method: "document" | "id_lookup" | "wallet"
res.sendStatus(200);
});
Body fields you will use: session_id, status, webhook_type, workflow_id,
vendor_data, decision.
Status values: Approved, Declined, In Review, In Progress, Not Started,
Abandoned.
## 6. Reading the result
The decision is the V3 shape: every feature result is a plural array with one
entry per workflow node. ID Verification results live in
decision.id_verifications[] — there is no singular decision.kyc (that is the
V2 shape) and no decision.id_verification. Select your entry by node_id (the
id of your ID Verification node in the workflow graph); with a single ID step,
take index 0. Each entry carries, next to the document fields:
verification_method "document" | "id_lookup" | "wallet"
assurance "documentary" | "data_match" | "cryptographic"
wallet_provider the catalog wallet id the user signed in with; null
on document and id_lookup entries
wallet_verification provider, provider_name, issuing_authority,
issuing_country, credential_type, level_of_assurance
(low | substantial | high), verified_at,
signature_valid, attributes (what the wallet shared),
portrait when the wallet shares one; null otherwise
fallback_from { method, reason, action } when the session fell
back to document capture or was declined; else null
A wallet entry that succeeds is assurance cryptographic — the highest of the
three. Check wallet_verification.signature_valid before you trust attributes.
Field-by-field reference: https://docs.didit.me/reference/data-models#id-verification
## 7. Billing
- published customer prices in USD per completed wallet verification:
- MitID personal: $0.35; production availability: Coming soon
- BankID Sweden: $0.30; production availability: Coming soon
- BankID Norway High: $0.35; production availability: Coming soon
- Vipps Plus: $0.28; production availability: Coming soon
- Buypass ID: Coming soon; production availability: Coming soon
- itsme: Coming soon; production availability: Coming soon
- iDIN full identification: $0.85; production availability: Coming soon
- Finnish Trust Network: $0.30; production availability: Coming soon
- Personalausweis Profile 2: $0.45; production availability: Coming soon
- Freja eID: Coming soon; production availability: Coming soon
- UAE PASS: Coming soon; production availability: Coming soon
- gov.br: Coming soon; production availability: Coming soon
- OneID: Coming soon; production availability: Coming soon
- GOV.UK Wallet: Coming soon; production availability: Coming soon
- Smart-ID: Coming soon; production availability: Coming soon
- Mobile-ID: Coming soon; production availability: Coming soon
- Bank iD: Coming soon; production availability: Coming soon
- MojeID: Coming soon; production availability: Coming soon
- Diia: Coming soon; production availability: Coming soon
- FranceConnect: Coming soon; production availability: Coming soon
- Auðkenni: Coming soon; production availability: Coming soon
- EUDI Wallet: Coming soon; production availability: Coming soon
- an announced price does not enable a wallet; check the live workflow catalog
- wallet checks are outside the document free tier; other checks are billed separately
- full pricing: https://docs.didit.me/core-technology/id-verification/digital-id-wallets#pricing
- document capture bills its own price when the user falls back
## 8. Hard rules — do not change
- base URL for v3 endpoints: verification.didit.me
- auth header: x-api-key (lowercase, hyphenated)
- webhook headers: X-Signature-V2 plus X-Timestamp; canonical JSON, never
raw bytes; freshness from the signed body timestamp
- feature enum: OCR (uppercase) — the ID Verification feature; per-country
methods go under its config.methods
- method keys: document, id_lookup, wallet (lowercase, snake_case)
- wallet ids come from the catalog verbatim, lowercase, snake_case
- country keys: ISO 3166-1 alpha-3, uppercase
- result path: decision.id_verifications[] (array), never decision.kyc
## 9. Verify your integration
- run one session per accepted wallet in sandbox
- assert the id_verifications[] entry for your node has verification_method
wallet and wallet_verification.signature_valid true
- cancel a wallet sign-in and assert your on_failure setting actually fires
- assert your webhook accepts a correctly signed payload with reordered
keys, whitespace and integer-like metadata keys ("10" before "2"), and
rejects a wrong X-Signature-V2, a payload whose signed timestamp is older
than 300 seconds, and that same stale payload with only the X-Timestamp
header refreshed
Docs: https://docs.didit.me/integration/integration-prompt
以下价格为每次完成钱包验证的美元费用。这些费用涵盖了指定的身份产品;其他工作流检查和文档回退将单独计费。每月500次免费文档检查不包括钱包。已公布的价格不代表钱包已上线:可用性单独显示。未公布的价格表示即将推出。身份钱包用于验证个人;加密钱包筛选是单独的产品。
阅读详细文档| 身份钱包 | 美元/次完成验证 | 国家/地区 | 生产可用性 |
|---|---|---|---|
| MitID personal | US$0.35 |
| 即将推出 |
| BankID Sweden | US$0.30 |
| 即将推出 |
| BankID Norway High | US$0.35 |
| 即将推出 |
| Vipps Plus | US$0.28 |
| 即将推出 |
| Buypass ID | 即将推出 |
| 即将推出 |
| itsme | 即将推出 |
| 即将推出 |
| iDIN full identification | US$0.85 |
| 即将推出 |
| Finnish Trust Network | US$0.30 |
| 即将推出 |
| Personalausweis Profile 2 | US$0.45 |
| 即将推出 |
| Freja eID | 即将推出 |
| 即将推出 |
| UAE PASS | 即将推出 |
| 即将推出 |
| gov.br | 即将推出 |
| 即将推出 |
| OneID | 即将推出 |
| 即将推出 |
| GOV.UK Wallet | 即将推出 |
| 即将推出 |
| Smart-ID | 即将推出 |
| 即将推出 |
| Mobile-ID | 即将推出 |
| 即将推出 |
| Bank iD | 即将推出 |
| 即将推出 |
| MojeID | 即将推出 |
| 即将推出 |
| Diia | 即将推出 |
| 即将推出 |
| FranceConnect | 即将推出 |
| 即将推出 |
| Auðkenni | 即将推出 |
| 即将推出 |
| EUDI Wallet | 即将推出 |
| 即将推出 |
适用于构建、测试和您的首批用户。
25+ 模块,价格公开透明。自动享受批量折扣。
适用于大批量和受监管项目。
使用量增长时自动享受批量折扣——无需谈判,无需销售电话。
Didit 是身份和欺诈基础设施,是我们自己构建产品时希望拥有的平台:开放、灵活且对开发者友好,因此它可以作为您技术栈的真正一部分,而不是一个需要您围绕其集成的黑盒。
一个 API 涵盖了人员验证(KYC,了解您的客户)、企业验证(KYB,了解您的业务)、加密钱包筛选(KYT,了解您的交易)以及实时监控交易,其技术栈旨在实现:
其底层支持:48 种以上语言的 14,000 多种证件类型、1,000 多个数据源以及每次会话的 200 多个欺诈信号。Didit 基础设施从每次会话中动态学习并日益完善。
用户使用他们已有的政府或银行数字身份登录——丹麦的 MitID、瑞典和挪威的 BankID、比利时的 itsme、阿联酋的 UAE PASS、巴西的 gov.br、EUDI 钱包——钱包会返回关于他们的签名属性。
Didit 会检查签发者签名,然后将已验证的属性写入会话。无需证件照片、自拍或输入。
它是 ID_VERIFICATION 中的一种方法,可按国家/地区与证件捕获和非证件查询一起接受。
目录中包含34个国家的22种数字身份钱包:MitID(丹麦)、BankID(瑞典和挪威)、Vipps和Buypass ID(挪威)、itsme(比利时、卢森堡、荷兰)、iDIN(荷兰)、Finnish Trust Network(芬兰)、Personalausweis(德国)、Freja eID(瑞典)、UAE PASS(阿联酋)、gov.br(巴西)、OneID和GOV.UK Wallet(英国)、Smart-ID和Mobile-ID(波罗的海国家)、Bank iD和MojeID(捷克)、Diia(乌克兰)、FranceConnect(法国)、Auðkenni(冰岛)以及EUDI Wallet(覆盖30个欧盟和欧洲经济区国家)。
目前均未上线生产环境。所有钱包都显示“即将推出”,无法在工作流中启用,也没有确切的上线日期。此列表由方法目录提供,因此钱包一旦准备就绪即可使用——此页面上的任何内容都不会手动更改。
整个流程通常在 30 秒内完成——这是市场上最快的。传统提供商完成相同流程通常需要超过 90 秒。
钱包登录通常是所有路径中最短的:用户点击他们的钱包,批准请求,然后返回。在后端,Didit 在 p99 下不到两秒内返回结果。
钱包签发者会对其返回的属性进行签名,Didit 在将任何内容写入会话之前会验证该签名。signature_valid 在结果中,因此您可以自行断言。
由于凭证由银行或政府签发并绑定到持有人,因此没有可伪造的证件图像,也没有可深度伪造的人脸。这就是钱包达到加密保证(三个层级中最高级别)的原因。
一个开关处理所有三种情况:无钱包、已取消或登录失败。它会回退到文档捕获或拒绝会话,您可以按国家/地区设置。
结果会记录回退方法和原因,因此被放弃的钱包登录不会被忽视。
每个钱包都会返回持有人的全名,除两个例外,还会返回出生日期,以及签名断言本身。大多数还会添加钱包公开的国家/地区标识符——BankID 的瑞典个人号码、MitID 的 CPR 别名、itsme 的国家注册号码、gov.br 的 CPF——少数还会添加地址或肖像:UAE PASS、GOV.UK Wallet 和 Diia 会返回持有人的照片。
EUDI Wallet 返回成员国签发的个人身份数据 (PID)。在工作流程中取消勾选任何可选属性,它将永远不会写入会话。
每个钱包的具体属性列表请参见 docs.didit.me。
在您选择的区域内,数据在传输和静态时均已加密,并符合 SOC 2 Type 1 和 Type 2、ISO 27001 和 GDPR 标准。
钱包仅共享请求所需的属性,您可以取消勾选任何可选属性,使其完全不被存储。必需属性始终存储,以及审计员所需的签名断言引用。
完整详情请参见 /security-compliance。
Didit 已在受监管行业(金融科技、银行、iGaming、加密货币、市场、医疗保健和政府)的 2,000 多家公司中投入生产。
钱包登录达到加密级别的保障,这是三种方法中最强的证据,并且每个会话都会记录保障级别。如果监管机构指定了特定的国家/地区 eID,接受该钱包通常是满足要求的最佳方式。
备忘录请参见 /security-compliance。
几分钟,三种方式。
从 business.didit.me 开始,或阅读 docs.didit.me/integration/integration-prompt。