IBAN Element Quickstart Public Beta

    Securely collect IBANs using Elements, our pre-built UI components.

    The IBAN Element lets you collect your customers’ International Bank Account Number (IBAN) in order to create SEPA Direct Debit Sources or bank_account tokens. It currently supports IBANs from countries that are part of the Single Euro Payments Area (SEPA).

    <script src="https://js.stripe.com/v3/"></script>
    
    <form action="/charge" method="post" id="payment-form">
      <div class="form-row inline">
        <div class="col">
          <label for="name">
            Name
          </label>
          <input id="name" name="name" placeholder="Jane Doe" required>
        </div>
        <div class="col">
          <label for="email">
            Email Address
          </label>
          <input id="email" name="email" type="email" placeholder="jane.doe@example.com" required>
        </div>
      </div>
    
      <div class="form-row">
        <label for="iban-element">
          IBAN
        </label>
        <div id="iban-element">
          <!-- A Stripe Element will be inserted here. -->
        </div>
        <div id="bank-name"></div>
      </div>
    
      <button>Submit Payment</button>
    
    See all 44 lines <!-- 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 and 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>
    /**
    * The CSS shown here will not be introduced in the Quickstart guide, but
    * shows how you can use CSS to style your Element's container.
    */
    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;
    See all 31 lines }
    // Create a Stripe client.
    // Note: this merchant has been set up for demo purposes.
    var stripe = Stripe('pk_test_6pRNASCoBOKtIshFeQd4XMUh');
    
    // Create an instance of Elements.
    var elements = stripe.elements();
    
    // Custom styling can be passed to options when creating an Element.
    // (Note that this demo uses a wider set of styles than the guide below.)
    var style = {
      base: {
        color: '#32325d',
        fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif',
        fontSmoothing: 'antialiased',
        fontSize: '16px',
        '::placeholder': {
          color: '#aab7c4'
        },
        ':-webkit-autofill': {
          color: '#32325d',
        },
      },
      invalid: {
        color: '#fa755a',
        iconColor: '#fa755a',
        ':-webkit-autofill': {
          color: '#fa755a',
        },
      }
    };
    See all 95 lines // Create an instance of the iban Element. var iban = elements.create('iban', { style: style, supportedCountries: ['SEPA'], }); // Add an instance of the iban Element into the `iban-element` <div>. iban.mount('#iban-element'); var errorMessage = document.getElementById('error-message'); var bankName = document.getElementById('bank-name'); iban.on('change', function(event) { // Handle real-time validation errors from the iban Element. if (event.error) { errorMessage.textContent = event.error.message; errorMessage.classList.add('visible'); } else { errorMessage.classList.remove('visible'); } // Display bank name corresponding to IBAN, if available. if (event.bankName) { bankName.textContent = event.bankName; bankName.classList.add('visible'); } else { bankName.classList.remove('visible'); } }); // Handle form submission. var form = document.getElementById('payment-form'); form.addEventListener('submit', function(event) { event.preventDefault(); showLoading(); var sourceData = { type: 'sepa_debit', currency: 'eur', owner: { name: document.querySelector('input[name="name"]').value, email: document.querySelector('input[name="email"]').value, }, mandate: { // Automatically send a mandate notification email to your customer // once the source is charged. notification_method: 'email', } }; // Call `stripe.createSource` with the iban Element and additional options. stripe.createSource(iban, sourceData).then(function(result) { if (result.error) { // Inform the customer that there was an error. errorMessage.textContent = result.error.message; errorMessage.classList.add('visible'); stopLoading(); } else { // Send the Source to your server to create a charge. errorMessage.classList.remove('visible'); stripeSourceHandler(result.source); } }); });

    Try it out using the following test IBANs:

    • DE89 3704 0044 0532 0130 00
    • NL91 ABNA 0417 1643 00

    Additional features of the IBAN Element include:

    • Instant client-side formatting and validation of IBANs from all SEPA countries
    • Bank logo icon for popular banks in Austria, Belgium, Germany, and the Netherlands
    • Bank name information for IBANs from many SEPA countries
    • Locale-based placeholders e.g. German users see a “DE” IBAN placeholder, and Dutch users see an “NL” one
    • Keyboard and screen reader accessibility
    • Cross-browser support and mobile optimization
    • Localization in 15 languages

    Building a custom payment form with Elements to create sepa_debit Sources requires four steps:

    1. Set up Stripe Elements
    2. Create your payment form
    3. Create a Source object
    4. Submit the Source and the rest of your form to your server

    Step 1: Set up Stripe Elements

    Elements is available as part of Stripe.js. To get started, include this script on your pages—it should always be loaded directly from https://js.stripe.com:

    <script src="https://js.stripe.com/v3/"></script>

    To best leverage Stripe’s advanced fraud functionality, include this script on every page on your site, not just the checkout page. Including the script on every page allows Stripe to detect anomalous behavior that may be indicative of fraud as users browse your website.

    Next, create an instance of Elements:

    var stripe = Stripe('pk_test_6pRNASCoBOKtIshFeQd4XMUh');
    var elements = stripe.elements();
    const stripe = Stripe('pk_test_6pRNASCoBOKtIshFeQd4XMUh');
    const elements = stripe.elements();

    We've placed a random API key in the code. Replace it with your actual publishable API key to test this code through your Stripe account.

    When you’re ready to accept live SEPA Direct Debit payments, replace the test key with your live key. Learn more about how the keys play into test and live modes.

    Step 2: Create your payment form

    To securely collect IBANs from your customers, Elements creates a UI component for you that is hosted by Stripe. It is then placed into your payment form, rather than you creating it directly.

    To determine where to insert these components, create empty DOM elements (containers) with unique IDs within your payment form. We recommend placing your container within a <label> or next to a <label> with a for attribute that matches the unique id of the Element container. By doing so, the Element automatically gains focus when the customer clicks on the corresponding label.

    For example:

    <form action="/charge" method="post" id="payment-form">
      <div class="form-row inline">
        <div class="col">
          <label for="name">
            Name
          </label>
          <input id="name" name="name" placeholder="Jane Doe" required>
        </div>
        <div class="col">
          <label for="email">
            Email Address
          </label>
          <input
            id="email"
            name="email"
            type="email"
            placeholder="jane.doe@example.com"
            required
          >
        </div>
      </div>
    
      <div class="form-row">
        <label for="iban-element">
          IBAN
        </label>
        <div id="iban-element">
          <!-- A Stripe Element will be inserted here. -->
        </div>
      </div>
    
      <button>Submit Payment</button>
    
      <!-- Used to display form errors. -->
      <div id="errors" 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 and 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 claimedwithin 8 weeks starting from the
        date on which your account was debited.
      </div>
    </form>

    When the form above has loaded, create an instance of an iban Element and mount it to the Element container created above:

    // 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 being 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');
    // Custom styling can be passed to options when creating an Element.
    const style = {
      base: {
        // Add your base input styles here. For example:
        fontSize: '16px',
        color: "#32325d",
      },
    };
    
    const options = {
      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 being used
      // as placeholer will reflect the IBAN format of that country.
      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');

    You can update the configuration options (e.g., the style or the placeholderCountry) of the iban Element at any point using element.update(options).

    Elements 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('errors');
      if (event.error) {
        displayError.textContent = event.error.message;
      } else {
        displayError.textContent = '';
      }
    });
    iban.on('change', ({error}) => {
      const displayError = document.getElementById('errors');
      if (error) {
        displayError.textContent = error.message;
      } else {
        displayError.textContent = '';
      }
    });

    The change event also contains a few other helpful properties:

    elementType
    string
    iban, the name of the Element.
    empty
    Boolean
    true if the value is empty.
    complete
    Boolean
    true if the value is well-formed and potentially complete.
    complete can be used to progressively disclose the next parts of your form or to enable form submission.
    complete is not an indicator of whether a customer is done with their input—it only indicates that the Element contains a potentially complete, well-formed value. In many cases the customer could still add further input.
    complete should not be used to perform an action such as advancing the cursor to a subsequent field or performing a create source request.
    country
    string
    The country of the entered IBAN.
    bankName
    string
    The financial institution that services the account whose IBAN was entered into the Element.
    error
    object
    The current validation error, if any. Comprised of message, code, and type set to validation_error.

    Step 3: Create a Source object

    The payment details collected using Elements can then be converted into a source. Create an event handler that handles the submit event on the form. The handler sends the fields to Stripe for source creation and prevents the form’s submission (the form is submitted by JavaScript in the next step).

    // Create a source or display an error when the form is submitted.
    var form = document.getElementById('payment-form');
    
    form.addEventListener('submit', function(event) {
      event.preventDefault();
    
      var sourceData = {
        type: 'sepa_debit',
        currency: 'eur',
        owner: {
          name: document.querySelector('input[name="name"]').value,
          email: document.querySelector('input[name="email"]').value,
        },
        mandate: {
          // Automatically send a mandate notification email to your customer
          // once the source is charged.
          notification_method: 'email',
        },
      };
    
      // Call `stripe.createSource` with the IBAN Element and additional options.
      stripe.createSource(iban, sourceData).then(function(result) {
        if (result.error) {
          // Inform the customer that there was an error.
          var errorElement = document.getElementById('errors');
          errorElement.textContent = result.error.message;
        } else {
          // Send the Source to your server.
          stripeSourceHandler(result.source);
        }
      });
    });
    // Create a source or display an error when the form is submitted.
    const form = document.getElementById('payment-form');
    
    form.addEventListener('submit', async (event) => {
      event.preventDefault();
    
      const sourceData = {
        type: 'sepa_debit',
        currency: 'eur',
        owner: {
          name: document.querySelector('input[name="name"]').value,
          email: document.querySelector('input[name="email"]').value,
        },
        mandate: {
          // Automatically send a mandate notification email to your customer
          // once the source is charged.
          notification_method: 'email',
        },
      };
    
      // Call `stripe.createSource` with the IBAN Element and additional options.
      const {source, error} = await stripe.createSource(iban, sourceData);
    
      if (error) {
        // Inform the customer that there was an error.
        const errorElement = document.getElementById('errors');
        errorElement.textContent = error.message;
      } else {
        // Send the Source to your server.
        stripeSourceHandler(source);
      }
    });

    The stripe.createSource method takes two arguments:

    • element, the Element containing payment source information. If applicable, the Element pulls data from other Elements you’ve created on the same instance of elements.
    • sourceData, a required object containing the type of Source you want to create, and any additional payment source information that you have collected. See the Sources API reference for details.

    It returns a Promise which resolves with a result object. This object has either:

    • result.source, a Source was created successfully.
    • result.error, there was an error. This includes client-side validation errors. Refer to the SEPA Direct Debit guide for more information on errors.

    Step 4: Submit the Source and the rest of your form to your server

    The last step is to submit the Source, along with any additional information that has been collected, to your server for use in a charge.

    function stripeSourceHandler(source) {
      // Insert the Source ID into the form so it gets submitted to the server.
      var form = document.getElementById('payment-form');
      var hiddenInput = document.createElement('input');
      hiddenInput.setAttribute('type', 'hidden');
      hiddenInput.setAttribute('name', 'stripeSource');
      hiddenInput.setAttribute('value', source.id);
      form.appendChild(hiddenInput);
    
      // Submit the form.
      form.submit();
    }
    const stripeSourceHandler = (source) => {
      // Insert the Source ID into the form so it gets submitted to the server.
      const form = document.getElementById('payment-form');
      const hiddenInput = document.createElement('input');
      hiddenInput.setAttribute('type', 'hidden');
      hiddenInput.setAttribute('name', 'stripeSource');
      hiddenInput.setAttribute('value', source.id);
      form.appendChild(hiddenInput);
    
      // Submit the form.
      form.submit();
    }

    Next steps

    Congrats! You now have a custom payment form to create sepa_debit sources. You can continue with Step 2 of the SEPA Direct Debit guide to learn more about how to charge the source.