Save Bacs Direct Debit bank details
Learn how to use Checkout to save payment method details for future Bacs Direct Debit payments.
Use Stripe Checkout to collect Bacs Direct Debit payment details in advance, with the final amount or payment date determined later. This is useful for:
- Saving payment methods to a wallet to streamline future purchases.
- Collecting surcharges after fulfilling a service.
- Starting a free trial for a subscription .
Set up Stripe Server-side
First, you need a Stripe account. Register now.
Use our official libraries for access to the Stripe API from your application:
Command Line
Select a language
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
# Available as a gem
sudo gem install stripe
Gemfile
Select a language
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
# If you use bundler, you can add this line to your Gemfile
gem 'stripe'
Create or retrieve a customer Server-side
To reuse a Bacs Direct Debit payment method for future payments, attach it to an object that represents your customer.
Use the Accounts v2 API to represent customers
The Accounts v2 API is generally available for Connect users, and in public preview for other Stripe users. If you’re part of the Accounts v2 preview, you need to specify a preview version in your code.
To join the Accounts v2 preview, go to Account previews and features in your Dashboard and enable Reusable payment methods for Global Payouts.
For most use cases, we recommend modeling your customers as customer-configured Account objects instead of using Customer objects.
Create a customer-configured Account or Customer when your customer creates an account with your business, or when saving a payment method. Associate the object’s ID with your own internal representation of a customer.
Create a new customer or retrieve an existing one to associate with this payment.
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
Create a Checkout Session Client-side Server-side
Before you can accept Direct Debit payments, your customer must provide their bank account information and give permission to debit their account (also known as a mandate) through Stripe Checkout.
Add a checkout button to your website that calls a server-side endpoint to create a Checkout Session.
index.html
<html>
<head>
<title>Checkout</title>
</head>
<body>
<form action="/create-checkout-session" method="POST">
<button type="submit">Checkout</button>
</form>
</body>
</html>
Create a Checkout Session in setup mode to collect the required information. After creating the Checkout Session, redirect your customer to the URL returned in the response. Enable the payment method in your Dashboard. Stripe displays eligible payment methods automatically.
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
When your customer provides their payment method details, they’re redirected to the success_url, a page on your website that informs them that their payment method was saved successfully. Make the Session ID available on your success page by including the {the related setting} template variable in the success_url as in the above example.
Caution
Don’t rely on the redirect to the success_url alone for detecting payment initiation, because:
- Malicious users could directly access the success _ url without paying and gain access to your goods or services.
- After a successful payment, customers might close their browser tab before they’re redirected to the success _ url .
You should also be aware of the notification requirements specific to Bacs Direct Debit.
Note
The Bacs Direct Debit rules require that customers are sent an email notification when payment details are collected. By default, these emails are sent automatically by Stripe. You can also opt to send your own Bacs notifications.
Retrieve the payment method Server-side
After a customer submits their payment details, retrieve the PaymentMethod object. A PaymentMethod stores the customer’s bank account information for future payments. You can retrieve the PaymentMethod synchronously using the success_url or asynchronously using webhooks.
The decision to retrieve the PaymentMethod synchronously or asynchronously depends on your tolerance for dropoff, as customers might not always reach the success_url after a successful payment (for example, it’s possible for them to close their browser tab before the redirect occurs). Using webhooks prevents your integration from experiencing this form of dropoff.
Handle checkout.session.completed webhooks, which contain a Session object. To learn more, see setting up webhooks. The following example is a checkout.session.completed response.
{
"id": "evt_1Ep24XHssDVaQm2PpwS19Yt0",
"object": "event",
"api_version": "2019-03-14",
"created": 1561420781,
"data": {
"object": {
"id": "cs_test_MlZAaTXUMHjWZ7DcXjusJnDU4MxPalbtL5eYrmS2GKxqscDtpJq8QM0k",
"object": "checkout.session",
"billing_address_collection": null,
"client_reference_id": null,
"customer": null,
"customer_email": null,
"display_items": [],
"mode": "setup",
"setup_intent": "seti_1EzVO3HssDVaQm2PJjXHmLlM",
"submit_type": null,
"subscription": null,
"success_url": "https://example.com/success"
}
},
"livemode": false,
"pending_webhooks": 1,
"request": {
"id": null,
"idempotency_key": null
},
"type": "checkout.session.completed"
}
Note the value of the setup_intent key, which is the ID for the SetupIntent created with the Checkout Session. A SetupIntent is an object used to set up the customer bank account information for future payments. Retrieve the SetupIntent object with the ID. The returned object contains the payment_method ID.
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
Handle post-setup events Server-side
Once the Checkout Session completes, payment details are submitted to the bank as a mandate.
The mandate can change at any time after you’ve collected it. This might be the result of the customer instructing their bank to amend the mandate or because of a change in the bank itself (for example, the customer changes to a different one). Stripe sends the following events when the mandate changes:
| Event name | Description | Can accept payments? |
|---|---|---|
mandate.updated | Occurs whenever a mandate is rejected, canceled, or reactivated by the Bacs network. Check mandate.status to determine if the mandate can continue to be used. | Yes, if the new status is active |
payment_method.automatically_updated | Occurs when a customer’s bank account details change. | Yes |
These events are available in the Dashboard, but you can set up a webhook to handle these programmatically.
Test the integration
There are several test bank account numbers you can use in a sandbox to make sure this integration is ready. You can also use the corresponding token to skip manually entering bank account details.
| Sort code | Account number | Token | Description |
|---|---|---|---|
108800 | 00012345 | pm_bacsDebit_success | The payment succeeds and the PaymentIntent transitions from processing to succeeded. |
108800 | 90012345 | pm_bacsDebit_successDelayed | The payment succeeds after three minutes and the PaymentIntent transitions from processing to succeeded. |
108800 | 33333335 | pm_bacsDebit_debitNotAuthorized | The payment is accepted but then immediately fails with a debit_not_authorized failure code and the PaymentIntent transitions from processing to requires_payment_method. The mandate becomes inactive and the PaymentMethod can’t be used again. |
108800 | 93333335 | pm_bacsDebit_debitNotAuthorizedDelayed | The payment fails after three minutes with a debit_not_authorized failure code and the PaymentIntent transitions from processing to requires_payment_method. The mandate becomes inactive and the PaymentMethod can’t be used again. |
108800 | 22222227 | pm_bacsDebit_insufficientFunds | The payment fails with an insufficient_funds failure code and the PaymentIntent transitions from processing to requires_payment_method. The mandate remains active and the PaymentMethod can be used again. |
108800 | 92222227 | pm_bacsDebit_insufficientFundsDelayed | The payment fails after three minutes with an insufficient_funds failure code and the PaymentIntent transitions from processing to requires_payment_method. The mandate remains active and the PaymentMethod can be used again. |
108800 | 55555559 | pm_bacsDebit_dispute | The payment succeeds after three minutes and the PaymentIntent transitions from processing to succeeded, but a dispute is immediately created. |
108800 | 00033333 | pm_bacsDebit_mandateRefused | PaymentMethod creation succeeds, but the mandate is refused by the customer’s bank and immediately transitions to inactive. |
108800 | 00044444 | — | The request to set up Bacs Direct Debit fails immediately due to an invalid account number and the customer is prompted to update their information before submitting. Payment details aren’t collected, so no synthetic token corresponds to this scenario. |
108800 | 34343434 | pm_bacsDebit_exceedsWeeklyLimit | The payment fails with a charge_exceeds_source_limit failure code due to the payment amount causing the account to exceed its weekly payment volume limit. |
108800 | 12121212 | pm_bacsDebit_exceedsTransactionLimit | The payment fails with a charge_exceeds_transaction_limit failure code due to the payment amount exceeding the account’s transaction volume limit. |
You can test using any of the account numbers provided above. However, because Bacs Direct Debit payments take several days to process, use the test account numbers that operate on a three-minute delay to better simulate the behavior of live payments.
Note
By default, Stripe automatically sends emails to the customer when payment details are initially collected and each time a debit will be made on their account. These notifications aren’t sent in sandboxes.
Use the payment method for future payments Server-side
After you set up a PaymentMethod, you can accept future Bacs Direct Debit payments by creating and confirming a PaymentIntent.
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
