跳到主要内容
Didit 融资 750 万美元,打造身份与欺诈基础设施
Didit
EUDI Wallet · eIDAS 2

准备好接受
欧盟数字身份钱包。

每个欧盟成员国必须在2026年12月24日前提供欧盟数字身份(EUDI)钱包,受监管企业必须在2027年12月24日前受理该钱包。Didit目前支持五种国家电子身份(eID),EUDI 钱包受理功能即将集成到同一工作流程中。

投资方
Y CombinatorRobinhood Ventures
Firecrawl
Slash
Crnogorski Telekom
UCSF Neuroscape
Bit2Me

全球3,000多家组织信赖。

EUDI 钱包是什么

一人一钱包。
只获取您所需数据。

EUDI 钱包是一款免费应用程序,根据eIDAS 2法规(EU)2024/1183,每个欧盟成员国都必须提供。它包含个人身份识别数据(PID),即姓名、出生日期和地点、国籍,以及驾驶执照或文凭等属性的电子证明。使用它是自愿的。

当企业请求数据时,用户可以看到请求方,并且只共享所请求的属性。这被称为选择性披露:网站可以确认某人已年满18岁,而无需查看其出生日期。该钱包以“高”保障级别运行,这是 eIDAS 三个级别中最高的;企业在依赖这些数据之前,会先核验发行方签名。

最后审阅日期:2026年10月5日。非法律建议。

关键日期

各成员国须在2026年底前推出钱包。2027年12月24日前必须受理。

这些是法规(EU)2024/1183及其执行法案中规定的日期,企业应以此为规划依据。
  1. 2024年4月30日

    eIDAS 2 发布

    修订eIDAS法规(EU)No 910/2014的法规(EU)2024/1183在欧盟官方公报上发布。发布后第二十天生效。

  2. 2024年12月24日

    首批钱包规则生效

    首批五项钱包实施法规生效:个人身份识别数据、核心功能、通知、认证以及协议和接口。它们启动了下面的24个月和36个月倒计时。

  3. 2026年7月15日

    钱包规则更新

    欧盟委员会通过实施法规(EU)2026/1731。它设定了两种凭证格式:SD-JWT VC和ISO/IEC mdoc,并计划在2028年强制要求肖像。

  4. 2026年7月23日

    ARF v3.0.0

    架构和参考框架(ARF)是钱包和依赖方所依据的技术蓝图,其版本号达到 3.0.0。

  5. 2026年12月24日

    所有成员国均提供钱包

    每个成员国必须提供至少一个EUDI 钱包。关于注册依赖方的规则,即实施法规(EU)2025/848,自同日起适用。

  6. 2027年12月24日

    私营企业必须接受

    除微型企业和小型企业外,依法或依合同必须使用强用户认证的私营企业,在用户要求使用钱包时必须予以受理(第 5f(2) 条)。该期限为自首批实施法案于 2024 年 12 月 24 日生效起 36 个月,即到 2027 年 12 月 24 日为止。

  7. 2028年8月11日

    肖像和注册检查

    肖像成为强制性个人身份识别数据的一部分,钱包必须对每个依赖方的注册证书进行认证和验证。

谁必须接受

谁必须接受钱包,以及何时。

经法规(EU)2024/1183修订的eIDAS法规第5f条规定了接受义务。在任何情况下,用户都可以选择使用钱包,您也可以保留其他身份识别方式。

谁

公共部门机构

通俗易懂的解释

如果成员国要求使用电子身份识别来访问公共在线服务,则该服务也必须接受 EUDI 钱包。

条款 · 日期

第 5f(1) 条

谁

必须使用强用户认证的私人服务

通俗易懂的解释

如果法律或合同要求您使用强用户认证进行在线身份识别,您也必须受理 EUDI 钱包。判断依据是该项要求本身,而非您所在的行业。

条款 · 日期

第 5f(2) 条 · 2027 年 12 月 24 日

谁

条款中提及的领域

通俗易懂的解释

交通、能源、银行、金融服务、社会保障、医疗、饮用水、邮政服务、数字基础设施、教育和电信。该条款称“包括”,因此该列表仅为示例,并非封闭。

条款 · 日期

第 5f(2) 条

谁

微型企业和小型企业

通俗易懂的解释

根据委员会建议 2003/361/EC 的定义,免除私人部门义务。他们仍可选择接受钱包。

条款 · 日期

第 5f(2) 条

谁

仅限用户请求

通俗易懂的解释

当用户请求使用钱包时,应予以受理。个人使用钱包属自愿行为,服务方必须继续对其他身份识别和认证方式保持开放。

条款 · 日期

第 5f(2) 条,第 5a(15) 条

谁

超大型在线平台

通俗易懂的解释

根据《数字服务法》指定的、需要用户认证的平台,必须在用户请求时接受钱包,且仅限于服务所需的最低数据。文本未为此义务设定单独日期。

条款 · 日期

第 5f(3) 条

依赖方还必须在其所在成员国注册,并且只能请求其已注册的数据(第 5b 条)。最后审阅日期:2026 年 10 月 5 日。非法律建议。

企业如何接受

依赖方接受 EUDI 钱包的五个步骤。

步骤 01 / 05

注册为依赖方

在您所在的成员国注册,提供您的详细信息和您打算请求的数据。您将收到一个访问证书,用于向钱包进行身份验证,如果您的成员国颁发,还会收到一个列出您已注册属性的注册证书。

EUDI 钱包接受功能上线后(即将推出),Didit 将为您完成这些步骤。

您收到的信息与 KYC 仍需的信息

钱包证明了身份。尽职调查需要更多信息。

根据《反洗钱条例》(AMLR),即欧盟法规 2024/1624,实质性或高级别的电子身份识别是验证身份的两种方式之一(第 22(6) 条)。它并未涵盖客户身份识别 (KYC) 检查所需的所有信息。以下是个人身份识别数据 (PID) 包含的内容,以及 Didit 目前如何涵盖每个项目。

尽职调查需求

所有姓名

AMLR 第 22(1)(a) 条

