SEPA Direct Debit with Setup Intents

    Use the Setup Intents API to save and set up 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:

    • Saving payment methods to a wallet to streamline future purchases
    • Collecting surcharges after fulfilling a service
    • Starting a free trial for a subscription

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

    • Immediately before collecting and saving payment method details
    • After collecting payment method details

    The following example shows how to create a SetupIntent on your server:

    curl https://api.stripe.com/v1/setup_intents \
      -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
      -d "payment_method_types[]"=sepa_debit
    

    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 using IBAN Element

    To set up the payment method on the client side, pass the client_secret of the SetupIntent object that you created in Step 1 to Stripe.js.

    Setting up Stripe.js and Stripe Elements allows you to build a payment form and securely collect payment information.

    var stripe = Stripe('pk_test_TYooMQauvdEDq54NiTphI7jx');
    var elements = stripe.elements();
    

    Payment information is sensitive by nature. Using Stripe.js and the IBAN Element prevents IBAN details from touching your server and reduces the amount of sensitive data that you need to handle securely. Elements creates a UI component that is hosted by Stripe and placed on your payment form, rather than you creating it directly.

    You can determine where to insert the component by creating an empty DOM element (container) with a unique ID on your payment form.

    <form action="/charge" method="post" id="setup-form">
      <div class="form-row inline">
        <div class="col">
          <label for="name">
            Name
          </label>
          <input id="name" name="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>
    
      <button id="submit-button">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 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 8 weeks starting from the date on which your account was debited.
      </div>
    </form>
    

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

    // Custom styling can be passed to options when creating an Element.
    var style = {
      base: {
      // Add your base input styles here. For example:
      fontSize: '16px',
      color: "#32325d",
      }
    };
    
    var options = {
      style: style,
      supportedCountries: ['SEPA'],
      // If you know the country of the customer, you can optionally pass it to
      // the Element as placeholderCountry. The example IBAN that is used
      // as placeholder reflects the IBAN format of that country.
      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');
    

    For more information about handling the IBAN element, see the SEPA Debit Payment Intents guide.

    3 Submit the payment method details to Stripe Client-side

    To create a payment on the client side, pass the client secret of the PaymentIntent object that you created in Step 1.

    Retrieve the client secret and then use stripe.confirmSepaDebitSetup< to complete the setup.

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

    var form = document.getElementById('setup-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
            }
          }
        }
      );
    });
    

    4 Attach the PaymentMethod to a Customer after success

    When you create a new Customer, pass the PaymentMethod ID to immediately add a PaymentMethod.

    curl https://api.stripe.com/v1/customers \
      -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
      -d payment_method="{PAYMENT_METHOD_ID}"
    

    If you have an existing Customer, 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}"
    

    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 create a test charge that is either successful or failed by doing the following:

    1. Create a test PaymentMethod with a test IBAN account number.
    2. Use the resulting PaymentMethod in a confirmSepaDebitSetup request to create the test charge.
    Test IBAN account numbers
    Account Number Description
    AT611904300234573201 The charge status transitions from pending to succeeded.
    AT861904300235473202 The charge status transitions from pending to failed.
    AT591904300235473203 The charge status transitions from pending to succeeded, but a dispute is immediately created.
    Account Number Description
    BE62510007547061 The charge status transitions from pending to succeeded.
    BE68539007547034 The charge status transitions from pending to failed.
    BE08510007547063 The charge status transitions from pending to succeeded, but a dispute is immediately created.
    Account Number Description
    DK5000400440116243 The charge status transitions from pending to succeeded.
    DK8003450003179681 The charge status transitions from pending to failed.
    DK9300400440116245 The charge status transitions from pending to succeeded, but a dispute is immediately created.
    Account Number Description
    FR1420041010050500013M02606 The charge status transitions from pending to succeeded.
    FR8420041010050500013M02607 The charge status transitions from pending to failed.
    FR5720041010050500013M02608 The charge status transitions from pending to succeeded, but a dispute is immediately created.
    Account Number Description
    DE89370400440532013000 The charge status transitions from pending to succeeded.
    DE62370400440532013001 The charge status transitions from pending to failed.
    DE35370400440532013002 The charge status transitions from pending to succeeded, but a dispute is immediately created.
    Account Number Description
    IE29AIBK93115212345678 The charge status transitions from pending to succeeded.
    IE02AIBK93115212345679 The charge status transitions from pending to failed.
    IE51AIBK93115212345670 The charge status transitions from pending to succeeded, but a dispute is immediately created.
    Account Number Description
    IT40S0542811101000000123456 The charge status transitions from pending to succeeded.
    IT60X0542811101000000123456 The charge status transitions from pending to failed.
    IT83S0542811101000000123458 The charge status transitions from pending to succeeded, but a dispute is immediately created.
    Account Number Description
    LU280019400644750000 The charge status transitions from pending to succeeded.
    LU980019400644750001 The charge status transitions from pending to failed.
    LU710019400644750002 The charge status transitions from pending to succeeded, but a dispute is immediately created.
    Account Number Description
    NL39RABO0300065264 The charge status transitions from pending to succeeded.
    NL91ABNA0417164300 The charge status transitions from pending to failed.
    NL82RABO0300065266 The charge status transitions from pending to succeeded, but a dispute is immediately created.
    Account Number Description
    PT50000201231234567890154 The charge status transitions from pending to succeeded.
    PT23000201231234567890155 The charge status transitions from pending to failed.
    PT93000201231234567890156 The charge status transitions from pending to succeeded, but a dispute is immediately created.
    Account Number Description
    ES0700120345030000067890 The charge status transitions from pending to succeeded.
    ES9121000418450200051332 The charge status transitions from pending to failed.
    ES5000120345030000067892 The charge status transitions from pending to succeeded, but a dispute is immediately created.

    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