> ## 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.

# Bank verification methods

> Bank sign-in or account check: what each Bank Verification method proves and returns, and how to choose and order them country by country.

Bank Verification confirms that a bank account belongs to the person or company an earlier step of your workflow verified. It is one workflow step with two methods: the person either signs in at their bank, or types their account details and the bank confirms the name on the account. You choose which methods each country offers and which one comes first.

> [!NOTE]
>
> Bank Verification compares the account holder with an identity **another step** established, so it is not identity proof on its own. Put ID Verification, Database Validation, a questionnaire or `expected_details` before the step. The person never types the name that is checked: Didit always compares the name the session already verified.

## The two methods

| | Bank sign-in | Account check |
| - | - | - |
| Method value | `open_banking` | `account_lookup` |
| What the person does | Signs in at their bank and shares the account. | Types the account details: an IBAN, a sort code and account number, a CLABE and so on. No sign-in. |
| What it proves | Control of the account, plus the holder the bank returns. | The bank's holder name for that account matches the verified name. |
| Data it adds | Balances, transactions and income, when the step asks for them. | None: ownership only. |
| Typical use | Onboarding, lending, affordability, high-risk customers. | Payouts and withdrawals, low-friction onboarding, countries without bank sign-in. |

Both methods give the same kind of result: whether the holder matches, the holder the bank returned and the masked account. Methods differ by country, and a country can offer one of them, both, or both in either order. See the [account check](https://docs.didit.me/core-technology/bank-verification/account-check.md) for its account formats, results and sandbox values.

Micro-deposits and a statement upload stay fallbacks after the two methods (`bank_microdeposits_enabled`, `bank_statement_enabled`). They are offered only after a billed bank sign-in or account check in the same session, at no extra charge.

## What the person sees

In each country, the person starts on the first method the country offers. The second one is its backup:

* **Bank sign-in first:** the bank picker opens. Its last row, **Enter your account details**, starts the account check. If the bank sign-in fails, the same row appears again under **Other ways to verify**.
* **Account check first:** the account form opens, with a **Sign in to your bank instead** link under it.
* **One method only:** the person sees only that one.

Where a country offers the account check, it also backs up a bank that bank sign-in cannot reach right now, because the bank is degraded or down: the person moves to the account form before any consent is asked, as long as they have account checks left. A method that no route serves in a country is left out there, so the person never sees a method that cannot run.

## Choose the methods per country

### The step order

`bank_method_order` sets which methods the step offers, and in what order, for every country that sets none of its own. It lists `open_banking`, `account_lookup` or both, the first one first.

```json theme={null}
{
  "bank_method_order": ["open_banking", "account_lookup"]
}
```

A save that sends no `bank_method_order` gets `["open_banking", "account_lookup"]`: bank sign-in first, the account check as its backup. An empty list is refused with `Choose a method: bank sign-in, account check, or both.`

The step order is a default. In a country where no route serves one of its methods, that method is left out, and the country offers the rest. A country left with no method at all is refused on save, for example `Choose a method: bank sign-in, account check, or both. ARE offers account check.`

### A country's own order

`methods` on a country in `bank_countries` overrides the step order for that country. The person starts on the first method and is offered the second as its backup.

```json theme={null}
{
  "bank_method_order": ["open_banking", "account_lookup"],
  "bank_countries": {
    "GBR": { "enabled": true, "institutions": "all" },
    "NOR": {
      "enabled": true,
      "institutions": "all",
      "methods": ["open_banking"]
    },
    "MEX": {
      "enabled": true,
      "institutions": "all",
      "methods": ["account_lookup", "open_banking"]
    }
  }
}
```

Here the United Kingdom follows the step order, Norway offers bank sign-in only, and Mexico starts on the account check with bank sign-in as its backup. A country with `methods` set to `null`, or without the key, follows the step order. The save is refused, under `bank_countries.<ISO3>`, when an enabled country:

* sets `methods` to an empty list, or
* names a method no route serves there, for example `Account check is not available in NOR.`

### In the console

In the Bank verification step, **Countries and methods** lists each country with what bank sign-in and the account check offer there, and which method comes first. Its presets fill in every country at once:

| Preset | Order |
| - | - |
| Bank sign-in, account check as backup (the default) | `["open_banking", "account_lookup"]` |
| Bank sign-in only | `["open_banking"]` |
| Account check only | `["account_lookup"]` |
| Account check, bank sign-in as backup | `["account_lookup", "open_banking"]` |

A preset never leaves a country with nothing: where a country has only one of the two methods, that one stays on.

## Financial data needs bank sign-in

Only bank sign-in reads balances, transactions and income. When the step asks for them in `bank_scopes` and a country offers the account check, a person who verifies by account check passes without the data. The step does not fail: the result lists what was not collected in `financial_data.not_collected`.

```json theme={null}
"financial_data": {
  "balances": null,
  "transactions": null,
  "income": null,
  "categorization": null,
  "not_collected": ["balances", "transactions"]
}
```

`not_collected` is an empty list whenever the method collected everything the step asked for. To require the data, offer only bank sign-in in the countries where you need it.

## Account check settings

These keys shape the account check only. Bank sign-in keeps its own settings.

| Config field | Effect |
| - | - |
| `bank_account_check_accept_close_match` | On (the default): a name the bank scores between `bank_partial_match_floor` and `bank_name_match_threshold` is a close match. The person confirms the name the bank holds when `bank_suggest_holder_name` is on, and `bank_partial_match_action` decides. Off: that close match is a no match (`OWNER_NAME_MISMATCH`), decided by `bank_no_match_action`, and it spends the attempt. |
| `bank_account_check_max_attempts` | How many account checks the person gets, `1` to `5`, `3` when unset: how many times they can type the account details for a check the bank answers. An account refused as typed, or a check the bank could not answer, spends none. |

Attempts are counted per method. `bank_max_attempts` counts bank sign-in attempts, and a micro-deposit or statement fallback spends one of them too. `bank_account_check_max_attempts` counts account checks. The step ends on `bank_attempts_exhausted_action` once every method the country offers has spent its attempts without a successful connection.

## Read the method in the result

### Decision and webhooks

Each Bank Verification step is an item of `bank_verifications[]` in the [session decision](https://docs.didit.me/sessions-api/retrieve-session.md#bank-verification) and in the `decision` object of [`status.updated` webhooks](https://docs.didit.me/integration/webhooks#v3-plural-arrays-important). Its `method` says how the account was verified:

| `method` | Shown as |
| - | - |
| `open_banking` | Bank sign-in |
| `account_lookup` | Account check |
| `microdeposits` | Micro-deposits |
| `statement` | Statement upload |

`method` is `null` until an account has been evaluated. Read `method`, and not `ownership.method`, to tell the methods apart: `ownership.method` is the name comparison that produced the score, such as `exact` or `fuzzy`.

```json theme={null}
{
  "bank_verifications": [
    {
      "node_id": "feature_bank_verification",
      "status": "Approved",
      "method": "account_lookup",
      "ownership": {
        "result": "match",
        "method": "exact"
      },
      "financial_data": {
        "balances": null,
        "transactions": null,
        "income": null,
        "categorization": null,
        "not_collected": []
      }
    }
  ]
}
```

The example shows only the fields this page discusses. Every field is in the `SessionDecision` schema of the [API reference](https://docs.didit.me/sessions-api/retrieve-session.md).

### Workflow rules

Branches and custom status rules read the same value as `bank.method`, labelled **Bank Verification Method** in the rule builder, with the values **Bank Sign-in**, **Account Check**, **Micro-deposits** and **Statement Upload**. A rule compares the method value, for example a branch after an AML Screening step that sends an account check with a high risk score to review:

```json theme={null}
{
  "id": "account_check_high_risk",
  "rules": [
    {
      "field": "bank.method",
      "operator": "equals",
      "value": "account_lookup"
    },
    {
      "field": "aml.risk_score",
      "operator": "greater_than",
      "value": 70
    }
  ],
  "logic": "and",
  "goto": "status_in_review"
}
```

### Session report

The session PDF report names the method in its **Verification method** row.

## Nodes saved before the methods

`bank_open_banking_enabled` and `bank_account_lookup_enabled` are retired. A node saved before `bank_method_order` existed now runs with the order its two switches gave:

| `bank_open_banking_enabled` | `bank_account_lookup_enabled` | The node runs with |
| - | - | - |
| On or unset | Off or unset | `["open_banking"]` |
| On or unset | On | `["open_banking", "account_lookup"]` |
| Off | On | `["account_lookup"]` |

Where the account check was on next to bank sign-in, the person now sees it as a backup in the bank picker, **Enter your account details**, not only when their bank is down. A node with both switches off, which offered only micro-deposits or a statement upload, is left as it is; a later save must turn on at least one of the two methods.

For one release, a save that sends no `bank_method_order` but sends either switch still sets the order from the switches. Every save writes both switches back, as whether any country offers bank sign-in and whether any country offers the account check. Use `bank_method_order` and `bank_countries.<ISO3>.methods` in new integrations.

## Pricing

Each method is billed at its own price, per country:

* **Bank sign-in** has its own price, and balances, transactions and income each add theirs.
* **The account check** is billed once per check the bank answers: a match, a close match, a no match, an account it could not verify and an account it did not find. An account refused as typed is never billed.

Where a country offers both methods, a session can cost either price, depending on the method the person uses. Micro-deposits and the statement upload are included at no extra charge after a billed attempt. The [Account check API](https://docs.didit.me/standalone-apis/bank-account-check.md) runs the same check from your backend, with no session, at the same account check price.

## Test in sandbox

A sandbox application serves both methods in every country, in the order the step sets, and bills nothing. With the default order, the person starts on bank sign-in and picks **Enter your account details** to run the account check. To start on the account check, set `bank_method_order` to `["account_lookup", "open_banking"]`. The last four characters of the account choose the account check's answer: see [Test it in sandbox](https://docs.didit.me/core-technology/bank-verification/account-check.md#test-it-in-sandbox).

## Related

* [Account check](https://docs.didit.me/core-technology/bank-verification/account-check.md): account formats, results and sandbox values.
* [Account check API](https://docs.didit.me/standalone-apis/bank-account-check.md): check a payout account from your backend, with no session.
* [Bank Verification config keys](https://docs.didit.me/management-api/workflows/feature-configs.md#bank-verification): every key of the step.
* [Sandbox testing](https://docs.didit.me/integration/sandbox-testing.md).


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