EUDI 钱包 PID 中包含的信息

姓氏和名字,均为必填项。

Didit 目前如何涵盖

实时国家 eID 返回完整姓名。文档路径可从 14,000 多种文档类型中读取。

尽职调查需求

出生地和完整出生日期

AMLR 第 22(1)(a) 条

EUDI 钱包 PID 中包含的信息

出生日期和出生地,均为必填项。

Didit 目前如何涵盖

实时国家 eID 返回出生日期。文档路径会读取文档上打印的出生地。

尽职调查需求

国籍

AMLR 第 22(1)(a) 条

EUDI 钱包 PID 中包含的信息

国籍,必填,一个或多个国家。

Didit 目前如何涵盖

文档路径从身份证明文件或其芯片中读取国籍。

尽职调查需求

国家识别号码(如适用)

AMLR 第 22(1)(a) 条

EUDI 钱包 PID 中包含的信息

个人管理号码,可选。每个成员国自行决定是否签发。

Didit 目前如何涵盖

实时国家 eID 返回方案标识符:瑞典的 personnummer、芬兰的个人身份代码或波罗的海的个人代码。MitID 返回假名化标识符,而非 CPR 号码。

尽职调查需求

常住地

AMLR 第 22(1)(a) 条

EUDI 钱包 PID 中包含的信息

地址字段是可选的,且经常缺失。AMLA 的最终标准草案规定,缺失的属性必须通过其他方式获取。

Didit 目前如何涵盖

没有实时国家 eID 返回地址。地址证明会核查水电费账单、银行对账单或政府信函。

尽职调查需求

税务识别号(如适用)

AMLR 第 22(1)(a) 条

EUDI 钱包 PID 中包含的信息

不属于 PID。

Didit 目前如何涵盖

在同一工作流程中通过问卷步骤收集。

尽职调查需求

个人与身份匹配

ARF · 用户绑定

EUDI 钱包 PID 中包含的信息

肖像在 2028 年 8 月 11 日成为强制性要求之前,仍为可选。

Didit 目前如何涵盖

在完整的 KYC 检查中,以 $0.33 的价格进行被动活体检测和与文档照片或芯片肖像的 1:1 人脸匹配。

尽职调查需求

公司的受益所有人

AMLR 第 20(1)(b) 条

EUDI 钱包 PID 中包含的信息

不在 PID 中。钱包识别的是个人,而非公司的所有者。

Didit 目前如何涵盖

Business Verification 会从注册机构中提取注册数据和所有者信息(如果注册机构持有),并对每个所有者进行身份验证。

尽职调查需求

制裁和政治公众人物 (PEPs)

AMLR 第 20(1)(d), (g) 条

EUDI 钱包 PID 中包含的信息

不在 PID 中。

Didit 目前如何涵盖

针对 1,300 多个制裁、PEP 和观察名单进行 AML 筛选,每次检查 $0.20。

尽职调查需求

关系目的和持续监控

AMLR 第 25、26 条

EUDI 钱包 PID 中包含的信息

不在 PID 中。

Didit 目前如何涵盖

问卷记录关系目的。持续监控每天重新筛选客户,每人每年 $0.07。

客户尽职调查仍是您的义务。Didit 提供核查和证据,但不保证您完全合规。AMLR 将于 2027 年 7 月 10 日生效,AMLA 的技术标准最终草案日期为 2026 年 9 月 30 日,尚未成为法律。

各国准备情况

各国数字钱包现状,附日期和来源。

下表列出各国已发布的信息,或指明来源的报道内容,每一行都附有日期和链接。

截至 2026年10月5日 的状态

国家

意大利

钱包或应用

IT-Wallet (app IO)

状态

已上线应用

日期

2026年2月17日

已知信息

已在 IO 应用中上线,截至 2026 年 2 月 17 日,已激活 1010 万次,加载了 1730 万份文件。对成年人免费且可选,可通过 CIE 或 SPID 登录。

来源: innovazione.gov.it

国家

丹麦

钱包或应用

AltID

状态

已上线应用

日期

2026年8月4日

已知信息

AltID 已上线,提供数字身份证和年龄证明,截至 2026 年 8 月 4 日已有 281,390 人创建。数字政府机构正在分阶段实施该钱包。

来源: digst.dk

国家

法国

钱包或应用

France Identité

状态

已上线应用

日期

暂无官方日期

已知信息

据 Euronews 报道,法国是先行者之一,France Identité 应用将与 EUDI 规则保持一致。

来源: Euronews

国家

捷克

钱包或应用

eDoklady

状态

已上线应用

日期

暂无官方日期

已知信息

据 NFCW 报道,eDoklady 应用作为 EUDI 钱包的中间步骤推出。

来源: NFCW

国家

德国

钱包或应用

EUDI-Wallet (BMDS)

状态

沙盒

日期

2027年1月

已知信息

自 2025 年 12 月起提供公共沙盒。该应用预计于 2027 年初推出,首先是身份识别功能。实施法案已于 2026 年 9 月 23 日在联邦议院进行首次审议。

来源: eudi-wallet.gov.de

国家

西班牙

钱包或应用

Cartera Digital (Beta)

状态

试点中

日期

2026年

已知信息

是 2026 年期间在国家钱包内试点欧盟年龄验证解决方案的七个国家之一。

来源: ageverification.dev

国家

希腊

钱包或应用

Gov.gr Wallet

状态

试点中

日期

2026年

已知信息

是 2026 年期间在国家钱包内试点欧盟年龄验证解决方案的七个国家之一。

来源: ageverification.dev

国家

爱尔兰

钱包或应用

Government Digital Wallet

状态

试点中

日期

2026年

已知信息

是 2026 年期间在国家钱包内试点欧盟年龄验证解决方案的七个国家之一。

来源: ageverification.dev

国家

塞浦路斯

钱包或应用

National wallet

状态

试点中

日期

2026年

已知信息

是 2026 年期间在国家钱包内试点欧盟年龄验证解决方案的七个国家之一。

来源: ageverification.dev

国家

