Skip to main content

Overview

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.

Supported schemes

The bank payment method supports the following schemes:
SchemeRegionDescription
achUSACH bank account transactions using account number and routing number.
sepaEU/EEASEPA direct debit transactions using IBAN.
bacsUKBACS direct debit transactions using account number and sort code.

ACH fields

When creating a transaction or storing a payment method with the ach scheme, provide the following fields:
FieldTypeRequiredDescription
methodstringYesSet to bank.
schemestringYesSet to ach.
account_numberstringYesThe bank account number.
routing_numberstringYesThe bank routing number (ABA number).
account_typestringYesEither checking or savings.
account_holderobjectYesThe account holder’s name. Provide either first_name and last_name, or company_name.
is_tokenizedbooleanNoSet to true if the account number is already tokenized. Defaults to false.

SEPA fields

When creating a transaction or storing a payment method with the sepa scheme, provide the following fields:
FieldTypeRequiredDescription
methodstringYesSet to bank.
schemestringYesSet to sepa.
account_numberstringYesThe IBAN (International Bank Account Number), for example DE89370400440532013000.
routing_numberstringNoThe BIC (Bank Identifier Code), also known as the SWIFT code, for example COBADEFFXXX.
account_holderobjectYesThe account holder’s name. Provide either first_name and last_name, or company_name.

BACS fields

When creating a transaction or storing a payment method with the bacs scheme, provide the following fields:
FieldTypeRequiredDescription
methodstringYesSet to bank.
schemestringYesSet to bacs.
account_numberstringYesThe UK bank account number (8 digits), for example 31926819.
routing_numberstringYesThe sort code (6 digits), for example 200000.
account_holderobjectYesThe account holder’s name. Provide either first_name and last_name, or company_name.

Create a transaction

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.
var transaction = await client.Transactions.CreateAsync(
    transactionCreate: new TransactionCreate()
    {
        Amount = 1299,
        Currency = "USD",
        Country = "US",
        Intent = TransactionCreate.IntentEnum.Capture,
        PaymentMethod = TransactionCreatePaymentMethod.CreateACHBankPaymentMethodCreate(
            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"
                }
            }
        ),
        PaymentServiceId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    }
);
Key parameters:
  • method — Set to bank to indicate a direct bank payment.
  • scheme — The bank scheme: ach (US), sepa (EU/EEA), or bacs (UK).
  • account_number — The customer’s bank account number (or IBAN for SEPA).
  • routing_number — The bank’s routing number: ABA number for ACH, routing number for SEPA, or sort code for BACS.
  • account_type — Either checking or savings. Required for ACH only.
  • account_holder — The name on the account. If available, send first_name and last_name for personal accounts, or company_name for business accounts.
  • payment_service_id — The UUID of your bank payment connector (found in the Gr4vy dashboard).

Vault a bank account

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.

Vault during a transaction

Set store: true on the transaction to vault the bank account at the same time as processing the payment.
var res = await client.Transactions.CreateAsync(
    transactionCreate: new TransactionCreate()
    {
        Amount = 1299,
        Currency = "USD",
        Country = "US",
        Intent = TransactionCreate.IntentEnum.Capture,
        PaymentMethod = TransactionCreatePaymentMethod.CreateACHBankPaymentMethodCreate(
            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"
                }
            }
        ),
        Store = true,
        PaymentSource = TransactionCreate.PaymentSourceEnum.Recurring,
        MerchantInitiated = false,
        IsSubsequentPayment = false,
        PaymentServiceId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    }
);

Vault without a transaction

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"
    }
);

Recurring payments

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"
    }
);

Supported connectors

The following connectors support direct bank payments:
  • Adyen bank—Process ACH, SEPA, and BACS transactions through Adyen using raw bank account details.

Limitations

  • 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.