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.
Collect mandate acknowledgement
Confirming a PaymentIntent or SetupIntent requires having your customer authorize a mandate to debit the account. Learn more about SEC codes to understand which authorization type is right for your business.
In some cases, you might have pre-authorization from your customer from an earlier purchase or Setup Intent that you can use to create an off-session payment. For example:
- If you previously collected an online mandate from the customer, you can use both the IP address and user agent information to create a mandate object. If you didn’t retain your customer’s IP address or user agent information, you can provide placeholder data. If you provide placeholder data, we recommend selecting any value you can easily identify in the future.
- If you previously collected payment and mandate information offline, you can create a PPD mandate .
Authorization is only required the first time you use a BankAccount object with the Payment Intents or Setup Intents API. After that, you can use the BankAccount object as a PaymentMethod to accept future payments.
You can create and confirm a Setup Intent to create a mandate without the need to charge a customer:
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
You can also provide mandate data when confirming a PaymentIntent. Include setup_future_usage: "off_session" to create a multi-use mandate for future off-session payments:
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
Create a PaymentIntent with a Bank Account
You can provide the ID of a saved BankAccount as the payment_method when creating a PaymentIntent, which eliminates the need to re-collect payment details. However, make sure to update your integration to create PaymentMethods instead of BankAccounts when saving new payment methods.
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
Similarly, you can provide the ID of a saved BankAccount as the payment_method when creating a SetupIntent.
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
Retrieve a BankAccount as a PaymentMethod
You can retrieve saved BankAccounts through the Payment Methods API:
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
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
To create an Invoice using a saved BankAccount, you need to first record the mandate acknowledgement when confirming a PaymentIntent or SetupIntent. Then, either update your customer’s default payment method or set the Invoice ’s default_payment_method parameter.
To update a customer’s default payment method:
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
To create an invoice with a bank account as a payment method:
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
Subscriptions
To create a Subscription using a saved BankAccount, you need to first record the mandate acknowledgement when confirming a PaymentIntent or SetupIntent. Then, either update your customer’s default payment method or set the Subscription ’s default_payment_method parameter.
To update a customer’s default payment method:
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
To create a subscription with a bank account as a payment method:
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
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 Payment Intents API with a payment _ method _ type of ach _ debit .