斯洛伐克

钱包或应用

National EUDI Wallet

状态

试点中

日期

暂无官方日期

已知信息

据 Euronews 报道,斯洛伐克钱包仍处于私人测试阶段。

来源: Euronews

国家

荷兰

钱包或应用

NL Wallet

状态

计划中

日期

暂无官方日期

已知信息

NL 钱包正在开发中,一旦国家实施法案通过即可使用。

来源: nldigitalgovernment.nl

国家

波兰

钱包或应用

mObywatel

状态

计划中

日期

暂无官方日期

已知信息

据 CHIP.pl 报道,波兰 EUDI 钱包的试点已在计划中,将作为一个与 mObywatel 关联的独立应用。

来源: CHIP.pl

国家

芬兰

钱包或应用

National EUDI Wallet (DVV)

状态

计划中

日期

暂无官方日期

已知信息

据 Euronews 报道,芬兰是先行者之一。

来源: Euronews

国家

保加利亚

钱包或应用

National EUDI Wallet

状态

计划中

日期

暂无官方日期

已知信息

据 Euronews 报道,保加利亚是先行者之一。

来源: Euronews

国家

克罗地亚

钱包或应用

Certilia

状态

计划中

日期

暂无官方日期

已知信息

据 Euronews 报道,Certilia 钱包正在根据欧盟技术框架进行重建。

来源: Euronews

国家

罗马尼亚

钱包或应用

National EUDI Wallet

状态

计划中

日期

暂无官方日期

已知信息

据 Euronews 报道,罗马尼亚正通过私人合作加速其钱包的开发。

来源: Euronews

国家

瑞典

钱包或应用

Digital identitetsplånbok (DIGG)

状态

计划中

日期

暂无官方日期

已知信息

据 Euronews 报道,瑞典已发布其 EUDI 钱包的上线路线图。

来源: Euronews

未列出的国家:奥地利, 比利时, 爱沙尼亚, 匈牙利, 拉脱维亚, 立陶宛, 卢森堡, 马耳他, 葡萄牙, 斯洛文尼亚。我们在此日期未找到它们的公开状态。我们将随着国家应用的发布更新此表格。

Didit 助您实现目标 · 五行

立即接受国家电子身份。 下一步,集成 EUDI 钱包。

EUDI 钱包是新增的验证途径,而非替代现有途径。您只需构建一次工作流:现在可支持各国电子身份和证件,待 EUDI 钱包上线后,即可在同一身份验证步骤中接受其验证。
01 · 各国电子身份,已上线

接受客户已在使用的各国电子身份。

Didit 已上线五种各国电子身份,覆盖七个国家:MitID、BankID Sweden、Finnish Trust Network、Smart-ID 和 Mobile-ID。用户通过电子身份登录后,会话将收到已签名的属性:全名、出生日期、方案标识符(例如瑞典的 personnummer;MitID 返回的是假名化标识符)以及方案声明的保障级别。仅对完成登录的会话收费。
查看 eID 验证
02 · EUDI 钱包,即将推出

EUDI 钱包受理,集成到现有工作流。

EUDI 钱包受理功能即将上线。我们的钱包目录中列出了30个欧洲经济区国家/地区的EUDI 钱包,与国家eID在同一身份验证步骤中。目前尚未公布具体上线日期和价格。
联系我们
03 · 证件验证途径

为没有钱包的用户提供证件验证途径。

并非所有人都会拥有或使用钱包,法律也允许其他验证方式。证件验证途径通过 NFC 读取护照和身份证芯片($0.15),执行被动活体检测,并将人脸与证件照片进行比对,支持 220 多个国家和地区的 14,000 多种证件类型。
查看 NFC 验证
04 · 年龄验证

以最少数据证明年龄。

EUDI 钱包可以在不提供出生日期的情况下证明某人已满 18 岁。在钱包普及之前,通过自拍进行年龄估算每次检查费用为 $0.10,并将临界结果交由身份验证方式兜底处理。实时电子身份登录也会返回已签名的出生日期,无需证件照片。
查看年龄验证
05 · 尽职调查的其余部分

筛选、持续监控和公司核验,一站式完成。

身份验证是客户尽职调查的一部分。在同一工作流中,您可以根据 1,300 多个制裁名单、PEP 和观察名单筛选人员(每次检查 $0.20),通过持续监控每天重新筛选(每人每年 $0.07),并验证公司及其所有者。
查看 AMLR 解决方案
查看流程

用户会看到什么,四个界面。

正如 ARF 所描述的跨设备呈现:用户在电脑上开始,并在持有钱包的手机上完成。
  1. 扫描二维码

    服务显示二维码,用户使用钱包应用扫描。

  2. 查看请求

    钱包显示请求方和请求的属性。

  3. 共享

    用户批准后,只有请求的属性会离开手机。

  4. 已验证

    服务检查发行方签名并继续。未共享其他任何信息。

标准流程示意图。Didit 的 EUDI 钱包验证即将推出。

立即集成

立即集成,EUDI 钱包上线后即可使用。

Didit 尚未推出 EUDI 专属 API。您可以为接受现有国家电子身份和文档的工作流创建会话,然后读取结果。EUDI 钱包受理功能计划在同一身份验证步骤中实现。
POST /v3/session/开始检查
$ curl -X POST https://verification.didit.me/v3/session/ \
  -H "x-api-key: $DIDIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_id": "YOUR_EID_WORKFLOW_UUID",
    "vendor_data": "customer_8412"
  }'
201已创建{ "url": "https://verify.didit.me/session/…" }
每个客户一个会话。您的参考信息将随每个结果返回。docs
GET /v3/session/{id}/decision/读取结果
{
  "id_verifications": [{
    "status": "Approved",
    "verification_method": "wallet",
    "assurance": "cryptographic",
    "wallet_provider": "mitid",
    "wallet_verification": {
      "issuing_country": "DNK",
      "level_of_assurance": "substantial",
      "signature_valid": true,
      "attributes": {
        "full_name": "Freja Nielsen",
        "date_of_birth": "1988-03-02"
      },
      "portrait": null
    }
  }]
}
200OKverification_method: "wallet"
实时电子身份登录返回已签名的属性,不含地址,也不含肖像。docs
代理就绪集成

