> ## 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 提供。

> [!NOTE]
>
> 在生产环境中，账户核验支持尼日利亚、加纳和肯尼亚。
> 其他国家的请求会返回 `404` 和 `code: country_not_covered`，且不计费。
> 更多国家将陆续开放，[银行验证定价](https://docs.didit.me/zh/getting-started/bank-verification-pricing.md)始终显示各国当前提供的服务。

您的后端发送姓名和账户，并读取结果。它相当于银行验证步骤中的[账户核验](https://docs.didit.me/zh/core-technology/bank-verification/account-check.md)，但不包含本人验证。

## 按各国的书写方式提供账户信息

| 国家 | `account` |
| - | - |
| IBAN 国家 | `{"iban": "..."}` |
| 英国 | `{"sort_code": "...", "account_number": "..."}` |
| 美国 | `{"routing_number": "...", "account_number": "..."}` |
| 加拿大 | `{"transit_institution": "...", "account_number": "..."}` |
| 澳大利亚 | `{"bsb": "...", "account_number": "..."}` |
| 印度 | `{"ifsc": "...", "account_number": "..."}` |
| 尼日利亚 | `{"bank_code": "...", "account_number": "..."}`，附带银行的 6 位 NIP 代码（Access Bank 为 `000014`）和 10 位 NUBAN |
| 加纳 | `{"bank_code": "...", "account_number": "..."}`，附带银行的 3 位字母代码（GCB Bank 为 `GCB`） |
| 肯尼亚 | `{"bank_code": "...", "account_number": "..."}`，附带银行的 2 位数字代码（KCB 为 `01`） |
| 墨西哥 | `{"clabe": "..."}` |
| 阿根廷 | `{"cbu_cvu": "..."}` |

部分国家还要求提供 `bic`；企业账户还需提供 `registration_id`。空格、短横线和点号会被忽略。如果某个国家的核验所需的键缺失，将返回 `400` 并指明该字段，例如 `"field": "account.bank_code", "reason": "required"`。

要核验个人账户，请发送 `holder.full_name`；要核验企业账户，请发送 `holder.business_name`。

## 发送账户持有人的同意

在某些国家，每次账户核验前都需要账户持有人的明确同意。
请在您的产品中征得同意，然后发送 `"consent": true`。
如果未发送，这些国家的核验请求将被拒绝，返回 `400`（`field: consent`，`reason: required`），且不计费。
在其他国家，`consent` 为可选项；如果您发送了该字段，Didit 会将其与该次核验的费用一并记录。
沙盒密钥与正式密钥在同样的国家要求同意。

## 读取结果

| `result` | 含义 | 典型的下一步 |
| - | - | - |
| `match` | 银行中该账户的持有人与您发送的姓名一致。 | 转账。 |
| `close_match` | 银行中该账户的持有人姓名与您发送的相近。若银行返回了该姓名，则 `holder_name` 即为该姓名。 | 比对 `holder_name`，或请该用户确认。 |
| `no_match` | 银行中该账户的持有人是另一个姓名，或该账户不存在。 | 请勿转账。 |
| `cannot_verify` | 银行在未比对姓名的情况下做出了响应，例如账户已冻结或已注销。 | 应用您自己的政策，例如要求提供其他账户。 |

## 计费与重试

银行做出应答的每次核验，均按该账户所在国家的[账户核验价格](https://docs.didit.me/zh/getting-started/bank-verification-pricing.md)计费一次，无论结果如何。返回错误的请求不计费：请求体被拒绝（`400`）、额度不足（`402`）、账户暂不支持核验（`404`）或银行无法应答（`503`）。

没有幂等键，也没有可用于回读核验结果的 endpoint。重试的请求会执行一次新的核验，并生成新的 `request_id`，且会再次计费，因此请务必保存响应。Didit 仅存储费用记录，包括请求 ID、国家、结果和脱敏后的账户，绝不存储姓名或完整的账号。

## 在沙盒中测试

沙盒 API 密钥不会调用银行，也不产生任何费用。若存在 IBAN，则取其最后 4 个字符；否则取账号的最后 4 个字符，以决定返回的结果：

| 结尾为 | 结果 |
| - | - |
| `0001` | `close_match`，并返回 `holder_name` |
| `0002` | `close_match`，`holder_name: null` |
| `0003`、`0006` | `no_match` |
| `0004` | `cannot_verify` |
| `0005` | `503`，`account_check_unavailable` |
| `0009` | `400`，`reason: rejected` |
| 其他情况 | `match` |

IBAN、CLABE 和 CBU 包含校验位。请使用通过所有格式校验的[沙盒示例值](https://docs.didit.me/zh/core-technology/bank-verification/account-check.md#在沙盒中测试)。

## 访问方式

使用应用的 `x-api-key` 进行身份验证，或使用其客户端凭证 bearer token（持有者 token）。限定范围的 API 密钥需要具备会话的写入权限。该 endpoint 与其他接口共享写入限制，即每个 API 密钥每分钟 300 次请求。


## OpenAPI

````yaml zh/openapi-25.json POST /v3/bank/account-check/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: 身份证件验证 API。使用 x-api-key 请求头进行身份验证。
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/bank/account-check/:
    post:
      tags:
        - Standalone APIs
      summary: 核验银行账户
      description: >-
        在向银行账户汇款之前，核验该账户是否属于您指定的个人或企业。无需会话也无需登录：发送名称和账户，读取结果。这是银行验证步骤中的[账户核验](/zh/core-technology/bank-verification/account-check)，从您的后端运行。


        **您发送的内容。** 账户的 `country`（ISO 3166-1 alpha-3）、按该国家/地区书写方式填写的
        `account`，以及 `holder` 名称：个人填写 `full_name`，企业填写
        `business_name`。企业名称用于核验企业账户。


        **您收到的结果。** `result` 为 `match`、`close_match`、`no_match` 或
        `cannot_verify`。在 `close_match` 时，如果银行返回了开户人名称，`holder_name`
        即为银行记录中的账户所属名称。返回的 `account` 会脱敏仅显示后 4 位字符。


        **计费。** 无论结果如何，银行回复的每次核验均按该账户所在国家/地区的账户核验价格计费一次：`no_match`、账户不存在以及
        `cannot_verify` 同样计费。返回错误响应的请求绝不计费。


        **每个请求都是一次新的核验。** 没有幂等性密钥，也没有用于重新读取核验结果的 endpoint，因此重试的请求会再次运行并计费。请存储响应。


        **沙盒。** 使用带有示例账户信息的沙盒 API 密钥。沙盒密钥不会调用银行，也不会产生费用。IBAN（如果无 IBAN 则为账号）的后 4
        位字符决定回复结果：`0001` 为带有 `holder_name` 的 `close_match`，`0002` 为不带该名称的
        `close_match`，`0003` 和 `0006` 为 `no_match`，`0004` 为
        `cannot_verify`，`0005` 为 `503`，`0009` 为 `400`。任何其他结尾均为 `match`。


        **API 密钥。** 带有作用域的 API 密钥需要会话的写入权限。
      operationId: post_v3_bank_account_check
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BankAccountCheckRequest'
            examples:
              Person, Nigeria:
                summary: 银行代码和账号，根据个人姓名进行核验
                value:
                  country: NGA
                  account:
                    bank_code: '000014'
                    account_number: '0123450001'
                  holder:
                    full_name: Maria Oliveira
                  vendor_data: payout_20481
              Company, Nigeria:
                summary: 银行代码和账号，根据企业名称进行核验
                value:
                  country: NGA
                  account:
                    bank_code: '000014'
                    account_number: '0123456789'
                  holder:
                    business_name: Northwind Trading Ltd
      responses:
        '200':
          description: 银行已响应。无论结果如何，该核验均会计费。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BankAccountCheckResponse'
              examples:
                Close match:
                  summary: 银行持有的账户姓名与提交的姓名相近
                  value:
                    request_id: c2f4a9e0-7b1d-4c3a-9e55-1d0a6b8f2a47
                    result: close_match
                    holder_name: MARIA R OLIVEIRA
                    account: '****0001'
                    vendor_data: payout_20481
                    created_at: '2026-10-21T14:32:08Z'
                Match:
                  summary: 银行持有的账户姓名与提交的姓名一致
                  value:
                    request_id: 5b0e2d7c-41a8-4f6e-9c3b-8e7d1a2f6c90
                    result: match
                    holder_name: null
                    account: '****6789'
                    vendor_data: null
                    created_at: '2026-10-21T14:35:41Z'
        '400':
          description: >-
            按原样拒绝，且不计费。`field` 指出需修正的请求体字段，`reason`
            说明原因，其原因与托管账户表单显示的原因相同。仅报告第一个被拒绝的字段。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BankAccountCheckError'
              examples:
                Missing field:
                  summary: 该国家/地区的核验需要银行代码
                  value:
                    detail: The bank code is not valid (required).
                    code: invalid_account_input
                    field: account.bank_code
                    reason: required
                Invalid IBAN:
                  summary: IBAN 长度与该国家/地区不符
                  value:
                    detail: The iban is not valid (length).
                    code: invalid_account_input
                    field: account.iban
                    reason: length
                Refused by the bank:
                  summary: 银行拒绝了按所提交信息发送的账户
                  value:
                    detail: The account was refused as typed (rejected).
                    code: invalid_account_input
                    field: account.account_number
                    reason: rejected
                No name:
                  summary: '`holder` 既没有 `full_name` 也没有 `business_name`'
                  value:
                    detail: >-
                      Send full_name for a person or business_name for a
                      company.
                    code: invalid_account_input
                    field: holder
                    reason: required
                Consent required:
                  summary: 该国家/地区的账户核验需要账户持有人的同意
                  value:
                    detail: >-
                      Account checks in this country need the account holder's
                      explicit consent. Ask for it, then send `consent=true`.
                    code: invalid_account_input
                    field: consent
                    reason: required
        '401':
          description: 作用域 API 密钥已过期。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BankAccountCheckError'
              examples:
                Expired key:
                  summary: 密钥的到期日期已过
                  value:
                    detail: This API key has expired.
        '402':
          description: 无法支付此项检查的费用，因此未运行。请为您的余额充值，然后重新发送。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BankAccountCheckError'
              examples:
                Out of credit:
                  summary: 您的余额不足以支付单次核验费用
                  value:
                    detail: >-
                      You don't have enough credits to perform this request.
                      Please top up at https://business.didit.me
                    code: insufficient_credits
                Not in your contract:
                  summary: 您的合同中未包含 Account check API 的价格
                  value:
                    detail: >-
                      Your contract does not price the Account check API.
                      Contact your account manager.
                    code: contract_rate_missing
        '403':
          description: >-
            `x-api-key` 请求头或 Bearer token 缺失或无效，请求来自密钥 IP
            名单之外的地址，或者限定权限的密钥对会话没有写入权限。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BankAccountCheckError'
              examples:
                Missing or invalid credentials:
                  summary: 无有效的 API 密钥或 token
                  value:
                    detail: You do not have permission to perform this action.
                No sessions write:
                  summary: 对会话没有写入权限的作用域受限密钥
                  value:
                    detail: This API key has no write access to sessions.
        '404':
          description: >-
            尚无账户检查支持此账户，因此未进行任何检查或计费。`country_not_covered`：没有任何账户检查支持其所在国家/地区，或支持该国家/地区中的此类账户（个人或企业）。`bank_not_covered`：没有任何账户检查支持其所属银行。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BankAccountCheckError'
              examples:
                Country not covered:
                  summary: 没有支持该国家/地区的账户检查
                  value:
                    detail: No account check serves this country yet.
                    code: country_not_covered
                Bank not covered:
                  summary: 没有支持该账户所属银行的账户检查
                  value:
                    detail: No account check serves this account's bank yet.
                    code: bank_not_covered
        '429':
          $ref: '#/components/responses/RateLimitedWrite'
        '503':
          description: 银行未能响应。未执行核验亦未计费；请稍后重新发送核验请求。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BankAccountCheckError'
              examples:
                Unavailable:
                  summary: 银行未响应
                  value:
                    detail: >-
                      The account check is temporarily unavailable and this
                      request was not charged. Please try again.
                    code: account_check_unavailable
      security:
        - ApiKeyAuth: []
        - BearerAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: |-
            curl -X POST https://verification.didit.me/v3/bank/account-check/ \
              -H 'x-api-key: YOUR_API_KEY' \
              -H 'Content-Type: application/json' \
              -d '{
                "country": "NGA",
                "account": {"bank_code": "000014", "account_number": "0123450001"},
                "holder": {"full_name": "Maria Oliveira"},
                "vendor_data": "payout_20481"
              }'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.bank.account_check(
                country="NGA",
                account={
                    "account_number": "0123450001",
                    "bank_code": "000014",
                },
                holder={
                    "full_name": "Maria Oliveira",
                },
                vendor_data="payout_20481",
            )
            print(result)
        - lang: javascript
          label: Node.js
          source: |-
            import Didit from "@didit-protocol/sdk-node";

            // Reads DIDIT_API_KEY.
            const didit = new Didit();

            const result = await didit.bank.accountCheck({
              country: "NGA",
              account: {
                account_number: "0123450001",
                bank_code: "000014",
              },
              holder: {
                full_name: "Maria Oliveira",
              },
              vendor_data: "payout_20481",
            });
            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Bank.AccountCheck(ctx, didit.BankAccountCheckRequest{\n\tCountry: \"NGA\",\n\tAccount: didit.BankAccountCheckRequestAccount{\n\t\tAccountNumber: didit.String(\"0123450001\"),\n\t\tBankCode:      didit.String(\"000014\"),\n\t},\n\tHolder: didit.BankAccountCheckHolder{\n\t\tFullName: didit.String(\"Maria Oliveira\"),\n\t},\n\tVendorData: didit.String(\"payout_20481\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
        - lang: java
          label: Java
          source: >-
            import me.didit.Didit;

            import me.didit.types.BankAccountCheckHolder;

            import me.didit.types.BankAccountCheckPersonHolder;

            import me.didit.types.BankAccountCheckRequest;


            // Reads DIDIT_API_KEY.

            Didit client = new Didit();


            var result =
            client.bank().accountCheck(BankAccountCheckRequest.builder()
                    .country("NGA")
                    .account(BankAccountCheckRequest.Account.builder()
                            .accountNumber("0123450001")
                            .bankCode("000014")
                            .build())
                    .holder(BankAccountCheckHolder.ofBankAccountCheckPersonHolder(BankAccountCheckPersonHolder.builder()
                            .fullName("Maria Oliveira")
                            .build()))
                    .vendorData("payout_20481")
                    .build());
            System.out.println(result);
        - lang: php
          label: PHP
          source: |-
            <?php

            require 'vendor/autoload.php';

            use Didit\DiditClient;

            // Reads DIDIT_API_KEY.
            $didit = new DiditClient();

            $result = $didit->bank->accountCheck([
                'country' => 'NGA',
                'account' => [
                    'account_number' => '0123450001',
                    'bank_code' => '000014',
                ],
                'holder' => [
                    'full_name' => 'Maria Oliveira',
                ],
                'vendor_data' => 'payout_20481',
            ]);
            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

            # Reads DIDIT_API_KEY.
            didit = Didit::Client.new

            result = didit.bank.account_check(
              country: "NGA",
              account: {
                account_number: "0123450001",
                bank_code: "000014",
              },
              holder: {
                full_name: "Maria Oliveira",
              },
              vendor_data: "payout_20481"
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: >-
            using System;

            using System.Text.Json;

            using Didit;


            // Reads DIDIT_API_KEY.

            using var client = new DiditClient();


            var result = await client.Bank.AccountCheckAsync(new
            BankAccountCheckRequest

            {
                Country = "NGA",
                Account = new()
                {
                    AccountNumber = "0123450001",
                    BankCode = "000014",
                },
                Holder = new()
                {
                    FullName = "Maria Oliveira",
                },
                VendorData = "payout_20481",
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  schemas:
    BankAccountCheckRequest:
      type: object
      required:
        - country
        - account
        - holder
      properties:
        country:
          type: string
          minLength: 3
          maxLength: 3
          description: 账户所在的国家/地区，采用 ISO 3166-1 alpha-3 代码，例如 `NGA`。支持小写。
          example: NGA
        account:
          type: object
          description: >-
            按所在国家/地区记录方式填写的账户：`iban`，或带有该国家/地区所需银行代码或分支机构代码（`sort_code`、`routing_number`、`transit_institution`、`bsb`、`ifsc`、`bank_code`
            或 `bic`）的 `account_number`。墨西哥使用 `clabe`，阿根廷使用
            `cbu_cvu`，这两者已标识银行。如果所在国家/地区有要求，企业账户需添加
            `registration_id`。空格、短横线和点号将被忽略。该国家/地区的核验中未使用的键将被忽略；如果缺少其所需的键，则会返回指明该键的
            `400`。
          properties:
            iban:
              type: string
              maxLength: 64
              description: 使用 IBAN 的国家/地区的 IBAN。它必须属于 `country`。
            account_number:
              type: string
              maxLength: 64
              description: 账号，适用于其账户记录方式包含独立银行代码或分支机构代码的国家/地区。
            sort_code:
              type: string
              maxLength: 64
              description: 英国：6 位清算号。
            routing_number:
              type: string
              maxLength: 64
              description: 美国：9 位 ABA 路由号。
            transit_institution:
              type: string
              maxLength: 64
              description: 加拿大：8 位 transit 和机构编号。
            bsb:
              type: string
              maxLength: 64
              description: 澳大利亚：6 位 BSB。
            ifsc:
              type: string
              maxLength: 64
              description: 印度：11 个字符的 IFSC 编码。
            bank_code:
              type: string
              maxLength: 64
              description: 银行代码，适用于所在国家/地区需要该项的情况，例如在尼日利亚。
            bic:
              type: string
              maxLength: 64
              description: 银行的 BIC，适用于所在国家/地区的核验需要该项的情况。
            clabe:
              type: string
              maxLength: 64
              description: 墨西哥：18 位 CLABE。它已包含银行名称。
            cbu_cvu:
              type: string
              maxLength: 64
              description: 阿根廷：22 位 CBU 或 CVU。其中已指明银行名称。
            registration_id:
              type: string
              maxLength: 64
              description: 企业账户的注册号（当所在国家/地区要求提供时）。
          additionalProperties:
            type: string
            maxLength: 64
          example:
            bank_code: '000014'
            account_number: '0123450001'
        holder:
          $ref: '#/components/schemas/BankAccountCheckHolder'
        vendor_data:
          type: string
          nullable: true
          description: 您为此项检查指定的自身参考编号，将原样返回。
          example: payout_20481
        consent:
          type: boolean
          default: false
          description: >-
            当账户持有人明确同意此项核查时设为 `true`。在账户核查需要此类同意的国家/地区为必填项：若未提供，核查将被拒绝并返回
            `400`（其 `field` 为 `consent`，`reason` 为
            `required`），且不计费。在其他国家/地区此项为选填，当您发送时，Didit 会将其与核查费用一同记录。
          example: true
    BankAccountCheckResponse:
      type: object
      required:
        - request_id
        - result
        - holder_name
        - account
        - vendor_data
        - created_at
      properties:
        request_id:
          type: string
          format: uuid
          description: 此检查的 ID。
        result:
          type: string
          enum:
            - match
            - close_match
            - no_match
            - cannot_verify
          description: >-
            `match`：银行持有以您发送的姓名开设的账户。`close_match`：以相近姓名开设，例如缺少中间名或有拼写错误。`no_match`：以其他姓名开设，或不存在此类账户。`cannot_verify`：银行未比对姓名即返回响应，例如账户已被冻结或注销。
        holder_name:
          type: string
          nullable: true
          description: 仅在 `close_match` 时，且仅在银行返回时提供：银行记录中的账户名称。其他情况下为 `null`。
        account:
          type: string
          description: 账户，已脱敏并仅保留后 4 位字符。
        vendor_data:
          type: string
          nullable: true
          description: 您的自身参考编号，与您发送的内容一致。
        created_at:
          type: string
          format: date-time
          description: 检查运行的时间，以 UTC 表示。
    BankAccountCheckError:
      type: object
      required:
        - detail
      properties:
        detail:
          type: string
          description: 错误详情（英文）。
        code:
          type: string
          description: 用于分支判断的稳定代码。对于 `401` 和 `403` 不存在。
        field:
          type: string
          description: 仅限 `400`：需更正的请求体字段，格式为以点分隔的路径，例如 `account.sort_code`。
        reason:
          type: string
          enum:
            - required
            - length
            - format
            - checksum
            - country_mismatch
            - rejected
          description: >-
            仅限 `400`：字段被拒绝的原因。`required`、`length`、`format`、`checksum` 以及
            `country_mismatch`（其他国家的 IBAN）为 Didit 自身的检查；`rejected`
            表示银行拒绝了所提交的账户。
    BankAccountCheckHolder:
      description: 核对账户所依据的名称。`full_name` 和 `business_name` 中仅能传入一个。
      oneOf:
        - $ref: '#/components/schemas/BankAccountCheckPersonHolder'
        - $ref: '#/components/schemas/BankAccountCheckBusinessHolder'
    BankAccountCheckPersonHolder:
      type: object
      description: 应持有该账户的人员。
      required:
        - full_name
      properties:
        full_name:
          type: string
          maxLength: 255
          description: 应持有该账户的人员的姓名。
          example: Maria Oliveira
    BankAccountCheckBusinessHolder:
      type: object
      description: 应持有该账户的企业。用于检查企业账户。
      required:
        - business_name
      properties:
        business_name:
          type: string
          maxLength: 255
          description: 应当持有该账户的公司名称。用于核验企业账户。
  responses:
    RateLimitedWrite:
      description: 已超出每个 API 密钥每分钟 300 次请求的共享写入限制。在重试之前请遵循 `Retry-After`。
      content:
        application/json:
          schema:
            type: object
            required:
              - detail
            properties:
              detail:
                type: string
          example:
            detail: >-
              Write request rate limit exceeded. You can make up to 300 requests
              per minute.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        您的应用 API 密钥，可在 Business Console 的“开发者 -> API
        密钥”中获取。主密钥拥有完整访问权限。指定名称的密钥可设置作用域：针对每个资源设为无权限、只读或读写，限定于特定工作流或已通过的会话、限定于
        IP 地址列表，以及设置到期日期。401 表示密钥错误、已撤销或已过期；403 表示未发送密钥、密钥无权访问该资源或操作，或请求来自其 IP
        列表之外的地址；在会话路由上返回 404 表示该会话不在该密钥允许的工作流或状态范围内。没有媒体访问权限的密钥获取到的图片、视频和 PDF
        URL 将为 null；没有会话写入权限的密钥获取到的会话链接和 token 将为 null。请参阅
        https://docs.didit.me/console/api-keys。
    BearerAuth:
      type: http
      scheme: bearer
      description: 该应用的客户端凭证访问 token。

````

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