Create account
Sign in
Home
Payments
Business operations
Financial services
Developer tools
Security
All products
Home
Payments
Business operations
Home
Payments
Business operations
Financial services
Developer tools
Support
Overview
Overview
Bank debits
ACH Direct Debit
Bacs Direct Debit
Accept a payment
Save bank details
BECS Direct Debit
SEPA Direct Debit
Bank redirects
Bank transfers
Buy now pay later
Vouchers
Wallets
Testing
HomePaymentsBank debitsBacs Direct Debit

Save Bacs Direct Debit bank details

Learn how to use Checkout to save payment method details for future Bacs Direct Debit payments.

You can use Checkout in setup mode 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

1 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:

Ruby Python PHP Java Node Go .NET
Terminal
# Available as a gem gem install stripe
# Available as a gem gem install stripe
Gemfile
# If you use bundler, you can add this line to your Gemfile gem 'stripe'
# If you use bundler, you can add this line to your Gemfile gem 'stripe'
Terminal
# Install through pip pip install --upgrade stripe
# Install through pip pip install --upgrade stripe
PyPI
# Or find the Stripe package on http://pypi.python.org/pypi/stripe/
# Or find the Stripe package on http://pypi.python.org/pypi/stripe/
requirements.txt
# Find the version you want to pin: # https://github.com/stripe/stripe-python/blob/master/CHANGELOG.md # Specify that version in your requirements.txt file stripe>=2.48.0,<3.0
# Find the version you want to pin: # https://github.com/stripe/stripe-python/blob/master/CHANGELOG.md # Specify that version in your requirements.txt file stripe>=2.48.0,<3.0
Terminal
# Install the PHP library via Composer composer require stripe/stripe-php
# Install the PHP library via Composer composer require stripe/stripe-php
Source
# Or download the source directly: https://github.com/stripe/stripe-php/releases
# Or download the source directly: https://github.com/stripe/stripe-php/releases
build.gradle
/* For Gradle, add the following dependency to your build.gradle and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest */ implementation "com.stripe:stripe-java:{VERSION}"
/* For Gradle, add the following dependency to your build.gradle and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest */ implementation "com.stripe:stripe-java:{VERSION}"
pom.xml
<!-- For Maven, add the following dependency to your POM and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest --> <dependency> <groupId>com.stripe</groupId> <artifactId>stripe-java</artifactId> <version>{VERSION}</version> </dependency>
<!-- For Maven, add the following dependency to your POM and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest --> <dependency> <groupId>com.stripe</groupId> <artifactId>stripe-java</artifactId> <version>{VERSION}</version> </dependency>
Other environments
# For other environments, manually install the following JARs: # - The Stripe JAR from https://github.com/stripe/stripe-java/releases/latest # - Google Gson from https://github.com/google/gson
# For other environments, manually install the following JARs: # - The Stripe JAR from https://github.com/stripe/stripe-java/releases/latest # - Google Gson from https://github.com/google/gson
Terminal
# Install via npm npm install --save stripe
# Install via npm npm install --save stripe
Terminal
# Make sure your project is using Go Modules go mod init # Install stripe-go go get -u github.com/stripe/stripe-go/v71
# Make sure your project is using Go Modules go mod init # Install stripe-go go get -u github.com/stripe/stripe-go/v71
app.go
// Then import the package import ( "github.com/stripe/stripe-go/v71" )
// Then import the package import ( "github.com/stripe/stripe-go/v71" )
Terminal
# Install via dotnet dotnet add package Stripe.net dotnet restore
# Install via dotnet dotnet add package Stripe.net dotnet restore
Terminal
# Or install via NuGet PM> Install-Package Stripe.net
# Or install via NuGet PM> Install-Package Stripe.net

2 Create or retrieve a Customer Server-side

To reuse a Bacs Direct Debit payment method for future payments, it must be attached to a Customer.

You should create a Customer object when your customer creates an account with your business. Associating the ID of the Customer object with your own internal representation of a customer will enable you to retrieve and use the stored payment method details later. If your customer is making a payment as a guest, you can still create a Customer object before payment and associate it with your internal representation of the customer’s account later.

Create a new customer or retrieve an existing customer to associate with this payment. Include the following code on your server to create a new customer.