通过一个提示,为 EUDI 钱包做好准备。

将此提示复制到您的编码代理中。它将构建您今天即可运行的工作流,包括实时国家电子身份(带文档回退)、会话调用和已签名的 webhook。它不会创建任何 EUDI 端点,因为目前尚不存在。
didit-integration-prompt.md
# Didit: get ready for the EUDI Wallet with the ID Verification step you run today

You are adding electronic identification to my_stack so the product is ready
for the EU Digital Identity (EUDI) Wallet. Every URL, header and enum value
below is canonical. Do not paraphrase or "improve" them.

## 0. What exists today, and what does not
- EUDI Wallet acceptance on Didit is coming soon. There is NO EUDI-specific
  endpoint, wallet id, field or flag to integrate yet. Do not invent one, do
  not send any EUDI identifier in a workflow, and do not build an OpenID4VP
  verifier yourself as part of this task.
- What is live: national digital ID wallets inside the ID Verification step,
  with document capture (chip reading, liveness, face match) as the fallback.
  EUDI Wallet acceptance is planned for the same ID Verification step, so the
  workflow, session call and webhook you build now are the ones you keep.
- The live wallets, as listed by the methods catalog:
  - MitID: wallet id mitid, country keys DNK (Denmark)
  - BankID: wallet id bankid_se, country keys SWE (Sweden)
  - Finnish Trust Network: wallet id ftn, country keys FIN (Finland)
  - Smart-ID: wallet id smart_id, country keys EST (Estonia), LVA (Latvia), LTU (Lithuania), BEL (Belgium)
  - Mobile-ID: wallet id mobile_id, country keys EST (Estonia), LTU (Lithuania)
  Check the catalog for your environment before you go live. Never
  hard-code dates.

## 1. Provision an account
- Sign up: https://business.didit.me (no credit card required).
- Copy the API key of your application from the console.

## 2. Read the methods catalog
Availability is server-driven per country. Only wallets marked available can
be enabled on a live application.
  - Business Console: your application -> Workflows -> the ID Verification
    step -> Countries -> "Wallets accepted". Coming-soon wallets are listed
    but cannot be switched on. https://docs.didit.me/console/id-verification-methods
  - Didit MCP server (https://mcp.didit.me/mcp), tool
    didit_workflow_get_id_verification_methods_catalog; pass country as ISO
    3166-1 alpha-3 to narrow it. The MCP server signs in with "Log in with
    Didit" (OAuth). It does not accept the x-api-key.
    https://docs.didit.me/integration/mcp/tools
  - Public coverage table (no sign-in, read-only):
    https://docs.didit.me/core-technology/id-verification/digital-id-wallets#supported-wallets
If your code holds only an API key, it cannot read the catalog itself: use the
wallet ids listed in this prompt, and treat the answer of the workflow save as
the check. A live application answers 400 for a wallet that is not available
in that country ("<wallet> is not offered in <ISO3>", "unknown wallet").

## 3. Create the workflow (ID Verification = feature OCR)
POST https://verification.didit.me/v3/workflows/
  -H "x-api-key: <your-api-key>"
  -H "Content-Type: application/json"

{
  "workflow_label": "eID onboarding",
  "features": [
    {
      "feature": "OCR",
      "config": {
        "methods": {
          "DNK": {
            "document": { "enabled": true },
            "wallet": {
              "enabled": true,
              "providers": ["mitid"],
              "on_failure": "fallback_to_document"
            }
          },
          "EST": {
            "document": { "enabled": true },
            "wallet": {
              "enabled": true,
              "providers": ["smart_id", "mobile_id"],
              "on_failure": "fallback_to_document"
            }
          }
        }
      }
    }
  ]
}

Response: 201. The workflow id is uuid (workflow_id carries the same value);
the workflow is published straight away. Create it once and keep the id:
every call to this endpoint makes a new workflow.
is_desktop_allowed defaults to false: on a desktop browser the hosted flow
then shows a QR code to continue on a phone. Add "is_desktop_allowed": true
next to workflow_label to let people finish on desktop.

Rules the API enforces:
  - OCR is UPPERCASE; ID_VERIFICATION is rejected in this body (the decision
    later lists the step as ID_VERIFICATION in its features)
  - country keys are ISO 3166-1 alpha-3; method keys are document, id_lookup, wallet
  - providers is an accept-list, not a ranking; the end user picks
  - on_failure is fallback_to_document or decline
  - a wallet the catalog does not mark available rejects the whole save (400)
  - every other country keeps document capture, so people without an eID
    can still verify
  - this body runs document capture only. Chip reading, liveness and face
    match are their own features: add { "feature": "NFC" },
    { "feature": "LIVENESS" } and { "feature": "FACE_MATCH" } to features
    when your policy needs them

## 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 session_id, session_token, url and status "Not Started".
Redirect the user to url (hosted flow) or open it in the Web, iOS, Android,
React Native or Flutter SDK. The field is named url on this response.
One unfinished session exists per workflow_id and vendor_data pair: calling
create again with the same pair answers 201 again with that same session.

## 5. Webhook
Register a destination in the console (API & Webhooks), or over the API:

POST https://verification.didit.me/v3/webhook/destinations/
  -H "x-api-key: <your-api-key>"
  -H "Content-Type: application/json"
  -d '{
    "label": "Verification webhooks",
    "url": "https://<your-public-host>/webhooks/didit",
    "webhook_version": "v3",
    "subscribed_events": ["status.updated", "data.updated"]
  }'

label, url and subscribed_events are required. url must be a public HTTPS
address: Didit does not deliver to localhost or private addresses. Response:
201 with uuid and secret_shared_key. Store secret_shared_key as the webhook
secret (DIDIT_WEBHOOK_SECRET); it is unique to this destination. Remove a
destination with DELETE /v3/webhook/destinations/{uuid}/ (204).

