Skip to main content

Save Bank Accounts

A saved bank account has an id that starts with ba_. You use it to create ACH payments and payouts. Save a bank account in one of two ways:

  • Credova Elements captures the bank account in your web app, by manual entry or instant verification. Account numbers never touch your servers.
  • The Direct API sends the bank account from your servers.

Before you start​

Credova account
Sign up or sign in to the Credova Portal.
Publishable Key
Loads Credova Elements in the browser. It is safe to put in frontend code.
Secret Key
Authenticates requests from your server. Never send it to the browser.

Request Account Setting Access​

Each way to collect a bank account needs an account setting. Request the setting for the option you plan to use:

  • Manual Entry needs the payment-methods:bank-accounts:manual-creation account setting type. In the merchant portal, it is the Manual Bank Account Creation setting.
  • Instant Verification needs the payment-methods:bank-accounts:verification account setting type. In the merchant portal, it is the Bank Account Verification setting.

To request a setting, go to the merchant portal and click the Request this feature button next to it. Alternatively, you can request access via the API.

Your account needs the setting before manual bank account creation or instant bank account verification works.

The payment-methods:bank-accounts:manual-creation setting also lets you send bank account details when you process an ACH payment or an ACH payout. You do not need to create the bank account first.

Save a Bank Account with Credova Elements​

Credova Elements gives you two ways to collect a bank account:

  • Manual Entry: your customer types the routing number and account number into the Bank Account Elements.
  • Instant Verification: your customer connects their bank account and Credova verifies it instantly.

With either option, you create a bank account that holds the non-sensitive information about the bank account. You can safely store the bank account's id value in your database to link it with the appropriate payment or customer association.

When you create the bank account, you can optionally pass in a customer_id to associate with an existing Created Customer and billing_details to remove the requirement to pass them when Creating a Payment.

Configuring Credova Elements​

Credova Elements are available for the following technologies. Click below for detailed instructions on how to install and configure them.

Javascript
React

Manual Entry​

Manual entry captures the routing number and account number in your frontend application and stores them securely in your account.

Adding Bank Account Elements​

Once installed and configured, add the Bank Account Elements to your application.

index.html
<form>
<input type="text" id="accountHolderName" placeholder="Account holder name" />
<div id="bankAccount" style="width: 100%;"></div>
</form>
index.js
import { PublicSquare } from '@publicsquare/elements-js';

let publicsquare;
let bankAccountElement;

async function init() {
publicsquare = await new PublicSquare().init('<PUBLISHABLE_API_KEY>');

// Creates an Bank Account instance that includes the routing number and account number
bankAccountElement = publicsquare.createBankAccountElement();
bankAccountElement.mount('#bankAccount');
}

init();

Storing Bank Accounts​

Now that you are capturing bank account data in your web application, it is time to store the bank account in your account.

To do this, we will call the create bank account method from the SDK, passing the Bank Account Elements as data points in the payload.

Add a submit function along with a button to trigger it:

async function submit (e: FormEvent<HTMLFormElement>,) {
try {
const formData = new FormData(e.currentTarget)
const account_holder_name = formData.get('accountHolderName');
const routing_number = bankAccountElement.routingNumber.el.value
const account_number = bankAccountElement.accountNumber.el.value
const bankAccount = await publicsquare.bankAccounts.create({
account_holder_name,
routing_number,
account_number,
});
console.log(bankAccount); // e.g { id: 'ba_1234567890', ... }
} catch (error) {
console.error(error);
}
}

The created bank account object contains the non-sensitive information about the bank account:

{
"id": "ba_7Ay5mcUXAxwrN6wQEQUVEHBCJ",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "production",
"customer_id": "cus_7Ay5mcUXAxwrN6wQEQUVEHBCJ",
"billing_details": {
"address_line_1": "111 Colorado Ave.",
"address_line_2": "Apt 403",
"city": "Des Moines",
"state": "IA",
"postal_code": "51111",
"country": "US"
},
"created_at": "2024-06-30T01:02:29.212Z",
"modified_at": "2024-06-30T01:02:29.212Z",
"account_holder_name": "John Doe",
"account_holder_type": "individual",
"account_type": "checking",
"routing_number": "110000000",
"account_number_last4": "1011"
}

Instant Verification​

Instant verification lets your customer connect their bank account so that Credova can verify it instantly, then stores the verified bank account in your account.

Adding Bank Account Verification Elements​

Credova has partnered with Flinks to provide a secure way to collect bank accounts. Once installed and configured, add the Bank Account Verification Elements to your application.

index.html
<div id="bank-account-verification-element">
<button
onclick={onConnectBankAccountWithVerification}
>
Connect Bank Account
</button>
</div>
index.js
import { PublicSquare } from '@publicsquare/elements-js';

