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 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 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.
Collect payment detailsClient-side
Collect payment details on the client with the Payment Element. The Payment Element is a prebuilt UI component that simplifies collecting payment details for a variety of payment methods.
The Payment Element contains an iframe that securely sends payment information to Stripe over an HTTPS connection. Avoid placing the Payment Element within another iframe because some payment methods require redirecting to another page for payment confirmation.
The checkout page address must start with https://
rather than http://
for your integration to work. You can test your integration without using HTTPS, but remember to enable it when you’re ready to accept live payments.
The Payment Element renders a dynamic form that allows your customer to pick a payment method. For each payment method, the form automatically asks the customer to fill in all necessary payment details.
Customize appearance
Customize the Payment Element to match the design of your site by passing the appearance object into options
when creating the Elements
provider.
Collect addresses
By default, the Payment Element only collects the necessary billing address details. To collect a customer’s full billing address (to calculate the tax for digital goods and services, for example) or shipping address, use the Address Element.
Upon confirmation, Stripe automatically opens a modal to display the bank transfer details to your customer.
Submit payment to StripeClient-side
Use stripe.confirmPayment to complete the payment using details from the Payment Element. Provide a return_url to this function to indicate where Stripe should redirect the user after they complete the payment. Your user may be first redirected to an intermediate site, like a bank authorization page, before being redirected to the return_
. Card payments immediately redirect to the return_
when a payment is successful.
If you don’t want to redirect for card payments after payment completion, you can set redirect to if_
. This only redirects customers that check out with redirect-based payment methods.
Make sure the return_
corresponds to a page on your website that provides the status of the payment. When Stripe redirects the customer to the return_
, we provide the following URL query parameters:
Parameter | Description |
---|---|
payment_ | The unique identifier for the PaymentIntent . |
payment_ | The client secret of the PaymentIntent object. |
Caution
If you have tooling that tracks the customer’s browser session, you might need to add the stripe.
domain to the referrer exclude list. Redirects cause some tools to create new sessions, which prevents you from tracking the complete session.
Use one of the query parameters to retrieve the PaymentIntent. Inspect the status of the PaymentIntent to decide what to show your customers. You can also append your own query parameters when providing the return_
, which persist through the redirect process.
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
.
Your webhook endpoint needs to be set up to start receiving the payment_
event. When the PaymentIntent is partially funded, the status remains in requires_
status.
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.
Caution
The Stripe CLI doesn’t support triggering beta API version events, such as payment_
.
The following events are sent during the payment funding flow when the PaymentIntent is updated.
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 the API, Dashboard, or a beta version of the Stripe CLI.
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.