Save SEPA Direct Debit details for future payments

    Use the Setup Intents API to save payment method details for future SEPA Direct Debit payments.

    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:

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

    curl https://api.stripe.com/v1/setup_intents \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=sepa_debit
    # 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.create({ payment_method_types: ['sepa_debit'], })
    # 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' stripe.SetupIntent.create( payment_method_types=['sepa_debit'], )
    // 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'); \Stripe\SetupIntent::create([ 'payment_method_types' => ['sepa_debit'], ]);
    // 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 paymentMethodTypes = new ArrayList(); params.put("payment_method_types", Arrays.asList("sepa_debit")); SetupIntent.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')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const setupIntent = await stripe.setupIntents.create({ payment_method_types: ['sepa_debit'], });
    // 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", }), } setupintent.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 service = new SetupIntentService(); var options = new SetupIntentCreateOptions { PaymentMethodTypes = new List<string> { "sepa_debit", }, }; var intent = service.Create(options);

    After creating a SetupIntent on your server, you can associate the SetupIntent ID with the current session’s customer in your application’s data model. This allows you to retrieve the information after you have successfully collected a payment method.

    2 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 a 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

    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.

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

    var stripe = Stripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); var 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.

    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.

    <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 PaymentIntent as a data attribute --> <button id="submit-button" data-secret="{CLIENT_SECRET}"> Set up SEPA Direct Debit </button> <!-- Used to display form errors. --> <div id="error-message" role="alert"></div> <!-- Display mandate acceptance text. --> <div id="mandate-acceptance"> By providing your IBAN, you are authorizing *Rocketship Inc* and Stripe, our payment service provider, to send instructions to your bank to debit your account in accordance with those instructions. Subsequent payments 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 eight weeks starting from the date on which your account was debited. </div> </form>

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

    // 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');

    Install @stripe/react-stripe-js and @stripe/stripe-js:

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

    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.

    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.

    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.

    /** * 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 IBAN and confirming this payment, you are authorizing Rocketship Inc. and Stripe, our payment service provider, to send instructions to your bank to debit your account in accordance with those instructions. 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 eight weeks starting from the date on which your account was debited. </div> </form> ); };
    /** * 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.

    3 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 1. 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 charge. Do not log it, embed it in URLs, or expose it to anyone but the customer.

    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.

    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, }, }, } ); });

    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.

    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 {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> ); }

    4 Attach the PaymentMethod to a Customer Server-side

    To save the payment method details, create a new Customer object and pass in the PaymentMethod ID.

    curl https://api.stripe.com/v1/customers \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d payment_method="{{PAYMENT_METHOD_ID}}"
    # 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' Stripe::Customer.create({ payment_method: '{{PAYMENT_METHOD_ID}}', })
    # 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' stripe.Customer.create( payment_method='{{PAYMENT_METHOD_ID}}', )
    // 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'); \Stripe\Customer::create([ 'payment_method' => '{{PAYMENT_METHOD_ID}}', ]);
    // 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>(); params.put("payment_method", "{{PAYMENT_METHOD_ID}}"); 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 const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const customer = await stripe.customers.create({ paymentMethod: '{{PAYMENT_METHOD_ID}}', });
    // 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{ PaymentMethod: stripe.String("{{PAYMENT_METHOD_ID}}"), } 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 StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new CustomerCreateOptions { PaymentMethod = "{{PAYMENT_METHOD_ID}}", }; var service = new CustomerService(); var customer = service.Create(options);

    If you have an existing Customer object, you can attach the PaymentMethod to that object.

    curl https://api.stripe.com/v1/payment_methods/{{PAYMENT_METHOD_ID}}/attach \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d customer="{{CUSTOMER_ID}}"
    # 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' Stripe::PaymentMethod.attach( '{{PAYMENT_METHOD_ID}}', { customer: '{{CUSTOMER_ID}}', } )
    # 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' stripe.PaymentMethod.attach( '{{PAYMENT_METHOD_ID}}', customer='{{CUSTOMER_ID}}', )
    // 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'); \Stripe\PaymentMethod::retrieve('{{PAYMENT_METHOD_ID}}'); $payment_method->attach([ 'customer' => '{{CUSTOMER_ID}}', ]);
    // 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"; PaymentMethod paymentMethod = PaymentMethod.retrieve("{{PAYMENT_METHOD_ID}}"); Map<String, Object> params = new HashMap<String, Object>(); params.put("customer", "{{CUSTOMER_ID}}"); paymentMethod = paymentMethod.attach(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')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const paymentMethod = await stripe.paymentMethods.attach( '{{PAYMENT_METHOD_ID}}', { customer: '{{CUSTOMER_ID}}', } );
    // 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.PaymentMethodAttachParams{ Customer: stripe.String("{{CUSTOMER_ID}}"), } paymentMethod, _ := paymentMethod.Attach( "{{PAYMENT_METHOD_ID}}", 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 PaymentMethodAttachOptions { Customer = "{{CUSTOMER_ID}}", }; var service = new PaymentMethodService(); service.Attach("{{PAYMENT_METHOD_ID}}", options);

    After you attach the PaymentMethod to a Customer object, you can associate the ID of the Customer object with your internal representation of a customer. This allows you to use the stored PaymentMethod to collect future payments without prompting for your customer’s payment method details.

    5 Test the integration

    You can test your form by doing the following:

    1. Create a test PaymentMethod with a test account number.
    2. Use the resulting PaymentMethod in a confirmSepaDebitSetup request to submit payment method details.
    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:

    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 = ''; } });
    <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

    Congrats, you are done with your integration! You can learn about accepting a SEPA Direct Debit payment and integrating with Connect.

    Was this page helpful?

    Thank you for helping improve Stripe's documentation. If you need help or have any questions, please consider contacting support.

    On this page