Direct bank payments allow you to process bank transactions using raw bank account details instead of linking accounts through Plaid. This is useful when:
You already collected bank account data through your own onboarding flow (for example, micro-deposits or a third-party verification service).
Your payment processor does not support Plaid’s native token exchange.
You want to process a payment without requiring the customer to go through the Plaid Link flow.
The bank payment method accepts account details directly via the API and routes them to a compatible bank payment connector such as Adyen Bank.
If you use Plaid for bank account linking, the system can also extract raw bank details from Plaid automatically when the target connector requires them. This works for ACH, SEPA, and BACS schemes. See Plaid for details.
To create a direct bank payment, set the method to bank and the scheme to the appropriate value (ach, sepa, or bacs). Provide the account details in the payment_method object and set the payment_service_id to the UUID of your bank payment connector (for example, your Adyen bank connection).The following example uses the ach scheme. For SEPA, replace the scheme with sepa and provide the IBAN as the account_number. For BACS, replace the scheme with bacs and provide the sort code as the routing_number.See the POST /transactions API endpoint for more details.
You can store bank account details for future use by setting store: true on the transaction. The system returns a payment_method.id that you can use for subsequent charges without collecting bank details again.
You can also store bank account details without processing a payment using the POST /payment-methods endpoint. This creates a stored payment method that you can use for future transactions.
var res = await client.PaymentMethods.CreateAsync( paymentMethodCreate: new ACHBankPaymentMethodCreate() { Method = ACHBankPaymentMethodCreate.MethodEnum.Bank, Scheme = ACHBankPaymentMethodCreate.SchemeEnum.Ach, AccountNumber = "1234567890", RoutingNumber = "011000138", AccountType = ACHBankPaymentMethodCreate.AccountTypeEnum.Checking, AccountHolder = new BankAccountHolder() { FirstName = "John", LastName = "Doe" }, BuyerId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" });
After vaulting a bank account, use the stored payment_method.id to charge the account without collecting bank details again. Set payment_source to recurring, and mark the transaction as merchant-initiated and subsequent.
var res = await client.Transactions.CreateAsync( transactionCreate: new TransactionCreate() { Amount = 1299, Currency = "USD", Country = "US", Intent = TransactionCreate.IntentEnum.Capture, PaymentMethod = TransactionCreatePaymentMethod.CreateId("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"), PaymentSource = TransactionCreate.PaymentSourceEnum.Recurring, MerchantInitiated = true, IsSubsequentPayment = true, PaymentServiceId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" });
Direct routing only—Flow rules are not supported for direct bank payments. You must specify the payment_service_id to route the transaction to a specific connector.