curl Ruby Python PHP Java Node Go .NET
curl https://api.stripe.com/v1/customers \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -X POST
curl https://api.stripe.com/v1/customers \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -X POST
server.rb
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' customer = Stripe::Customer.create
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' customer = Stripe::Customer.create
server.py
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' customer = stripe.Customer.create()
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' customer = stripe.Customer.create()
index.php
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $customer = \Stripe\Customer::create();
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $customer = \Stripe\Customer::create();
Server.java
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; CustomerCreateParams params = CustomerCreateParams.builder() .build(); Customer customer = Customer.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; CustomerCreateParams params = CustomerCreateParams.builder() .build(); Customer customer = Customer.create(params);
server.js
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const customer = await stripe.customers.create();
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const customer = await stripe.customers.create();
server.go
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CustomerParams{} c, _ := customer.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CustomerParams{} c, _ := customer.New(params)
Controller.cs
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new CustomerCreateOptions{}; var service = new CustomerService(); var customer = service.Create(options);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new CustomerCreateOptions{}; var service = new CustomerService(); var customer = service.Create(options);

3 Create a Session for collecting payment details 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). You can collect all of this using a setup mode Session in Stripe Checkout.

Stripe Checkout provides a hosted payment page that is compliant with Bacs Direct Debit rules. If you would like to design your own Bacs Direct Debit form, please contact our sales team.

To create a setup mode Session, use the mode parameter with a value of setup when creating the Session.

After your customer provides their payment method details, they are redirected to the success_url, a page on your website that informs your customer their payment method was saved successfully.

When your customer clicks on your logo in a Checkout Session without providing their payment method details, Checkout redirects them back to your website by navigating to the cancel_url. Typically, this is the page on your website that the customer viewed prior to redirecting to Checkout.

See the Checkout Session API reference for a complete list of parameters that you can use for Session creation.

curl Ruby Python PHP Java Node Go .NET
curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=bacs_debit \ -d mode=setup \ -d customer="{{CUSTOMER_ID}}" \ -d success_url="https://example.com/success?session_id={CHECKOUT_SESSION_ID}" \ -d cancel_url="https://example.com/cancel"
curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=bacs_debit \ -d mode=setup \ -d customer="{{CUSTOMER_ID}}" \ -d success_url="https://example.com/success?session_id={CHECKOUT_SESSION_ID}" \ -d cancel_url="https://example.com/cancel"
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create( payment_method_types: ['bacs_debit'], mode: 'setup', customer: customer.id, success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url: 'https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create( payment_method_types: ['bacs_debit'], mode: 'setup', customer: customer.id, success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url: 'https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( payment_method_types=['bacs_debit'], mode='setup', customer=customer.id, success_url='https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url='https://example.com/cancel', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( payment_method_types=['bacs_debit'], mode='setup', customer=customer.id, success_url='https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url='https://example.com/cancel', )
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['bacs_debit'], 'mode' => 'setup', 'customer' => $customer->id, 'success_url' => 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['bacs_debit'], 'mode' => 'setup', 'customer' => $customer->id, 'success_url' => 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; Map<String, Object> params = new HashMap<String, Object>(); ArrayList<String> paymentMethodTypes = new ArrayList<>(); paymentMethodTypes.add("bacs_debit"); params.put("payment_method_types", paymentMethodTypes); params.put("mode", "setup"); params.put("customer", customer.getId()); params.put("success_url", "https://example.com/success?session_id={CHECKOUT_SESSION_ID}"); params.put("cancel_url", "https://example.com/cancel"); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; Map<String, Object> params = new HashMap<String, Object>(); ArrayList<String> paymentMethodTypes = new ArrayList<>(); paymentMethodTypes.add("bacs_debit"); params.put("payment_method_types", paymentMethodTypes); params.put("mode", "setup"); params.put("customer", customer.getId()); params.put("success_url", "https://example.com/success?session_id={CHECKOUT_SESSION_ID}"); params.put("cancel_url", "https://example.com/cancel"); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ payment_method_types: ['bacs_debit'], mode: 'setup', customer: customer.id, success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ payment_method_types: ['bacs_debit'], mode: 'setup', customer: customer.id, success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "bacs_debit", }), Mode: stripe.String(string(stripe.CheckoutSessionModeSetup)), Customer: stripe.String(c.ID), SuccessURL: stripe.String("https://example.com/success?session_id={CHECKOUT_SESSION_ID}"), CancelURL: stripe.String("https://example.com/cancel"), } s, err := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "bacs_debit", }), Mode: stripe.String(string(stripe.CheckoutSessionModeSetup)), Customer: stripe.String(c.ID), SuccessURL: stripe.String("https://example.com/success?session_id={CHECKOUT_SESSION_ID}"), CancelURL: stripe.String("https://example.com/cancel"), } s, err := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "bacs_debit", }, Mode = "setup", Customer = customer.Id, SuccessUrl = "https://example.com/success?session_id={CHECKOUT_SESSION_ID}", CancelUrl = "https://example.com/cancel", }; var sessionService = new SessionService(); var session = sessionService.Create(options);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "bacs_debit", }, Mode = "setup", Customer = customer.Id, SuccessUrl = "https://example.com/success?session_id={CHECKOUT_SESSION_ID}", CancelUrl = "https://example.com/cancel", }; var sessionService = new SessionService(); var session = sessionService.Create(options);

