> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# 工作流功能配置 API 参考

> Didit 工作流功能配置参考：说明使用 features 数组构建简单线性工作流时，POST 和 PATCH /v3/workflows/ 接受的所有配置字段。

以下 `config` 字段用于 [`POST /v3/workflows/`](https://docs.didit.me/zh/management-api/workflows/create) 和 [`PATCH /v3/workflows/{settings_uuid}/`](https://docs.didit.me/zh/management-api/workflows/update) 的 `features` 数组中每个条目内。

```json theme={null}
{
  "workflow_label": "Standard KYC",
  "features": [
    {
      "feature": "OCR",
      "config": {
        "documents_allowed": {
          "USA": {
            "DL": {
              "enabled": 1,
              "sides": 2
            }
          }
        }
      }
    }
  ]
}
```

v3 工作流 API 会根据有序的 `features` 数组构建线性的节点式工作流。请按照实际执行顺序发送各项功能。

> [!NOTE]
>
> 某项功能由哪个引擎运行（Didit 自有引擎，还是第三方服务商）不在下列 config 字段之列。它通过控制台的 [市场](https://docs.didit.me/zh/console/marketplace.md) 管理，市场会为你在该功能的 `config` 对象上设置 `provider_key` 和 `fallback_to_native`。

## 验证规则

* 省略 `config.documents_allowed`、将其设为 `null` 或 `{}` 时，`OCR` 默认覆盖所有受支持的国家/地区和证件类型。如果你发送自定义的 `documents_allowed` 对象，它必须至少包含一个有效的国家/地区和一种已启用的证件类型。每个证件配置都可以将 `sides` 设为 `1`（仅采集正面）或 `2`（采集正反面）。
* `QUESTIONNAIRE` 需要 `config.questionnaire_uuid`。
* `KYB_DOCUMENTS` 需要 `config.kyb_required_document_groups`。
* `SIGNATURE` 在合格电子签名可用之前，会以 `qes_not_available` 拒绝 `signature_level: "qes"`。当工作流上的 `signature_availability.aes` 为 `false` 时，新的 `signature_level: "aes"` 步骤会以 `aes_not_available` 被拒绝。其文件必须在创建会话时已存在：当 `signature_documents_source` 设为 `workflow` 时，该步骤需要在控制台中上传文件，没有文件的步骤可以保留为草稿，但无法上线；设为 `session` 时，每次创建调用都必须发送 `sign.documents`。
* `FACE_MATCH` 在简单工作流请求中必须位于 `OCR` 之后。
* 同一工作流中同时出现 `NFC` 和 `DATABASE_VALIDATION` 时，二者都需要 `OCR`。`AML` 之前需要有 `OCR`、`KYB_REGISTRY` 或 `DOCUMENT_AI` 之一。如果其前面只有 `DOCUMENT_AI`，则待筛查的 `full_name` 必须能够被填充：它可以来自前面已将键设为 `full_name` 的 Document AI 字段（系统会为你自动映射），也可以来自显式的 `config.aml_field_sources` 条目（参见 [AML](#aml)）。
* `KYB_DOCUMENTS` 和 `KYB_KEY_PEOPLE` 等 KYB 子功能要求工作流中更早的位置已有 `KYB_REGISTRY`。
* 工作流只能是个人（KYC）工作流或企业（KYB）工作流，二者不能同时存在。使用了任一 KYB 功能（`KYB_REGISTRY`、`KYB_DOCUMENTS`、`KYB_KEY_PEOPLE`）的工作流，只能与 `AML`、`DOCUMENT_AI`、`QUESTIONNAIRE`、`PHONE_VERIFICATION`、`EMAIL_VERIFICATION`、`IP_ANALYSIS` 和 `SIGNATURE` 组合。它不能包含仅适用于个人的功能，例如 `OCR`、`LIVENESS`、`FACE_MATCH`、`NFC`、`PROOF_OF_ADDRESS`、`DATABASE_VALIDATION` 或 `AGE_ESTIMATION`；个人工作流也不能包含 KYB 功能。在企业工作流中，`DOCUMENT_AI` 会将任何标记为 `is_full_name` 的字段与已核验的公司进行比对，而不是与个人比对。若要核验公司背后的人员，请单独创建一个 KYC 工作流，并在 `KYB_KEY_PEOPLE` 节点中通过 `kyb_ubo_verification_workflow`、`kyb_officer_verification_workflow` 或 `kyb_shareholder_verification_workflow` 引用该工作流。
* 操作字段使用 `DECLINE`、`REVIEW` 或 `NO_ACTION`，除非下文说明某字段受到限制。
* 分数和阈值字段为 `0` 到 `100` 之间的数字，除非列出了更窄的范围。

## 通用状态规则

每个功能都支持可选的 `status_rules` 数组。当字段条件匹配时，可使用它覆盖功能状态。

```json theme={null}
{
  "status_rules": [
    {
      "field": "kyc.issuing_state",
      "operator": "in",
      "value": ["VEN", "IRN"],
      "status": "In Review",
      "value_type": "literal"
    },
    {
      "field": "kyc.extra_fields.profession",
      "operator": "fuzzy_match",
      "value": "Soft. Engineer",
      "score": 80,
      "status": "Declined",
      "value_type": "literal"
    },
    {
      "field": "kyc.extra_fields.dl_class_code_b_to",
      "operator": "less_than",
      "value": "2030-01-01",
      "status": "In Review",
      "value_type": "literal"
    },
    {
      "field": "kyc.extra_fields.dl_class_code_b_from",
      "operator": "less_than",
      "value": { "direction": "past", "amount": 3, "unit": "years" },
      "status": "Declined",
      "value_type": "relative_date"
    }
  ]
}
```

| 字段 | 类型 | 说明 |
| - | - | - |
| `field` | 字符串 | 要检查的字段路径，例如 `kyc.issuing_state` 或 `kyc.document_type`。 |
| `operator` | 字符串 | 以下之一：`equals`、`not_equals`、`greater_than`、`greater_than_or_equals`、`less_than`、`less_than_or_equals`、`contains`、`not_contains`、`in`、`not_in`、`is_empty`、`is_not_empty`、`regex` 或 `fuzzy_match`。 |
| `value` | 任意类型 | 比较值。对于不需要值的运算符，可省略或发送 `null`。 |
| `status` | 字符串 | 以下之一：`Approved`、`Declined`、`In Review` 或 `No Action`。 |
| `value_type` | 字符串 | 可选。默认为 `literal`。使用 `field` 可与另一个字段比较，使用 `list` 可在运行时解析 Didit 列表 UUID，使用 `relative_date` 可将日期字段与今天加上或减去某个时长进行比较。 |
| `score` | 数字 | `fuzzy_match` 必填。最低相似度分数，范围为 `0` 到 `100`。当计算出的相似度大于或等于此值（`similarity >= score`）时，规则匹配。例如，当相似度至少为 `80` 时，`Software Engineer` 可以匹配 `Soft. Engineer`。 |

按如下方式理解上面的示例：`kyc.extra_fields.profession` 以 `80` 为最低分数进行模糊匹配 `Soft. Engineer`，则将功能状态设置为 `Declined`。

对于身份证件验证，可以指定提取的 `extra_fields` 值，例如 `kyc.extra_fields.profession`；驾照类别的有效期日期，例如 `kyc.extra_fields.dl_class_code_b_from` 和 `kyc.extra_fields.dl_class_code_b_to`；或各类别的限制/说明代码，例如 `kyc.extra_fields.dl_class_code_b_notes`（英国驾照的第 12 列）。这些值来自 OCR 结果的 `extra_fields` 对象，不属于 `expected_details`。

> [!NOTE]
>
> `dl_class_code_*_from` 和 `dl_class_code_*_to` 始终是有效的 ISO 日期，或者不会出现在 `extra_fields` 中。Didit 绝不会在日期字段中返回无法识别的 OCR 文本。如果无法读取类别表中的单元格，该字段将被省略，而不会以原始字符串形式发送。因此，请使用 `is_empty` 运算符将无法识别的类别日期路由到相应的处理流程，而不要假设该字段始终存在。

对于日期字段，请使用 `value_type: "relative_date"`，并将值设置为如下结构的对象：`{ "direction": "past" | "future", "amount": number, "unit": "days" | "months" | "years" }`。例如，使用 `operator: "less_than"` 和 `{ "direction": "past", "amount": 3, "unit": "years" }`，可匹配从今天起三年以前的日期。

### 与特定步骤比较

图形化工作流可以多次运行同一功能，例如运行三个身份证件验证步骤。
当使用 `value_type: "field"` 时，在值后追加 `@<node_id>`，即可读取某个特定步骤的值。
被引用的节点必须是功能步骤，并且在到达该规则所在步骤的每条路径上，都必须始终先于该规则所在的步骤运行；或者它就是该规则所在的步骤本身。
不带后缀的值将从该规则所在的步骤读取。

```json theme={null}
{
  "status_rules": [
    {
      "field": "kyc.full_name",
      "operator": "fuzzy_match",
      "value": "kyc.full_name@ocr_1",
      "value_type": "field",
      "score": 80,
      "status": "Declined"
    }
  ]
}
```

请将此规则理解为：设置在第三个身份证件验证步骤上的规则，要求该步骤的 `kyc.full_name` 以 `80` 为最低分数，模糊匹配步骤 `ocr_1` 读取的全名，则将功能状态设置为 `Declined`。
在控制台中，变量选择器会按画布上的编号列出每个符合条件的步骤，并自动为您存储后缀。

## OCR / 身份证件验证

功能值：`OCR`。

| 配置字段 | 类型 | 说明 |
| - | - | - |
| `documents_allowed` | object | 可选。省略该字段、发送 `null` 或发送 `{}`，即允许所有受支持的国家/地区和证件类型。仅当您需要限制允许的证件时，才为 ISO3 国家代码发送证件类型配置。至少有一个自定义证件必须设置 `enabled: 1`。证件配置可包含 `sides: 1`（仅采集正面）或 `sides: 2`（采集正反面）。证件类型包括 `P`、`ID`、`DL`、`RP`、`HIC`、`TC`、`SSC` 以及其他国家/地区支持的值。 |
| `methods` | object | 每个国家/地区可使用的三种[身份证件验证方法](https://docs.didit.me/zh/core-technology/id-verification/verification-methods.md)：证件采集、针对政府或其他权威来源的非证件查询，以及数字身份钱包。省略该键、某个国家/地区或国家/地区内的某种方法，则该国家/地区仅使用证件采集。每种方法和钱包都必须在能力目录中标记为该国家/地区可用，否则保存会被拒绝。参见下方的[各国家/地区的方法](#按国家/地区设置的方法)。 |
| `document_blur_fields_by_country` | object | ISO3 国家/地区代码到需在证件图像上进行模糊处理（打码）的字段名称的映射。 |
| `image_capture_methods_allowed` | string\[] | 允许的采集方式。取值包括 `CAMERA_SCAN` 和 `UPLOAD`。 |
| `duplicated_user_action` | action | 重复用户的操作。 |
| `is_age_restrictions_enabled` | boolean | 启用最低和最高年龄检查。 |
| `age_restrictions_by_country` | object | ISO3 国家代码到年龄配置的映射，年龄配置包含 `minimum_age`、可选的 `maximum_age` 和可选的 `states`。 |
| `minimum_age` | integer | 全局最低年龄，取值范围为 `1` 至 `120`。 |
| `minimum_age_action` | action | 用户年龄低于 `minimum_age` 时的操作。 |
| `maximum_age` | integer | 全局最高年龄，取值范围为 `1` 至 `120`。 |
| `maximum_age_action` | action | 用户年龄高于 `maximum_age` 时的操作。 |
| `expiration_date_not_detected_action` | action | 证件有效期缺失时的操作。 |
| `invalid_code_action` | action | 条形码或机器可读码无效时的操作。 |
| `invalid_mrz_action` | action | MRZ 无效时的操作。 |
| `inconsistent_data_action` | action | 提取的证件字段相互冲突时的操作。 |
| `invalid_validation_action` | action | 证件验证失败时的操作。 |
| `expected_details_mismatch_action` | action | 预期的用户信息与证件不符时的操作。 |
| `image_too_blurry_action` | action | 证件图像模糊时的操作。 |
| `image_too_dark_action` | action | 证件图像过暗时的操作。 |
| `image_too_bright_action` | action | 证件图像过曝时的操作。 |
| `unparsed_address_action` | action | 无法解析证件上的地址时的操作。 |
| `address_validation_enabled` | boolean | 根据邮政参考数据验证本步骤读取的地址（印刷在身份证件上）：确认地址存在并进行标准化，且绝不会将其与某个人关联。结果为决策中本步骤的 `address_validation` 对象。**每个已验证地址收费 \$0.10**；无法运行的验证（`unavailable`）不收费。默认关闭。 |
| `address_not_verified_action` | action | 地址验证无法将地址确认到楼栋级别（`ADDRESS_NOT_VERIFIED`：`partially_verified` 或 `not_verified`）时的操作。仅在 `address_validation_enabled` 开启时适用。默认为 `NO_ACTION`，即仅记录警告。 |
| `document_or_personal_number_format_mismatch_action` | action | 证件号或个人编号格式与预期模式不符时的操作。 |
| `critical_field_occlusion_action` | action | 遮挡检查报告所采集证件上的关键印刷字段（证件号码、姓名、出生日期或到期日期）被物理遮挡时的操作。遮挡证件号码属于篡改信号而非采集质量问题，因此默认为 `REVIEW`；无论如何，被遮挡字段的读取值都会从提取结果中剔除。若已打码的证件绝不能到达审核员，请将其提高为 `DECLINE`。 |
| `document_without_portrait_action` | action | 识别出的证件类型在任一面都不带人像照片时的操作（部分居留许可、健康卡、登记证书以及目录中已知的其他无人像证件类别）。默认为 `REVIEW`。当人脸比对是工作流身份核验的锚点时，可考虑设为 `DECLINE`。 |
| `is_document_selfie_portrait_match_enabled` | boolean | 启用证件人像与自拍照的比对。 |
| `document_selfie_portrait_match_decline_threshold` | integer | 证件人像与自拍照比对的拒绝阈值。 |
| `document_selfie_portrait_match_review_threshold` | integer | 证件人像与自拍照比对的审核阈值。 |
| `document_selfie_face_search_enabled` | boolean | 对证件采集期间拍摄的自拍照运行[人脸搜索 1:N](https://docs.didit.me/zh/core-technology/face-search/overview.md#证件采集期间拍摄的自拍照)（需要开启 `is_document_selfie_portrait_match_enabled`）：将其与人脸黑名单和已验证用户进行比对。自拍照仅用于比对，其模板绝不会被存储。默认开启。设为 `false` 将跳过搜索，证件自拍照的重复人脸相关操作将无从触发；活体检测步骤上的 `face_search_enabled: false` 也会跳过该搜索，因为该选择退出适用于本次会话的所有自拍照。 |
| `document_selfie_duplicated_face_action` | action | 证件采集自拍照与本应用中已验证用户的人脸匹配或可能匹配时的判定结果。默认为 `NO_ACTION`。 |
| `document_selfie_duplicated_face_name_mismatch_action` | action | 证件采集自拍照与已以不同姓名通过验证的用户匹配时的判定结果。只能升级 `document_selfie_duplicated_face_action`。默认为 `REVIEW`。 |
| `document_selfie_duplicated_face_document_mismatch_action` | action | 证件采集自拍照与证件上出生日期不同的已验证用户匹配时的判定结果。同一人持不同或换发的证件，不会被标记。只能升级 `document_selfie_duplicated_face_action`。默认为 `REVIEW`。 |
| `id_verification_name_match_score_threshold` | integer | 多次身份证件验证之间的姓名匹配阈值。 |
| `id_verification_max_retry_attempts` | integer | 身份证件验证的重试次数上限，取值为 `2` 至 `5`。 |
| `id_document_quality_threshold` | integer | 证件图像必须达到的最低采集质量分数（`0` 至 `100`），才会被接受。质量检查始终运行，只有该阈值可配置。默认值为 `20`，经过调校，可拒绝模糊、抖动和文字无法辨认等质量不佳的采集，同时通过清晰可读的证件。如需更严格的采集要求，请调高该值。控制台以感知滑块显示该值，默认值 `20` 显示为均衡的 50%。 |
| `cross_org_fraud_document_action` | action | 该证件被网络中其他机构标记为欺诈时的判定。 |
| `document_audio_recording_enabled` | boolean | 证件采集期间录制麦克风音频，以便审核员可以听到会话内容。默认关闭。 |
| `document_liveness_portrait_replace_decline_threshold` | integer | 人像替换分数（`0` 至 `100`，分数越高越可能为真实）低于该值时，会话将被拒绝。默认值为 `35`。参见[证件活体阈值](https://docs.didit.me/zh/core-technology/id-verification/warnings-id-verification.md#配置证件活体检测阈值)。 |
| `document_liveness_portrait_replace_review_threshold` | integer | 人像替换分数低于该值时，若会话尚未被拒绝，则进入审核中状态。设为 `100` 时，几乎所有会话都会被转入审核。默认值为 `70`。参见[证件活体阈值](https://docs.didit.me/zh/core-technology/id-verification/warnings-id-verification.md#配置证件活体检测阈值)。 |
| `document_liveness_printed_copy_decline_threshold` | integer | 印刷件副本分数（`0` 至 `100`，分数越高越可能为真实）低于该值时，会话将被拒绝。默认值为 `35`。参见[证件活体阈值](https://docs.didit.me/zh/core-technology/id-verification/warnings-id-verification.md#配置证件活体检测阈值)。 |
| `document_liveness_printed_copy_review_threshold` | integer | 印刷件副本分数低于该值时，若会话尚未被拒绝，则进入审核中状态。设为 `100` 时，几乎所有会话都会被转入审核。默认值为 `77`。参见[证件活体阈值](https://docs.didit.me/zh/core-technology/id-verification/warnings-id-verification.md#配置证件活体检测阈值)。 |
| `document_liveness_screen_replay_decline_threshold` | integer | 屏幕采集分数（`0` 至 `100`，分数越高越可能为真实）低于该值时，会话将被拒绝。默认值为 `30`。参见[证件活体阈值](https://docs.didit.me/zh/core-technology/id-verification/warnings-id-verification.md#配置证件活体检测阈值)。 |
| `document_liveness_screen_replay_review_threshold` | integer | 屏幕采集分数低于该值时，若会话尚未被拒绝，则进入审核中状态。设为 `100` 时，几乎所有会话都会被转入审核。默认值为 `70`。参见[证件活体阈值](https://docs.didit.me/zh/core-technology/id-verification/warnings-id-verification.md#配置证件活体检测阈值)。 |
| `id_verification_injection_attack_action` | action | 证件，或为证件查询拍摄的自拍照，是通过注入而非设备自身摄像头采集时（`INJECTION_ATTACK_DETECTED`）的判定：包括软件虚拟摄像头、由页面或浏览器自动化生成的摄像头画面、被挂钩的摄像头，或附加到应用上的插桩工具。取值为 `DECLINE`、`REVIEW`、`NO_ACTION`。默认值为 `DECLINE`。真实用户所能产生的信号绝不会触发该判定。在活体检测和人脸比对中，风险则改为遵循 `frame_injection_action`。 |
| `image_quality_too_low_action` | action | 证件图像整体质量低于标准时的判定。 |
| `is_image_capture_review_screen_enabled` | boolean | 每次证件采集后向用户显示审核界面，允许其在提交前重拍。默认关闭。 |
| `is_ocr_id_verification_data_review_enabled` | boolean | 允许用户在该步骤完成前审核并更正提取出的身份信息。默认关闭。用户的更正会与 `ocr_id_verification_data_review_critical_fields` 进行比对，若存在不一致，则根据字段是否属于关键字段，采取关键操作或次要操作。若工作流包含 NFC，审核仍会运行，之后的芯片读取结果会直接取代它。 |
| `ocr_id_verification_data_review_critical_fields` | string\[] | 用户编辑 OCR 结果时，哪些提取出的身份字段属于关键字段，使不一致时采取关键操作而非次要操作。格式：`["first_name" \| "last_name" \| "date_of_birth" \| ...]`。 |
| `ocr_id_verification_data_review_critical_mismatch_action` | restricted action | 用户编辑内容与 OCR 在关键字段上不一致时的判定。 |
| `ocr_id_verification_data_review_minor_mismatch_action` | action | 用户编辑内容与 OCR 在非关键字段上不一致时的判定。 |
| `status_rules` | array | 可选的自定义状态规则。 |

> [!NOTE]
>
> 以上六个 `document_liveness_*` 阈值用于配置证件活体检测，而不是按信号配置的判定字段。`portrait_replacement_action`、`printed_copy_action` 和 `screen_capture_action` 是账户级设置，**不接受**在工作流功能配置中设置：API 在保存时会去除未知的配置键，因此在此发送它们不会生效。每个信号都有拒绝阈值和审核阈值，取值范围为 `0`-`100`，分数越高表示证件越可能为真实。

示例：

```json theme={null}
{
  "feature": "OCR",
  "config": {
    "documents_allowed": {
      "USA": {
        "DL": {
          "enabled": 1,
          "sides": 2
        }
      }
    },
    "duplicated_user_action": "REVIEW",
    "image_capture_methods_allowed": ["CAMERA_SCAN", "UPLOAD"]
  }
}
```

### 按国家/地区设置的方法

`methods` 以 [ISO 3166-1 alpha-3](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3) 国家/地区代码为键。每个国家/地区最多包含三个方法对象；未填写的项目使用默认值。

```json theme={null}
{
  "feature": "OCR",
  "config": {
    "methods": {
      "ZAF": {
        "document": { "enabled": true },
        "id_lookup": {
          "enabled": true,
          "max_attempts": 2,
          "skip_liveness_and_face_match": true,
          "on_partial_match": "fallback_to_document",
          "on_no_match": "fallback_to_document",
          "on_provider_error": "fallback_to_document"
        },
        "wallet": { "enabled": false, "providers": [], "on_failure": "fallback_to_document" }
      },
      "DNK": {
        "document": { "enabled": true },
        "id_lookup": { "enabled": true, "on_no_match": "decline" }
      }
    }
  }
}
```

`wallet.on_failure` 的取值为 `fallback_to_document`、`decline` 或 `retry`。`retry`（仅适用于钱包，且该国家/地区已关闭证件采集）会让登录未在钱包步骤完成的用户再次尝试；会话绝不会因此被拒绝，并会保持开放，直到用户完成或会话过期。id\_lookup 开关仅接受 `fallback_to_document` 或 `decline`。

若要让证件不出现在第一屏，仅在钱包或查询未成功时才提供证件，请设置 `document.fallback_only`。示例使用芬兰，其中芬兰可信网络优先，证件采集作为备用。芬兰还需要在 `documents_allowed` 中启用其证件类型（例如护照和身份证），以便备用方案有可提供的证件。

```json theme={null}
{
  "FIN": {
    "document": { "enabled": true, "fallback_only": true },
    "wallet": { "enabled": true, "providers": ["ftn"], "on_failure": "fallback_to_document" }
  }
}
```

以上两项查询在当前目录中均为 `available`，因此该配置可按原样保存。本示例有意省略钱包部分：只有在目录将钱包标记为 `available` 的国家/地区，钱包配置才能保存；在其他国家/地区设置 `wallet.enabled: true` 会被拒绝，并导致整个保存失败，包括查询配置在内。若目录将某国家/地区的钱包标记为 `available`，请在该国家/地区添加钱包：

```json theme={null}
{
  "DNK": {
    "document": { "enabled": true },
    "wallet": { "enabled": true, "providers": ["mitid"], "on_failure": "fallback_to_document" }
  }
}
```

| 键 | 类型 | 默认值 | 说明 |
| - | - | - | - |
| `<ISO3>.document.enabled` | boolean | `true` | 是否在该国家/地区接受拍摄的证件。可接受的证件仍由 `documents_allowed` 决定。 |
| `<ISO3>.document.fallback_only` | boolean | `false` | 保留证件采集功能，但不在首屏展示。用户先开始该国家/地区的钱包或身份查询。只有钱包登录失败、被取消或超时，或查询未匹配（即 `on_failure`、`on_partial_match`、`on_no_match` 和 `on_provider_error` 开关设为 `fallback_to_document`）的用户才会进入证件采集。只有一个钱包时，用户直接进入该钱包。如果不是只有一个钱包，钱包或查询会与证件采集并列显示。除非 `document.enabled` 为 `true`，且该国家/地区至少有一个钱包或身份查询回退至证件采集，否则会返回 HTTP 400 错误并拒绝保存。 |
| `<ISO3>.id_lookup.enabled` | boolean | `false` | 提供针对该国家/地区政府或其他权威数据源的非证件查询。若目录未将该国家/地区的数据源标记为 `available`，则会被拒绝。 |
| `<ISO3>.id_lookup.max_attempts` | integer | `1` | `1` 到 `5`。在回退开关触发前，用户可获得的**已响应**查询次数。未通过客户端格式检查的编号不会发送到登记库，因此既不计数，也不计费。 |
| `<ISO3>.id_lookup.skip_liveness_and_face_match` | boolean | `true` | 与返回人像的登记库匹配成功后，跳过工作流自身的活体检测和人脸比对步骤，因为查询已对自拍照执行被动活体检测，并将其与该人像比对。对于不返回人像的数据源，保存时会强制设为 `false`，因为此开关在该情况下没有意义。 |
| `<ISO3>.id_lookup.on_partial_match` | `fallback_to_document` \| `decline` | `fallback_to_document` | 登记库已响应，但部分字段不匹配时的处理方式。 |
| `<ISO3>.id_lookup.on_no_match` | `fallback_to_document` \| `decline` | `fallback_to_document` | 登记库已响应，但没有匹配记录时的处理方式。 |
| `<ISO3>.id_lookup.on_provider_error` | `fallback_to_document` \| `decline` | `fallback_to_document` | 无法连接登记库时的处理方式。不计费。 |
| `<ISO3>.id_lookup.response_fields` | string\[] \| null | `null` | 数据源响应字段键的可选子集。未知键会被拒绝，数据源的必需字段始终会被加回，因此保存的值始终是有效的选择。当前预发布环境会将此选择应用于比对输出、可选的性别字段和保留的登记库人像。必需身份字段仍会保留。请参阅下方的上线与保留说明。 |
| `<ISO3>.wallet.enabled` | boolean | `false` | 在该国家/地区提供数字身份钱包登录。 |
| `<ISO3>.wallet.providers` | string\[] | `[]` | 该国家/地区接受的目录钱包 ID。这是接受列表，而非排名。您发送的顺序会被规范化为目录顺序。当 `enabled` 为 `true` 时，至少需要一个钱包。未在该国家/地区提供，或仍为即将推出的钱包会被拒绝。 |
| `<ISO3>.wallet.on_failure` | `fallback_to_document` \| `decline` \| `retry` | `fallback_to_document` | 登录被取消、超时或失败时的处理方式。`retry` 会让用户停留在钱包步骤重试（仅适用于钱包）。与 `document.fallback_only` 同时设置时会被拒绝。 |

保存时 API 会执行以下验证：

* 未知的国家代码、国家内的未知键或方法内的未知键都会被拒绝，不会静默丢弃任何内容。
* 所有方法均未启用的国家/地区会被拒绝，因为该地区的用户无法完成验证。
* 只有在该国家/地区启用证件采集时，钱包或查询才能回退至证件采集。在 `document.enabled` 为 `false` 的国家/地区，`fallback_to_document` 会在运行时导致拒绝，因为没有可回退的目标。
* 除非 `document.enabled` 为 `true`，且该国家/地区至少有一个钱包或身份查询回退至证件采集，否则 `document.fallback_only: true` 会返回 HTTP 400 错误。

> [!WARNING]
>
> 当前预发布环境会将 `id_lookup.response_fields` 应用于比对输出、可选的性别字段和保留的登记库人像。必需身份字段仍是验证记录的一部分。这并不保证所有中间供应商有效载荷都会被排除在处理之外。本次变更尚未在生产环境中验证。在依赖字段选择来满足保留要求之前，请先在目标环境中确认其行为。

在编写 `methods` 之前，请先查看能力目录。您可以通过控制台的 **国家** 标签页查看，也可以使用 [`didit_workflow_get_id_verification_methods_catalog`](https://docs.didit.me/zh/integration/mcp/tools) MCP 工具。行为、覆盖范围和计费信息见[身份证件验证方法](https://docs.didit.me/zh/core-technology/id-verification/verification-methods.md)。

## NFC / 电子护照

功能值：`NFC`。

| 配置字段 | 类型 | 描述 |
| - | - | - |
| `allow_nfc_skip` | boolean | 允许用户在证件支持芯片读取时跳过 NFC。 |
| `skip_nfc_action` | action | 用户跳过 NFC 时的操作。 |
| `unverified_chip_action` | action | 芯片验证失败时的操作。 |
| `trust_anchor_missing_action` | action | 当芯片的数据组哈希完整，但由于未加载签发国家/地区的 CSCA 信任锚而无法验证证书链时的判定结果。 |
| `jpki_request_attributes` | boolean | 日本 My Number Card（[JPKI](https://docs.didit.me/zh/core-technology/nfc-verification/overview.md#日本个人编号卡（jpki）)，仅限原生 SDK）：同时读取签名证书。这需要卡片的签名 PIN，证书包含持卡人的姓名、出生日期、性别和地址，并会与证件验证数据进行比对。默认为 `true`。设为 `false` 时仅读取用户认证证书（4 位 PIN），该证书可证明卡片和 PIN，但不包含持卡人信息。 |
| `jpki_certificate_invalid_action` | action | 当 My Number Card 证书无法链接到 JPKI 认证机构、超出有效期，或不是所请求类型的卡片证书（`JPKI_CERTIFICATE_INVALID`）时的判定结果。默认为 `DECLINE`。 |
| `jpki_signature_invalid_action` | action | 当 My Number Card 对一次性挑战的签名无法验证，因而无法证明持卡人持有卡片并知晓其 PIN（`JPKI_SIGNATURE_INVALID`）时的判定结果。默认为 `DECLINE`。 |
| `jpki_certificate_revoked_action` | action | 当吊销检查报告 My Number Card 证书已被吊销（`JPKI_CERTIFICATE_REVOKED`）时的判定结果。默认为 `DECLINE`。 |
| `jpki_revocation_unchecked_action` | action | 当 My Number Card 已完成验证，但无法获得吊销查询结果，因而无法排除该卡已被吊销（`JPKI_REVOCATION_UNCHECKED`）时的判定结果。默认为 `REVIEW`。 |
| `jpki_inconsistent_data_action` | action | 当 My Number Card 签名证书中的姓名、出生日期、性别或地址，与同一张卡的证件验证数据不一致（`JPKI_AND_OCR_DATA_NOT_SAME`）时的判定结果。默认为 `REVIEW`。 |
| `status_rules` | array | 可选的自定义状态规则。 |

## 活体检测

功能值：`LIVENESS`。

| 配置字段 | 类型 | 描述 |
| - | - | - |
| `face_liveness_method` | 字符串 | 取值之一：`ACTIVE_3D`、`FLASHING` 或 `PASSIVE`。 |
| `face_liveness_mode` | 字符串 | 活体检测模式覆盖设置。 |
| `face_liveness_flash_mode` | 字符串 | 适用于 `ACTIVE_3D` 和 `FLASHING` 方法的闪光模式。`"0"`（非严格，默认）用于验证屏幕上闪烁的颜色是否在用户面部形成反光；`"1"`（严格）还要求反光与闪烁的颜色序列完全一致，对重放攻击和视频注入攻击的防范更强，但误拒率更高。 |
| `face_liveness_score_decline_threshold` | 整数 | 拒绝阈值。 |
| `face_liveness_score_review_threshold` | 整数 | 审核阈值。 |
| `face_liveness_possible_duplicated_face_action` | 操作 | 可能存在重复人脸时的操作。 |
| `face_liveness_multiple_faces_action` | 操作 | 检测到多张人脸时的操作。 |
| `face_liveness_video_anomaly_action` | 操作 | 存储的录制内容中包含重复运动序列时的操作。默认 `NO_ACTION`；`REVIEW` 和 `DECLINE` 可以异步地升级已作出决定的验证。仅有稀疏或重复的静态帧不会触发该操作。 |
| `face_liveness_attack_face_match_action` | 操作 | 活体人脸与本应用中较早会话的另一用户人脸匹配，且该用户的采集已被高置信度判定为活体攻击时的操作（警告 `FACE_MATCHES_LIVENESS_ATTACK`）。接受 `NO_ACTION` 或 `REVIEW`；`DECLINE` 也可设置，但会按 `REVIEW` 执行，因为真实用户可能被误拒一次后再通过。默认为 `NO_ACTION`。 |
| `race_map_similarity_thresholds` | 对象 | 按人口统计群体划分的相似度阈值。 |
| `face_privacy_mode_enabled` | 布尔值 | 为人脸资源启用隐私模式。 |
| `face_quality_review_threshold` | 整数 | 人脸图像质量的审核阈值。 |
| `face_quality_decline_threshold` | 整数 | 人脸图像质量的拒绝阈值。必须小于或等于审核阈值。 |
| `face_luminance_min_threshold` | 整数 | 最低亮度阈值。必须低于 `face_luminance_max_threshold`。 |
| `face_luminance_min_action` | 操作 | 亮度过低时的操作。 |
| `face_luminance_max_threshold` | 整数 | 最高亮度阈值。 |
| `face_luminance_max_action` | 操作 | 亮度过高时的操作。 |
| `face_liveness_max_attempts` | 整数 | 每次会话的活体提交总次数，取值 `1` 至 `3`。默认 `3` 表示一次初始尝试加两次重试。设为 `1` 并不会禁用因采集质量失败而进行的重试：如果某次尝试的所有警告都属于环境因素（`LOW_FACE_LUMINANCE`、`HIGH_FACE_LUMINANCE`、`LOW_FACE_QUALITY`、`HIGH_FACE_OCCLUSION`、`NO_FACE_DETECTED`），用户始终会获得第二次尝试以及可操作的反馈。 |
| `cross_org_fraud_face_action` | 操作 | **已弃用，不再生效。** 它将人脸当作带有欺诈结论来处理，而稳定的生物识别身份无法承载此类结论。仍然接受该配置，以便现有工作流继续通过校验。请改用 `cross_org_identity_claim_pattern_action`。 |
| `cross_org_identity_claim_pattern_action` | 操作 | 网络中其他机构曾记录过针对同一人的身份声明事件，且其中声明的身份不一致时的结论。仅可设为审核或无操作，此处设置的拒绝会降级为审核。参见[跨机构身份声明](https://docs.didit.me/zh/core-technology/liveness/cross-organization-identity-claims.md)。 |
| `external_capture_device_action` | 操作 | 检测到外部采集设备时的结论。 |
| `face_audio_recording_enabled` | 布尔值 | 在自拍采集期间录制麦克风，以便审核员可以听取会话内容。默认关闭。 |
| `face_search_enabled` | 布尔值 | 对自拍照运行自动[人脸搜索 1:N](https://docs.didit.me/zh/core-technology/face-search/overview.md#关闭自动人脸搜索)：将其与此前已验证的用户、人脸黑名单和白名单进行比对，并保存其生物特征模板以供后续比对。默认开启。设为 `false` 会跳过搜索，此步骤不保存人脸模板，重复人脸相关操作将无可执行的内容。 |
| `face_liveness_uncertain_retry_enabled` | 布尔值 | 仅适用于原生 SDK 主动活体检测。开启后，活体分数严格介于 `face_liveness_score_decline_threshold` 与 `face_liveness_score_review_threshold` 之间的采集，无论引擎附带何种结论，都不会作出决定：系统会告知用户结果不明确，并每次都要求其重新采集，且此类重新采集不计入 `face_liveness_max_attempts` 次数限制（该限制仍适用于引擎无法评分的采集）。默认关闭；网页流程忽略此设置。 |
| `face_liveness_duplicated_face_name_mismatch_action` | 操作 | 在不同姓名下发现重复人脸时的结论。 |
| `face_liveness_duplicated_face_document_mismatch_action` | 操作 | 发现重复人脸，且匹配用户的身份证件显示的出生日期不同时的结论。同一人使用不同或换发的证件不会被标记。默认为 `REVIEW`。 |
| `frame_injection_action` | 操作 | 检测到注入视频帧时的结论。 |
| `screen_capture_action` | 操作 | 自拍照为屏幕照片时的结论。 |
| `virtual_camera_action` | 操作 | 检测到虚拟摄像头输入时的结论。 |
| `status_rules` | 数组 | 可选的自定义状态规则。 |

## 人脸比对

功能值：`FACE_MATCH`。

| 配置字段 | 类型 | 说明 |
| - | - | - |
| `face_match_score_decline_threshold` | 整数 | 拒绝阈值。 |
| `face_match_score_review_threshold` | 整数 | 审核阈值。 |
| `face_match_max_attempts` | 整数 | 每次会话的人脸比对提交总次数，取值为 `1` 至 `3`。默认值 `3` 表示一次初始尝试加两次重试。 |
| `face_match_not_computed_action` | 受限操作 | 无法生成人脸比对分数时（缺少人像照片或自拍照）的判定结果。 |
| `face_match_eyes_covered_action` | 操作 | 自拍照中眼部区域被遮挡时的判定结果。默认值为 `NO_ACTION`，即记录证据但不改变人脸比对结果。该信号仍在校准中，因此在该区域报告为已校准之前，它仅以影子模式运行：现在设置 `REVIEW` 或 `DECLINE`，则从该时间点起生效。 |
| `face_match_mouth_covered_action` | 操作 | 自拍照中嘴部区域被遮挡时的判定结果。默认值同样为 `NO_ACTION`，校准说明与 `face_match_eyes_covered_action` 相同。 |
| `face_match_face_covered_action` | 操作 | 自拍照中整张脸被遮挡时的判定结果。默认值同样为 `NO_ACTION`，校准说明与 `face_match_eyes_covered_action` 相同。 |
| `status_rules` | 数组 | 可选的自定义状态规则。 |

## 年龄估算

功能值：`AGE_ESTIMATION`。

| 配置字段 | 类型 | 描述 |
| - | - | - |
| `enable_id_verification_fallback` | boolean | 当年龄估算结果落在边界范围内时，运行身份证件验证。 |
| `minimum_age_threshold` | integer | 可接受的最低年龄，取值 `1` 至 `100`。 |
| `borderline_minimum_age_threshold` | integer | 边界范围的下限，取值 `1` 至 `100`。 |
| `borderline_maximum_age_threshold` | integer | 边界范围的上限，取值 `1` 至 `100`。 |
| `face_liveness_method` | string | 可选值之一：`ACTIVE_3D`、`FLASHING` 或 `PASSIVE`。 |
| `face_liveness_flash_mode` | string | `ACTIVE_3D` 和 `FLASHING` 方法的闪光模式。`"0"`（非严格，默认）用于验证屏幕上闪烁的颜色是否在用户脸上形成反光；`"1"`（严格）还要求反光与闪烁的精确颜色序列一致。 |
| `face_liveness_score_decline_threshold` | number | 年龄估算所用活体检测的拒绝阈值。 |
| `face_liveness_score_review_threshold` | number | 年龄估算所用活体检测的审核阈值。 |
| `face_liveness_possible_duplicated_face_action` | action | 可能存在重复人脸时的操作。 |
| `face_liveness_multiple_faces_action` | action | 检测到多张人脸时的操作。 |
| `face_liveness_video_anomaly_action` | action | 存储的录制内容中包含重复运动序列时的操作。默认 `NO_ACTION`；`REVIEW` 和 `DECLINE` 可以异步地将已作出判定的验证升级。仅有稀疏或重复的静态帧不会触发该操作。 |
| `face_liveness_attack_face_match_action` | action | 活体人脸与本应用中另一用户较早会话的人脸相匹配，且该用户的采集被高置信度判定为活体攻击时的操作（警告 `FACE_MATCHES_LIVENESS_ATTACK`）。接受 `NO_ACTION` 或 `REVIEW`；`DECLINE` 可以设置，但会按 `REVIEW` 执行，因为真实用户可能被误拒一次后随后通过。默认为 `NO_ACTION`。 |
| `face_privacy_mode_enabled` | boolean | 为人脸资源启用隐私模式。 |
| `face_quality_review_threshold` | integer | 人脸质量的审核阈值。 |
| `face_quality_decline_threshold` | integer | 人脸质量的拒绝阈值。 |
| `face_luminance_min_threshold` | integer | 最低亮度阈值。 |
| `face_luminance_min_action` | action | 亮度过低时的操作。 |
| `face_luminance_max_threshold` | integer | 最高亮度阈值。 |
| `face_luminance_max_action` | action | 亮度过高时的操作。 |
| `face_liveness_max_attempts` | integer | 每次会话的活体提交总次数，取值 `1` 至 `3`。默认 `3` 表示一次初始尝试加两次重试。设置为 `1` 并不会禁用因采集质量失败而进行的重试：当该次尝试的所有警告都属于环境因素（`LOW_FACE_LUMINANCE`、`HIGH_FACE_LUMINANCE`、`LOW_FACE_QUALITY`、`HIGH_FACE_OCCLUSION`、`NO_FACE_DETECTED`）时，用户始终会获得第二次尝试以及可操作的提示。 |
| `external_capture_device_action` | action | 检测到外部采集设备时的判定。 |
| `face_audio_recording_enabled` | boolean | 在自拍照采集期间录制麦克风音频，以便审核员能够听到会话内容。默认关闭。 |
| `face_search_enabled` | boolean | 对自拍照运行自动的[人脸搜索 1:N](https://docs.didit.me/zh/core-technology/face-search/overview.md#关闭自动人脸搜索)：将其与先前已验证的用户、人脸黑名单和白名单进行比对，并存储其生物特征模板以供后续比对。默认开启。设为 `false` 会跳过搜索，此步骤不保留人脸模板，重复人脸相关操作也就没有可执行的对象。 |
| `face_liveness_uncertain_retry_enabled` | boolean | 仅适用于原生 SDK 主动活体检测。开启后，活体分数严格介于 `face_liveness_score_decline_threshold` 与 `face_liveness_score_review_threshold` 之间的采集，无论引擎为其附加了何种判定，都不会作出决定：系统会告知用户结果不明确，并每次都要求重新采集，且不计入 `face_liveness_max_attempts` 的次数限制（该限制仍适用于引擎无法评分的采集）。默认关闭；网页流程忽略此设置。 |
| `face_liveness_duplicated_face_name_mismatch_action` | action | 在不同姓名下发现重复人脸时的判定。 |
| `face_liveness_duplicated_face_document_mismatch_action` | action | 发现重复人脸，且匹配用户的身份证件显示的出生日期不同时的判定。同一人使用不同或换发的证件不会被标记。默认为 `REVIEW`。 |
| `frame_injection_action` | action | 检测到注入视频帧时的判定。 |
| `screen_capture_action` | action | 自拍照为屏幕照片时的判定。 |
| `virtual_camera_action` | action | 检测到虚拟摄像头输入时的判定。 |
| `status_rules` | array | 可选的自定义状态规则。 |

## 电话验证

功能值：`PHONE_VERIFICATION`。

| 配置字段 | 类型 | 描述 |
| - | - | - |
| `code_size` | 整数 | OTP 位数，取值为 `4` 至 `8`。 |
| `phone_max_retries` | 整数 | 最大发送重试次数，取值为 `1` 至 `5`。 |
| `phone_max_check_attempts` | 整数 | OTP 最大校验次数，取值为 `1` 至 `5`。 |
| `phone_verification_countries` | 对象 | ISO2 国家/地区代码到渠道配置的映射。示例：`{ "US": { "sms": { "enabled": true } } }`。 |
| `disposable_number_action` | 操作 | 一次性号码的处理操作。 |
| `voip_number_action` | 操作 | VoIP 号码的处理操作。 |
| `duplicated_phone_number_action` | 操作 | 重复电话号码的处理操作。 |
| `high_risk_phone_action` | 操作 | 投递服务商拦截 OTP 发送时的处理操作。仅可为 `DECLINE` 或 `REVIEW`，默认值为 `DECLINE`。仅当步骤中的每个拦截项的 `risk_factors` 都恰好为 `["device_attribute"]` 时才会应用此设置；任何其他风险因素、包含该因素的任意组合，或完全没有风险因素，均无论此设置如何都会拒绝。 |
| `phone_shared_device_mode` | 布尔值 | 允许使用共享设备的电话验证模式。 |
| `phone_enrichment_enabled` | 布尔值 | 启用电话情报增强（号码线路类型风险、信任指数、运营商、号码转网与 SIM 卡换绑历史、欺诈风险评分）。**每次验证额外收取 \$0.05**，另计电话验证的价格。 |
| `phone_intelligence_score_action` | 操作 | 欺诈风险评分大于或等于 `phone_intelligence_score_threshold` 时的处理操作。 |
| `phone_intelligence_score_threshold` | 整数 | 触发 `phone_intelligence_score_action` 的欺诈风险评分（`0` 至 `100`，分数越高风险越大）。默认值为 `80`。 |
| `phone_type_risk_action` | 操作 | 号码被标记为高风险电话类型时的处理操作。 |
| `recent_port_action` | 操作 | 号码近期发生转网时的处理操作（SIM 卡换绑或转网信号）。 |
| `low_phone_trust_action` | 操作 | 电话信任指数小于或等于 `phone_trust_index_threshold` 时的处理操作。 |
| `phone_trust_index_threshold` | 整数 | 信任指数阈值（`0` 至 `100`，分数越低风险越大）。信任指数小于或等于该值时应用 `low_phone_trust_action`。默认值为 `30`。 |
| `phone_social_enabled` | 布尔值 | 启用社交足迹检查，即已验证号码在哪些即时通讯、社交、电子商务和职业平台上注册。**每次验证额外收取 \$0.05**，另计电话验证的价格，且与 `phone_enrichment_enabled` 相互独立。 |
| `phone_no_social_presence_action` | 操作 | 社交足迹检查发现号码未在其覆盖的任何平台上注册时的处理操作，这是常见的合成身份信号。默认值为 `NO_ACTION`。 |
| `cross_org_fraud_phone_action` | 操作 | 该号码被网络中其他组织标记为欺诈时的判定结果。 |
| `status_rules` | 数组 | 可选的自定义状态规则。 |

在组织完成首次充值之前，电话验证处于禁用状态。

> [!NOTE]
>
> 电话情报增强是可选的附加功能。当 `phone_enrichment_enabled` 为 `true` 时，每次完成的电话验证都会附带电话情报增强，并在标准电话验证费用之外**每次请求收取 \$0.05**。基于评分的操作只有在增强评分可用后才会生效；信任指数、电话类型和转网相关操作在增强运行后即会应用。
>
> 社交足迹检查是第二个独立的附加功能。当 `phone_social_enabled` 为 `true` 时，每次完成的电话验证还会返回该号码注册的在线平台，包括即时通讯、社交媒体、电子商务和专业服务，并且**每次请求收取 \$0.05**。它可以与 `phone_enrichment_enabled` 同时启用，也可以单独启用：两个附加功能的定价和计费相互独立。如果查询结果显示号码未在其覆盖的任何平台上注册，这同样是有效且计费的结果，并会触发 `phone_no_social_presence_action`。若要在工作流图谱中根据结果进行分支，请使用 `phone.social_profiles_registered`（号码注册的平台数量）。

## 邮箱验证

功能值：`EMAIL_VERIFICATION`。

| 配置字段 | 类型 | 说明 |
| - | - | - |
| `email_code_size` | 整数 | 一次性验证码的长度，范围为 `4` 至 `8`。 |
| `email_max_retries` | 整数 | 最大发送重试次数，范围为 `1` 至 `5`。 |
| `email_max_check_attempts` | 整数 | 验证码最大校验次数，范围为 `1` 至 `5`。 |
| `email_alphanumeric_code` | 布尔值 | 使用字母数字组合的邮箱验证码。 |
| `breached_email_action` | 操作 | 针对已泄露邮箱的操作。 |
| `disposable_email_action` | 操作 | 针对一次性邮箱的操作。 |
| `duplicated_email_action` | 操作 | 针对重复邮箱的操作。 |
| `only_corporate_emails_allowed` | 布尔值 | 拒绝非企业邮箱地址。 |
| `email_enrichment_enabled` | 布尔值 | 启用邮箱情报增强（送达率、域名信誉、数据泄露暴露情况、欺诈风险分数）。**每次验证额外收取 \$0.05**，叠加在邮箱验证费用之上。 |
| `email_intelligence_score_action` | 操作 | 当邮箱欺诈风险分数大于或等于 `email_intelligence_score_threshold` 时采取的操作。 |
| `email_intelligence_score_threshold` | 整数 | 触发 `email_intelligence_score_action` 的欺诈风险分数，范围为 `0` 至 `100`，分数越高风险越大。默认值为 `80`。 |
| `recent_email_breach_action` | 操作 | 邮箱出现在近期已知数据泄露事件中时采取的操作。 |
| `frequent_email_breach_action` | 操作 | 邮箱出现在多起已知数据泄露事件中时采取的操作。 |
| `email_social_enabled` | 布尔值 | 启用社交足迹检查：查询已验证的邮箱地址在哪些邮箱、社交、专业、电子商务和娱乐平台上注册过。**每次验证额外收取 \$0.05**，叠加在邮箱验证费用之上，与 `email_enrichment_enabled` 相互独立。 |
| `email_no_social_presence_action` | 操作 | 社交足迹检查发现该地址未在任何覆盖的平台上注册时采取的操作，这是常见的合成身份信号。默认值为 `NO_ACTION`。 |
| `cross_org_fraud_email_action` | 操作 | 该地址被网络中其他机构标记为欺诈时的判定结果。 |
| `status_rules` | 数组 | 可选的自定义状态规则。 |

> [!NOTE]
>
> 邮箱情报增强是可选的附加功能。当 `email_enrichment_enabled` 为 `true` 时，每次完成的邮箱验证都会进行邮箱情报增强，**每次请求收取 \$0.05**，另加标准的邮箱验证费用。基于分数的操作会在情报增强评分可用后生效；泄露相关操作则在增强运行后立即生效。
>
> 社交足迹检查是第二个独立的附加功能。当 `email_social_enabled` 为 `true` 时，每次完成的邮箱验证还会报告该地址在哪些在线平台上注册过，包括邮箱服务商、社交媒体、专业、电子商务和娱乐服务，并且**每次请求收取 \$0.05**。它可以与 `email_enrichment_enabled` 同时启用，也可以单独启用，两项附加功能的定价和计费相互独立。如果查询发现该地址未在任何覆盖的平台上注册，这依然是有效且计费的结果，并会触发 `email_no_social_presence_action`。如需在工作流图中根据结果进行分支，请使用 `email.social_profiles_registered`（该地址已注册的平台数量）。

## 数据库核验

功能值：`DATABASE_VALIDATION`。

| 配置字段 | 类型 | 说明 |
| - | - | - |
| `database_validation_countries` | object | 将 ISO3 国家/地区代码映射到 `{ "services": ["service_id"] }`。使用数据库核验目录中的服务 ID。 |
| `database_validation_partial_match_action` | action | 数据库核验返回部分匹配时的操作。 |
| `database_validation_no_match_action` | action | 数据库核验返回无匹配时的操作。 |
| `database_validation_not_applicable_action` | action | 数据库核验因证件不包含已配置服务所需的标识符（例如没有身份证号码的护照）而无法运行时的操作。默认为 `NO_ACTION`。 |
| `database_validation_field_sources` | object | 读取前面步骤无法填充的数据库输入项的来源。`source` 指定生产者，`key` 指定其中的值：`document_ai` 使用 Document AI 字段键，`questionnaire` 使用问卷节点 ID，`expected_data` 使用 `expected_details.<field>` 或 `metadata.<key>`。与上游步骤的键名精确匹配会自动解析，并且特意不予保存，因此重命名 Document AI 字段不会把过时的映射固化到配置中。格式错误的条目会被拒绝，返回 `400`，并指出对应的输入字段。结构：`{"<db_validation_input_field>": {"source": "document_ai"\|"questionnaire"\|"expected_data", "key": "<docai field key>\|<questionnaire node id>\|expected_details.<field>\|metadata.<key>"}}`。 |
| `status_rules` | array | 可选的自定义状态规则。 |

示例：

```json theme={null}
{
  "feature": "DATABASE_VALIDATION",
  "config": {
    "database_validation_countries": {
      "BRA": {
        "services": ["SERVICE_ID_FROM_CATALOG"]
      }
    },
    "database_validation_field_sources": {
      "tax_id": {
        "source": "expected_data",
        "key": "expected_details.document_number"
      }
    },
    "database_validation_no_match_action": "REVIEW",
    "database_validation_partial_match_action": "REVIEW"
  }
}
```

> [!WARNING]
>
> `database_validation_countries` 决定此步骤是否真正执行检查。保存时未包含它的 `DATABASE_VALIDATION` 功能会被接受，但不会执行任何检查，因此请务必至少发送一个国家/地区及至少一个服务 ID。

如果步骤无法运行某个服务 ID，保存将被拒绝，返回 `400`，错误信息会指明该 ID 并说明原因，且不会保存任何内容。这包括：ID 不在目录中、ID 属于其他国家、服务尚未开放，以及服务仅通过独立的 [`POST /v3/database-validation/`](https://docs.didit.me/zh/core-technology/database-validation/overview) 提供。如果某个服务所需的输入无法由任何前面的步骤提供，同样会被拒绝，并列出缺失的输入。已保存的工作流中如果包含某个已无法运行的服务，重新保存时该服务会被移除。

例如，此阿根廷工作流从身份证件验证读取 DNI 号码和性别，并在不使用自拍照的情况下将其与 RENAPER 核对：

```json theme={null}
{
  "workflow_label": "Argentina DNI check",
  "features": [
    {"feature": "OCR"},
    {
      "feature": "DATABASE_VALIDATION",
      "config": {"database_validation_countries": {"ARG": {"services": ["arg_renaper_data"]}}}
    }
  ]
}
```

如需同时将自拍照与 RENAPER 持有的照片进行比对，请改用 `arg_renaper`，并在 `LIVENESS` 步骤之后使用。其人脸比对分数和阈值参见 [RENAPER](https://docs.didit.me/zh/api-reference/database-validation/argentina/renaper.md)。

## 银行验证

功能值：`BANK_VERIFICATION`。

用户验证银行账户，银行报告的账户持有人会与工作流中较早步骤确立的身份进行比对。用户可通过两种方式之一完成验证：银行登录（`open_banking`），即在自己的银行登录；或账户核验（`account_lookup`），即输入账户信息，由银行确认其上的户名。`bank_method_order` 以及每个国家/地区的 `methods` 决定某个国家/地区提供哪些方式，以及哪种方式排在最前；参见 [银行验证方式](https://docs.didit.me/zh/core-technology/bank-verification/verification-methods.md)。该步骤会生成证据，包括户名匹配分数、生成该分数的比对以及原因代码；`bank_*_action` 键则将这些证据转换为状态。

节点是否执行任何操作，取决于两个因素。`bank_countries` 是白名单，因此空映射不会提供任何银行，也不会执行任何检查。此外，持有人还需要有可供比对的依据：在该节点前放置 `OCR`、`DATABASE_VALIDATION` 或 `QUESTIONNAIRE` 步骤，在创建会话时发送 `expected_details`，或使用 `bank_field_sources` 自行映射字段。若以上条件均不满足，账户归属只能为 `unknown`，此时由 `bank_reference_identity_missing_action` 决定如何处理。

> [!NOTE]
>
> 银行验证功能仍在逐步推出，因此只有在已为其启用该功能的账户上，`BANK_VERIFICATION` 节点才会被接受。在其他账户上，保存会被拒绝，并会说明原因。此处同样不配置由哪条路由执行该步骤：路由由控制台 [Marketplace](https://docs.didit.me/zh/console/marketplace.md) 为您设置的 `provider_key` 与 `fallback_to_native` 这一组参数决定。

### 连接账户

| 配置字段 | 类型 | 说明 |
| - | - | - |
| `bank_countries` | 对象 | 用户可在哪些国家/地区连接银行账户。这是白名单：空映射表示该节点不提供任何银行，也不执行任何检查。`institutions` 将选择器限定为特定机构 ID；`"all"` 则提供该国家/地区所有具备身份验证能力的银行。节点的任何路由都不服务的国家/地区会被保留：它只提供其备用方式，并提供“不通过银行继续”的选项，参见 [用户无法验证其银行时](https://docs.didit.me/zh/core-technology/bank-verification/fallbacks.md)。不对应任何国家/地区的代码在保存时会被拒绝。`methods` 设置该国家/地区提供的银行登录（`open_banking`）和账户核验（`account_lookup`）方式及其顺序，覆盖 `bank_method_order`：用户首先使用第一种方式，第二种作为备用。若某个已启用国家/地区的 `methods` 包含节点的任何路由在该国家/地区都不提供的方式，保存时会被拒绝；路由服务某国家/地区而 `methods` 在该国家/地区不留任何可用方式时，同样会被拒绝。格式：`{"<ISO3>": {"enabled": true\|false, "institutions": ["<institution_id>", ...]\|"all", "methods"?: ["open_banking"\|"account_lookup", ...]}}`。 |
| `bank_method_order` | 字符串数组 | 在未设置自有 `methods` 的每个国家/地区中，本步骤提供哪两种方式以及顺序：`open_banking`（银行登录：用户在自己的银行登录，且只有此方式可读取余额、交易和收入）和 `account_lookup`（账户核验：无需登录，仅核验归属）。在每个国家/地区，用户首先使用该国家/地区有路由提供的第一种方式，并将另一种作为备用；没有路由在某国家/地区提供的方式会被排除在该国家/地区之外。至少需要一种方式。保存请求未指定任何方式时，则取 `["open_banking", "account_lookup"]`；除非请求发送了 `bank_open_banking_enabled` 或 `bank_account_lookup_enabled`，此时由这些字段设置所提供的方式及其顺序。 |
| `bank_scopes` | 对象 | 用户被请求同意共享的内容。`ownership` 是产品核验的内容，无法关闭。`identifiers` 会解除对 IBAN 或账号的遮蔽；`balances`、`transactions` 和 `income` 读取真实的金融数据，各自单独计费，且除非您的应用具备金融数据权限，否则保存时会被拒绝。只有银行登录会读取数据：提供账户核验的国家/地区不会因此被拒绝，通过账户核验的用户无需提供数据即可通过，结果中会在 `financial_data.not_collected` 中列出未收集的数据。已关闭的范围永远不会被请求，因此银行不会在其同意页面上显示该项。默认仅为 `ownership`。格式：`{"ownership": true, "identifiers": true\|false, "balances": true\|false, "transactions": true\|false, "income": true\|false}`。 |
| `bank_eligible_account_types` | 字符串数组 | 用户可选择的账户类型：`checking`、`current`、`savings`、`business` 或 `other`。信用卡、贷款和投资账户永远不符合条件，因为它们不能证明支付账户的归属。默认为活期账户和支票账户。 |
| `bank_account_selection` | 字符串 | `user` 允许用户选择要验证的已连接账户；`auto` 则取第一个符合条件的账户。 |
| `bank_require_oauth_only` | 布尔值 | 仅提供可通过 OAuth 或应用间方式访问的机构，永不展示传统的凭据采集页面。在开放银行已使 OAuth 成为唯一途径的市场中，此设置不产生任何影响。 |
| `bank_max_attempts` | 整数 | 用户可进行的银行登录尝试次数，范围为 `1` 至 `5`；小额存款验证或对账单上传同样计为一次尝试。账户核验有其自己的 `bank_account_check_max_attempts`。当所有验证方式（包括对账单上传）均已用尽尝试次数且未成功连接时，由 `bank_attempts_exhausted_action` 决定后续处理。 |
| `bank_connection_timeout_minutes` | 整数 | 已开始的连接在放弃该次尝试前保持开放的时长，范围为 `5` 至 `60` 分钟。 |
| `bank_allow_skip` | 布尔值 | 已由 `bank_continue_without_bank` 取代：用户现在始终可以不通过银行继续。在一个发布周期内，若保存请求未发送 `bank_continue_without_bank`，则读取此值：`true` 设为 `from_start`，其他值设为 `when_needed`。每次保存都会回写此字段：`from_start` 对应 `true`，`when_needed` 对应 `false`。 |

### 用户无法完成验证时

用户始终可以不通过银行继续，该步骤不会使用户陷入停滞。参见 [用户无法验证其银行时](https://docs.didit.me/zh/core-technology/bank-verification/fallbacks.md)。

| 配置字段 | 类型 | 说明 |
| - | - | - |
| `bank_continue_without_bank` | string | 当步骤显示 **Continue without your bank** 时。`when_needed` 为默认值，会在用户所在国家或银行没有可用方式、其银行无法连接且没有其他方式能够验证用户时显示一次，例如账户核验也无法连接银行，或用户表示没有网上银行。`from_start` 还会在第一个界面就显示该选项。该选项无法关闭。保存时若既未发送此字段也未发送 `bank_allow_skip`，则取值为 `when_needed`。 |
| `bank_statement_standalone_enabled` | boolean | 与 `bank_statement_enabled` 一起启用时，即使没有进行任何银行尝试，也会在任何国家/地区提供银行对账单上传，包括没有银行登录或账户核验路径覆盖的国家/地区。此时它单独计费，计费项为 `bank_statement_upload`，在应用您的合同费率或特殊价格之前，每评估一份对账单按 USD 0.20 计费：参见 [定价](https://docs.didit.me/zh/core-technology/bank-verification/fallbacks.md#定价)。沙盒会话可在不计费的情况下测试该功能。默认开启。 |

用户选择继续时，会话会根据其继续的原因执行 `bank_unsupported_action`、`bank_attempts_exhausted_action` 或 `bank_skipped_action` 中对应的操作，除非此前已有某次尝试评估并已决定该步骤的结果：参见 [判定操作](#判定操作)。

### 比对账户持有人

| 配置字段 | 类型 | 说明 |
| - | - | - |
| `bank_reference_identity` | string | 指定账户持有人用于比对的身份由哪个先前步骤提供：`kyc`（身份证件验证）、`database_validation`、`expected_details`（创建会话时您发送的内容）、`questionnaire`，或 `auto`，即使用工作流生成的任一结果。实际提供该身份的步骤会在结果中以 `reference_identity_source` 返回。 |
| `bank_field_sources` | object | 当工作流中没有任何先前步骤能够填充参考身份字段时，从何处读取该字段。映射的键（KEY）为 `full_name`、`first_name`、`last_name`、`address` 之一；`source` 指定数据来源，`key` 指定该来源中的值名称：`document_ai` 时为 Document AI 字段键，`questionnaire` 时为问卷节点 ID，`expected_data` 时为 `expected_details.<field>` 或 `metadata.<key>`。`expected_details.` 下的值只能指定会话创建请求实际携带的字段：`address`、`country`、`date_of_birth`、`first_name`、`gender`、`id_country`、`identification_number`、`ip_address`、`last_name`、`nationality` 或 `poa_country`。格式错误的条目会在保存时被拒绝，而不会被丢弃。格式：`{"full_name"\|"first_name"\|"last_name"\|"address": {"source": "document_ai"\|"questionnaire"\|"expected_data", "key": "<docai field key>\|<questionnaire node id>\|expected_details.<field>\|metadata.<key>"}}`。 |
| `bank_name_match_threshold` | integer | 分数达到或超过该值时，持有人姓名即判定为匹配。取值为 `50` 至 `100`，默认为 `85`。 |
| `bank_partial_match_floor` | integer | 分数低于该值时，持有人姓名判定为不匹配。取值为 `0` 至 `99`，默认为 `70`。下限与阈值之间的区间为部分匹配，因此下限必须严格低于阈值，否则保存会被拒绝。此处显式传入 `null` 表示“使用默认值”，因此只设置阈值为 `50` 而不设置下限会被拒绝：系统会将 `50` 与默认下限 `70` 进行比较。 |
| `bank_require_address_match` | boolean | 同时要求持有人地址匹配。姓名达到阈值但地址分数低于阈值时，降为部分匹配。未返回地址的机构可免除此要求；若会话本身没有可比对的地址，则不予免除，结果为部分匹配。默认关闭。 |
| `bank_use_provider_score` | boolean | 同时读取机构自身给出的持有人姓名分数。当该分数高于 Didit 的分数，或 Didit 没有可评分的持有人姓名时，由该分数决定结果。以此方式决定的结果，其匹配方式报告为 `provider_only`；若连接未返回此类分数，则记录 `provider_score_unavailable` 警告。默认开启。 |
| `bank_show_match_result_to_user` | boolean | 在验证流程中向用户展示所有权比对结果。关闭时，结果仅记录在会话中，从不向用户展示。 |

### 账户核验

以下配置仅适用于账户核验。银行登录保留其自身的近似匹配以及 `bank_max_attempts`。

| 配置字段 | 类型 | 说明 |
| - | - | - |
| `bank_account_check_accept_close_match` | boolean | 开启（默认）时，银行评分介于 `bank_partial_match_floor` 与 `bank_name_match_threshold` 之间的姓名视为近似匹配：若开启 `bank_suggest_holder_name`，用户需确认银行所持有的姓名，结果由 `bank_partial_match_action` 决定。关闭时，该近似匹配视为不匹配（`OWNER_NAME_MISMATCH`，结果由 `bank_no_match_action` 决定），并占用一次尝试机会。 |
| `bank_account_check_max_attempts` | integer | 用户可进行账户核验的次数，取值为 `1` 至 `5`，未设置时为 `3`：即用户可输入账户信息、进行银行可作答核验的次数。与 `bank_max_attempts` 分别计数。因输入内容不被接受而被拒绝的核验（例如 IBAN 无效），或银行无法作答的核验，均不占用尝试次数。 |

### 财务数据

`bank_expected_currencies` 仅依赖默认的 `ownership` 授权范围即可使用。其他三个配置项读取真实的财务数据，因此每一项都需要在 `bank_scopes` 中配置对应的授权范围，否则保存会被拒绝。

| 配置字段 | 类型 | 说明 |
| - | - | - |
| `bank_expected_currencies` | string\[] | 账户预期所使用的 ISO 4217 货币。为空表示任意货币；货币不匹配时，通过 `bank_currency_mismatch_action` 报告。 |
| `bank_min_balance` | number | 最低可用余额，以账户本身的货币计。低于该值时触发 `bank_low_balance_action`。需要 `balances` 授权范围。`0` 是有效的阈值，与省略该配置项不同：透支账户会触发该操作。该操作默认为 `NO_ACTION`，即保持判定结果不变，因此若要拒绝透支账户，还需设置 `bank_low_balance_action: "DECLINE"`。 |
| `bank_transactions_history_days` | 整数 | 读取交易历史的时间范围，为 `30` 至 `365` 天。默认为 `90`。需要 `transactions` 权限范围。 |
| `bank_refresh_enabled` | 布尔值 | 在步骤已作出判定之后，只要银行同意仍然有效，就重新获取该账户的财务数据。需要 `balances`、`transactions` 或 `income` 权限范围中的至少一个。之后失效的同意由 `bank_consent_expired_action` 处理。 |

### 存储内容

| 配置字段 | 类型 | 说明 |
| - | - | - |
| `bank_store_full_identifiers` | 布尔值 | 以未脱敏的形式存储账户标识符，而非脱敏形式。需要 `identifiers` 权限范围。即便如此，未脱敏的形式也只返回给拥有银行验证读取权限的调用方。 |
| `bank_store_raw_owner_data` | 布尔值 | 保留银行返回的持有人信息，并与所有权证据一同保存。关闭时，仅保留比对结果本身：分数、匹配方式和原因代码。 |

### 判定操作

除非标记为受限，否则此处每个键都接受 `DECLINE`、`REVIEW` 或 `NO_ACTION`。省略或发送 `null` 时，将使用下方的默认值。凡不属于明确所有权证据的结果，默认都不会通过；只有能够证明与用户不符的证据才会导致拒绝。

| 配置字段 | 类型 | 说明 |
| - | - | - |
| `bank_no_match_action` | 受限操作 | 账户持有人被证明并非已验证本人时的判定，即最佳姓名分数低于 `bank_partial_match_floor`。使用 `DECLINE` 或 `REVIEW`。默认为 `DECLINE`。 |
| `bank_partial_match_action` | 操作 | 持有人姓名分数介于 `bank_partial_match_floor` 与 `bank_name_match_threshold` 之间时的判定。默认为 `REVIEW`，且默认绝不会通过。 |
| `bank_not_verifiable_action` | 操作 | 机构已连接，但未返回可供比对的持有人身份时的判定。默认为 `REVIEW`。 |
| `bank_unknown_action` | 操作 | 重试后仍无法获取证据（临时性故障）时的判定。默认为 `REVIEW`。 |
| `bank_reference_identity_missing_action` | 操作 | 此前的步骤未生成可供比对持有人的身份，因此所有权只能为 `unknown` 时的判定。默认为 `REVIEW`。 |
| `bank_joint_account_action` | 操作 | 账户有多个持有人时的判定。默认为 `NO_ACTION`。 |
| `bank_business_account_action` | 操作 | 机构将持有人标记为企业而非个人时的判定。在个人工作流中默认为 `REVIEW`；在企业（KYB）工作流中，因为会话本就预期找到企业持有人，默认为 `NO_ACTION`。 |
| `bank_unsupported_action` | 操作 | 用户在没有任何验证方式能够验证其国家或银行的情况下选择不使用银行继续时的判定：没有银行登录或账户核验路径覆盖该国家，或用户所选的银行无法用于此步骤。此时结果中 `continued_without_bank` 为 true，原因代码中包含 `NOT_COVERED`。默认为 `REVIEW`。 |
| `bank_skipped_action` | 受限操作 | 用户在仍有可用验证方式时选择「不使用银行继续」的判定。此时结果中 `continued_without_bank` 为 true，原因代码中包含 `SKIPPED`。使用 `DECLINE` 或 `REVIEW`。默认为 `REVIEW`。 |
| `bank_attempts_exhausted_action` | 受限操作 | 用户耗尽了仍然提供的每种验证方式的尝试次数（包括 `bank_max_attempts`（对账单上传），以及该国家提供账户核验时的 `bank_account_check_max_attempts`），仍未成功连接的判定，包括之后选择不使用银行继续的情况。使用 `DECLINE` 或 `REVIEW`。默认为 `DECLINE`。 |
| `bank_consent_expired_action` | 操作 | 步骤已作出判定后银行同意失效时的判定。仅在启用 `bank_refresh_enabled` 时有意义。默认为 `NO_ACTION`。 |
| `bank_currency_mismatch_action` | 操作 | 账户货币不在 `bank_expected_currencies` 中时的判定。默认为 `NO_ACTION`。 |
| `bank_country_mismatch_action` | 操作 | 机构所在国家/地区与预期国家或证件国家不同时的判定。默认为 `NO_ACTION`。 |
| `bank_low_balance_action` | 操作 | 可用余额低于 `bank_min_balance` 时的判定。需要 `balances` 权限范围。默认为 `NO_ACTION`。 |
| `status_rules` | 数组 | 可选的自定义状态规则。 |

### 更多控制

这些键均为可选。每个操作键接受 `DECLINE`、`REVIEW` 或 `NO_ACTION`。

| 配置字段 | 类型 | 说明 |
| - | - | - |
| `bank_abandoned_action` | 操作 | 用户在银行端中途离开且从未返回（尝试超时），步骤结束时仍未匹配时的判定。 |
| `bank_account_age_action` | 操作 | 账户历史短于 `bank_account_age_days` 时的判定，这是典型的人头账户模式。 |
| `bank_account_age_days` | 整数 | 账户历史记录的起始时间距今少于此天数的，视为新账户，取值 1 至 365，默认为 30。从交易历史中读取，因此仅在具有 `transactions` 权限范围时生效。 |
| `bank_account_lookup_enabled` | 布尔值 | 已停用：请改用 `bank_method_order` 和 `bank_countries.<ISO3>.methods`。在一个版本内，对于未发送 `bank_method_order` 的保存，会读取此字段：在 `bank_open_banking_enabled` 启用时，本字段会设置方法顺序：本字段启用时将账户核验安排在银行登录之后；本字段关闭或未设置时则不纳入。每次保存都会将其回写为是否有任何国家提供账户核验。 |
| `bank_account_type_action` | 操作 | 已验证账户为储蓄账户时的判定。 |
| `bank_address_match_threshold` | 整数 | 分数达到或超过此值时，视为持有人地址匹配，取值 50 至 100，默认为 70。仅在启用 `bank_require_address_match` 时读取。 |
| `bank_address_mismatch_action` | 操作 | 持有人地址不一致时的判定，这会将匹配转为近似匹配。仅在启用 `bank_require_address_match` 时生效。 |
| `bank_auto_add_countries` | 布尔值 | 为该节点可提供路线的每个国家/地区提供服务，包括节点保存后新增的国家/地区，但 `bank_countries` 已关闭的国家/地区除外。未设置该键时为关闭，因此已有节点不会自行扩大范围。 |
| `bank_cash_flow_action` | 操作 | 资金流入后直接流出，或有大量小额转入（过手资金流）时的判定结果。需要 `transactions` 权限范围。 |
| `bank_dob_match_enabled` | 布尔值 | 如银行提供，则比对账户持有人的出生日期与已验证的出生日期。不一致不会影响账户归属结果，但会触发 `bank_dob_mismatch_action`。默认开启。 |
| `bank_dob_match_threshold` | 整数 | 达到或高于此分数时视为出生日期匹配，范围 50 至 100，默认值为 70。日期要么是同一天，要么不是，因此得分只会是 100 或 0。 |
| `bank_dob_mismatch_action` | 操作 | 账户持有人出生日期不一致时的判定结果。仅在 `bank_dob_match_enabled` 开启时生效。 |
| `bank_email_match_enabled` | 布尔值 | 比对银行记录中的邮箱与会话中已验证的邮箱。不一致时触发 `bank_email_mismatch_action`。默认关闭。 |
| `bank_email_match_threshold` | 整数 | 达到或高于此分数时视为邮箱匹配，范围 50 至 100，默认值为 70。 |
| `bank_email_mismatch_action` | 操作 | 账户持有人邮箱不一致时的判定结果。仅在 `bank_email_match_enabled` 开启时生效。 |
| `bank_evidence_retention_days` | 整数 | 判定结果作出后经过此天数即删除银行证据，可选值为 30、90、365 或 1825。设为 null 时，证据随会话保留。以下内容将被删除：账户持有人详细信息、用于比对的身份信息、账户标识符、财务数据，以及已上传的对账单；仍处于活动状态的连接将被撤销。判定结果、分数和原因代码会保留。删除会话时，所有数据都会被删除，以先到者为准。 |
| `bank_fallback_used_action` | 操作 | 账户通过小额存款或上传对账单完成验证时的判定结果。 |
| `bank_match_any_holder` | 布尔值 | 联名或共同所有的账户，只要列出的任一持有人与该用户匹配即视为匹配。关闭时，仅将银行列出的第一位持有人与该用户进行匹配。默认开启。 |
| `bank_microdeposits_enabled` | 布尔值 | 提供小额存款作为备选方式：两笔小额款项打入账户，用户输入金额。仅在可发送小额存款的国家/地区提供，且须在同一会话中先进行过一次收费的银行验证尝试。该功能不额外收费，客户仅需支付一次通道价格。沙盒会话可测试此功能且不计费。持有人为会话中已验证的姓名，即用户声明该账户所属的人，因此已验证的账户会记录 `holder_declared` 警告。默认开启。 |
| `bank_mule_score_action` | 操作 | 资金中转风险分达到或高于 `bank_mule_score_threshold` 时的判定结果。 |
| `bank_mule_score_threshold` | 整数 | 资金中转风险分达到或高于此值（范围 0 至 100）时，触发 `bank_mule_score_action`，默认值为 70。该分数综合了新开账户、过手资金流、余额被清空以及大量小额转入等因素，依据交易记录计算（需要 `transactions` 权限范围）。 |
| `bank_open_banking_enabled` | 布尔值 | 已停用：请改用 `bank_method_order` 和 `bank_countries.<ISO3>.methods`。在一个版本周期内，若保存时未发送 `bank_method_order`，则会读取此项：与 `bank_account_lookup_enabled` 一起使用时，它会设置方法顺序；此项开启或未设置时，顺序中包含银行登录。每次保存都会将其回写为是否有任一国家/地区提供银行登录。 |
| `bank_phone_match_enabled` | 布尔值 | 比对银行记录中的电话与会话中已验证的电话。不一致时触发 `bank_phone_mismatch_action`。默认关闭。 |
| `bank_phone_match_threshold` | 整数 | 达到或高于此分数时视为电话匹配，范围 50 至 100，默认值为 70。 |
| `bank_phone_mismatch_action` | 操作 | 账户持有人电话不一致时的判定结果。仅在 `bank_phone_match_enabled` 开启时生效。 |
| `bank_popular_mode` | 字符串 | `auto`（默认）按各国家/地区用户连接最多的银行对热门银行排序；`manual` 则改为按 `bank_countries` 中各国家/地区 `popular_institutions` 的顺序显示。 |
| `bank_statement_document_checks_action` | 操作 | 上传的对账单存在编辑或篡改痕迹时的判定结果。默认为 `REVIEW`。 |
| `bank_statement_enabled` | 布尔值 | 提供对账单上传作为备选方式：要求为近 3 个月的对账单，检查是否被篡改，并且其账户持有人姓名的比对方式与银行相同。在同一会话中先进行过一次收费的银行验证尝试后提供，不额外收费。开启 `bank_statement_standalone_enabled` 后，即使之前没有银行验证尝试，也会在任何国家/地区提供，此时单独计费。沙盒会话可测试此功能且不计费。默认关闭。 |
| `bank_suggest_holder_name` | 布尔值 | 接近匹配时，向用户显示银行记录中该账户的持有人姓名，并请用户确认是否为本人，或连接另一个账户。用户的回答会记录为 `holder_confirmation`；确认后，该步骤按 `bank_partial_match_action` 结束。默认开启。 |
| `fallback_to_native` | 布尔值 | 市场连接无法建立时，是否回退到 Didit 原生通道。默认关闭：静默回退会用您的 Didit 余额为本应使用您自有服务商合同运行的会话付费。回退连接会记录为 `credential_source = native`，并按原生价格计费。 |
| `provider_key` | 字符串 | 决定由哪个通道运行该步骤。留空（默认值）即使用 Didit 原生 Bank Verification，这是一项与服务商无关的产品，Didit 会根据用户所在国家/地区和机构，将请求路由至对应的区域开放银行服务商，并按 Didit 的合同和计费运行。填写一个值则指定一个市场服务商，该服务商的凭证须已由本应用连接：此时会话在您的服务商账户上运行、计费并撤销，Didit 仅收取市场平台费用。未连接的服务商在保存时会被拒绝。 |

示例 `config` 对象，适用于已启用 Bank Verification 且所选通道覆盖您所列国家/地区的账户：

```json theme={null}
{
  "bank_method_order": ["open_banking", "account_lookup"],
  "bank_countries": {
    "ESP": { "enabled": true, "institutions": "all" }
  },
  "bank_scopes": { "ownership": true },
  "bank_eligible_account_types": ["checking", "current"],
  "bank_name_match_threshold": 85,
  "bank_partial_match_floor": 70,
  "bank_partial_match_action": "REVIEW",
  "bank_no_match_action": "DECLINE"
}
```

> [!WARNING]
>
> `bank_countries` 决定此步骤是否生效，并且会根据该节点所运行的通道进行校验，而不是对照全局国家列表。若该通道无法建立账户归属，则该国家/地区在保存时会被拒绝，并在错误信息中注明。因此请仔细阅读错误信息，不要假定该国家/地区已被接受，并会在运行时被跳过。

## AML

功能值：`AML`。

对于 KYC 个人筛查，请使用以下字段：

| 配置字段 | 类型 | 说明 |
| - | - | - |
| `is_aml_ongoing_monitoring_enabled` | boolean | 启用持续 AML 监控。 |
| `aml_score_approve_threshold` | integer | 通过阈值。 |
| `aml_score_review_threshold` | integer | 审核阈值。 |
| `aml_match_score_threshold` | integer | 可能匹配的匹配分数阈值。 |
| `aml_name_weight` | integer | 姓名权重。如果提供了任何 AML 权重，则姓名、出生日期和国家/地区的权重之和必须为 `100`。 |
| `aml_dob_weight` | integer | 出生日期权重。 |
| `aml_country_weight` | integer | 国家/地区权重。 |
| `create_cases_on_hit` | boolean | 筛查返回命中结果时自动开启案件，而不是留待在会话中进行分诊。默认关闭。 |
| `case_blueprint` | uuid | 自动创建的案件基于哪个案件蓝图。仅在设置 `create_cases_on_hit` 时有效；未设置时使用账户默认值。 |
| `status_rules` | array | 可选的自定义状态规则。 |

对于 KYB 企业筛查，请使用以下字段：

| 配置字段 | 类型 | 说明 |
| - | - | - |
| `kyb_score_approve_threshold` | integer | 企业 AML 通过阈值。 |
| `kyb_score_review_threshold` | integer | 企业 AML 审核阈值。 |
| `kyb_enable_ongoing_monitoring` | boolean | 启用 KYB 持续 AML 监控。 |
| `kyb_company_aml_match_score_threshold` | integer | 企业 AML 匹配分数阈值。 |
| `kyb_company_aml_name_weight` | integer | 企业名称权重。提供时，企业 AML 权重之和必须为 `100`。 |
| `kyb_company_aml_dob_weight` | integer | 成立日期或出生日期权重。 |
| `kyb_company_aml_country_weight` | integer | 国家/地区权重。 |

### 筛查 Document AI 步骤提取的实体

AML 步骤通常从 `OCR` 步骤（个人）或 `KYB_REGISTRY` 步骤（企业）读取其要筛查的对象。如果工作流唯一的提取步骤是 `DOCUMENT_AI`（例如税务证明或成立文件等非标准化文件），则两者都没有，因此必须说明每个筛查输入来自何处。

| 配置字段 | 类型 | 说明 |
| - | - | - |
| `aml_field_sources` | object | 要筛查的实体从何处读取。`source` 指定数据来源，`key` 指定其中的值：`document_ai` 使用 Document AI 字段键，`questionnaire` 使用问卷节点 ID，`expected_data` 使用 `expected_details.<field>` 或 `metadata.<key>`。映射的键是四个筛查输入之一：`full_name`、`date_of_birth`、`nationality`、`document_number`；对于企业，分别对应法定名称、成立日期、国家/地区和注册号。已被设为这四个键之一的 Document AI 字段会自动映射，且刻意不保存，因此重命名该字段不会固化过时的映射。显式映射优先于自动映射和身份证件，运行时无法解析到任何内容的映射会使该输入留空，而不会回退。在企业（KYB）工作流中，`KYB_REGISTRY` 步骤返回的企业信息具有权威性：只有显式映射可以覆盖其中的某个输入，自动映射不会叠加在登记记录之上；如果没有登记步骤，则映射就是完整的身份信息。格式：`{"full_name"\|"date_of_birth"\|"nationality"\|"document_number": {"source": "document_ai"\|"questionnaire"\|"expected_data", "key": "<docai field key>\|<questionnaire node id>\|expected_details.<field>\|metadata.<key>"}}`。 |
| `aml_entity_type` | string | `person` 或 `company`。在个人（KYC）工作流中默认为 `person`，在企业（KYB）工作流中默认为 `company`。若要在没有 `KYB_REGISTRY` 步骤的情况下筛查上传文件中提到的企业，请设为 `company`：服务商会搜索企业记录，并按企业方式计算匹配分数。 |
| `aml_incomplete_data_action` | action | 当筛查所用身份信息不完整（不包含姓名、出生日期和国家/地区）时的结论。默认为 `REVIEW`。`NO_ACTION` 会在数据不完整的情况下继续处理，适用于工作流明确只持有姓名的情况。无论如何都会执行筛查，也都会记录不完整数据日志；此设置仅决定其对状态的影响。 |

示例：筛查墨西哥 *acta constitutiva*（公司设立文件）中提到的公司，且工作流中没有任何身份证件：

```json theme={null}
{
  "feature": "AML",
  "config": {
    "aml_entity_type": "company",
    "aml_field_sources": {
      "full_name": { "source": "document_ai", "key": "razon_social" },
      "document_number": { "source": "document_ai", "key": "rfc" },
      "date_of_birth": { "source": "document_ai", "key": "fecha_constitucion" },
      "nationality": { "source": "document_ai", "key": "pais" }
    },
    "aml_incomplete_data_action": "REVIEW"
  }
}
```

> [!WARNING]
>
> 如果之前没有 `OCR` 和 `KYB_REGISTRY` 步骤，`AML` 步骤必须能够填充 `full_name`，因为没有名称就无法进行服务商搜索。如果工作流未映射任何内容，或映射了上游步骤未提取的 Document AI 键，保存时将被拒绝，而不会保存后却不进行任何筛查。AML 的精确度直接取决于您提供的标识符数量：仅凭姓名进行的筛查会产生大量误报。

## 设备与 IP 分析

功能值：`IP_ANALYSIS`。

| 配置字段 | 类型 | 描述 |
| - | - | - |
| `ip_mismatch_action` | action | IP 地理位置与预期数据不一致时的操作。 |
| `ip_location_not_determined_action` | action | 未记录用于识别终端用户的 IP 地址、因此会话完全没有 IP 位置时的判定结果。此时国家/地区、城市、ISP、坐标和时区均不可用，`ip_geofencing_by_country`、证件国家/地区比对以及 VPN 与数据中心检查也无法运行。默认值为 `NO_ACTION`，即保留会话上的 `IP_LOCATION_NOT_DETERMINED` 警告显示，但不改变其判定结果；如果未定位的会话不得通过，请设置为 `REVIEW` 或 `DECLINE`。 |
| `vpn_detection_action` | action | 检测到 VPN 或代理使用时的操作。 |
| `expected_ip_mismatch_action` | action | IP 与预期 IP 不一致时的操作。 |
| `duplicated_ip_action` | action | IP 被可疑地重复使用时的操作。 |
| `duplicated_device_action` | action | 同一持久设备指纹在来自不同 `vendor_data` 值的会话中被重复使用时的操作。 |
| `recovered_device_action` | action | 在持久设备 ID 发生变化后，v2 指纹恢复将会话与一个此前见过的设备高置信度关联时的操作。 |
| `is_ip_geofencing_enabled` | boolean | 启用 IP 地理围栏限制。设为 `false` 时，`ip_geofencing_by_country` 会被保留但不会强制执行。 |
| `ip_geofencing_by_country` | object | 按 ISO-3 国家代码设置的 IP 位置规则：`{"USA": {"allowed": true, "states": {"California": {"allowed": false}}}}`。州/地区条目会覆盖国家级标志；未列出的国家/地区默认允许。 |
| `ip_geofencing_action` | action | 会话 IP 位于不允许的国家/地区或州/地区时的操作。默认值为 `DECLINE`。 |
| `automation_detected_action` | action | 会话看起来由自动化程序而非真人操作时的判定结果。 |
| `cross_org_fraud_device_action` | action | 该设备被网络中的其他组织标记为欺诈时的判定结果。 |
| `cross_org_fraud_ip_action` | action | 该 IP 被网络中的其他组织标记为欺诈时的判定结果。 |
| `device_app_tampered_action` | action | 宿主应用二进制文件看起来被篡改时的判定结果。 |
| `device_blocklist_action` | action | 设备位于组织黑名单中时的判定结果。 |
| `device_debugger_action` | action | 宿主应用上附加了调试器时的判定结果。 |
| `device_emulator_action` | action | 设备为模拟器而非真实硬件时的判定结果。 |
| `device_hooking_action` | action | 检测到运行时挂钩或插桩时的判定结果。 |
| `device_integrity_missing_action` | action | 未返回平台设备完整性证明时的判定结果。 |
| `device_rooted_action` | action | 设备已 root 或越狱时的判定结果。 |
| `multiple_devices_action` | action | 会话由一台以上设备操作时的判定结果。 |
| `device_liveness_attack_history_action` | action | 同一设备（按其持久设备 ID 匹配）曾在另一用户的较早会话中使用，且该用户的活体采集被判定为攻击时（警告 `DEVICE_LINKED_TO_LIVENESS_ATTACK`）的操作。默认值为 `NO_ACTION`。 |
| `device_model_inconsistency_action` | action | 同一设备（按其持久设备 ID 匹配）在较早会话中被报告为不同设备型号时（警告 `DEVICE_MODEL_INCONSISTENT`）的操作。默认值为 `NO_ACTION`。 |
| `status_rules` | array | 可选的自定义状态规则。 |

示例：

```json theme={null}
{
  "feature": "IP_ANALYSIS",
  "config": {
    "vpn_detection_action": "REVIEW",
    "duplicated_device_action": "REVIEW",
    "recovered_device_action": "REVIEW",
    "is_ip_geofencing_enabled": true,
    "ip_geofencing_by_country": {
      "USA": { "allowed": true, "states": { "California": { "allowed": false } } },
      "RUS": { "allowed": false, "states": null }
    },
    "ip_geofencing_action": "DECLINE"
  }
}
```

如果您希望在自动拒绝高置信度已恢复设备之前先对其进行监控，请将 `recovered_device_action` 与 `duplicated_device_action` 分开配置。这在上线推广期间很有用，因为已恢复设备匹配旨在检测欺诈团伙，但仍应结合您自身的流量进行校准。

## 位置验证

功能值：`GEOLOCATION`。

通过设备位置或连接的 IP 位置，检查用户在验证过程中所处的位置，并将其与允许区域、禁止区域、IP 位置和证件地址进行比对。
步骤的运行方式请参阅[位置验证](https://docs.didit.me/zh/core-technology/location-verification/overview.md)，决策字段请参阅[其报告](https://docs.didit.me/zh/core-technology/location-verification/report-location-verification.md)。
如果你需要计算与证件地址的距离，请将此步骤放在身份证件验证或地址证明之后，因为只有存在已登记地址时才会测量该距离。
当 `geolocation_position_source` 未设置时，与 IP 位置的距离需要同一工作流中包含设备与 IP 分析步骤。
所有字段均为可选：`config` 为空的步骤会要求设备提供精度在 250 米以内、时间不超过 120 秒的位置，允许用户尝试 3 次，并且不应用任何区域规则。

每个检测结果都有各自的操作字段。未设置的操作字段采用你所选 `geolocation_preset` 的默认值；若未选择预设，则采用下方列出的各字段默认值。
位置不确定或被拒绝时默认为 `REVIEW`，而不是 `DECLINE`，因为权限被拒绝或半径过大并不构成欺诈证据。
你显式设置的操作始终优先于预设。
重放的挑战（`LOCATION_REPLAY_DETECTED`）和失败的设备证明（`LOCATION_INTEGRITY_FAILED`）始终会拒绝，且没有操作字段。

| 配置字段 | 类型 | 说明 |
| - | - | - |
| `geolocation_position_source` | string | 位置的来源。`device_and_ip` 会请求设备位置，并将其与提交该请求的连接的 IP 位置进行比较（若该 IP 尚未缓存，则先进行 IP 情报查询）。未设置时（默认值）同样会请求设备位置，并且与该字段出现之前的行为一致，将其与会话的设备与 IP 分析步骤所观察到的 IP 位置进行比较，因此没有该步骤就无法计算距离，且从不查询该连接。例外情况是：若节点针对 VPN、代理或 Tor 检测结果采取操作（无论是其自身操作还是其预设），则会针对该检测结果查询该连接，并与 `device_and_ip` 的做法完全一致地将设备位置与之比较。`device_only` 从不与 IP 位置比较，且仅针对这些检测结果查询连接；`ip_only` 从不请求用户提供位置，而是改为判断连接的 IP 位置，以城市级别、50 公里半径进行判断，不适用精度、时效性或近似授权规则；若设置了 `geolocation_areas`，沿海城市在其所属国家内判断，除非该半径内还有另一个国家。在请求设备位置的节点上，若某次尝试没有设备位置，则按其实际情况判定为拒绝或失败：IP 位置绝不能代替它。 |
| `geolocation_preset` | string | 本节点每个未设置操作所采用的默认值。`licensing`：在区域外、禁止区域、VPN、Tor 或模拟器中会拒绝；代理及其他检测结果进入审核，缺少设备证明时保持无操作。`fraud_screening`：与 licensing 相同，但 Licensing 拒绝的情况改为进入审核。为 null 时保留长期以来的默认值。显式设置的操作始终优先。 |
| `geolocation_accuracy_mode` | string | 请求设备提供何种位置。`precise` 要求操作系统提供精确位置；若用户只授予近似位置，在仍有尝试次数时会再次请求，之后由 `geolocation_approximate_action` 判定。`approximate_allowed` 接受近似授权，不做该判定。无论采用哪种模式，`geolocation_max_accuracy_radius_m` 都同样适用。未设置时为 `precise`。 |
| `geolocation_max_accuracy_radius_m` | integer | 设备位置仍可接受的最大不确定半径，单位为米。范围为 10 至 50000 米；未设置时为 250 米。不确定半径超过该值的位置，或未报告半径的位置，按 `geolocation_low_accuracy_behavior` 的规定处理，并由 `geolocation_low_accuracy_action` 判定。`ip_only` 节点没有设备半径，也从不应用该字段。 |
| `geolocation_max_accuracy_radius_unit` | string | 控制台显示 `geolocation_max_accuracy_radius_m` 所用的单位。仅用于显示：存储值始终为米，没有任何规则依赖于它，步骤数据只是转发该单位，以便客户端显示相同的单位。 |
| `geolocation_low_accuracy_behavior` | string | 位置的不确定半径超过 `geolocation_max_accuracy_radius_m`，或未报告半径时的处理方式：`ask_again`（默认）在仍有尝试次数时请用户重试；`fail` 在遇到第一次此类情况时即结束步骤。 |
| `geolocation_max_age_seconds` | integer | 服务器接收设备位置时，该位置允许的最大时长，单位为秒。范围为 5 至 3600 秒；未设置时为 120 秒。过旧的位置在仍有尝试次数时会要求重试，之后由 `geolocation_stale_fix_action` 判定。 |
| `geolocation_timeout_seconds` | integer | 客户端在每次尝试中允许设备查找位置的时长，单位为秒；服务器在步骤数据中转发该值，自身不做任何强制执行。范围为 5 至 120 秒；未设置时为 20 秒。在时限内未找到位置的尝试会以 `timeout` 提交，在仍有尝试次数时要求重试，之后由 `geolocation_unavailable_action` 判定。 |
| `geolocation_max_attempts` | integer | 用户在本节点可获得的尝试次数。范围为 1 至 5 次；未设置时为 3 次。用户仍可更改的尝试（拒绝、不确定半径过大、过时或近似的位置，或节点所针对的区域或匿名化工具检测结果）在仍有尝试次数时会要求重试，最后一次尝试决定步骤结果。模拟位置，或节点所针对的模拟器，会在报告该结果的那次尝试时结束步骤。 |
| `geolocation_allow_qr_handoff` | boolean | 在步骤仍开放时，提供用二维码在手机上继续的选项（步骤数据中的 `allow_qr_handoff`，以及每个提交答案中的 `can_handoff`）。原生 SDK 已在手机上运行，因此从不显示二维码。默认开启。 |
| `geolocation_allow_skip` | boolean | 允许用户随时（从介绍页或重试页面）在没有位置的情况下继续（`skipped: true`）。跳过会结束步骤，并由 `geolocation_unavailable_action` 判定；但若跳过是在 `geolocation_refusal_path` 设置为 `continue_without_location` 时回应拒绝，则记录为该拒绝。默认关闭。 |
| `geolocation_deep_link_enabled` | boolean | 以 `deep_link_enabled` 的形式在步骤数据中传给客户端：改为提供打开客户自有应用的选项。服务器不对其应用任何规则。默认关闭。 |
| `geolocation_refusal_path` | string | 用户拒绝授予位置权限时提供的后续方式。`retry_then_handoff`（默认值）在仍有尝试次数时再次请求，并提供转为电话处理的选项；`continue_without_location` 允许用户继续操作，同时记录此次拒绝；`end_session` 在首次拒绝时即结束该步骤和整个会话，并要求 `geolocation_permission_denied_action` 设为审核或拒绝，且工作流需具有以已拒绝、审核中或最终决策结束的节点。会话根据已运行的步骤作出决策，且从不会被判定为通过。若工作流无法以该决策结束，则采用另一种非通过的结束方式（审核中改为已拒绝，已拒绝改为审核中）。 |
| `is_geolocation_geofencing_enabled` | boolean | 开启区域规则：`geolocation_areas` 或较早的 `geolocation_geofencing_by_country` 仅在此值为 true 时生效，且只有此时步骤数据才会列出 `available_areas`。默认关闭。开启后，`geolocation_areas` 列表至少需要一个允许区域。 |
| `geolocation_areas` | array | 允许和禁止区域，在 `is_geolocation_geofencing_enabled` 为 true 时生效。只有位于允许区域内的位置才能通过，且禁止区域始终优先于允许区域。位置按其完整精度圆计算：若该圆跨越了决定结果的边界，则结果为未定，绝不视为在区域之外。国家或地区的范围止于其他陆地开始之处，而非海岸线。若轮廓将某位置置于任何陆地之外（例如简化海岸线所剪去的海滨或码头），则对于其半径加 12 海里范围内的每个国家或地区，结果均为未定。`id` 是分支规则以及 `geolocation.inside_areas` / `geolocation.blocked_areas` 所引用的名称；`kind` 决定区域的形状：整个 `country`（ISO 3166-1 alpha-3，且有公开轮廓；若轮廓将某领土绘制为另一国家的一部分，则应作为 `region` 使用，例如留尼汪作为法国的 `FR-RE`，或博奈尔、圣尤斯特歇斯和萨巴作为 `NL-BQ1` 至 `NL-BQ3`）、`region`（同一国家中具有公开边界的 ISO 3166-2 代码）、`circle`（1 至 500 公里）或 `polygon`（3 至 200 个点，构成一个边不相交、不相接的环）。最多 50 个区域，id 必须唯一，且开启区域规则时至少需要一个允许区域。不能与 `geolocation_geofencing_by_country` 同时使用。 |
| `geolocation_geofencing_by_country` | object | 针对设备自身位置的国家和地区允许/拒绝规则，仅在 `is_geolocation_geofencing_enabled` 为 true 时生效。结构与 IP 分析的 `ip_geofencing_by_country` 相同，但 `states` 的键为 ISO 3166-2 代码（如 `US-NJ`），而非州名，因为位置会被解析到行政区划，而不是服务商提供的城市标签。未列出的国家默认允许。若为没有公开 ISO 3166-2 边界的国家设置地区规则，保存会被拒绝，而不会被静默忽略。 |
| `geolocation_ip_distance_km` | integer | 设备位置与 IP 位置之间可以相距的公里数，在减去两者的不确定半径后，超过该值即触发 `geolocation_ip_distance_action`。省略该键时为 200；设为 null 则关闭此比较。只有 `geolocation_position_source` 为 `device_and_ip` 或未设置的节点才会进行比较，该键说明与哪一种 IP 位置进行比较。 |
| `geolocation_ip_distance_unit` | string | 控制台显示 `geolocation_ip_distance_km` 所用的单位。仅用于显示：存储值始终为公里，且任何规则都不依赖此单位。 |
| `geolocation_document_distance_km` | integer | 位置（在 `ip_only` 节点上为 IP 位置）与 `geolocation_document_distance_basis` 所指地址之间可以相距的公里数，超过该值即触发 `geolocation_document_distance_action`。未设置或为 null（默认值）时关闭。 |
| `geolocation_document_distance_unit` | string | 控制台显示 `geolocation_document_distance_km` 所用的单位。仅用于显示：存储值始终为公里，且任何规则都不依赖此单位。 |
| `geolocation_document_distance_basis` | string | `geolocation_document_distance_km` 所依据的地址：`document`（默认值：证件上的地址，其次为地址证明）、仅 `proof_of_address`，或 `declared`（创建会话时提供的 `expected_details.address`，并经过地理编码）。 |
| `geolocation_travel_tolerance_enabled` | boolean | 当同一人（相同的 `vendor_data`）在过去 `geolocation_travel_max_days` 天内曾被检测到位于该地址的 `geolocation_travel_usual_area_km` 范围之内时，豁免其与该地址之间的距离。绝不豁免 VPN、伪造位置、禁止区域或位于允许区域之外的情况。只有设备实际测得的位置才算在该处被检测到：模拟或仿真的定位、模拟器或未通过的证明永远不算。 |
| `geolocation_travel_usual_area_km` | integer | 视为该人常驻区域的、以该地址为圆心的半径。范围为 10 至 500 公里；未设置时为 100。 |
| `geolocation_travel_max_days` | integer | 在常驻区域被检测到之后，距离较远的位置仍被视为出行的天数上限。范围为 1 至 90 天；未设置时为 14。 |
| `geolocation_consecutive_mismatch_count` | integer | 当本次检查与同一人（相同的 `vendor_data`）此前的检查连续这么多次均位于允许区域之外、禁止区域之内，或距离地址过远时，触发 LOCATION\_CONSECUTIVE\_MISMATCHES。未进行比较的检查既不延长也不打断该连续记录，设备未测得的位置（模拟或仿真的定位、模拟器、未通过的证明）同样如此。范围为 2 至 10；null（默认值）时关闭。 |
| `geolocation_approximate_action` | action | 用户授予了近似位置，而 `geolocation_accuracy_mode` 要求精确位置时的判定结果。默认为 `REVIEW`。 |
| `geolocation_blocked_area_action` | action | 位置及其完整精度圆落在 `geolocation_areas` 的禁止区域内时的判定结果。默认为拒绝。 |
| `geolocation_consecutive_mismatch_action` | 操作 | 当连续出现 `geolocation_consecutive_mismatch_count` 次不匹配时给出的判定。默认为审核。 |
| `geolocation_document_distance_action` | 操作 | 当设备位置与证件地址的距离超过 `geolocation_document_distance_km` 时给出的判定。该地址经过粗略地理编码，因此这是一个较弱的信号。默认为 `REVIEW`。 |
| `geolocation_emulator_action` | 操作 | 当分享位置的应用报告其运行在模拟器上时给出的判定。浏览器无法报告此情况。除非设置为无操作，否则该判定会在此次尝试时结束该步骤：再次检查无法改变设备。除非进行了设置或预设另有规定，否则默认无操作。 |
| `geolocation_geofence_undetermined_action` | 操作 | 当位置的精度圆与边界相交，导致无法判断其位于围栏内还是围栏外时给出的判定。不确定性绝不会被报告为位于围栏外。默认为 `REVIEW`。 |
| `geolocation_geofencing_action` | 操作 | 当设备位置及其整个不确定性圆都位于 `geolocation_geofencing_by_country` 之外时给出的判定。默认为 `DECLINE`。 |
| `geolocation_integrity_missing_action` | 操作 | 当原生客户端提交的位置没有设备证明令牌时给出的判定。默认为无操作；Web 客户端会被记录为不支持而非缺失，因为没有浏览器能够进行证明。 |
| `geolocation_ip_distance_action` | 操作 | 在减去两个不确定半径后，设备位置与会话 IP 位置之间的距离仍超过 `geolocation_ip_distance_km` 时给出的判定。默认为 `REVIEW`。 |
| `geolocation_low_accuracy_action` | 操作 | 当没有任何一次尝试达到所需精度时给出的判定：最佳位置的不确定半径宽于 `geolocation_max_accuracy_radius_m`，或未报告任何半径。没有半径的位置永远不会被视为满足该限制。默认为 `REVIEW`。 |
| `geolocation_mock_location_action` | 操作 | 当操作系统将位置报告为模拟而非实际测量时给出的判定（Android 模拟位置提供程序，iOS 软件模拟）。默认为 `REVIEW`。 |
| `geolocation_permission_denied_action` | 操作 | 当用户在每次允许的尝试中都拒绝或关闭位置权限提示时给出的判定。默认为审核：拒绝是一种选择，而非欺诈信号。 |
| `geolocation_proxy_action` | 操作 | 当分享位置的连接通过开放、匿名或私有中继代理时给出的判定。除非进行了设置或预设另有规定，否则默认无操作。 |
| `geolocation_stale_fix_action` | 操作 | 当位置测量时间比服务器接收时间早于 `geolocation_max_age_seconds` 以上时给出的判定。默认为 `REVIEW`。 |
| `geolocation_tor_action` | 操作 | 当分享位置的连接是 Tor 出口节点时给出的判定。除非进行了设置或预设另有规定，否则默认无操作。 |
| `geolocation_unavailable_action` | 操作 | 当无法获取任何位置时给出的判定：位置服务已关闭或受限、定位系统未返回任何结果、尝试超时、用户跳过该步骤，或客户端版本过旧而不支持该功能。默认为 `REVIEW`。 |
| `geolocation_vpn_action` | 操作 | 当分享位置的连接是商业 VPN 时给出的判定。除非设置为无操作，否则系统会要求用户关闭 VPN 并在剩余尝试次数内再次检查。除非进行了设置或预设另有规定，否则默认无操作。 |
| `status_rules` | 数组 | 可选的自定义状态规则。您可以针对 [位置验证报告](https://docs.didit.me/zh/core-technology/location-verification/report-location-verification.md#状态规则与分支的字段) 中列出的 `geolocation.*` 字段设置规则。 |

### 区域形状

`geolocation_areas` 中的每一项都有一个 `id`（1 至 64 个字符，仅限 `A-Z a-z 0-9 _ -`，且在列表中唯一）、一个可选的 `label`（最多 80 个字符）、一个 `type`（取值为 `allowed` 或 `blocked`），以及一个用于选择形状的 `kind`。

| `kind` | 额外字段 | 含义 |
| - | - | - |
| `country` | `country`（ISO 3166-1 alpha-3） | 一个有已发布边界的整个国家。 |
| `region` | `country`、`regions`（该国的 ISO 3166-2 代码） | 一个国家中一个或多个带有已发布边界的行政区。 |
| `circle` | `center`（`latitude`、`longitude`）、`radius_km`（1 至 500） | 以圆心为中心、半径范围内的每个点。 |
| `polygon` | `points`（3 至 200 项，每项包含 `latitude`、`longitude`） | 一个闭合环，其各边永不相交或接触。 |

一个列表最多包含 50 个区域，并且在 `is_geolocation_geofencing_enabled` 为 `true` 时，至少需要一个 `allowed` 区域。
`geolocation_areas` 与 `geolocation_geofencing_by_country` 不能同时发送，并且 `geolocation_refusal_path: "end_session"` 要求 `geolocation_permission_denied_action` 为 `REVIEW` 或 `DECLINE`。
对于永远无法匹配的区域（例如某个国家没有已发布边界的区域），API 会拒绝该区域，而不予保存。

示例：

```json theme={null}
{
  "feature": "GEOLOCATION",
  "config": {
    "geolocation_position_source": "device_and_ip",
    "geolocation_preset": "licensing",
    "geolocation_max_accuracy_radius_m": 250,
    "geolocation_max_attempts": 3,
    "is_geolocation_geofencing_enabled": true,
    "geolocation_areas": [
      { "id": "spain", "label": "Spain", "type": "allowed", "kind": "country", "country": "ESP" },
      { "id": "ceuta-melilla", "type": "blocked", "kind": "region", "country": "ESP", "regions": ["ES-CE", "ES-ML"] }
    ],
    "geolocation_ip_distance_km": 200,
    "geolocation_ip_distance_action": "REVIEW",
    "geolocation_vpn_action": "DECLINE"
  }
}
```

## 地址证明

功能值：`PROOF_OF_ADDRESS`。

| 配置字段 | 类型 | 描述 |
| - | - | - |
| `poa_documents_allowed` | object | ISO3 国家代码到地址证明证件类型配置的映射。至少应启用一种有效的证件类型。 |
| `poa_languages_allowed` | object | ISO 639-1 语言代码到 `0` 或 `1` 的映射。至少应启用一种语言。 |
| `poa_name_or_address_mismatch_action` | action | 姓名或地址与预期数据不一致时的操作。 |
| `poa_document_issues_action` | action | 证件存在质量或提取问题时的操作。 |
| `poa_max_attempts_exceeded_action` | restricted action | 用户超出重试次数时的操作。请使用 `DECLINE` 或 `REVIEW`。 |
| `poa_document_authenticity_action` | restricted action | 真实性检查未通过时的操作。请使用 `DECLINE` 或 `REVIEW`。 |
| `poa_document_unproven_text_replacement_action` | action | 某个文本字段被清空后以其他字体重新输入，且文件无法证明其内容是否发生变化时的操作（`POA_DOCUMENT_UNPROVEN_TEXT_REPLACEMENT`）。 |
| `poa_unsupported_document_type_action` | action | 证件类型不受支持时的操作。 |
| `poa_unsupported_language_action` | action | 证件语言不受支持时的操作。 |
| `poa_issuer_not_identified_action` | action | 无法识别证件签发机构时的操作。 |
| `poa_issue_date_not_detected_action` | action | 缺少签发日期时的操作。 |
| `poa_unparsable_or_invalid_address_action` | action | 地址无效或无法解析时的操作。 |
| `address_validation_enabled` | boolean | 根据邮政参考数据验证本步骤读取的地址（印在地址证明上的地址；只有通过证件检查的上传文件才会被验证）。验证会确认地址存在并将其标准化，且绝不会将地址与某个人关联。结果位于决策中的该步骤 `address_validation` 对象内。**每个经验证的地址收费 \$0.10**；无法运行的验证（`unavailable`）免费。默认关闭。 |
| `address_not_verified_action` | action | 地址验证无法将地址确认到具体建筑时的操作（`ADDRESS_NOT_VERIFIED`：`partially_verified` 或 `not_verified`）。仅在 `address_validation_enabled` 开启时适用。默认为 `NO_ACTION`，即仅记录警告。 |
| `poa_name_match_score_threshold` | integer | 姓名匹配阈值。 |
| `poa_max_retry_attempts` | integer | 重试次数上限，取值为 `2` 至 `5`。 |
| `status_rules` | array | 可选的自定义状态规则。 |

## 问卷

功能值：`QUESTIONNAIRE`。

| 配置字段 | 类型 | 描述 |
| - | - | - |
| `questionnaire_uuid` | UUID | 必填。请使用 `POST /v3/questionnaires/` 返回的 `questionnaire_id`。 |
| `review_questionnaire_manually` | boolean | 将问卷回答提交人工审核。 |
| `status_rules` | array | 可选的自定义状态规则。您可以针对 `questionnaire.answers.<question_id>` 字段设置规则。 |

## KYB 公司登记

功能值：`KYB_REGISTRY`。

| 配置字段 | 类型 | 描述 |
| - | - | - |
| `kyb_accepted_countries` | object | 用于公司登记查询的旧版 ISO3 国家允许名单。已被 `kyb_registry_countries_config` 取代；仍可读取，对于现有工作流，仍会从该配置生成，但已不再是配置新工作流的方式。 |
| `kyb_manual_company_action` | action | 公司需要人工处理时的操作。 |
| `kyb_registry_fields_config` | object | 托管流程中登记表单各字段的可见性和必填性。详见下文。 |
| `kyb_registry_countries_config` | object | 按国家划分的登记路由，格式为 `{"<ISO2>": {"enabled": bool, "tier": "basic" \| "shareholders" \| "ubo"}}`。每个已启用的国家决定选择公司时收取的数据层级（`basic` 为 Lite 层级），并且只有[定价接口](https://docs.didit.me/zh/getting-started/kyb-registry-pricing.md)标明该国家可用的层级才能启用。至少必须启用一个国家：不在任何国家进行搜索的登记检查将被拒绝。手动输入的公司单独计费，不使用此配置。 |
| `kyb_registry_monitoring_enabled` | boolean | 在 Shareholders 或 UBO 结果返回后，对该公司的登记记录进行持续监控：状态、高管、股权结构或地址发生变化时，会将会话退回审核并触发 Webhook。仅在登记服务提供方支持监控的地区可用。每家公司每年 USD 2.00，可随时取消。默认关闭。 |
| `kyb_vat_invalid_action` | action | 公司的增值税号未通过欧盟 VIES 验证时的操作。默认为 `REVIEW`。 |
| `kyb_vat_unverified_action` | action | 由于 VIES 不可用而无法验证增值税号时的操作。默认为 `NO_ACTION`。 |
| `status_rules` | array | 可选的自定义状态规则。 |

`kyb_registry_fields_config` 将每个可配置字段键映射为 `{"enabled": bool, "required": bool}`。`enabled: false` 隐藏该字段，`enabled: true, required: false` 将其显示为可选，`enabled: true, required: true` 则使其在提交时必填。`company_name`、`country_code` 和 `region` 始终显示且必填，无法配置。当该对象被省略、为 `null` 或为 `{}` 时，采用默认设置：仅 `incorporation_date` 为必填，其余字段均为可选。

```json theme={null}
{
  "kyb_registry_fields_config": {
    "registration_number": { "enabled": true, "required": true },
    "incorporation_date": { "enabled": true, "required": true },
    "vat_number": { "enabled": true, "required": false },
    "control_scheme": { "enabled": false, "required": false }
  }
}
```

可配置的字段键：`registration_number`、`incorporation_date`、`legal_address`、`vat_number`、`alternative_names`、`tax_number`、`company_type`、`legal_entity_identifier`、`location_of_registration`、`nature_of_business`、`registered_capital_amount`、`registered_capital_currency`、`website`、`email`、`phone`、`control_scheme`。有关终端用户的行为，请参阅[可配置的登记表单字段](https://docs.didit.me/zh/business-verification/company-data.md#可配置的登记表单字段)；有关 `vat_number` 和 `tax_number` 的检查方式，请参阅[增值税号与税号验证](https://docs.didit.me/zh/business-verification/company-data.md#vat-号码与税号验证)。

## KYB 证件

功能值：`KYB_DOCUMENTS`。

| 配置字段 | 类型 | 说明 |
| - | - | - |
| `kyb_required_document_groups` | 对象或数组 | 必填。必需的 KYB 证件组。 |
| `kyb_document_subtype_config` | 对象 | 按证件子类型启用与时效配置。 |
| `kyb_document_tampering_action` | 受限操作 | 检测到篡改时的操作。使用 `DECLINE` 或 `REVIEW`。 |
| `kyb_document_unproven_text_replacement_action` | 操作 | 当企业证件中的某个文本字段被清空并以其他字体重新输入，且文件无法证明其内容是否发生过更改时的操作（`KYB_DOCUMENT_UNPROVEN_TEXT_REPLACEMENT`）。 |
| `kyb_document_critical_mismatch_action` | 受限操作 | 严重证件不一致时的操作。使用 `DECLINE` 或 `REVIEW`。 |
| `kyb_document_non_critical_mismatch_action` | 操作 | 非严重证件不一致时的操作。 |
| `kyb_document_age_action` | 操作 | 证件时效规则不通过时的操作。 |
| `kyb_document_max_retry_attempts` | 整数 | KYB 证件的重试次数上限。 |
| `kyb_document_max_attempts_exceeded_action` | 受限操作 | 超过最大尝试次数时的操作。使用 `DECLINE` 或 `REVIEW`。 |
| `status_rules` | 数组 | 可选的自定义状态规则。 |

## KYB 关键人员

功能值：`KYB_KEY_PEOPLE`。

| 配置字段 | 类型 | 说明 |
| - | - | - |
| `kyb_ubo_ownership_threshold` | 整数 | UBO 持股阈值，取值范围为 `0` 至 `100`。 |
| `kyb_shareholder_ownership_threshold` | 整数 | 股东持股阈值，取值范围为 `0` 至 `100`。不能高于 `kyb_ubo_ownership_threshold`。 |
| `kyb_key_people_ownership_required` | 布尔值 | 要求提交的每位关键人员都必须填写持股比例。在提交时强制执行，并同步到托管界面，托管界面会将该字段标记为必填。默认值为 `false`。 |
| `kyb_require_ubo_kyc` | 布尔值 | 要求 UBO 完成个人验证工作流。 |
| `kyb_ubo_verification_workflow` | UUID | 当 `kyb_require_ubo_kyc` 为 `true` 时必填。必须引用同一应用中的非 KYB 工作流。 |
| `kyb_require_officer_kyc` | 布尔值 | 要求高管完成个人验证。 |
| `kyb_shareholder_verification_workflow` | UUID | 股东的个人验证工作流。 |
| `kyb_officer_verification_workflow` | UUID | 高管的个人验证工作流。 |
| `kyb_require_corporate_ubo_kyb` | 布尔值 | 要求企业类 UBO 完成 KYB。 |
| `kyb_corporate_ubo_verification_workflow` | UUID | 当 `kyb_require_corporate_ubo_kyb` 为 `true` 时必填。必须引用同一应用中的 KYB 工作流。 |
| `kyb_reject_if_ubo_rejected` | 布尔值 | 当必需的 UBO 验证被拒绝时，拒绝该企业。 |
| `kyb_wait_for_all_ubos` | 布尔值 | 在决定 KYB 会话结果之前，等待所有必需的 UBO 验证完成。 |
| `kyb_role_config` | 对象或数组 | 按角色配置。每个必需的 KYC 角色都必须包含 `verification_workflow`。 |
| `kyb_reuse_verified_individuals` | 布尔值 | 在可能的情况下复用已验证的个人。 |
| `kyb_notify_parties_by_email` | 布尔值 | 向受邀的关键人员发送邮件通知。 |
| `kyb_key_people_company_fields` | 对象 | 为 CORPORATE 类关键人员收集哪些企业信息。其描述符列表结构和规则与 `kyb_key_people_person_fields` 相同。结构：`[{"key": "<field key>", "label": "<label>", "type": "text"\|"number"\|"date"\|"phone"\|"email", "required": true\|false, "custom": true\|false}]`。 |
| `kyb_key_people_document_mismatch_action` | 操作 | 当关键人员的证件与为其声明的信息不一致时的判定结果。 |
| `kyb_key_people_person_fields` | 对象 | 为个人关键人员收集哪些个人信息，以有序列表（不是映射）形式的字段描述符表示。`key` 为必填且不能为空；`type` 必须是 text、number、date、phone 或 email 之一；`custom` 用于标记由客户添加而非内置的字段。结构：`[{"key": "<field key>", "label": "<label>", "type": "text"\|"number"\|"date"\|"phone"\|"email", "required": true\|false, "custom": true\|false}]`。 |
| `kyb_key_people_prefill_from_registry` | 布尔值 | 用公司登记结果预填关键人员列表，让客户确认和修正，而不必逐一输入每位高管和股东。 |
| `status_rules` | 数组 | 可选的自定义状态规则。 |

## Document AI

功能值：`DOCUMENT_AI`。

向用户请求一份或多份证件，并借助视觉模型提取您定义的指定字段。每个已配置的字段都会成为可用于分支的值 `document_ai.<key>`，该步骤的结果为 `document_ai.status`。

| 配置字段 | 类型 | 说明 |
| - | - | - |
| `document_ai_documents` | 数组 | 必填。要请求的证件（最多 `3` 份）。每一项都是一个证件对象（见下文）。 |
| `document_ai_unreadable_document_action` | 操作 | 证件无法读取或无法提取任何数据时执行的操作。 |
| `document_ai_missing_required_fields_action` | 操作 | 无法提取必填字段时执行的操作。 |
| `document_ai_document_tampering_action` | 受限操作 | 证件显示出篡改迹象时执行的操作。仅可使用 `DECLINE` 或 `REVIEW`。 |
| `document_ai_name_mismatch_action` | 操作 | 提取的姓名与已验证身份不一致时执行的操作。需要存在一个标记了 `is_full_name` 的字段。 |
| `document_ai_unsupported_file_action` | 操作 | 上传的文件类型不受支持时执行的操作。 |
| `document_ai_max_attempts_exceeded_action` | 受限操作 | 用户超出重试次数时执行的操作。仅可使用 `DECLINE` 或 `REVIEW`。 |
| `document_ai_name_match_score_threshold` | 整数 | 提取的姓名与已验证身份相匹配所需的最低分数（`0`–`100`）。低于该分数时，将执行 `document_ai_name_mismatch_action`。 |
| `document_ai_max_retry_attempts` | 整数 | 重试次数上限，范围为 `2` 至 `5`。 |
| `status_rules` | 数组 | 可选的自定义状态规则。您可以针对 `document_ai.<key>` 字段设置规则。 |

`document_ai_documents` 中的每一项都是一个证件：

| 证件字段 | 类型 | 说明 |
| - | - | - |
| `document_key` | 字符串 | 必填。证件的稳定标识符，在该步骤内必须唯一。 |
| `title` | 字符串 | 必填。展示给用户的标题。 |
| `description` | 字符串 | 必填。展示给用户的上传说明，告知应上传什么。 |
| `title_i18n` | 对象 | 可选。区域设置代码到翻译后标题的映射（例如 `{ "es": "Comprobante de fondos" }`）。 |
| `description_i18n` | 对象 | 可选。区域设置代码到翻译后说明的映射。 |
| `fields` | 数组 | 必填。要提取的字段（至少一个）。同一证件内的字段键必须唯一。 |

证件 `fields` 中的每一项都是一个字段：

| 字段 | 类型 | 说明 |
| - | - | - |
| `key` | 字符串 | 必填。提取值的稳定 JSON 键，在同一证件内必须唯一。以 `document_ai.<key>` 的形式用于分支判断。 |
| `name` | 字符串 | 必填。便于阅读的字段标签。 |
| `name_i18n` | 对象 | 可选。区域设置代码到翻译后字段名称的映射。 |
| `instruction` | 字符串 | 可选。告诉模型该字段应提取什么内容的说明。 |
| `type` | 字符串 | 字段类型：`text`、`number` 或 `date`。默认为 `text`。 |
| `required` | 布尔值 | 该字段是否必须存在。默认为 `false`。设为 `true` 且值缺失时，将执行 `document_ai_missing_required_fields_action`。 |
| `is_full_name` | 布尔值 | 可选，默认为 `false`。标记值为证件持有人姓名的字段，并将其与已验证身份（身份证件验证中的姓名，或会话中预期的详细信息）进行比对。**每个证件最多只能有一个字段**将其设为 `true`，且该字段**并非必填**。一个证件也可以不设置任何字段，此时该证件不进行姓名比对。只有 `text` 字段可以作为姓名字段。 |

示例：

```json theme={null}
{
  "feature": "DOCUMENT_AI",
  "config": {
    "document_ai_documents": [
      {
        "document_key": "proof_of_funds",
        "title": "Proof of Funds",
        "description": "Upload a recent bank statement.",
        "title_i18n": { "es": "Comprobante de fondos" },
        "fields": [
          {
            "key": "account_holder",
            "name": "Account holder",
            "instruction": "The full name of the account holder as printed on the statement.",
            "type": "text",
            "required": true,
            "is_full_name": true
          },
          {
            "key": "closing_balance",
            "name": "Closing balance",
            "instruction": "The closing balance amount.",
            "type": "number",
            "required": false
          }
        ]
      }
    ],
    "document_ai_missing_required_fields_action": "REVIEW",
    "document_ai_name_mismatch_action": "REVIEW",
    "document_ai_name_match_score_threshold": 80
  }
}
```

## 电子签名

功能值：`SIGNATURE`。

让已验证的个人或企业的关键人员，在文档上签名。签名级别可选简单（默认）或高级（AES）。请将其放在验证签署人的步骤之后：身份证件验证，以及用于接收验证码的邮箱或电话验证。参见 [电子签名](https://docs.didit.me/zh/core-technology/electronic-signature/overview.md)。

| 配置字段 | 类型 | 说明 |
| - | - | - |
| `signature_documents` | 数组 | 在控制台中上传到此工作流的文档，按签署人看到的顺序排列，格式为 `[{"uuid", "title", "file_name", "pages", "size_bytes"}]`。仅读取 `uuid` 的值及其顺序，其余信息来自已存储的文件。最多 20 份文档，总计 50 MB。默认 `[]`。 |
| `signature_documents_source` | 字符串 | 文档的来源：`workflow`（默认）、`session`（[创建会话](https://docs.didit.me/zh/sessions-api/create-session.md#电子签名文档) 中的 `sign.documents`）或 `both`（工作流文档在前）。 |
| `signature_require_read_to_end` | 布尔值 | 签署人必须将每份不含字段的文档阅读到末尾，才能表示同意。默认 `true`。 |
| `signature_consent_per_document` | 布尔值 | 签署人对每份不含字段的文档分别表示同意。对于含字段的文档，由引导式字段和最终同意取代此项。默认 `true`。 |
| `signature_signer` | 字符串 | 签署人：`verified_person`（默认，KYC），若为 KYB，则为 `legal_representative`（角色为 `representative` 或 `authorized_signatory` 的关键人员），或 `key_people`（每位拥有 KYC 会话的个人关键人员）。 |
| `signature_level` | 字符串 | `simple`（默认）：无需身份验证、邮箱、电话或验证码，签署人输入姓名并在会话链接上签名。`aes`：需要已通过的身份验证、已验证的邮箱或电话，以及一次性验证码。对于 `legal_representative` 和 `key_people` 签署人，`simple` 会被拒绝，并返回 `signature_simple_requires_verified_person`。当工作流中的 `signature_availability.aes` 为 `false` 时，保存新的 `aes` 步骤会返回 `400`，错误码为 `aes_not_available`。`qes` 即将推出：保存时会返回 `400`，错误码为 `qes_not_available`。 |
| `signature_format` | 字符串 | `pades`（默认）。对于 AES，`xades` 和 `cades` 会被拒绝，并返回 `signature_format_not_supported`。 |
| `signature_otp_channel` | 字符串 | 一次性验证码的发送渠道：`email`（默认）或 `sms`。验证码仅发送至会话中此前已验证的联系方式。 |
| `signature_email_signed_copy` | 布尔值 | 向签署人发送已签署文档的副本。需要已验证的邮箱。默认 `true`。 |
| `signature_evidence_page` | 布尔值 | 将证据页附加到每份已签署的 PDF。默认 `true`。 |
| `signature_link_validity_days` | 整数 | 签名链接的有效期，从会话创建起计算，为 `1` 至 `30` 天。默认 `7`。 |
| `signature_declined_action` | 操作 | 签署人拒绝签署时的判定结果。不收取任何费用。默认 `REVIEW`。 |
| `signature_otp_failed_action` | 操作 | 输错验证码 3 次或以上，或请求验证码超过 5 次后的判定结果。默认 `DECLINE`。 |
| `signature_name_mismatch_action` | 操作 | 关键人员申报的姓名与其已验证姓名不一致时的判定结果。默认 `DECLINE`。 |
| `signature_identity_not_verified_action` | 操作 | 签署人没有已通过的身份证明时的判定结果。默认 `DECLINE`。 |
| `signature_document_changed_action` | 操作 | 文档与展示时记录的 SHA-256 不再一致时的判定结果。默认 `DECLINE`。 |
| `status_rules` | 数组 | 可选的自定义状态规则。可针对 `signature.status`、`signature.level` 和 `signature.format` 设置规则。 |

工作流文档中的字段在控制台的模板编辑器中设置。对于会话文档，请在 `sign.documents[].fields` 中发送字段，并在 `sign.field_values` 中发送 `api.<key>` 字段的值。参见 [创建会话](https://docs.didit.me/zh/sessions-api/create-session.md#电子签名文档)。

示例，适用于每次会话都发送文档的情况：

```json theme={null}
{
  "feature": "SIGNATURE",
  "config": {
    "signature_documents_source": "session",
    "signature_signer": "verified_person",
    "signature_level": "aes",
    "signature_otp_channel": "email",
    "signature_link_validity_days": 14,
    "signature_declined_action": "REVIEW"
  }
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.