Bacs Direct Debit payments
Learn to accept Bacs Direct Debit payments.
Caution
Stripe automatically presents your customers payment method options by evaluating their currency, payment method restrictions, and other parameters. We recommend that you configure your payment methods from the Stripe Dashboard using the instructions in Accept a payment.
If you want to continue manually configuring the payment methods you present to your customers with Checkout, use this guide. Otherwise, update your integration to configure payment methods in the Dashboard.
Stripe users in the UK can use Checkout in payment mode to accept Bacs Direct Debit payments.
A Checkout Session represents the details of your customer’s intent to purchase. You create a Session when your customer wants to pay for something. After redirecting your customer to a Checkout Session, Stripe presents a payment form where your customer can complete their purchase. Once your customer has completed a purchase, they are redirected back to your site.
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 products and prices
To use Checkout, you first need to create a Product and a Price. Different physical goods or levels of service should be represented by products. Each product’s pricing is represented by one or more prices.
For example, you can create a T-shirt product that has two prices for different currencies, 20 GBP and 25 EUR. This allows you to change and add prices without needing to change the details of your underlying products. You can either create a product and price through the API or in the Dashboard.
If you determine your price at checkout (for example, the customer sets a donation amount) or you prefer not to create prices upfront, you can also create ad-hoc prices at Checkout Session creation using an existing product.
Caution
If you have an existing Checkout integration that doesn’t use Prices, the Checkout API has changed since we introduced Prices. You can use this migration guide to upgrade, or keep your existing integration.
Create a Checkout SessionClient-sideServer-side
Add a checkout button to your website that calls a server-side endpoint to create a Checkout Session.
<html> <head> <title>Checkout</title> </head> <body> <form action="/create-checkout-session" method="POST"> <button type="submit">Checkout</button> </form> </body> </html>
Create a Session with line_items. Line items represent a list of items the customer is purchasing.
When your customer successfully completes their payment, they are redirected to the success_
, a page on your website that informs the customer that their payment details have been successfully collected and their payment is being processed.
When your customer clicks on your logo in a Checkout Session without completing a payment, Checkout redirects them back to your website by navigating to the cancel_
. Typically, this is the page on your website that the customer viewed prior to redirecting to Checkout.
Checkout can accept a payment and save the payment method for future use. Payment methods saved this way can be used for future payments using a PaymentIntent. After creating the Checkout Session, redirect your customer to the URL returned in the response.
Note
The Bacs Direct Debit rules require that customers receive debit notification emails when payment details are initially collected and when their account is debitted. Stripe sends these emails for you by default.
Creating a Checkout Session returns a Session ID. Make the Session ID available on your success page by including the {CHECKOUT_
template variable in the success_
as in the above example.
Caution
Don’t rely on the redirect to the success_
alone for detecting payment initiation, as:
- Malicious users could directly access the
success_
without paying and gain access to your goods or services.url - Customers may not always reach the
success_
after a successful payment—they might close their browser tab before the redirect occurs.url
Handle post-payment eventsServer-side
When your customer completes a payment, Stripe redirects them to the URL that you specified in the success_
parameter. Typically, this is a page on your website that informs your customer that their payment was successful.
However, Bacs Direct Debit is a delayed notification payment method, which means that funds are not immediately available. A Bacs Direct Debit payment typically takes 3 business days to make the funds available. Because of this, you’ll want to delay order fulfilment until the funds are available. Once the payment succeeds, the underlying PaymentIntent status changes from processing
to succeeded
.
The following Checkout events are sent when the payment status changes:
Event Name | Description | Next steps |
---|---|---|
checkout.session.completed | The customer has successfully authorised the debit payment by submitting the Checkout form. | Wait for the payment to succeed or fail. |
checkout.session.async_payment_succeeded | The customer’s payment succeeded. | Fulfill the goods or services that the customer purchased. |
checkout.session.async_payment_failed | The customer’s payment was declined, or failed for some other reason. | Contact the customer via email and request that they place a new order. |
Your webhook code will need to handle all 3 of these Checkout events.
Each Checkout webhook payload includes the Checkout Session object, which contains information about the Customer and PaymentIntent.
The checkout.
webhook is sent to your server before your customer is redirected. Your webhook acknowledgement (any 2xx
status code) triggers the customer’s redirect to the success_
. If Stripe doesn’t receive successful acknowledgement within 10 seconds of a successful payment, your customer is automatically redirected to the success_
page.
On your success_
page, you’ll want to show a success message to your customer, and let them know that fulfilment of the order will take a few days as the Bacs Direct Debit payment method is not instant.
When accepting instant payments (such as credit cards) in addition to delayed notification payments, you’ll need to update your webhook endpoint to handle both kinds of payments when receiving a checkout.
event.
You can get information about the customer and payment by retrieving the Customer or PaymentIntent objects referenced by the customer
, payment_
properties in the webhook payload.
Testing webhooks locally
To test webhooks locally, you can use Stripe CLI. Once you have it installed, you can forward events to your server:
stripe listen --forward-to localhost:4242/webhook Ready! Your webhook signing secret is '{{WEBHOOK_SIGNING_SECRET}}' (^C to quit)
Learn more about setting up webhooks.
Test the integration
By this point you should have a basic Bacs Direct Debit integration that collects bank account details and accepts a payment.
There are several test bank account numbers you can use in test mode to make sure this integration is ready.
Sort code | Account number | Description |
---|---|---|
108800 | 00012345 | The payment succeeds and the PaymentIntent transitions from processing to succeeded . |
108800 | 90012345 | The payment succeeds after three minutes and the PaymentIntent transitions from processing to succeeded . |
108800 | 33333335 | The payment is accepted but then immediately fails with a debit_ failure code and the PaymentIntent transitions from processing to requires_ . The Mandate becomes inactive and the PaymentMethod can not be used again. |
108800 | 93333335 | The payment fails after three minutes with a debit_ failure code and the PaymentIntent transitions from processing to requires_ . The Mandate becomes inactive and the PaymentMethod can not be used again. |
108800 | 22222227 | The payment fails with an insufficient_ failure code and the PaymentIntent transitions from processing to requires_ . The Mandate remains active and the PaymentMethod can be used again. |
108800 | 92222227 | The payment fails after three minutes with an insufficient_ failure code and the PaymentIntent transitions from processing to requires_ . The Mandate remains active and the PaymentMethod can be used again. |
108800 | 55555559 | The payment succeeds after three minutes and the PaymentIntent transitions from processing to succeeded , but a dispute is immediately created. |
108800 | 00033333 | Payment Method 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 are not collected. |
108800 | 34343434 | The payment fails with a charge_ failure code due to the payment amount causing the account to exceed its weekly payment volume limit. |
108800 | 12121212 | The payment fails with a charge_ 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 test mode.
Payment failures
Payments can fail for a variety of reasons. The reason for a failure is available through charge.failure_code. You can only retry payments with certain failure codes. If you can’t retry a payment, we recommend contacting the customer and asking them to pay again using a different bank account or a different payment method.
Below is a list of failure codes we currently send for Bacs Direct Debit. We might add more at any time, so in developing and maintaining your code, don’t assume that only these types exist.
Failure code | Description | Retryable |
---|---|---|
account_ | The bank account has been closed. | No |
bank_ | The account has been transferred to a new Payment Service Provider (PSP). Check if you have been notified of the new PSP’s details. If not, you must collect a new mandate from the customer. | No |
debit_ | The customer has notified their bank that this payment was unauthorized or there is no mandate held by the paying bank. | No |
generic_ | This payment could not be processed. | Yes |
insufficient_ | The customer’s account has insufficient funds to cover this payment. | Yes |
invalid_ | The account number is not valid. This could mean it is not for a GBP account or that the account cannot process Direct Debit payments. | No |
To retry a payment, confirm the PaymentIntent again using the same PaymentMethod.
To ensure success, we recommend reaching out to the payer before retrying a payment.