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
BECS Direct Debit
SEPA Direct Debit
Accept a payment
Save bank details
Bank redirects
Bank transfers
Buy now pay later
Vouchers
Wallets
Testing
HomePaymentsBank debitsSEPA Direct Debit

Save SEPA Direct Debit details for future payments

Learn how to save payment method details for future SEPA Direct Debit payments.

Prebuilt Checkout page Custom form

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

SEPA Direct Debit is a delayed notification payment method, which means that funds are not immediately available after payment. A payment typically takes 5 business days to arrive in your account.

1 Create or retrieve a Customer Server-side

To reuse a SEPA 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);

2 Set up future payments

This guide builds on the foundational set up future payments Checkout integration.

This guide walks you through enabling SEPA Direct Debit and shows the differences between setting up future payments for cards and using SEPA Direct Debit.

Enable SEPA Direct Debit as a payment method

When creating a new Checkout Session, you need to add sepa_debit to the list of payment_method_types.

Ruby Python PHP Java Node Go .NET
Stripe::Checkout::Session.create({ mode: 'setup', payment_method_types: ['card'], payment_method_types: ['sepa_debit'], # or you can take multiple payment methods with # payment_method_types: ['card', 'sepa_debit', ...] customer: customer.id, success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', })
Stripe::Checkout::Session.create({ mode: 'setup', payment_method_types: ['card'], payment_method_types: ['sepa_debit'], # or you can take multiple payment methods with # payment_method_types: ['card', 'sepa_debit', ...] customer: customer.id, success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', })
stripe.checkout.Session.create( payment_method_types=['card'], payment_method_types=['sepa_debit'], # or you can take multiple payment methods with # payment_method_types=['card', 'sepa_debit', ...] mode='setup', customer=customer.id, success_url='https://example.com/success', cancel_url='https://example.com/cancel', )
stripe.checkout.Session.create( payment_method_types=['card'], payment_method_types=['sepa_debit'], # or you can take multiple payment methods with # payment_method_types=['card', 'sepa_debit', ...] mode='setup', customer=customer.id, success_url='https://example.com/success', cancel_url='https://example.com/cancel', )
$session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'payment_method_types' => ['sepa_debit'], // or you can take multiple payment methods with // 'payment_method_types' => ['card', 'sepa_debit', ...] 'mode' => 'setup', 'customer' => $customer->id, 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]);
$session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'payment_method_types' => ['sepa_debit'], // or you can take multiple payment methods with // 'payment_method_types' => ['card', 'sepa_debit', ...] 'mode' => 'setup', 'customer' => $customer->id, 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]);
SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addPaymentMethodType(SessionCreateParams.PaymentMethodType.SEPA_DEBIT) .setMode(SessionCreateParams.Mode.SETUP) .setCustomer(customer.getId()) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addPaymentMethodType(SessionCreateParams.PaymentMethodType.SEPA_DEBIT) .setMode(SessionCreateParams.Mode.SETUP) .setCustomer(customer.getId()) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
const session = await stripe.checkout.sessions.create({ payment_method_types: ['card'], payment_method_types: ['sepa_debit'], // or you can take multiple payment methods with // payment_method_types: ['card', 'sepa_debit', ...] mode: 'setup', customer: customer.id, success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', });
const session = await stripe.checkout.sessions.create({ payment_method_types: ['card'], payment_method_types: ['sepa_debit'], // or you can take multiple payment methods with // payment_method_types: ['card', 'sepa_debit', ...] mode: 'setup', customer: customer.id, success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', });
params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", "sepa_debit", }), Mode: stripe.String(string(stripe.CheckoutSessionModeSetup)), Customer: stripe.String(c.ID), SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } s, _ := session.New(params)
params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", "sepa_debit", }), Mode: stripe.String(string(stripe.CheckoutSessionModeSetup)), Customer: stripe.String(c.ID), SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } s, _ := session.New(params)
var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", "sepa_debit", }, Mode = "setup", Customer = customer.Id, SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); var session = service.Create(options);
var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", "sepa_debit", }, Mode = "setup", Customer = customer.Id, SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); var session = service.Create(options);

3 Test your integration

You can test your integration using the test account numbers below.

Test account numbers
Account Number Description
AT611904300234573201 The payment method details are successfully collected.
Account Number Description
BE62510007547061 The payment method details are successfully collected.
Account Number Description
DK5000400440116243 The payment method details are successfully collected.
Account Number Description
EE382200221020145689 The payment method details are successfully collected.
Account Number Description
FI2112345600000785 The payment method details are successfully collected.
Account Number Description
FR1420041010050500013M02606 The payment method details are successfully collected.
Account Number Description
DE89370400440532013000 The payment method details are successfully collected.
Account Number Description
IE29AIBK93115212345678 The payment method details are successfully collected.
Account Number Description
IT40S0542811101000000123456 The payment method details are successfully collected.
Account Number Description
LT121000011101001000 The payment method details are successfully collected.
Account Number Description
LU280019400644750000 The payment method details are successfully collected.
Account Number Description
NL39RABO0300065264 The payment method details are successfully collected.
Account Number Description
NO9386011117947 The payment method details are successfully collected.
Account Number Description
PT50000201231234567890154 The payment method details are successfully collected.
Account Number Description
ES0700120345030000067890 The payment method details are successfully collected.
Account Number Description
SE3550000000054910000003 The payment method details are successfully collected.
Account Number Description
GB82WEST12345698765432 The payment method details are successfully collected.

When processing SEPA Direct Debit payments using the Stripe Creditor ID, we recommend you use the Prebuilt Checkout page to save SEPA Direct Debit details for future use.

You can use the Setup Intents API to collect payment method 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 SEPA Direct Debit account 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 hasn’t created an account, you can still create a Customer object now 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 these payment details. 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 SetupIntent Server-side

A SetupIntent is an object that represents your intent and tracks the steps to set up your customer’s payment method for future payments. For SEPA Direct Debit, this includes collecting a mandate from the customer and checking the validity of the IBAN.

Create a SetupIntent on your server with payment_method_types set to sepa_debit and specify the Customer’s id.:

curl Ruby Python PHP Java Node Go .NET
curl https://api.stripe.com/v1/setup_intents \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=sepa_debit \ -d customer="{{CUSTOMER_ID}}"
curl https://api.stripe.com/v1/setup_intents \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=sepa_debit \ -d customer="{{CUSTOMER_ID}}"
server.rb
require 'sinatra' require 'json' require 'stripe' # 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' get '/wallet' do setup_intent = Stripe::SetupIntent.create({ payment_method_types: ['sepa_debit'], customer: customer['id'], }) client_secret = setup_intent['client_secret'] # Pass the client secret to the client end
require 'sinatra' require 'json' require 'stripe' # 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' get '/wallet' do setup_intent = Stripe::SetupIntent.create({ payment_method_types: ['sepa_debit'], customer: customer['id'], }) client_secret = setup_intent['client_secret'] # Pass the client secret to the client end
server.py
import stripe import json from flask import request, render_template app = Flask(__name__, static_folder=".", static_url_path="", template_folder=".") # 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' @app.route('/wallet') def wallet(): setup_intent = stripe.SetupIntent.create( payment_method_types=['sepa_debit'], customer=customer['id'] ) client_secret = setup_intent.client_secret # Pass the client secret to the client if __name__ == '__main__': app.run()
import stripe import json from flask import request, render_template app = Flask(__name__, static_folder=".", static_url_path="", template_folder=".") # 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' @app.route('/wallet') def wallet(): setup_intent = stripe.SetupIntent.create( payment_method_types=['sepa_debit'], customer=customer['id'] ) client_secret = setup_intent.client_secret # Pass the client secret to the client if __name__ == '__main__': app.run()
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'); // vendor using composer require_once('vendor/autoload.php'); $setup_intent = \Stripe\SetupIntent::create([ 'payment_method_types' => ['sepa_debit'], 'customer' => $customer->id, ]); $client_secret = $setup_intent->client_secret // Pass the client secret to the client
// 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'); // vendor using composer require_once('vendor/autoload.php'); $setup_intent = \Stripe\SetupIntent::create([ 'payment_method_types' => ['sepa_debit'], 'customer' => $customer->id, ]); $client_secret = $setup_intent->client_secret // Pass the client secret to the client
Server.java
import com.stripe.Stripe; import com.stripe.model.SetupIntent; import com.stripe.params.SetupIntentCreateParams; public class StripeJavaQuickStart { public static void main(String[] args) { // 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"; SetupIntentCreateParams params = SetupIntentCreateParams.builder() .addPaymentMethodType("sepa_debit") .setCustomer(cistomer.getId()) .build(); SetupIntent setupIntent = SetupIntent.create(params); String clientSecret = setupIntent.getClientSecret(); // Pass the client secret to the client } }
import com.stripe.Stripe; import com.stripe.model.SetupIntent; import com.stripe.params.SetupIntentCreateParams; public class StripeJavaQuickStart { public static void main(String[] args) { // 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"; SetupIntentCreateParams params = SetupIntentCreateParams.builder() .addPaymentMethodType("sepa_debit") .setCustomer(cistomer.getId()) .build(); SetupIntent setupIntent = SetupIntent.create(params); String clientSecret = setupIntent.getClientSecret(); // Pass the client secret to the client } }
server.js
// Using Express const express = require('express'); const app = express(); app.use(express.json()); const { resolve } = require("path"); // 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 setupIntent = await stripe.setupIntents.create({ payment_method_types: ['sepa_debit'], customer: customer.id, }); const clientSecret = setupIntent.client_secret; // Pass the client secret to the client
// Using Express const express = require('express'); const app = express(); app.use(express.json()); const { resolve } = require("path"); // 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 setupIntent = await stripe.setupIntents.create({ payment_method_types: ['sepa_debit'], customer: customer.id, }); const clientSecret = setupIntent.client_secret; // Pass the client secret to the client
server.go
package main import ( "encoding/json" "log" "net/http" "github.com/stripe/stripe-go/v71" "github.com/stripe/stripe-go/v71/setupintent" ) func main() { // 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.SetupIntentParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "sepa_debit", }), Customer: stripe.String(customer.ID), } si, _ := setupintent.New(params) clientSecret := si.ClientSecret // Pass the client secret to the client }
package main import ( "encoding/json" "log" "net/http" "github.com/stripe/stripe-go/v71" "github.com/stripe/stripe-go/v71/setupintent" ) func main() { // 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.SetupIntentParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "sepa_debit", }), Customer: stripe.String(customer.ID), } si, _ := setupintent.New(params) clientSecret := si.ClientSecret // Pass the client secret to the client }
Controllers.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"; using System; using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; using Stripe; namespace StripeExampleApi.Controllers { [Route("/wallet")] public class WalletController : Controller { public IActionResult Index() { var options = new SetupIntentCreateOptions { PaymentMethodTypes = new List<string> { "sepa_debit", }, Customer = "{{CUSTOMER_ID}}", }; var service = new SetupIntentService(); var setupIntent = service.Create(options); var clientSecret = setupIntent.ClientSecret; // Pass the client secret to the client } } }
// 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"; using System; using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; using Stripe; namespace StripeExampleApi.Controllers { [Route("/wallet")] public class WalletController : Controller { public IActionResult Index() { var options = new SetupIntentCreateOptions { PaymentMethodTypes = new List<string> { "sepa_debit", }, Customer = "{{CUSTOMER_ID}}", }; var service = new SetupIntentService(); var setupIntent = service.Create(options); var clientSecret = setupIntent.ClientSecret; // Pass the client secret to the client } } }

4 Collect payment method details and mandate acknowledgment Client-side

You’re ready to collect payment information on the client with Stripe Elements. Elements is a set of prebuilt UI components for collecting payment details.

A Stripe Element contains an iframe that securely sends the payment information to Stripe over an HTTPS connection. The checkout page address must also start with https:// rather than http:// for your integration to work.

You can test your integration without using HTTPS. Enable it when you’re ready to accept live payments.

Set up Stripe Elements

HTML + JS React

Stripe Elements is automatically available as a feature of Stripe.js. Include the Stripe.js script on your payment page by adding it to the head of your HTML file. Always load Stripe.js directly from js.stripe.com to remain PCI compliant. Do not include the script in a bundle or host a copy of it yourself.

payment_setup.html
<head> <title>Submit Payment</title> <script src="https://js.stripe.com/v3/"></script> </head>
<head> <title>Submit Payment</title> <script src="https://js.stripe.com/v3/"></script> </head>

Create an instance of Elements with the following JavaScript on your payment page:

JavaScript JavaScript (ESNext)
var stripe = Stripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); var elements = stripe.elements();
var stripe = Stripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); var elements = stripe.elements();
const stripe = Stripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); const elements = stripe.elements();
const stripe = Stripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); const elements = stripe.elements();

Add and configure an IBAN Element

Elements needs a place to live in your payment form. Create empty DOM nodes (container) with unique IDs in your payment form. Additionally, your customer must read and accept the SEPA Direct Debit mandate.

Display the following standard authorization text for your customer to implicitly sign this mandate. Replace Rocketship Inc with your company name.

By providing your payment information and confirming this payment, you authorise (A) Rocketship Inc and Stripe, our payment service provider, to send instructions to your bank to debit your account and (B) your bank to debit your account in accordance with those instructions. As part of your rights, you are entitled to a refund from your bank under the terms and conditions of your agreement with your bank. A refund must be claimed within 8 weeks starting from the date on which your account was debited. Your rights are explained in a statement that you can obtain from your bank. You agree to receive notifications for future debits up to 2 days before they occur.

The details of the accepted mandate are generated when setting up a payment method. Because the customer has implicitly signed the mandate when accepting the terms suggested above, you must communicate the terms on the form or in an email.

payment_setup.html
<form action="/form" method="post" id="setup-form"> <div class="form-row inline"> <div class="col"> <label for="accountholder-name"> Name </label> <input id="accountholder-name" name="accountholder-name" placeholder="Jenny Rosen" required /> </div> <div class="col"> <label for="email"> Email Address </label> <input id="email" name="email" type="email" placeholder="jenny.rosen@example.com" required /> </div> </div> <div class="form-row"> <!-- Using a label with a for attribute that matches the ID of the Element container enables the Element to automatically gain focus when the customer clicks on the label. --> <label for="iban-element"> IBAN </label> <div id="iban-element"> <!-- A Stripe Element will be inserted here. --> </div> </div> <!-- Add the client_secret from the SetupIntent as a data attribute --> <button id="submit-button" data-secret="{CLIENT_SECRET}"> Set up SEPA Direct Debit </button> <!-- Display mandate acceptance text. --> <div id="mandate-acceptance"> By providing your payment information and confirming this payment, you authorise (A) Rocketship Inc and Stripe, our payment service provider, to send instructions to your bank to debit your account and (B) your bank to debit your account in accordance with those instructions. As part of your rights, you are entitled to a refund from your bank under the terms and conditions of your agreement with your bank. A refund must be claimed within 8 weeks starting from the date on which your account was debited. Your rights are explained in a statement that you can obtain from your bank. You agree to receive notifications for future debits up to 2 days before they occur. </div> <!-- Used to display form errors. --> <div id="error-message" role="alert"></div> </form>
<form action="/form" method="post" id="setup-form"> <div class="form-row inline"> <div class="col"> <label for="accountholder-name"> Name </label> <input id="accountholder-name" name="accountholder-name" placeholder="Jenny Rosen" required /> </div> <div class="col"> <label for="email"> Email Address </label> <input id="email" name="email" type="email" placeholder="jenny.rosen@example.com" required /> </div> </div> <div class="form-row"> <!-- Using a label with a for attribute that matches the ID of the Element container enables the Element to automatically gain focus when the customer clicks on the label. --> <label for="iban-element"> IBAN </label> <div id="iban-element"> <!-- A Stripe Element will be inserted here. --> </div> </div> <!-- Add the client_secret from the SetupIntent as a data attribute --> <button id="submit-button" data-secret="{CLIENT_SECRET}"> Set up SEPA Direct Debit </button> <!-- Display mandate acceptance text. --> <div id="mandate-acceptance"> By providing your payment information and confirming this payment, you authorise (A) Rocketship Inc and Stripe, our payment service provider, to send instructions to your bank to debit your account and (B) your bank to debit your account in accordance with those instructions. As part of your rights, you are entitled to a refund from your bank under the terms and conditions of your agreement with your bank. A refund must be claimed within 8 weeks starting from the date on which your account was debited. Your rights are explained in a statement that you can obtain from your bank. You agree to receive notifications for future debits up to 2 days before they occur. </div> <!-- Used to display form errors. --> <div id="error-message" role="alert"></div> </form>

When the form loads, you can create an instance of the IBAN Element and mount it to the Element container:

JavaScript JavaScript (ESNext)
// Custom styling can be passed to options when creating an Element. var style = { base: { color: '#32325d', fontSize: '16px', '::placeholder': { color: '#aab7c4' }, ':-webkit-autofill': { color: '#32325d', }, }, invalid: { color: '#fa755a', iconColor: '#fa755a', ':-webkit-autofill': { color: '#fa755a', }, }, }; var options = { style: style, supportedCountries: ['SEPA'], // Elements can use a placeholder as an example IBAN that reflects // the IBAN format of your customer's country. If you know your // customer's country, we recommend that you pass it to the Element as the // placeholderCountry. placeholderCountry: 'DE', }; // Create an instance of the IBAN Element var iban = elements.create('iban', options); // Add an instance of the IBAN Element into the `iban-element` <div> iban.mount('#iban-element');
// Custom styling can be passed to options when creating an Element. var style = { base: { color: '#32325d', fontSize: '16px', '::placeholder': { color: '#aab7c4' }, ':-webkit-autofill': { color: '#32325d', }, }, invalid: { color: '#fa755a', iconColor: '#fa755a', ':-webkit-autofill': { color: '#fa755a', }, }, }; var options = { style: style, supportedCountries: ['SEPA'], // Elements can use a placeholder as an example IBAN that reflects // the IBAN format of your customer's country. If you know your // customer's country, we recommend that you pass it to the Element as the // placeholderCountry. placeholderCountry: 'DE', }; // Create an instance of the IBAN Element var iban = elements.create('iban', options); // Add an instance of the IBAN Element into the `iban-element` <div> iban.mount('#iban-element');
// Custom styling can be passed to options when creating an Element. const style = { base: { color: '#32325d', fontSize: '16px', '::placeholder': { color: '#aab7c4' }, ':-webkit-autofill': { color: '#32325d', }, }, invalid: { color: '#fa755a', iconColor: '#fa755a', ':-webkit-autofill': { color: '#fa755a', }, }, }; const options = { style, supportedCountries: ['SEPA'], // Elements can use a placeholder as an example IBAN that reflects // the IBAN format of your customer's country. If you know your // customer's country, we recommend passing it to the Element as the // placeholderCountry. placeholderCountry: 'DE', }; // Create an instance of the IBAN Element const iban = elements.create('iban', options); // Add an instance of the IBAN Element into the `iban-element` <div> iban.mount('#iban-element');
// Custom styling can be passed to options when creating an Element. const style = { base: { color: '#32325d', fontSize: '16px', '::placeholder': { color: '#aab7c4' }, ':-webkit-autofill': { color: '#32325d', }, }, invalid: { color: '#fa755a', iconColor: '#fa755a', ':-webkit-autofill': { color: '#fa755a', }, }, }; const options = { style, supportedCountries: ['SEPA'], // Elements can use a placeholder as an example IBAN that reflects // the IBAN format of your customer's country. If you know your // customer's country, we recommend passing it to the Element as the // placeholderCountry. placeholderCountry: 'DE', }; // Create an instance of the IBAN Element const iban = elements.create('iban', options); // Add an instance of the IBAN Element into the `iban-element` <div> iban.mount('#iban-element');
npm umd

Install React Stripe.js and the Stripe.js loader from the npm public registry.

Terminal
npm install --save @stripe/react-stripe-js @stripe/stripe-js
npm install --save @stripe/react-stripe-js @stripe/stripe-js

We also provide a UMD build for sites that do not use npm or modules.

Include the Stripe.js script, which exports a global Stripe function, and the UMD build of React Stripe.js, which exports a global ReactStripe object. Always load the Stripe.js script directly from js.stripe.com to remain PCI compliant. Do not include the script in a bundle or host a copy of it yourself.

<!-- Stripe.js --> <script src="https://js.stripe.com/v3/"></script> <!-- React Stripe.js development build --> <script src="https://unpkg.com/@stripe/react-stripe-js@latest/dist/react-stripe.umd.js"></script> <!-- When you are ready to deploy your site to production, remove the above development script, and include the following production build. --> <script src="https://unpkg.com/@stripe/react-stripe-js@latest/dist/react-stripe.umd.min.js"></script>
<!-- Stripe.js --> <script src="https://js.stripe.com/v3/"></script> <!-- React Stripe.js development build --> <script src="https://unpkg.com/@stripe/react-stripe-js@latest/dist/react-stripe.umd.js"></script> <!-- When you are ready to deploy your site to production, remove the above development script, and include the following production build. --> <script src="https://unpkg.com/@stripe/react-stripe-js@latest/dist/react-stripe.umd.min.js"></script>

The demo in CodeSandbox lets you try out React Stripe.js without having to create a new project.

Add Stripe.js and Elements to your page

To use Element components, wrap the root of your React app in an Elements provider. Call loadStripe with your publishable key and pass the returned Promise to the Elements provider.

index.js
import React from 'react'; import ReactDOM from 'react-dom'; import {Elements} from '@stripe/react-stripe-js'; import {loadStripe} from '@stripe/stripe-js'; import PaymentSetupForm from './PaymentSetupForm'; // Make sure to call `loadStripe` outside of a component’s render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe("pk_test_TYooMQauvdEDq54NiTphI7jx"); function App() { return ( <Elements stripe={stripePromise}> <PaymentSetupForm /> </Elements> ); }; ReactDOM.render(<App />, document.getElementById('root'));
import React from 'react'; import ReactDOM from 'react-dom'; import {Elements} from '@stripe/react-stripe-js'; import {loadStripe} from '@stripe/stripe-js'; import PaymentSetupForm from './PaymentSetupForm'; // Make sure to call `loadStripe` outside of a component’s render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe("pk_test_TYooMQauvdEDq54NiTphI7jx"); function App() { return ( <Elements stripe={stripePromise}> <PaymentSetupForm /> </Elements> ); }; ReactDOM.render(<App />, document.getElementById('root'));

Add and configure an IbanElement component

Use the IbanElement to collect your users IBAN. Additionally, your customer must read and accept the SEPA Direct Debit mandate.

Display the following standard authorization text for your customer to implicitly sign this mandate. Replace Rocketship Inc with your company name.

By providing your payment information and confirming this payment, you authorise (A) Rocketship Inc and Stripe, our payment service provider, to send instructions to your bank to debit your account and (B) your bank to debit your account in accordance with those instructions. As part of your rights, you are entitled to a refund from your bank under the terms and conditions of your agreement with your bank. A refund must be claimed within 8 weeks starting from the date on which your account was debited. Your rights are explained in a statement that you can obtain from your bank. You agree to receive notifications for future debits up to 2 days before they occur.

The details of the accepted mandate are generated when setting up a payment method. Because the customer has implicitly signed the mandate when accepting the terms suggested above, you must communicate the terms on the form or in an email.

JSX CSS
IbanForm.js
/** * Use the CSS tab above to style your Element's container. */ import React from 'react'; import {IbanElement} from '@stripe/react-stripe-js'; import './IbanFormStyles.css' // Custom styling can be passed as options when creating an Element. const IBAN_STYLE = { base: { color: '#32325d', fontSize: '16px', '::placeholder': { color: '#aab7c4' }, ':-webkit-autofill': { color: '#32325d', }, }, invalid: { color: '#fa755a', iconColor: '#fa755a', ':-webkit-autofill': { color: '#fa755a', }, } }; const IBAN_ELEMENT_OPTIONS = { supportedCountries: ['SEPA'], // Elements can use a placeholder as an example IBAN that reflects // the IBAN format of your customer's country. If you know your // customer's country, we recommend that you pass it to the Element as the // placeholderCountry. placeholderCountry: 'DE', style: IBAN_STYLE, }; export default function IbanForm({onSubmit, disabled}) { return ( <form onSubmit={onSubmit}> <div className="form-row inline"> <div className="col"> <label> Name <input name="accountholder-name" placeholder="Jenny Rosen" required /> </label> </div> <div className="col"> <label> Email Address <input name="email" type="email" placeholder="jenny.rosen@example.com" required /> </label> </div> </div> <div className="form-row"> <label> IBAN <IbanElement options={IBAN_ELEMENT_OPTIONS} /> </label> </div> <button type="submit" disabled={disabled}> Set up SEPA Direct Debit </button> {/* Display mandate acceptance text. */} <div className="mandate-acceptance"> By providing your payment information and confirming this payment, you authorise (A) Rocketship Inc and Stripe, our payment service provider, to send instructions to your bank to debit your account and (B) your bank to debit your account in accordance with those instructions. As part of your rights, you are entitled to a refund from your bank under the terms and conditions of your agreement with your bank. A refund must be claimed within 8 weeks starting from the date on which your account was debited. Your rights are explained in a statement that you can obtain from your bank. You agree to receive notifications for future debits up to 2 days before they occur. </div> </form> ); };
/** * Use the CSS tab above to style your Element's container. */ import React from 'react'; import {IbanElement} from '@stripe/react-stripe-js'; import './IbanFormStyles.css' // Custom styling can be passed as options when creating an Element. const IBAN_STYLE = { base: { color: '#32325d', fontSize: '16px', '::placeholder': { color: '#aab7c4' }, ':-webkit-autofill': { color: '#32325d', }, }, invalid: { color: '#fa755a', iconColor: '#fa755a', ':-webkit-autofill': { color: '#fa755a', }, } }; const IBAN_ELEMENT_OPTIONS = { supportedCountries: ['SEPA'], // Elements can use a placeholder as an example IBAN that reflects // the IBAN format of your customer's country. If you know your // customer's country, we recommend that you pass it to the Element as the // placeholderCountry. placeholderCountry: 'DE', style: IBAN_STYLE, }; export default function IbanForm({onSubmit, disabled}) { return ( <form onSubmit={onSubmit}> <div className="form-row inline"> <div className="col"> <label> Name <input name="accountholder-name" placeholder="Jenny Rosen" required /> </label> </div> <div className="col"> <label> Email Address <input name="email" type="email" placeholder="jenny.rosen@example.com" required /> </label> </div> </div> <div className="form-row"> <label> IBAN <IbanElement options={IBAN_ELEMENT_OPTIONS} /> </label> </div> <button type="submit" disabled={disabled}> Set up SEPA Direct Debit </button> {/* Display mandate acceptance text. */} <div className="mandate-acceptance"> By providing your payment information and confirming this payment, you authorise (A) Rocketship Inc and Stripe, our payment service provider, to send instructions to your bank to debit your account and (B) your bank to debit your account in accordance with those instructions. As part of your rights, you are entitled to a refund from your bank under the terms and conditions of your agreement with your bank. A refund must be claimed within 8 weeks starting from the date on which your account was debited. Your rights are explained in a statement that you can obtain from your bank. You agree to receive notifications for future debits up to 2 days before they occur. </div> </form> ); };
IbanFormStyles.css
/** * Shows how you can use CSS to style your Element's container. * These classes are added to your Stripe Element by default. * You can override these classNames by using the options passed * to the IbanElement component. * https://stripe.com/docs/js/elements_object/create_element?type=iban#elements_create-options-classes */ input, .StripeElement { height: 40px; padding: 10px 12px; color: #32325d; background-color: white; border: 1px solid transparent; border-radius: 4px; box-shadow: 0 1px 3px 0 #e6ebf1; -webkit-transition: box-shadow 150ms ease; transition: box-shadow 150ms ease; } input:focus, .StripeElement--focus { box-shadow: 0 1px 3px 0 #cfd7df; } .StripeElement--invalid { border-color: #fa755a; } .StripeElement--webkit-autofill { background-color: #fefde5 !important; }
/** * Shows how you can use CSS to style your Element's container. * These classes are added to your Stripe Element by default. * You can override these classNames by using the options passed * to the IbanElement component. * https://stripe.com/docs/js/elements_object/create_element?type=iban#elements_create-options-classes */ input, .StripeElement { height: 40px; padding: 10px 12px; color: #32325d; background-color: white; border: 1px solid transparent; border-radius: 4px; box-shadow: 0 1px 3px 0 #e6ebf1; -webkit-transition: box-shadow 150ms ease; transition: box-shadow 150ms ease; } input:focus, .StripeElement--focus { box-shadow: 0 1px 3px 0 #cfd7df; } .StripeElement--invalid { border-color: #fa755a; } .StripeElement--webkit-autofill { background-color: #fefde5 !important; }

Elements are completely customizable. You can style Elements to match the look and feel of your site, providing a seamless checkout experience for your customers. It’s also possible to style various input states, for example when the Element has focus.

5 Submit the payment method details to Stripe Client-side

Rather than sending the entire SetupIntent object to the client, use its client secret from step 3. This is different from your API keys that authenticate Stripe API requests.

The client secret should still be handled carefully because it can complete the setup. Do not log it, embed it in URLs, or expose it to anyone but the customer.

HTML + JS React

Use stripe.confirmSepaDebitSetup to complete the setup when the user submits the form. Including the customer’s name and email address in the billing_details property of the payment_method parameter is required to create a SEPA Direct Debit PaymentMethod.

A successful setup will return a succeeded value for the SetupIntent’s status property. If the setup is not successful, inspect the returned error to determine the cause.

Because customer was set, the PaymentMethod will be attached to the provided Customer object after a successful setup. This allows you to use the stored PaymentMethod to collect future payments without prompting the customer for payment method details.

JavaScript JavaScript (ESNext)
var form = document.getElementById('payment-form'); var accountholderName = document.getElementById('accountholder-name'); var email = document.getElementById('email'); var submitButton = document.getElementById('submit-button'); var clientSecret = submitButton.dataset.secret; form.addEventListener('submit', function(event) { event.preventDefault(); stripe.confirmSepaDebitSetup( clientSecret, { payment_method: { sepa_debit: iban, billing_details: { name: accountholderName.value, email: email.value, }, }, } ); });
var form = document.getElementById('payment-form'); var accountholderName = document.getElementById('accountholder-name'); var email = document.getElementById('email'); var submitButton = document.getElementById('submit-button'); var clientSecret = submitButton.dataset.secret; form.addEventListener('submit', function(event) { event.preventDefault(); stripe.confirmSepaDebitSetup( clientSecret, { payment_method: { sepa_debit: iban, billing_details: { name: accountholderName.value, email: email.value, }, }, } ); });
const form = document.getElementById('payment-form'); const accountholderName = document.getElementById('accountholder-name'); const email = document.getElementById('email'); const submitButton = document.getElementById('submit-button'); const clientSecret = submitButton.dataset.secret; form.addEventListener('submit', (event) => { event.preventDefault(); stripe.confirmSepaDebitSetup( clientSecret, { payment_method: { sepa_debit: iban, billing_details: { name: accountholderName.value, email: email.value, }, }, } ); });
const form = document.getElementById('payment-form'); const accountholderName = document.getElementById('accountholder-name'); const email = document.getElementById('email'); const submitButton = document.getElementById('submit-button'); const clientSecret = submitButton.dataset.secret; form.addEventListener('submit', (event) => { event.preventDefault(); stripe.confirmSepaDebitSetup( clientSecret, { payment_method: { sepa_debit: iban, billing_details: { name: accountholderName.value, email: email.value, }, }, } ); });

Use stripe.confirmSepaDebitSetup to complete the payment when the user submits the form. Including the customer’s name and email address in the billing_details property of the payment_method parameter is required to create a SEPA Direct Debit PaymentMethod.

To call stripe.confirmSepaDebitSetup from your payment form component, use the useStripe and useElements hooks.

If you prefer traditional class components over hooks, you can instead use an ElementsConsumer.

Hooks Class Components
PaymentSetupForm.js
import React from 'react'; import {useStripe, useElements, IbanElement} from '@stripe/react-stripe-js'; import IbanForm from './IbanForm'; export default function PaymentSetupForm() { const stripe = useStripe(); const elements = useElements(); const handleSubmit = async (event) => { // We don't want to let default form submission happen here, // which would refresh the page. event.preventDefault(); if (!stripe || !elements) { // Stripe.js has not yet loaded. // Make sure to disable form submission until Stripe.js has loaded. return; } const iban = elements.getElement(IbanElement); // For brevity, this example is using uncontrolled components for // the accountholder's name and email. In a real world app you will // probably want to use controlled components. // https://reactjs.org/docs/uncontrolled-components.html // https://reactjs.org/docs/forms.html#controlled-components const accountholderName = event.target['accountholder-name']; const email = event.target.email; const result = await stripe.confirmSepaDebitSetup('{CLIENT_SECRET}', { payment_method: { sepa_debit: iban, billing_details: { name: accountholderName.value, email: email.value, }, } }); if (result.error) { // Show error to your customer. console.log(result.error.message); } else { // Show a confirmation message to your customer. // The SetupIntent is in the 'succeeded' state. } }; return ( <IbanForm onSubmit={handleSubmit} disabled={!stripe} /> ); }
import React from 'react'; import {useStripe, useElements, IbanElement} from '@stripe/react-stripe-js'; import IbanForm from './IbanForm'; export default function PaymentSetupForm() { const stripe = useStripe(); const elements = useElements(); const handleSubmit = async (event) => { // We don't want to let default form submission happen here, // which would refresh the page. event.preventDefault(); if (!stripe || !elements) { // Stripe.js has not yet loaded. // Make sure to disable form submission until Stripe.js has loaded. return; } const iban = elements.getElement(IbanElement); // For brevity, this example is using uncontrolled components for // the accountholder's name and email. In a real world app you will // probably want to use controlled components. // https://reactjs.org/docs/uncontrolled-components.html // https://reactjs.org/docs/forms.html#controlled-components const accountholderName = event.target['accountholder-name']; const email = event.target.email; const result = await stripe.confirmSepaDebitSetup('{CLIENT_SECRET}', { payment_method: { sepa_debit: iban, billing_details: { name: accountholderName.value, email: email.value, }, } }); if (result.error) { // Show error to your customer. console.log(result.error.message); } else { // Show a confirmation message to your customer. // The SetupIntent is in the 'succeeded' state. } }; return ( <IbanForm onSubmit={handleSubmit} disabled={!stripe} /> ); }
PaymentSetupForm.js
import React from 'react'; import {ElementsConsumer, IbanElement} from '@stripe/react-stripe-js'; import IbanForm from './IbanForm'; class PaymentSetupForm extends React.Component { handleSubmit = async (event) => { // We don't want to let default form submission happen here, // which would refresh the page. event.preventDefault(); const {stripe, elements} = this.props if (!stripe || !elements) { // Stripe.js has not yet loaded. // Make sure to disable form submission until Stripe.js has loaded. return; } const clientSecret = await getClientSecret(); const iban = elements.getElement(IbanElement); // For brevity, this example is using uncontrolled components for // the accountholder's name and email. In a real world app you will // probably want to use controlled components. // https://reactjs.org/docs/uncontrolled-components.html // https://reactjs.org/docs/forms.html#controlled-components const accountholderName = event.target['accountholder-name']; const email = event.target.email; const result = await stripe.confirmSepaDebitSetup('{CLIENT_SECRET}', { payment_method: { sepa_debit: iban, billing_details: { name: accountholderName.value, email: email.value, }, } }); if (result.error) { // Show error to your customer. console.log(result.error.message); } else { // Show a confirmation message to your customer. // The SetupIntent is in the 'succeeded' state. } }; render() { const {stripe} = this.props; return ( <IbanForm onSubmit={this.handleSubmit} disabled={!stripe} /> ); } } export default function InjectedPaymentSetupForm() { return ( <ElementsConsumer> {({stripe, elements}) => ( <PaymentSetupForm stripe={stripe} elements={elements} /> )} </ElementsConsumer> ); }
import React from 'react'; import {ElementsConsumer, IbanElement} from '@stripe/react-stripe-js'; import IbanForm from './IbanForm'; class PaymentSetupForm extends React.Component { handleSubmit = async (event) => { // We don't want to let default form submission happen here, // which would refresh the page. event.preventDefault(); const {stripe, elements} = this.props if (!stripe || !elements) { // Stripe.js has not yet loaded. // Make sure to disable form submission until Stripe.js has loaded. return; } const clientSecret = await getClientSecret(); const iban = elements.getElement(IbanElement); // For brevity, this example is using uncontrolled components for // the accountholder's name and email. In a real world app you will // probably want to use controlled components. // https://reactjs.org/docs/uncontrolled-components.html // https://reactjs.org/docs/forms.html#controlled-components const accountholderName = event.target['accountholder-name']; const email = event.target.email; const result = await stripe.confirmSepaDebitSetup('{CLIENT_SECRET}', { payment_method: { sepa_debit: iban, billing_details: { name: accountholderName.value, email: email.value, }, } }); if (result.error) { // Show error to your customer. console.log(result.error.message); } else { // Show a confirmation message to your customer. // The SetupIntent is in the 'succeeded' state. } }; render() { const {stripe} = this.props; return ( <IbanForm onSubmit={this.handleSubmit} disabled={!stripe} /> ); } } export default function InjectedPaymentSetupForm() { return ( <ElementsConsumer> {({stripe, elements}) => ( <PaymentSetupForm stripe={stripe} elements={elements} /> )} </ElementsConsumer> ); }

6 Test the integration

You can test your form using the test account numbers below with your confirmSepaDebitSetup request.

Test account numbers
Account Number Description
AT611904300234573201 The payment method details are successfully collected.
Account Number Description
BE62510007547061 The payment method details are successfully collected.
Account Number Description
DK5000400440116243 The payment method details are successfully collected.
Account Number Description
EE382200221020145689 The payment method details are successfully collected.
Account Number Description
FI2112345600000785 The payment method details are successfully collected.
Account Number Description
FR1420041010050500013M02606 The payment method details are successfully collected.
Account Number Description
DE89370400440532013000 The payment method details are successfully collected.
Account Number Description
IE29AIBK93115212345678 The payment method details are successfully collected.
Account Number Description
IT40S0542811101000000123456 The payment method details are successfully collected.
Account Number Description
LT121000011101001000 The payment method details are successfully collected.
Account Number Description
LU280019400644750000 The payment method details are successfully collected.
Account Number Description
NL39RABO0300065264 The payment method details are successfully collected.
Account Number Description
NO9386011117947 The payment method details are successfully collected.
Account Number Description
PT50000201231234567890154 The payment method details are successfully collected.
Account Number Description
ES0700120345030000067890 The payment method details are successfully collected.
Account Number Description
SE3550000000054910000003 The payment method details are successfully collected.
Account Number Description
GB82WEST12345698765432 The payment method details are successfully collected.

Optional Validate the IBAN Element

The IBAN Element validates user input as it is typed. To help your customers catch mistakes, you should listen to change events on the IBAN Element and display any errors:

HTML + JS React
JavaScript JavaScript (ESNext)
iban.on('change', function(event) { var displayError = document.getElementById('error-message'); if (event.error) { displayError.textContent = event.error.message; } else { displayError.textContent = ''; } });
iban.on('change', function(event) { var displayError = document.getElementById('error-message'); if (event.error) { displayError.textContent = event.error.message; } else { displayError.textContent = ''; } });
iban.on('change', (event) => { const displayError = document.getElementById('error-message'); if (event.error) { displayError.textContent = event.error.message; } else { displayError.textContent = ''; } });
iban.on('change', (event) => { const displayError = document.getElementById('error-message'); if (event.error) { displayError.textContent = event.error.message; } else { displayError.textContent = ''; } });
<IbanElement onChange={(event) => { if (event.error) { // Store event.error.message in state and display it. } else { // Remove existing error from state. } }}>
<IbanElement onChange={(event) => { if (event.error) { // Store event.error.message in state and display it. } else { // Remove existing error from state. } }}>

The change event contains other parameters that can help to build a richer user experience. Refer to the Stripe.js reference for more detail.

See also

  • Accept a SEPA Direct Debit payment
  • Connect Platforms Using the Payment Methods API
Was this page helpful?
Questions? Contact us.
Developer tutorials on YouTube.
You can unsubscribe at any time. Read our privacy policy.
On this page
Create or retrieve a Customer
Set up future payments
Test your integration