Make the Session ID available on your success page by including the {CHECKOUT_SESSION_ID} template variable in the success_url as in the above example.

Don’t rely on the redirect to the success_url alone for fulfilling purchases, as:

  • Malicious users could directly access the success_url without paying and gain access to your goods or services.
  • Customers may not always reach the success_url after a successful payment. It is possible they close their browser tab before the redirect occurs.

4 Redirect the customer to collect their payment details Client-side

To use Checkout on your website, you must add a snippet of code that includes the id field from the session that you created in the previous step.

Checkout relies on Stripe.js. To get started, include the following script tag on your website—always load it directly from https://js.stripe.com:

HTML ES Module
<script src="https://js.stripe.com/v3/"></script>
<script src="https://js.stripe.com/v3/"></script>
npm install @stripe/stripe-js
npm install @stripe/stripe-js

Next, create an instance of the Stripe object by providing your publishable API key as the first parameter:

JavaScript JavaScript (ESNext)
var stripe = Stripe('pk_test_TYooMQauvdEDq54NiTphI7jx');
var stripe = Stripe('pk_test_TYooMQauvdEDq54NiTphI7jx');
import {loadStripe} from '@stripe/stripe-js'; const stripe = await loadStripe('pk_test_TYooMQauvdEDq54NiTphI7jx');
import {loadStripe} from '@stripe/stripe-js'; const stripe = await loadStripe('pk_test_TYooMQauvdEDq54NiTphI7jx');

When your customer is ready to save or update their payment method, call redirectToCheckout to begin the setup process. This is where you provide the id from session creation as a parameter to Checkout.