What arrives:
  - webhook_type is "status.updated" (the session changed status) or
    "data.updated" (verification data was corrected after the fact)
  - a destination receives the events of every session of the application,
    so filter on workflow_id or vendor_data when several flows share it
  - creating a session already sends status.updated with status
    "Not Started". The decision key is present only when status is Approved,
    Declined, In Review or Abandoned.

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
               (Python json.dumps(sort_keys=True, separators=(",", ":"),
               ensure_ascii=False) after whole-valued floats become ints).
               Never hash the raw request bytes under this header.
  Freshness:   the signed body field timestamp is the dispatch time (Unix
               seconds). Reject when abs(now - timestamp) > 300 seconds, and
               reject when the X-Timestamp header does not equal it.
  Idempotency: event_id is the same on every retry of one event, so store it
               and skip a delivery you already processed. One session can
               still send the same status under two event ids, and the
               console's Try Webhook test deliveries carry no event_id, so
               also make the handler safe to run twice for one
               (session_id, status, webhook_type).
  Compare:     constant-time (crypto.timingSafeEqual)

Reference handler (Express). Keep the verification lines as written.
The handler is a fragment. Put this above it and app.listen(process.env.PORT)
below it. It needs Express and Node 21 or newer (an older Node rejects
every delivery). It expects a JSON body: answer 400 yourself if you accept
anything else on this route, and refuse to start without the secret.

const express = require("express");
const app = express();
const SECRET = process.env.DIDIT_WEBHOOK_SECRET; // secret_shared_key of the destination

// Your endpoint receives a signed payload
const crypto = require("node:crypto"); // ESM: import crypto from "node:crypto"
// X-Signature-V2 = HMAC over the canonical JSON, never the raw bytes. Match the sender byte for
// byte: keys sorted by code point, integers digit for digit, floats in Python's repr.
class Num { constructor(src) { this.src = src; } } // a number as written on the wire, not a double
const num = (s) => { if (/^-?\d+$/.test(s)) return BigInt(s).toString(); const n = +s; // ints stay exact
  if (Number.isInteger(n)) return BigInt(n).toString(); const [m, e] = n.toExponential().split("e"); // 27.0 -> 27
  return +e >= -4 ? String(n) : `${m}e-${String(-e).padStart(2, "0")}`; }; // 1e-05, not 0.00001
const byCodePoint = (a, b) => Buffer.compare(Buffer.from(a), Buffer.from(b)); // UTF-8 order = Python's
const canon = (v) => Array.isArray(v) ? `[${v.map(canon)}]` : v instanceof Num ? num(v.src)
  : v && typeof v === "object" ? `{${Object.keys(v).sort(byCodePoint).map((k) => `${JSON.stringify(k)}:${canon(v[k])}`)}}`
  : JSON.stringify(v);
// Read the body as text: express.json() would round 1000000000000000129 to a double first.
// Register this route ABOVE any global app.use(express.json()): the first parser to run
// consumes the stream, and a body it already parsed has lost the digits the signature covers.
app.post("/webhooks/didit", express.text({ type: "application/json" }), (req, res) => {
  const exact = JSON.parse(req.body, (k, v, c) => typeof v === "number" ? new Num(c.source) : v); // Node 21+
  const body = JSON.parse(req.body);
  const mac = crypto.createHmac("sha256", SECRET).update(canon(exact), "utf8").digest("hex");
  const sig = Buffer.from(String(req.headers["x-signature-v2"] ?? ""));
  // Freshness comes from the signed body timestamp; the header alone is unsigned and replayable.
  const ts = body.timestamp, fresh = String(ts) === req.headers["x-timestamp"]
    && Math.abs(Date.now() / 1000 - ts) <= 300;
  if (!fresh || sig.length !== mac.length
    || !crypto.timingSafeEqual(sig, Buffer.from(mac))) return res.sendStatus(401);
  const { status, decision } = 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);
});

Status values (exact strings): Not Started, In Progress, Approved, Declined,
In Review, Resubmitted, Expired, Abandoned, Kyc Expired. Awaiting User only
appears on business verification sessions.

## 6. Read the result
The same V3 decision reaches you two ways:
  - webhook body: body.decision.id_verifications[]
  - GET https://verification.didit.me/v3/session/{session_id}/decision/
      -H "x-api-key: <your-api-key>"
    This response IS the decision object. Read id_verifications at the top
    level: there is no decision wrapper here.
Until the user finishes the ID step, status is "Not Started" or "In Progress"
and id_verifications is null, not an empty array. Guard for it.

id_verifications[] has one entry per ID Verification node; with a single step
take index 0. A wallet sign-in sets:
  verification_method    "wallet"
  assurance              "cryptographic"
  wallet_provider        the catalog wallet id the user picked
  wallet_verification    provider, provider_name, issuing_authority,
                         issuing_country, credential_type, level_of_assurance,
                         verified_at, signature_valid, attributes, portrait
                         (null for the live wallets), face_match_score
  fallback_from          { method, reason, action } when the wallet sign-in failed
                         and on_failure declined the session; otherwise
                         null. After a document fallback that succeeds the
                         entry reads verification_method "document" with
                         fallback_from null
  full_name,             the normalised identity fields, on the entry itself
  date_of_birth
On a live application, check wallet_verification.signature_valid before you
trust attributes. The
live wallets return name, date of birth and a scheme identifier (for example
the Swedish personnummer; MitID returns a pseudonymised identifier), never an
address or a portrait: collect those through other steps if your policy
needs them.
Reference: https://docs.didit.me/core-technology/id-verification/digital-id-wallets

## 7. Billing
Only completed wallet sign-ins are billed; cancelled, timed-out and failed
ones are free. Prices per wallet: https://didit.me/pricing

