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

# Bank

> ACH bank payments with institution search or manual entry.

The `bank` element collects ACH bank credentials. Shoppers can search for their bank and sign in (fast, no typing) or enter routing and account numbers manually. You choose which modes are available and which is the default.

Configure `bank` inside [Checkout](/payment-elements/elements/checkout/sections/payment-methods) for the recommended integration path, or mount standalone when you need a bank-only form.

## Standalone example

```html theme={null}
<div id="bank"></div>
<button id="pay" disabled>Pay</button>

<script>
  const overflow = new Overflow('live_pub_...');

  const bank = overflow.bank({
    mode: { default: 'plaid' },
  });

  bank.on('onChange', ({ complete }) => {
    document.getElementById('pay').disabled = !complete;
  });

  bank.on('onSubmit', ({ value }) => {
    fetch('/api/authorize', {
      method: 'POST',
      body: JSON.stringify({ method: 'bank', bank: value }),
    });
  });

  bank.mount('#bank');
  document.getElementById('pay').addEventListener('click', () => bank.submit());
</script>
```

## Modes

The element renders one of two modes at a time. The shopper can toggle between them (unless you lock one in) using an in-element control.

| Mode       | Behavior                                                |
| ---------- | ------------------------------------------------------- |
| `'plaid'`  | Search for your bank, sign in, and pick an account.     |
| `'manual'` | Enter routing number, account number, and account type. |

Pick the default:

```javascript theme={null}
overflow.bank({
  mode: { default: 'manual' },
});
```

Lock the shopper to a single mode:

```javascript theme={null}
overflow.bank({
  mode: { lockTo: 'manual' },   // Toggle button is hidden.
});
```

## Manual fields

* `accountType`: `<select>` with values `'checking'` / `'savings'`. Default `'checking'`.
* `routingNumber`: 9-digit routing number.
* `accountNumber`: account number.
* `confirmAccountNumber`: must match `accountNumber` to complete.

Configure via `fields.accountType`, `fields.routingNumber`, `fields.accountNumber`, `fields.confirmAccountNumber`.

## Submitted value

`onSubmit` emits a discriminated union keyed by `mode`. Manual submissions carry encrypted routing and account numbers; fast-signin submissions carry a linked-account public token.

```javascript theme={null}
bank.on('onSubmit', ({ value }) => {
  if (value.mode === 'manual') {
    // value.bankAccountType:            'checking' | 'savings'
    // value.encryptedBankAccountNumber: encrypted string, forward verbatim
    // value.encryptedBankRoutingNumber: encrypted string, forward verbatim
  } else {
    // value.mode === 'plaid'
    // value.publicToken:      Linked-account public token.
    // value.accountId:        Linked account id.
    // value.institutionName:  Bank display name.
    // value.accountLast4:     Last four digits.
    // value.accountType?:     'checking' | 'savings'
  }
});
```

Forward `value` to your server as-is. See the [Bank reference](/payment-elements/elements/payment-methods/bank/reference) for the full type and the [authorize a payment API reference](/api-reference/payments/authorize-payment) for the authorize request.

## Retry on `UNKNOWN_KID`

If your authorize endpoint returns `400 { code: 'UNKNOWN_KID' }` after a manual-mode bank submission, call `overflow.invalidateBankFieldEncryptionCache()` and prompt the shopper to submit again. Checkout runs this recovery for you when the tagged error is recognized.

```javascript theme={null}
if (result.code === 'UNKNOWN_KID') {
  overflow.invalidateBankFieldEncryptionCache();
  showBanner('Please try again.');
}
```

## Inside Checkout

```javascript theme={null}
overflow.checkout({
  paymentMethods: ['card', 'bank'],
  bank: { mode: { default: 'manual' } },
});
```

The nested `bank` key accepts the same options the standalone element accepts. Values arrive on the Checkout envelope as `value.bank`.

## Next steps

<CardGroup cols={2}>
  <Card title="Best practices" href="/payment-elements/elements/payment-methods/bank/best-practices">
    Retry, mode selection, and disabling considerations.
  </Card>

  <Card title="Reference" href="/payment-elements/elements/payment-methods/bank/reference">
    Full options, fields, and value reference.
  </Card>
</CardGroup>