JavaScript JavaScript (ESNext)
var checkoutButton = document.getElementById('checkout-button'); checkoutButton.addEventListener('click', function() { stripe.redirectToCheckout({ // Make the id field from the Checkout Session creation API response // available to this file, so you can provide it as argument here // instead of the {{CHECKOUT_SESSION_ID}} placeholder. sessionId: '{{CHECKOUT_SESSION_ID}}' }).then(function (result) { // If `redirectToCheckout` fails due to a browser or network // error, display the localized error message to your customer // using `result.error.message`. }); });
var checkoutButton = document.getElementById('checkout-button'); checkoutButton.addEventListener('click', function() { stripe.redirectToCheckout({ // Make the id field from the Checkout Session creation API response // available to this file, so you can provide it as argument here // instead of the {{CHECKOUT_SESSION_ID}} placeholder. sessionId: '{{CHECKOUT_SESSION_ID}}' }).then(function (result) { // If `redirectToCheckout` fails due to a browser or network // error, display the localized error message to your customer // using `result.error.message`. }); });
const checkoutButton = document.getElementById('checkout-button'); checkoutButton.addEventListener('click', () => { stripe.redirectToCheckout({ // Make the id field from the Checkout Session creation API response // available to this file, so you can provide it as argument here // instead of the {{CHECKOUT_SESSION_ID}} placeholder. sessionId: '{{CHECKOUT_SESSION_ID}}' }) // If `redirectToCheckout` fails due to a browser or network // error, display the localized error message to your customer // using `error.message`. });
const checkoutButton = document.getElementById('checkout-button'); checkoutButton.addEventListener('click', () => { stripe.redirectToCheckout({ // Make the id field from the Checkout Session creation API response // available to this file, so you can provide it as argument here // instead of the {{CHECKOUT_SESSION_ID}} placeholder. sessionId: '{{CHECKOUT_SESSION_ID}}' }) // If `redirectToCheckout` fails due to a browser or network // error, display the localized error message to your customer // using `error.message`. });

This code is typically invoked from an event handler that triggers in response to an action taken by your customer, such as clicking on a setup button.

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.

Test bank account numbers and emails can be found in the Test the integration section.

5 Retrieve the PaymentMethod Server-side

After a customer submits their payment details, retrieve the PaymentMethod object that was created. A PaymentMethod is used to store the customer’s bank account information for future payments. Retrieving the PaymentMethod can be done synchronously using the success_url or asynchronously using webhooks.

The right choice depends on your tolerance for dropoff, as customers may not always reach the success_url after a successful payment. It’s possible for them close their browser tab before the redirect occurs. Handling webhooks prevents your integration from being susceptible to this form of dropoff.

Webhooks Success URL

Handle checkout.session.completed webhooks, which contain a Session object. Learn more about setting up webhooks.

Example checkout.session.completed payload:

{ "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, "cancel_url": "https://example.com/cancel", "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" }
{ "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, "cancel_url": "https://example.com/cancel", "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 during the Checkout Session. A SetupIntent is an object used to set up the customer’s bank account information for future payments.

Retrieve the SetupIntent object with the ID.

curl Ruby Python PHP Java Node Go .NET
curl https://api.stripe.com/v1/setup_intents/seti_1EzVO3HssDVaQm2PJjXHmLlM \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc:
curl https://api.stripe.com/v1/setup_intents/seti_1EzVO3HssDVaQm2PJjXHmLlM \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc:
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' intent = Stripe::SetupIntent.retrieve('seti_1EzVO3HssDVaQm2PJjXHmLlM')
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' intent = Stripe::SetupIntent.retrieve('seti_1EzVO3HssDVaQm2PJjXHmLlM')
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' intent = stripe.SetupIntent.retrieve('seti_1EzVO3HssDVaQm2PJjXHmLlM')
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' intent = stripe.SetupIntent.retrieve('seti_1EzVO3HssDVaQm2PJjXHmLlM')
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $intent = \Stripe\SetupIntent::retrieve('seti_1EzVO3HssDVaQm2PJjXHmLlM');
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $intent = \Stripe\SetupIntent::retrieve('seti_1EzVO3HssDVaQm2PJjXHmLlM');
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SetupIntent intent = Stripe.SetupIntent.retrieve("seti_1EzVO3HssDVaQm2PJjXHmLlM");
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SetupIntent intent = Stripe.SetupIntent.retrieve("seti_1EzVO3HssDVaQm2PJjXHmLlM");
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const intent = await stripe.setupIntents.retrieve('seti_1EzVO3HssDVaQm2PJjXHmLlM');
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const intent = await stripe.setupIntents.retrieve('seti_1EzVO3HssDVaQm2PJjXHmLlM');
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" intent, _ := setupintent.Get("seti_1EzVO3HssDVaQm2PJjXHmLlM", nil)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" intent, _ := setupintent.Get("seti_1EzVO3HssDVaQm2PJjXHmLlM", nil)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var service = new SetupIntentService(); var intent = service.Get("seti_1EzVO3HssDVaQm2PJjXHmLlM");
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var service = new SetupIntentService(); var intent = service.Get("seti_1EzVO3HssDVaQm2PJjXHmLlM");

Obtain the session_id from the URL when a user redirects back to your site.

To ensure the session_id is available from the URL, include the session_id={CHECKOUT_SESSION_ID} template variable in the success_url when creating the Session.

Retrieve the Session object.

curl Ruby Python PHP Java Node Go .NET
curl https://api.stripe.com/v1/checkout/sessions/{{SESSION_ID}} \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "expand[]"=setup_intent
curl https://api.stripe.com/v1/checkout/sessions/{{SESSION_ID}} \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "expand[]"=setup_intent
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.retrieve({ id: '{{SESSION_ID}}', expand: ['setup_intent'], }) intent = session.setup_intent
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.retrieve({ id: '{{SESSION_ID}}', expand: ['setup_intent'], }) intent = session.setup_intent
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.retrieve( id='{{SESSION_ID}}', expand=['setup_intent'], ) intent = session.setup_intent
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.retrieve( id='{{SESSION_ID}}', expand=['setup_intent'], ) intent = session.setup_intent
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::retrieve([ 'id' => '{{SESSION_ID}}', 'expand' => ['setup_intent'], ]); $intent = $session->setup_intent;
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::retrieve([ 'id' => '{{SESSION_ID}}', 'expand' => ['setup_intent'], ]); $intent = $session->setup_intent;
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionRetrieveParams params = SessionRetrieveParams.builder() .addExpand("setup_intent") .build(); Session session = Stripe.Session.retrieve( "{{SESSION_ID}}", params, null ); SetupIntent intent = session.getSetupIntentObject();
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionRetrieveParams params = SessionRetrieveParams.builder() .addExpand("setup_intent") .build(); Session session = Stripe.Session.retrieve( "{{SESSION_ID}}", params, null ); SetupIntent intent = session.getSetupIntentObject();
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.retrieve( '{{SESSION_ID}}', { expand: ['setup_intent'], } ); const intent = session.setup_intent;
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.retrieve( '{{SESSION_ID}}', { expand: ['setup_intent'], } ); const intent = session.setup_intent;
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" checkoutSessionParams := &stripe.CheckoutSessionParams{} checkoutSessionParams.AddExpand("setup_intent") sess, _ := session.Get("{{SESSION_ID}}", checkoutSessionParams) intent := sess.SetupIntent;
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" checkoutSessionParams := &stripe.CheckoutSessionParams{} checkoutSessionParams.AddExpand("setup_intent") sess, _ := session.Get("{{SESSION_ID}}", checkoutSessionParams) intent := sess.SetupIntent;
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionGetOptions(); options.AddExpand("setup_intent"); var sessionService = new SessionService(); var session = sessionService.Get("{{SESSION_ID}}", options); var intent = session.SetupIntent;
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionGetOptions(); options.AddExpand("setup_intent"); var sessionService = new SessionService(); var session = sessionService.Get("{{SESSION_ID}}", options); var intent = session.SetupIntent;

Note the SetupIntent created during the Checkout Session. A SetupIntent is an object used to set up the customer’s bank account information for future payments.

6 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 may be the result of the customer cancelling or amending the mandate or because it has been rejected by the bank. If a mandate’s status is updated to inactive, payment information must be recollected from the customer.

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, otherwise - no.
payment_method.automatically_updated Occurs whenever customer’s bank account details change Yes

You can see the events in your dashboard, but you should still set up a webhook endpoint.

7 Test the integration

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
10-88-00 00012345 The payment succeeds and the PaymentIntent transitions from processing to succeeded.
10-88-00 90012345 The payment succeeds after three minutes and the PaymentIntent transitions from processing to succeeded.
10-88-00 33333335 The payment 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 not be used again.
10-88-00 93333335 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 not be used again.
10-88-00 22222227 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.
10-88-00 92222227 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.
10-88-00 00033333 Payment detail collection succeeds, but the Mandate transitions immediately to inactive.
10-88-00 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.

You can test using any of the account numbers provided above. However, as Bacs Direct Debit payments take several days to process, you should use the test account numbers that operate on a three-minute delay to better simulate the behavior of live payments.

Emails will not be sent to the payer's email address when testing the integration.

Optional Use the PaymentMethod 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.

curl Ruby Python PHP Java Node Go .NET
curl https://api.stripe.com/v1/payment_intents \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=bacs_debit \ -d payment_method="{{PAYMENT_METHOD_ID}}" \ -d customer="{{CUSTOMER_ID}}" \ -d confirm=true \ -d amount=100 \ -d currency=gbp
curl https://api.stripe.com/v1/payment_intents \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=bacs_debit \ -d payment_method="{{PAYMENT_METHOD_ID}}" \ -d customer="{{CUSTOMER_ID}}" \ -d confirm=true \ -d amount=100 \ -d currency=gbp
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' intent = Stripe::PaymentIntent.create({ payment_method_types: ['bacs_debit'], payment_method: intent.payment_method, customer: intent.customer, confirm: true, amount: 100, currency: 'gbp', })
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' intent = Stripe::PaymentIntent.create({ payment_method_types: ['bacs_debit'], payment_method: intent.payment_method, customer: intent.customer, confirm: true, amount: 100, currency: 'gbp', })
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' intent = stripe.PaymentIntent.create( payment_method_types=['bacs_debit'], payment_method=intent.payment_method, customer=intent.customer, confirm=True, amount=100, currency='gbp', )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' intent = stripe.PaymentIntent.create( payment_method_types=['bacs_debit'], payment_method=intent.payment_method, customer=intent.customer, confirm=True, amount=100, currency='gbp', )
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $intent = \Stripe\PaymentIntent::create([ 'payment_method_types' => ['bacs_debit'], 'payment_method' => $intent->payment_method, 'customer' => $intent->customer, 'confirm' => true, 'amount' => 100, 'currency' => 'gbp', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $intent = \Stripe\PaymentIntent::create([ 'payment_method_types' => ['bacs_debit'], 'payment_method' => $intent->payment_method, 'customer' => $intent->customer, 'confirm' => true, 'amount' => 100, 'currency' => 'gbp', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; Map<String, Object> intentParams = new HashMap<String, Object>(); ArrayList paymentMethodTypes = new ArrayList(); paymentMethodTypes.add("bacs_debit"); intentParams.put("payment_method_types", paymentMethodTypes); intentParams.put("payment_method", intent.getPaymentMethod()); intentParams.put("customer", intent.getCustomer()); intentParams.put("confirm", true); intentParams.put("amount", 100); intentParams.put("currency", "gbp"); PaymentIntent intent = PaymentIntent.create(intentParams);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; Map<String, Object> intentParams = new HashMap<String, Object>(); ArrayList paymentMethodTypes = new ArrayList(); paymentMethodTypes.add("bacs_debit"); intentParams.put("payment_method_types", paymentMethodTypes); intentParams.put("payment_method", intent.getPaymentMethod()); intentParams.put("customer", intent.getCustomer()); intentParams.put("confirm", true); intentParams.put("amount", 100); intentParams.put("currency", "gbp"); PaymentIntent intent = PaymentIntent.create(intentParams);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const intent = await stripe.paymentIntents.create({ payment_method_types: ['bacs_debit'], payment_method: intent.payment_method, customer: intent.customer, confirm: true, amount: 100, currency: 'gbp', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const intent = await stripe.paymentIntents.create({ payment_method_types: ['bacs_debit'], payment_method: intent.payment_method, customer: intent.customer, confirm: true, amount: 100, currency: 'gbp', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.PaymentIntentParams{ PaymentMethodTypes: stripe.StringSlice([]string{"bacs_debit"}), PaymentMethod: stripe.String(intent.PaymentMethod.ID), Customer: stripe.String(intent.Customer.ID), Confirm: stripe.Bool(true), Amount: stripe.Int64(100), Currency: stripe.String(string(stripe.CurrencyGBP)), } pi, _ := paymentintent.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.PaymentIntentParams{ PaymentMethodTypes: stripe.StringSlice([]string{"bacs_debit"}), PaymentMethod: stripe.String(intent.PaymentMethod.ID), Customer: stripe.String(intent.Customer.ID), Confirm: stripe.Bool(true), Amount: stripe.Int64(100), Currency: stripe.String(string(stripe.CurrencyGBP)), } pi, _ := paymentintent.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new PaymentIntentCreateOptions { PaymentMethodTypes = new List<string> { "bacs_debit" }, PaymentMethod = intent.PaymentMethodId, Customer = intent.CustomerId, Confirm = true, Amount = 100, Currency = "gbp", }; var service = new PaymentIntentService(); var intent = service.Create(options);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new PaymentIntentCreateOptions { PaymentMethodTypes = new List<string> { "bacs_debit" }, PaymentMethod = intent.PaymentMethodId, Customer = intent.CustomerId, Confirm = true, Amount = 100, Currency = "gbp", }; var service = new PaymentIntentService(); var intent = service.Create(options);
Was this page helpful?
Questions? Contact us.
Developer tutorials on YouTube.
You can unsubscribe at any time. Read our privacy policy.
On this page
Set up Stripe
Create or retrieve a Customer
Create a Session for collecting payment details
Redirect the customer to collect their payment details
Retrieve the PaymentMethod
Handle post-setup events
Test the integration
Use the PaymentMethod for future payments