## 8. Verify your integration
Sandbox (an application in sandbox mode: nothing is billed and no real eID is
called). https://docs.didit.me/integration/sandbox-testing
  - a sandbox application can enable every wallet in the catalog, the
    coming-soon ones included. A workflow that saves in sandbox can still be
    refused on a live application, so only use wallets marked available.
  - open the session url, pick the wallet and confirm: the default approve
    scenario simulates the sign-in. The entry then has verification_method
    "wallet", assurance "cryptographic" and wallet_provider set, and the
    normalised full_name and date_of_birth are filled. But
    wallet_verification.signature_valid and level_of_assurance are null and
    attributes is { "sandbox": true }: no real credential was checked.
    Assert signature_valid === true and the level of assurance only against
    a live application.
  - to exercise on_failure, create the session with
    "sandbox_scenario": "wallet_cancelled" (also wallet_timeout and
    wallet_provider_error). The wallet sign-in then fails and the flow moves
    to document capture or declines, as on_failure says. A fallback that
    ends in an approved document reads verification_method "document".
  - POST /v3/session/{session_id}/simulate/ forces a final status but writes
    no id_verifications entry, so it cannot stand in for a sign-in.

Checks:
  - create the workflow, create a session, and read its decision: expect 201,
    201 with url, and 200 with status "Not Started"
  - run one sandbox session per accepted wallet through the hosted flow and
    assert verification_method is "wallet" and wallet_provider is the wallet
    you picked
  - run one session with sandbox_scenario "wallet_cancelled" and assert the
    flow offers document capture
  - assert the webhook accepts a correctly signed payload and rejects a wrong
    X-Signature-V2, a changed body, and a payload whose signed timestamp is
    older than 300 seconds, even when X-Timestamp is refreshed
  - on a live application, assert wallet_verification.signature_valid is true

Docs: https://docs.didit.me/core-technology/id-verification/digital-id-wallets
合规性设计

一键开启新国家/地区业务。 我们为您解决难题。

我们负责设立当地子公司、获取许可证、进行渗透测试、获得认证,并与所有新法规保持一致。要在新国家/地区发布验证服务,只需轻点开关。已覆盖220多个国家/地区,每个季度进行审计和渗透测试, 是唯一一个被欧盟成员国政府正式认定比线下验证更安全的身份提供商。
阅读安全与合规性档案
SOC 2 · Type II — AICPA · 2026
SOC 2 · Type I — AICPA · 2026
ISO/IEC 27001 — 信息安全 · 2026
欧盟金融沙盒 — Tesoro · SEPBLAC · BdE
FIDO Alliance — 准会员 · 2026
iBeta Level 1 PAD — NIST / NIAP · 2026
GDPR — EU 2016/679
HIPAA — 45 CFR §160 · §164
DORA — EU 2022/2554
MiCA — EU 2023/1114
EBA 远程入驻 — EBA/GL/2022/15
AMLD6 · eIDAS 2.0 — 原生符合欧盟标准
Jugendschutz geprüft — FSM · JMStV §4(2) · 2026

数据证明

数据证明
  • 3,000+
    已投入生产的公司
  • 5
    Didit 上线国家电子身份数量
  • 30
    EUDI 钱包推广中的 EEA 国家数量
  • 220+
    支持文档验证的国家和地区数量
三个层级,一份价目表

免费开始,按需付费,可扩展至企业版。

每月500次免费验证,永久有效。之后仅按模块运行付费。企业版提供定制合同、数据驻留和SLA服务。

免费

$0/ 月 · 无需信用卡

适用于构建、测试和您的首批用户。

开始所需的一切:
  • 每月500次完整KYC验证
  • 身份、活体、人脸匹配、设备和IP验证
  • 200+欺诈信号、黑名单、重复项检测
  • Didit网络内可复用KYC
  • 工作流构建器、案件管理、SDK
  • AI 支持 控制台内 AI 助手、文档和社区支持。
最受欢迎

按需付费

$0.33每次完整 KYC

25+ 模块,价格公开透明。自动享受批量折扣。

包含 免费 的所有功能,以及:
  • AML 筛选和监控,低至 $0.07
  • 按国家/地区和数据层级划分的商业注册定价
  • 交易监控 $0.02 / 次
  • 钱包筛选 $0.15 / 次
  • 自有品牌白标流程
  • AI 支持 控制台内 AI 助手、文档和社区支持。

企业版

定制年度合同

适用于大批量和受监管项目。

包含 按需付费 的所有功能,以及:
  • 年度合同,承诺用量定价
  • 定制法律条款和99.99%正常运行时间SLA
  • 数据驻留、保留、安全审查
  • 按需提供人工审核员
  • 经销商和白标条款
  • 优先人工支持 24/7 共享 Slack 频道,专属客户成功经理。

使用量增长时自动享受批量折扣——无需谈判,无需销售电话。

FAQ

EUDI 钱包常见问题解答

最后审阅日期:2026年10月5日。非法律建议。
Didit 是什么?

Didit 是身份验证和欺诈防护的基础设施,是我们自己构建产品时梦寐以求的平台:开放、灵活、对开发者友好,能真正融入您的技术栈,而不是一个需要您围绕其进行集成的黑盒。

一个 API 即可覆盖个人验证(KYC,了解您的客户)、企业验证(KYB,了解您的业务)、加密钱包筛选(KYT,了解您的交易)以及实时交易监控。我们的技术栈旨在实现:

  • 快速:每次会话的 p99 延迟低于 2 秒
  • 可靠:已在 220 多个国家/地区的 3,000 多家公司中投入生产
  • 安全:通过 SOC 2 Type 1 & Type 2、ISO 27001 认证,原生支持 GDPR,并经西班牙金融监管机构正式证明比线下验证更安全

底层支持:14,000 多种文档类型,支持 48 种以上语言,1,000 多个数据源,每次会话提供 200 多个欺诈信号。Didit 基础设施通过每次会话动态学习,并日益优化。

什么是 EUDI 钱包?

根据修订了eIDAS法规(EU)No 910/2014的法规(EU)2024/1183(即eIDAS 2),每个欧盟成员国都必须提供欧盟数字身份(EUDI)钱包应用程序。该法律将其定义为一种电子身份识别方式,允许个人存储、管理和验证个人身份数据(PID)和电子属性证明,并与依赖方共享,以及使用合格的电子签名进行签署。

