Applies to: Bank Accounts API
Use the Bank Accounts API to retrieve seller bank accounts and manage customer bank accounts for ACH payment processing.
This guide covers the operational aspects of using the Bank Accounts API to:
- Retrieve seller bank account information
- Create and manage customer bank accounts for ACH payments
- List and filter bank accounts
- Handle bank account verification and status changes
For All Bank Accounts:
- ListBankAccounts - Retrieve bank accounts
- GetBankAccount - Retrieve a specific bank account by ID
For Customer Bank Accounts Only:
- CreateBankAccount - Store a new customer bank account
- DisableBankAccount - Disable a customer bank account
List all bank accounts for a specific location:
curl https://connect.squareup.com/v2/bank-accounts?location_id=LOCATION_ID \ -H 'Square-Version: 2025-12-17' \ -H 'Authorization: Bearer ACCESS_TOKEN' \ -H 'Content-Type: application/json'
{ "bank_account": { "id": "w3yRgCGYQnwmdl0R3GB", "account_number_suffix": "971", "country": "US", "currency": "USD", "account_type": "CHECKING", "holder_name": "Jane Doe", "primary_bank_identification_number": "112200303", "location_id": "MER9ST0SUIQ9W", "status": "VERIFIED", "creditable": true, "debitable": true, "version": 3, "bank_name": "Checking and Savings Bank" } }
To create a customer bank account, you'll need a source_id (a bank account token) obtained from your payment form or bank account verification flow:
curl https://connect.squareup.com/v2/bank-accounts \ -X POST \ -H 'Square-Version: 2025-12-17' \ -H 'Authorization: Bearer ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "idempotency_key": "4e43559a-f0fd-47d3-9da2-7ea1f97d94be", "source_id": "bnon:CA4SEHsQwr0rx6DbWLD5BQaqMnoYAQ", "customer_id": "HM3B2D5JKGZ69359BTEHXM2V8M" }'
Note
The source_id is a bank account token (prefixed with "bnon:") that represents the tokenized bank account details. This token is typically obtained from the Web Payments SDK or other Square payment form implementations.
{ "bank_account": { "id": "bact:OxfBTiXgByaXds1K4GB", "account_number_suffix": "000", "country": "US", "currency": "USD", "account_type": "CHECKING", "holder_name": "Nicola Snow", "primary_bank_identification_number": "011401533", "status": "VERIFICATION_IN_PROGRESS", "creditable": true, "debitable": true, "fingerprint": "sq-1-mO3XNctJpTLL8uYowOWpioS8nQyTc838gcBo90254XonoEJ_c7Uw6yqL6qihFNY8fA", "version": 1, "bank_name": "Citizens Bank", "customer_id": "HM3B2D5JKGZ69359BTEHXM2V8M" } }
Note
Note the fingerprint field in customer bank accounts - this unique identifier helps prevent duplicate bank accounts from being created for the same customer and underlying bank account combination.
Warning
Always include the customer_id parameter when retrieving customer bank accounts. Omitting this parameter will return the seller's bank accounts instead, potentially exposing sensitive financial information to unauthorized users (such as displaying the business owner's bank account to store employees).
The same ListBankAccounts endpoint is used for both seller and customer bank accounts. The customer_id parameter determines which accounts are returned:
For customer bank accounts (include customer_id):
curl https://connect.squareup.com/v2/bank-accounts?customer_id=HM3B2D5JKGZ69359BTEHXM2V8M \ -H 'Square-Version: 2025-12-17' \ -H 'Authorization: Bearer ACCESS_TOKEN' \ -H 'Content-Type: application/json'
For seller bank accounts (omit customer_id or use location_id):
# Returns seller accounts - DO NOT use this in customer-facing interfaces curl https://connect.squareup.com/v2/bank-accounts \ -H 'Square-Version: 2025-12-17' \ -H 'Authorization: Bearer ACCESS_TOKEN' \ -H 'Content-Type: application/json'
Always validate that you're passing the correct customer ID, especially in point-of-sale or customer-facing applications where exposing seller bank accounts would be a serious security breach.
Bank accounts cannot be deleted once created, but they can be disabled to prevent further use. Disabling a bank account is the recommended approach when:
- A customer wants to remove a bank account from their payment methods
- A bank account has been compromised or flagged for security reasons
- You need to prevent accidental charges to an outdated account
Once disabled, the bank account:
- Cannot be used for new payments
- Remains in the system for historical records and compliance
- Will still appear in list operations but with a
DISABLEDstatus - Cannot be re-enabled (a new bank account must be created if needed)
curl https://connect.squareup.com/v2/bank-accounts/bact:OxfBTiXgByaXds1K4GB/disable \ -X POST \ -H 'Square-Version: 2025-12-17' \ -H 'Authorization: Bearer ACCESS_TOKEN' \ -H 'Content-Type: application/json'
Once a customer bank account is verified, you can use it to process ACH payments:
curl https://connect.squareup.com/v2/payments \ -X POST \ -H 'Square-Version: 2025-12-17' \ -H 'Authorization: Bearer ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "source_id": "bact:OxfBTiXgByaXds1K4GB", "amount_money": { "amount": 5000, "currency": "USD" }, "customer_id": "HM3B2D5JKGZ69359BTEHXM2V8M", "idempotency_key": "payment-key-456" }'
Note
The Payments API will reject attempts to charge a seller's bank account. If you accidentally pass a seller bank account ID (which has a different format than customer bank account IDs), the API returns a NOT_FOUND error. Only customer bank accounts (prefixed with "bact:") can be used as payment sources.
When using ListBankAccounts, the response will include both seller and customer bank accounts. You can identify the type by checking for either location_id (seller accounts) or customer_id (customer accounts).
Use cursor-based pagination for large result sets:
curl https://connect.squareup.com/v2/bank-accounts?cursor=CURSOR_VALUE \ -H 'Square-Version: 2025-12-17' \ -H 'Authorization: Bearer ACCESS_TOKEN' \ -H 'Content-Type: application/json'
Configure webhook subscriptions to receive notifications for:
bank_account.created- New bank account linkedbank_account.verified- Account verification completedbank_account.disabled- Account disabled
{ "merchant_id": "MERCHANT_ID", "location_id": "LOCATION_ID", "type": "bank_account.verified", "event_id": "EVENT_ID", "created_at": "2026-01-14T09:30:00Z", "data": { "type": "bank_account", "id": "bact:OxfBTiXgByaXds1K4GB", "object": { "bank_account": { "id": "bact:OxfBTiXgByaXds1K4GB", "status": "VERIFIED", "customer_id": "HM3B2D5JKGZ69359BTEHXM2V8M", "version": 2 // ... additional fields } } } }
| Error Code | Description | Resolution |
|---|---|---|
INVALID_CUSTOMER_ID | Customer ID doesn't exist | Verify customer exists before creating bank account |
DUPLICATE_BANK_ACCOUNT | Bank account already exists for customer | Check fingerprint to avoid duplicates |
VERIFICATION_REQUIRED | Account not verified for payments | Complete verification process |
BANK_ACCOUNT_DISABLED | Account has been disabled | Use a different bank account |
Monitor the status field for verification progress:
VERIFICATION_IN_PROGRESS- Awaiting verificationVERIFIED- Ready for paymentsDISABLED- Cannot be used
- Implement tokenization - Set up the Web Payments SDK to securely tokenize bank account details before sending them to your server.
- Create customer profile - Ensure a customer profile exists in Square before attempting to store their bank account information.
- Handle duplicates - Use the fingerprint field to detect and prevent creating duplicate bank accounts for the same customer.
- Complete verification - Implement the verification flow using either micro-deposits or instant verification to activate the account.
- Configure webhooks - Set up webhook handlers to receive notifications when bank account status changes occur.
- Secure storage - Store the returned bank account ID securely in your database for processing future ACH payments.
- Enable account management - Provide functionality for customers to disable bank accounts they no longer wish to use.
- Request permissions - Ensure your OAuth application has
BANK_ACCOUNTS_READpermission to access seller bank accounts. - Display account info - Retrieve and display bank account information in your application's seller dashboard.
- Support multiple locations - Handle scenarios where sellers have different bank accounts linked to different locations.
- Monitor status changes - Implement webhook handlers to track when seller bank accounts are verified or disabled.
- Payments API - Process ACH payments using stored bank accounts
- Customers API - Manage customer profiles linked to bank accounts
- Webhooks API - Subscribe to bank account events
- Web Payments SDK - Tokenize bank account details