Fund via Plaid-Connected Bank Account
How do I fund a fiat account from a Plaid-connected bank account?
This guide walks you through funding a customer's fiat account from their Plaid-connected
external bank account.
Prerequisites
Before you begin, ensure you have:
- a customer already created and verified;
- a
fiataccount created for the customer; and, - a Plaid-connected external bank account linked to the customer. See Add Customer External Bank Accounts.
Overview
The Plaid funding process involves three main steps:
- Create a
fundingquote - Execute a
transferwith the customer'sexternal_bank_account_guid - Monitor the transfer until it reaches the
completedstate
Step 1: Create a funding quote
funding quoteCreate a quote via POST /api/quotes:
{
"product_type": "funding",
"customer_guid": "customer_guid",
"asset": "USD",
"side": "deposit",
"receive_amount": 10000
}
Base unitsThe
receive_amountis in the base units of the currency. In the example above, 10,000 = 10,000 cents = $100.00 USD. CallGET /api/assetsto get the number of base decimals for a currency.
Set asset to USD, side to deposit, and receive_amount to the desired amount. Once you
have your quote guid, proceed to the transfers API.
Step 2: Execute the transfer
transferYou need the customer's external_bank_account_guid for this step. Retrieve it by calling
GET /api/external_bank_accounts with the customer's guid.
Create a transfer via POST /api/transfers with transfer_type set to funding, the quote
guid, and the external_bank_account_guid:
{
"quote_guid": "quote_guid",
"transfer_type": "funding",
"external_bank_account_guid": "external_bank_account_guid",
"payment_rail": "ach",
"source_participants": [
{
"type": "customer",
"guid": "customer_guid",
"amount": 10000
}
],
"destination_participants": [
{
"type": "customer",
"guid": "customer_guid",
"amount": 10000
}
]
}
Sandbox limitExternal Bank Accounts with
account_kind=plaidare limited to $100.00 per funding transfer in sandbox. Transfers exceeding $100.00 will fail. You can perform an unlimited number of transfers up to $100.00.
Sandbox testingThe
expected_statefield is only available in sandbox to force specific transfer outcomes. Add"expected_state": "pending"to the transfer request body to test state handling.
Payment rails
The Cybrid Platform will default all USD transfers to use same-day ACH, i.e., "payment_rail":"ach", and
EFT for all CAD transfers, i.e., "payment_rail":"eft".
Accounts can be funded using other payment rails — see Fund via Deposit Bank Account.
Step 3: Monitor the transfer
Transfers are created asynchronously. Monitor the transfer until it reaches the completed state.
Settlement times depend on the payment_rail selected. For example, an ACH transfer requested at
4pm on a business day may not complete until 4pm the next business day. See
Fiat Transfer Settlement
for details.
Monitor transfer state by querying GET /api/transfers/{transfer_guid}, or register for
webhooks to receive automatic notifications on state
changes.
After creation, the transfer state is pending and progresses to completed when the fiat
settles.
Cancel a transfer
Transfers can only be cancelled between posting and bank execution -- a very small time window. No API endpoint is currently available for partner-initiated cancellation.
Contact Cybrid support to request a transfer cancellation.
Handle Plaid errors
Creating a funding transfer using an External Bank Account of "account_kind": "plaid" or
"account_kind": "plaid_processor_token" can produce several errors.
The Cybrid Platform informs the caller of errors or required actions when using Plaid-connected bank accounts.
Depending on the error received from Plaid, the associated External Bank Account for a transfer can be:
- Put into a
refresh_requiredstate. This occurs when the customer must re-authenticate to their bank account via Plaid. When this does occur the partner must put their customer through a flow where Plaid Link is initialized inupdatemode. See the guide Plaid Link Update Mode. The associated External Bank Account cannot be used until the account is re-authorized. - Put into a
deletingand eventuallydeletedstate. This occurs when Plaid has lost access to the customer's account completely or the customer has not granted sufficient permissions to Plaid to access their account. When this does occur the partner must instruct the customer to connect a different bank account via Plaid or to grant the required permissions to Plaid while interacting with Plaid Link.
Failure codes
When a funding transfer fails, the transfer state is failed with a failure_code.
Platform errors
| Failure code | Description | Action |
|---|---|---|
cancelled | The transfer was manually cancelled. | -- |
compliance_rejection | The transfer was rejected for compliance reasons. | -- |
internal_error | An internal error occurred. | Retry the transfer. |
limit_exceeded | The customer exceeded their activity limits. | -- |
non_sufficient_funds | The customer does not have enough funds. | -- |
party_name_invalid | The external bank account has an invalid party name. | -- |
payment_rail_invalid | The payment rail is not supported by the external bank account. | -- |
refresh_required | The external bank account must be reconnected via Plaid. | -- |
reversed | The transfer was reversed (returned). | -- |
Plaid errors
| Failure code | Description | Action |
|---|---|---|
plaid_access_not_granted | Permissions not granted. Account set to deleted. | Re-add via Plaid. Docs |
plaid_institution_not_responding | Balance could not be retrieved. | Retry. Docs |
plaid_internal_server_error | Balance could not be retrieved. | Retry. Docs |
plaid_item_not_found | Plaid lost access to the account. Account set to deleted. | Re-add via Plaid. Docs |
plaid_item_not_supported | Account not supported. Account set to deleted. | Connect a different account. Docs |
plaid_multiple_accounts | Multiple accounts selected in Plaid Link. Account set to deleted. | Select only one account. |
plaid_no_accounts | No compatible accounts found. Account set to deleted. | Docs |
plaid_none_balances_error | Error retrieving balances from Plaid. | Retry. |
plaid_unknown_error | Balance could not be retrieved. | Retry. Docs |
Withdraw funds
To withdraw funds from a customer's fiat account to their external bank account,
create a quote with side set to withdrawal:
{
"product_type": "funding",
"customer_guid": "customer_guid",
"asset": "USD",
"side": "withdrawal",
"receive_amount": 10000
}Then create a funding transfer via POST /api/transfers:
{
"quote_guid": "quote_guid",
"transfer_type": "funding",
"external_bank_account_guid": "external_bank_account_guid",
"payment_rail": "wire",
"beneficiary_memo": "Invoice #12345 payment",
"source_participants": [
{
"type": "customer",
"guid": "customer_guid",
"amount": 10000
}
],
"destination_participants": [
{
"type": "customer",
"guid": "customer_guid",
"amount": 10000
}
]
}The external_bank_account_guid can reference any type of external bank account — Plaid-connected or raw routing.
Beneficiary memo
The optional beneficiary_memo parameter sets the memo that appears on bank statements
and wire confirmations for the beneficiary.
Constraints:
- Maximum 128 characters
- Cannot be an empty string — use
nullor omit the field to skip - Only applies to withdrawal-direction funding transfers (not deposits, and not other transfer types such as book, crypto, or lightning)
Updated about 16 hours ago