对于企业而言,有三个重要特性:

  • 个人可以免费获取、使用和撤销(第5a(13)条)。
  • 它是自愿的,服务必须对其他方式保持开放(第5a(15)条)。
  • 它是在高保障级别的eID方案下提供的(第5a(11)条)。

国家eID应用程序并非自动成为EUDI 钱包。钱包必须符合EUDI规则,并根据第5c条获得认证后方可视为EUDI 钱包。

EUDI 钱包何时可用?

各成员国必须在首批实施法案生效(2024 年 12 月 24 日)后的 24 个月内提供至少一个 EUDI 钱包。这意味着截止日期为 2026 年 12 月 24 日。

截至 2026 年 10 月 5 日的进展:

  • 意大利的 IT-Wallet 在 2026 年 2 月 17 日前已达到 1010 万次激活,丹麦的 AltID 已上线,提供数字身份证和年龄证明。它们是进展最快的国家级应用。
  • 德国正在运行一个公共沙盒,其钱包应用预计将于 2027 年初推出。

该日期是根据实施法案的生效日期确定的,而非 eIDAS 2 本身的发布日期。多个国家级应用将会在不同日期推出,因此本页面的准备情况表格会显示每个国家的具体日期和来源。

我们是否必须接受 EUDI 钱包,从何时开始?

如果法律或合同要求您的企业使用强用户身份验证进行在线识别,那么是的。根据第 5f(2) 条,处于此情况的私人依赖方必须在用户要求使用 EUDI 钱包时接受,最迟不晚于2027 年 12 月 24 日,即第一批实施法案生效后的 36 个月。

该条款列举了交通、能源、银行、金融服务、社会保障、健康、饮用水、邮政服务、数字基础设施、教育和电信等领域作为示例。该列表并非封闭,因为测试标准是身份验证要求,而非行业。

需要电子身份识别的公共部门服务也必须接受该钱包(第 5f(1) 条)。需要用户身份验证的超大型在线平台必须根据用户请求接受,仅限所需的最少数据(第 5f(3) 条)。该文本未给出此义务的单独日期。

这仅为摘要,不构成法律建议。

小型企业是否豁免?

是的。第 5f(2) 条排除了微型企业和小型企业,其定义见委员会建议 2003/361/EC 附件第 2 条,该条规定了员工人数和营业额门槛。请根据该建议核对您的企业规模。

该豁免涵盖接受义务,而非接受选项。小型企业仍可选择接受钱包,例如为了提供更快的注册或不共享出生日期的年龄验证。

有两点不随企业规模而改变:

  • 如果您依赖钱包,您需要在您所在成员国注册为依赖方(第 5b(1) 条)。
  • 如果您是欧盟反洗钱规则下的义务实体,您仍然需要验证客户。从 2027 年 7 月 10 日起,AMLR 第 22(6) 条允许将保障级别为实质性或高级别的电子身份识别作为两种途径之一。

这仅为摘要,不构成法律建议。

什么是依赖方,我们如何注册?

依赖方是指任何依赖 EUDI 钱包识别用户或检查属性的企业或公共机构。根据第 5b(1) 条,依赖方必须在其所在成员国注册。注册时需说明您的身份、联系方式和预期用途,包括您计划请求的数据,且您不得请求其他任何数据(第 5b(3) 条)。

注册规则,即实施条例 (EU) 2025/848,自 2026 年 12 月 24 日起适用。注册后您将收到:

  • 访问证书,用于向钱包进行身份验证,以及
  • 如果您的成员国颁发,则为注册证书,其中列出了您注册的属性。

代表依赖方行事的中介机构被视为依赖方,不得存储有关交易内容的数据(第 5b(10) 条)。例如,德国规定每个组织和用例对应一个访问和注册证书。

我们可以从钱包请求哪些数据?

只能请求您已注册的属性,并且用户决定共享哪些数据。PID 包含强制属性:姓氏、名字、出生日期、出生地点和国籍,以及有效期、签发机构和签发国家。可选属性包括肖像、性别、地址字段和个人行政号码,每个成员国选择其颁发的属性。

除了 PID,钱包还持有电子属性证明,例如驾驶执照、文凭或年龄证明。成员国还必须提供一份最低限度的属性列表,可根据真实来源进行验证,包括地址、年龄、国籍和专业资格(附件 VI)。

通过选择性披露,您只会收到用户批准的数据,由签发方签署,并附带检查有效性所需的元数据。请求的数据越少,需要保护的个人数据就越少。

EUDI 钱包是否足以满足 AMLR 下的 KYC 要求?

对于身份验证,它可以。AMLR 第 22(6)(b) 条允许使用保障级别为实质性或高级别的电子身份识别方式进行验证,而 EUDI 钱包的工作级别为高级别。AMLA 关于客户尽职调查的最终草案标准(2026 年 9 月 30 日,提交给委员会的最终草案,非法律)指出,应尽可能使用 eID 方式,其中包括 EUDI 钱包。

但这并非尽职调查的全部:

  • 地址和税务识别号通常缺失于 PID。草案标准规定您必须通过其他方式获取缺失的属性。
  • 受益所有人、制裁和 PEP 筛选、关系目的和持续监控是独立的职责(AMLR 第 20、25 和 26 条)。

Didit 目前涵盖了这些部分:地址证明、问卷调查、企业验证、AML 筛选(每次检查 $0.20)以及持续监控(每人每年 $0.07)。

EUDI 钱包使用哪些协议(OpenID4VP、SD-JWT VC、mdoc)?

分为三层:

  • 凭证格式。 PID 以 SD-JWT VC(选择性披露 JSON Web Token 可验证凭证)和 ISO/IEC 18013-5 mdoc(移动驾驶执照格式)的形式签发。两者都将未披露的值隐藏在加盐哈希之后。SD-JWT VC 用于远程使用;mdoc 也涵盖面对面检查。
  • 呈现。 在线情况下,依赖方通过重定向或 W3C 数字凭证 API,使用高保障互操作性配置文件 (HAIP) 下的 OpenID for Verifiable Presentations (OpenID4VP) 或 ISO/IEC 18013-7 请求数据。面对面情况下,ISO/IEC 18013-5 从二维码或 NFC 开始,并通过蓝牙、NFC 或 Wi-Fi Aware 继续。
  • 签发。 钱包通过 OpenID4VCI 接收凭证。

架构和参考框架 (ARF) v3.0.0 于 2026 年 7 月 23 日发布,描述了整个技术栈。

EUDI 钱包能否在不共享出生日期的情况下证明年龄?

是的。通过选择性披露,钱包可以仅共享此人已满 18 岁。荷兰政府对此的描述是:您只需共享某人是否已满 18 岁,而无需提供出生日期。

欧盟还制定了年龄验证蓝图,这是一个独立的应用程序或钱包功能,于 2025 年 7 月发布并于 2025 年 10 月更新。其年龄证明不包含身份数据,证明以批次形式签发,一次性使用,并且签发方不会被告知证明的使用地点。2026 年 4 月,欧盟委员会敦促成员国在年底前提供该应用程序,丹麦、法国、希腊、意大利和西班牙率先采纳。

对于受《数字服务法》约束的平台,欧盟委员会关于未成年人的指南(2025 年 7 月)倾向于对 18 岁以上内容进行年龄验证,并将面部年龄估算视为临时过渡方案。

钱包里有面部照片吗?我们可以用它进行人脸匹配吗?

在 2028 年 8 月 11 日之前不可靠。根据实施条例 (EU) 2026/1731,肖像仅从该日期起成为 强制性 PID 的一部分。在此之前,它是可选的,每个成员国决定是否包含。共享肖像还需要选择性披露、向用户发出警告和日志记录。

ARF 将验证凭证持有者是否为合法持有人的检查称为用户绑定。在某些流程中,依赖方执行此操作;在其他流程中,它依赖于钱包本身的检查。

因此,目前,如果您的政策需要人脸匹配,请计划一个自拍步骤:被动活体检测加上与文档照片或通过 NFC 读取的芯片肖像进行 1:1 人脸匹配。在 Didit 上,这是完整 KYC 检查的一部分,费用为 $0.33。目前五个已上线的国家 eID 均不返回肖像。

目前哪些国家有钱包?

截至2026年10月5日,多个国家应用已上线或正在测试中:

  • 意大利:IO应用中的IT-Wallet,截至2026年2月17日已激活1010万次。
  • 丹麦:AltID,已上线,提供数字身份证和年龄证明,截至2026年8月4日已有281,390人创建。
  • 德国:自2025年12月起设立公共沙盒,应用预计于2027年初推出。
  • 荷兰:NL Wallet正在开发中,等待国家实施法案。
  • 西班牙、希腊、爱尔兰和塞浦路斯,以及丹麦、法国和意大利,正在2026年期间在其国家钱包中试行欧盟年龄验证解决方案。

本页面的准备情况表格列出了我们找到的每个具有公开状态的国家,以及每行的日期和来源。

Didit 目前是否接受 EUDI 钱包?

尚未。Didit 即将支持 EUDI 钱包。我们的钱包目录中列出了 30 个 EEA 国家/地区,并计划将其用于您今天配置的相同身份验证步骤。在上线之前,我们不会提供日期或价格。

目前可用的功能:

  • 五个国家 eID 已上线:MitID(丹麦)、BankID Sweden、Finnish Trust Network(芬兰)、Smart-ID(爱沙尼亚、拉脱维亚、立陶宛、比利时)和 Mobile-ID(爱沙尼亚、立陶宛)。它们返回全名、出生日期、方案标识符(例如瑞典的 personnummer;MitID 返回的是假名化标识符)和保障级别,并进行签名检查。仅对已完成的登录收费。
  • 文档作为备用方案:通过 NFC 进行芯片读取、被动活体检测和人脸匹配,支持 14,000 多种文档类型。

基于这些功能构建的工作流在 EUDI 钱包支持上线后仍将继续运行。如果钱包对您的发布计划很重要,请与我们联系。

接受 EUDI 钱包的成本是多少?

对于个人而言,钱包是免费的:签发、使用和撤销均不收取任何费用(第 5a(13) 条)。对于企业而言,情况则有所不同:

  • 该法规并未排除向依赖方收取费用。注册必须具有成本效益并与风险相称(第 5b(2) 条),每个成员国都设立了自己的注册和证书流程,因此任何费用都取决于您所在地的成员国。
  • 运行验证器、检查受信任列表并保留证据是您自己的工程成本,或者是提供商收取的费用。

Didit 将在 EUDI 钱包功能上线后,在定价页面公布其接受 EUDI 钱包的价格。目前,定价页面显示了每个已上线检查的公布价格,例如完整 KYC 检查为 $0.33,AML 筛选为 $0.20。

我们现在该如何准备?

在钱包到来之前,有五个步骤可以帮助您做好准备:

  • 检查第 5f(2) 条是否适用于您:是否存在使用强用户身份验证的法律或合同义务,并且您不是微型或小型企业。
  • 列出您每个用例真正需要的属性。您的注册将限制您只能使用这些属性,因此年龄门槛只需要 18 岁以上,而不是完整的身份信息。
  • 规划缺失部分:PID 始终包含姓名、出生日期、出生地和国籍。地址和其他属性是可选的,可能缺失;税号、受益所有人、筛选和监控不属于 PID。
  • 立即接受您客户所在国家/地区的 eID,并为其他人保留文档验证途径。在 Didit 上,五个国家 eID 已上线,EUDI 钱包即将支持相同的验证步骤。
  • 关注您所在的成员国:注册规则自 2026 年 12 月 24 日起适用,国家应用程序的发布日期各不相同。

最后审阅:2026 年 10 月 5 日。不构成法律建议。

身份与欺诈基础设施。

一个 API 即可实现 KYC、KYB、交易监控和钱包筛选。5 分钟即可集成。

让 AI 总结此页面