Skip to content
Create account or Sign in
The Stripe Docs logo
/
Ask AI
Create accountSign in
Get started
Payments
Revenue
Platforms and marketplaces
Money management
Developer resources
APIs & SDKsHelp
OverviewAccept a paymentUpgrade your integration
Online payments
OverviewFind your use case
Use Payment Links
Use a prebuilt checkout page
Build a custom integration with Elements
Build an in-app integration
Use Managed Payments
Recurring payments
In-person payments
Terminal
Payment methods
Add payment methods
    Overview
    Payment method integration options
    Manage default payment methods in the Dashboard
    Payment method types
    Cards
    Pay with Stripe balance
    Stablecoin payments
    Bank debits
      ACH Direct Debit
        Accept a payment
        Save bank details
        Migrating to new ACH Direct Debit APIs
          Migrate existing bank accounts
        Migrating from another processor
        Blocked bank accounts
        SEC codes
        Nacha rule for consumer e-commerce purchases
      Bacs Direct Debit
      Pre-authorized debit in Canada
      Australia BECS Direct Debit
      New Zealand BECS Direct Debit
      SEPA Direct Debit
    Bank redirects
    Bank transfers
    Credit transfers (Sources)
    Buy now, pay later
    Real-time payments
    Vouchers
    Wallets
    Enable local payment methods by country
    Custom payment methods
Manage payment methods
Faster checkout with Link
Payment operations
Analytics
Balances and settlement time
Compliance and security
Currencies
Declines
Disputes
Fraud prevention
Radar fraud protection
Payouts
ReceiptsRefunds and cancellations
Advanced integrations
Custom payment flows
Flexible acquiring
Off-Session Payments
Multiprocessor orchestration
Beyond payments
Incorporate your company
Crypto
Agentic commerce
Machine payments
Financial Connections
Climate
Verify identities
United States
English (United States)
HomePaymentsAdd payment methodsBank debitsACH Direct DebitMigrating to new ACH Direct Debit APIs

Migrate existing bank accounts

Learn how to migrate existing bank accounts to the Payment Intents API or Checkout Sessions API.

Stripe is removing support for ACH Direct Debit using legacy integrations.

If you create legacy ACH Direct Debit payments, you must migrate to the Payment Intents API or Checkout Sessions API.

If you previously collected customer payment details with Stripe using the Tokens API, you can continue using the saved BankAccount as a PaymentMethod.

You can only use customer bank accounts with the Payment Intents API or Checkout Sessions API after you meet the following requirements:

  • Checkout Sessions API: The customer’s bank account has been verified.

  • Payment Intents API: The customer’s bank account has been verified, and an active mandate exists for that bank account.

You don’t need to re-verify Bank Accounts that are already verified to use them with Payment Intents or Checkout Sessions.

Use Checkout Sessions

To display previously saved and verified bank accounts in Checkout, you need to:

  • Create a Checkout Session with a customer parameter
  • Set the filters to ['unspecified', 'always']
  • Specify us_bank_account in payment_method_types

When these requirements are met, Checkout automatically finds and displays all saved, verified bank accounts associated with that customer, eliminating the need to recollect payment details.

Command Line
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/checkout/sessions \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -d mode=payment \ -d ui_mode=custom \ -d customer=
"{{CUSTOMER_ID}}"
\ -d "payment_method_types[0]"=us_bank_account \ -d "line_items[0][price_data][currency]"=usd \ -d "line_items[0][price_data][product_data][name]"=T-shirt \ -d "line_items[0][price_data][unit_amount]"=1099 \ -d "line_items[0][quantity]"=1 \ -d "saved_payment_method_options[allow_redisplay_filters][0]"=unspecified \ -d "saved_payment_method_options[allow_redisplay_filters][1]"=always \ --data-urlencode return_url="YOUR_DOMAIN/complete?session_id={CHECKOUT_SESSION_ID}"

If the customer has an email attached, the customer’s email is prefilled in the Session and can’t be modified. You must check for an email and render your email input field accordingly.

const {checkout} = useCheckout(); const currentEmail = checkout.email; if (currentEmail) { return <input value={currentEmail} readOnly />; }

Retrieve a BankAccount as a PaymentMethod

You can retrieve saved BankAccounts through the Payment Methods API:

Command Line
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/payment_methods/
{{BANK_ACCOUNT_ID}}
\ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"

When using a BankAccount as a PaymentMethod, no new objects are created. The Payment Methods API simply provides a different view of the same underlying object.

{ "id": "ba_1IsleZ2eZvKYlo2CI3To1g72", "object": "payment_method", "billing_details": { "address": { "city": null, "country": null, "line1": null, "line2": null, "postal_code": null, "state": null }, "email": null, "name": "Jenny Rosen", "phone": null }, "us_bank_account": { "last4": "6789", "routing_number": "110000000", "fingerprint": "1JWtPxqbdX5Gamtc", "account_holder_type": "individual", "bank_name": "STRIPE TEST BANK", }, "created": 123456789, "customer": "cus_CY5bH92D99f4mn", "livemode": false, "metadata": {}, "type": "us_bank_account" }

Invoices

After you collect mandate acknowledgment, to continue using Invoicing you must either update your customer’s default payment method or set the default_payment_method parameter.

To update a customer’s default payment method:

Command Line
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/customers/
{{CUSTOMER_ID}}
\ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -d "invoice_settings[default_payment_method]"=
"{{BANK_ACCOUNT_ID}}"

To create an invoice with a bank account as a payment method:

Command Line
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/invoices \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -d customer=
"{{CUSTOMER_ID}}"
\ -d default_payment_method=
"{{BANK_ACCOUNT_ID}}"

Subscriptions

After you collect mandate acknowledgment, to continue using Subscriptions, you must either update your customer’s default payment method or set the default_payment_method parameter.

To update a customer’s default payment method:

Command Line
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/customers/
{{CUSTOMER_ID}}
\ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -d "invoice_settings[default_payment_method]"=
"{{BANK_ACCOUNT_ID}}"

To create an subscription with a bank account as a payment method:

Command Line
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/subscriptions \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -d customer=
"{{CUSTOMER_ID}}"
\ -d default_payment_method=
"{{BANK_ACCOUNT_ID}}"
\ -d "items[0][price]"=price_1MowQULkdIwHu7ixraBm864M

Identify Legacy ACH Payments

On a Charge object, the payment_method_details.type property is ach_debit for the legacy integration and us_bank_account for the newer integration.

A legacy ACH payment is created when a legacy BankAccount is the payment source. This happens when:

  • You call the Create Charge API.
  • A Subscription or Invoice charges a customer whose default_source is a legacy BankAccount, and no default_payment_method is set on the customer, subscription, or invoice.
  • You call the Create PaymentIntent API with source set to a legacy BankAccount.
Was this page helpful?
YesNo
  • Need help? Contact Support.
  • Chat with Stripe developers on Discord.
  • Check out our changelog.
  • Questions? Contact Sales.
  • LLM? Read llms.txt.
  • Powered by Markdoc
On this page