Accept a bank transfer
Use the Payment Intents API to accept bank transfer payments.
The first time you accept a bank transfer payment from a customer, Stripe generates a virtual bank account for them, which you can then share with them directly. All future bank transfer payments from this customer get sent to this bank account. In some countries, Stripe also provides you with a unique transfer reference number that your customer should include with each transfer to make it easier to match the transfer against outstanding payments. Some countries have limits on the number of virtual bank account numbers that you can create for free.
You can find an overview of the common steps when accepting a bank transfer payment in the following sequence diagram:
Handling underpayments and overpayments
With bank transfer payments, it’s possible that the customer sends you more or less than the expected payment amount. If the customer sends too little, Stripe partially funds an open payment intent. Invoices won’t be partially funded and remain open until incoming funds cover the full invoice amount.
If the customer sends more than the expected amount, Stripe attempts to reconcile the incoming funds against an open payment and keep the remaining excess amount in the customer cash balance. You can find more details on how Stripe handles reconciliation in the reconciliation section of our documentation.
Handling multiple open payments or invoices
You might have multiple open payments or invoices which can be paid with a bank transfer. In the default setup, Stripe attempts to automatically reconcile the bank transfer by using information like the transfer’s reference code or the amount transferred.
You can disable automatic reconciliation and manually reconcile payments and invoices yourself. You can override the automatic reconciliation behavior on a per-customer basis by setting reconciliation mode to manual.
Set up StripeServer-side
First, you need a Stripe account. Register now.
Use our official libraries for access to the Stripe API from your application:
Create or retrieve a CustomerServer-side
You must associate a Customer object to reconcile each bank transfer payment. If you have an existing Customer object, you can skip this step. Otherwise, create a new Customer object.
Create and confirm a PaymentIntentServer-side
A PaymentIntent is an object that represents your intent to collect payment from a customer and tracks the lifecycle of the payment process through each stage. Create and confirm a PaymentIntent on the server, specifying the amount and currency you want to collect. You must also populate the customer parameter of the PaymentIntent creation request. Bank transfers aren’t available on PaymentIntents without a customer.
Instruct the customer to complete a bank transferClient-side
If the customer balance isn’t high enough to cover the request amount, the PaymentIntent shows a requires_
status. The response has a next_
field containing a type
value of display_
. The next_
hash contains information to display to your customer so that they can complete the bank transfer.
Note
In live mode, Stripe supplies each customer with a unique set of bank transfer details. In contrast, Stripe offers invalid bank transfer details to all customers in test mode. Unlike live mode, these invalid details might not always be unique.
Confirm the PaymentIntent succeeded
The PaymentIntent stays in a requires_
status until funds arrive in the bank account. When funds are ready, the PaymentIntent status updates from requires_
to succeeded
.
You need to set up your webhook endpoint to start receiving the payment_
event.
You can add a webhook from the Dashboard.
Alternatively, you can use the Webhook Endpoints API to start receiving the payment_intent.partially_funded event.
Stripe sends the following events during the payment funding flow when we update the PaymentIntent.
Event | Description | Next steps |
---|---|---|
payment_ | Sent during confirmation when the customer balance doesn’t have sufficient funds to reconcile the PaymentIntent, the PaymentIntent transitions to requires_ . | Instruct your customer to send a bank transfer with the amount_ . |
payment_ | The customer sent a bank transfer that was applied to the PaymentIntent, but wasn’t enough to complete the payment. This might happen because the customer transferred an insufficient amount (because of a mistaken underpayment or fees charged by their bank) or because a remaining customer balance was applied to this PaymentIntent. PaymentIntents that are partially funded aren’t reflected in your account balance until the payment is complete. | Instruct your customer to send another bank transfer with the new amount_ to complete the payment. If you want to complete the payment with the partially applied funds, you can update the amount and confirm the PaymentIntent again. |
payment_ | The customer’s payment succeeded. | Fulfill the goods or services that the customer purchased. |
Caution
When you change the amount of a partially funded PaymentIntent, the funds are returned to the customer balance. If other PaymentIntents are open, Stripe funds those automatically. If the customer is configured for manual reconciliation, you need to apply the funds again.
We recommend using webhooks to confirm the charge has succeeded and to notify the customer that the payment is complete.
Sample code
View pending payments in the Dashboard
You can view all pending bank transfer PaymentIntents in the Dashboard by applying the Waiting on funding filter to Status .
Test your integration
You can test your integration by simulating an incoming bank transfer using either the Dashboard or an HTTP request.
With the Dashboard
To simulate a bank transfer using the Dashboard, navigate to the customer’s page in the Dashboard. Under Payment methods, click Add and select Fund cash balance (testmode only).
With the Stripe API
You can make an API call to simulate a bank transfer.
Handling temporary availability issues
The following error codes indicate temporary issues with the availability of the payment method:
Code | Description | Handling |
---|---|---|
payment_ | Too many requests were made in quick succession for this payment method, which has stricter limits than the API-wide rate limits. | These errors can persist for several API requests when many of your customers try to use the same payment method, such as during an ongoing sale on your website. In this case, ask your customers to choose a different payment method. |
Caution
If you anticipate heavy usage in general or because of an upcoming event, contact us as soon as you know about it.