let publicsquare;
let result;

async function init() {
publicsquare = await new PublicSquare().init('<PUBLISHABLE_API_KEY>');

async function onConnectBankAccountWithVerification() {
result = await publicsquare?.bankAccounts.openVerification(
`#${'bank-account-verification-element'}`
)
}
}

await init();

Storing Verified Bank Accounts​

Now that your customer has verified their bank account information, we need to create a bank account payment method from the results.

To do this, we will call the create bank account method from the SDK passing the bank_account_verification_id, returned from the bank account verification result.

Add a submit function along with a button to trigger it:

index.html
<div id="bank-account-verification-element">
<button
onclick={onConnectBankAccountWithVerification}
>
Connect Bank Account
</button>
</div>

<button id="submit">Submit</button>
import { PublicSquare } from '@publicsquare/elements-js';

let publicsquare;
let result;

async function init () {
publicsquare = await new PublicSquare().init('<PUBLISHABLE_API_KEY>');

async function onConnectBankAccountWithVerification() {
result = await publicsquare?.bankAccounts.openVerification(
`#${'bank-account-verification-element'}`
)
}

document.getElementById("submit").addEventListener("click", submit);
}

async function submit (e: FormEvent<HTMLFormElement>,) {
try {
const bankAccount = await publicsquare?.bankAccounts.create({
bank_account_verification_id: result?.bank_account_verification_id
});
console.log(bankAccount); // e.g { id: 'ba_1234567890', ... }
} catch (error) {
console.error(error);
}
}

await init();

The created bank account object contains the non-sensitive information about the bank account:

{
"id": "ba_7Ay5mcUXAxwrN6wQEQUVEHBCJ",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "production",
"customer_id": "cus_7Ay5mcUXAxwrN6wQEQUVEHBCJ",
"billing_details": {
"address_line_1": "111 Colorado Ave.",
"address_line_2": "Apt 403",
"city": "Des Moines",
"state": "IA",
"postal_code": "51111",
"country": "US"
},
"created_at": "2024-06-30T01:02:29.212Z",
"modified_at": "2024-06-30T01:02:29.212Z",
"account_holder_name": "John Doe",
"account_holder_type": "individual",
"account_type": "checking",
"routing_number": "110000000",
"account_number_last4": "1011",
"status": "verified"
}

If Credova has not yet received a response from Flinks, the API returns the validation message bank account verification result is still in progress.

Nightly Balance Refresh​

We automatically refresh the balance for all verified bank accounts for up to 30 days after verification. To obtain the most recent balance, you can make a call to the Get Bank Account Balance endpoint.

If more than 30 days have passed since the account was verified, you must re-verify the bank account to update its balance.

Bank accounts with MFA enabled do not support nightly balance refresh.

Save a Bank Account from Your Servers​

Your servers receive and send bank account numbers in this flow. To keep them off your servers, use Credova Elements.

A restricted key needs the payment-method:write or payment-method:capture permission. Your account also needs the payment-methods:bank-accounts:manual-creation account setting from Request Account Setting Access.

Save a Bank Account​

Send the bank account in a POST request to Create Bank Account:

Save a Bank Account
curl 'https://api.publicsquare.com/payment-methods/bank-accounts' \
-X 'POST' \
-H 'X-API-KEY: <SECRET_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"account_holder_name": "John Doe",
"account_holder_type": "individual",
"account_type": "checking",
"routing_number": "110000000",
"account_number": "000123456789",
"customer_id": "cus_7Ay5mcUXAxwrN6wQEQUVEHBCJ"
}'

The request body accepts these fields:

FieldDescription
account_holder_nameName on the bank account.
account_holder_typeindividual or company.
account_typechecking or savings.
routing_numberRouting number.
account_numberAccount number.
customer_idID of an existing customer to associate with the bank account.
billing_detailsBilling address for the bank account.

Send account_holder_name and account_holder_type. Some processors require them.

Bank Account Response​

The created bank_account object contains the non-sensitive information about the bank account:

bank-account.json
{
"id": "ba_7Ay5mcUXAxwrN6wQEQUVEHBCJ",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "production",
"customer_id": "cus_7Ay5mcUXAxwrN6wQEQUVEHBCJ",
"created_at": "2024-06-30T01:02:29.212Z",
"modified_at": "2024-06-30T01:02:29.212Z",
"account_holder_name": "John Doe",
"account_holder_type": "individual",
"account_type": "checking",
"routing_number": "110000000",
"account_number_last4": "6789"
}

Store the bank account's id in your database to use it in later payments and payouts.

You do not have to save the bank account first. You can also send the bank account details with the payment.

Conclusion​

You have saved a customer's bank account. To use it, follow these guides: