iDEAL Bank Element Quickstart

    Collect your customers’ iDEAL bank using Elements, our pre-built UI components.

    The iDEAL Bank Element lets you collect your customers’ bank to create iDEAL Sources. Collecting the bank isn’t required to create iDEAL Sources, but it is strongly recommended. If you collect the bank, you can redirect a customer directly to their bank’s payment page instead of an interstitial bank selection page.

    <script src="https://js.stripe.com/v3/"></script>
    
    <form id="payment-form">
      <div class="form-row">
        <label for="name">
          Name
        </label>
        <input id="name" name="name" placeholder="Jane Doe" required>
      </div>
    
      <div class="form-row">
        <label for="ideal-bank-element">
          iDEAL Bank
        </label>
        <div id="ideal-bank-element">
          <!-- A Stripe Element will be inserted here. -->
        </div>
      </div>
    
      <button>Submit Payment</button>
    
      <!-- Used to display form errors. -->
        <div id="error-message" role="alert"></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;
    
      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 {
      padding: 10px 12px;
    }
    
    input:focus,
    .StripeElement--focus {
      box-shadow: 0 1px 3px 0 #cfd7df;
    }
    
    .StripeElement--invalid {
      border-color: #fa755a;
    }
    See all 34 lines .StripeElement--webkit-autofill { background-color: #fefde5 !important; }
    // 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: {
        padding: '10px 12px',
        color: '#32325d',
        fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif',
        fontSmoothing: 'antialiased',
        fontSize: '16px',
        '::placeholder': {
          color: '#aab7c4'
        },
      },
      invalid: {
        color: '#fa755a',
      }
    };
    
    // Create an instance of the idealBank Element.
    var idealBank = elements.create('idealBank', {style: style});
    
    // Add an instance of the idealBank Element into the `ideal-bank-element` <div>.
    idealBank.mount('#ideal-bank-element');
    See all 67 lines var errorMessage = document.getElementById('error-message'); // Handle form submission. var form = document.getElementById('payment-form'); form.addEventListener('submit', function(event) { event.preventDefault(); showLoading(); var sourceData = { type: 'ideal', amount: 1099, currency: 'eur', owner: { name: document.querySelector('input[name="name"]').value, }, // Specify the URL to which the customer should be redirected // after paying. redirect: { return_url: 'https://shop.example.com/crtA6B28E1', }, }; // Call `stripe.createSource` with the idealBank Element and additional options. stripe.createSource(idealBank, 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 { // Redirect the customer to the authorization URL. errorMessage.classList.remove('visible'); stripeSourceHandler(result.source); } }); });

    Additional features of the iDEAL Bank Element include:

    • Constantly up-to-date list of iDEAL-member banks, along with their logos
    • Keyboard shortcuts and screen-reader accessibility
    • Cross-browser support and mobile optimization
    • Localization in 15 languages

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

    1. Set up Stripe Elements
    2. Create your payment form
    3. Create a Source object
    4. Redirect the customer to authorize payment

    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_g6do5S237ekq10r65BnxO6S0');
    var elements = stripe.elements();
    const stripe = Stripe('pk_test_g6do5S237ekq10r65BnxO6S0');
    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 iDEAL 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 collect the iDEAL bank 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 id="payment-form">
      <div class="form-row">
        <label for="name">
          Name
        </label>
        <input name="name">
      </div>
    
      <div class="form-row">
        <label for="ideal-bank-element">
          iDEAL Bank
        </label>
        <div id="ideal-bank-element">
          <!-- A Stripe Element will be inserted here. -->
        </div>
      </div>
    
      <button>Submit Payment</button>
    
      <!-- Used to display form errors. -->
      <div id="error-message" role="alert"></div>
    </form>

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

    var options = {
      // Custom styling can be passed to options when creating an Element.
      style: {
        base: {
          // Add your base input styles here. For example:
          fontSize: '16px',
          color: '#32325d',
          padding: '10px 12px',
        },
      }
    }
    
    // Create an instance of the idealBank Element.
    var idealBank = elements.create('idealBank', options);
    
    // Add an instance of the idealBank Element into
    // the `ideal-bank-element` <div>.
    idealBank.mount('#ideal-bank-element');
    const options = {
      // Custom styling can be passed to options when creating an Element.
      style: {
        base: {
          // Add your base input styles here. For example:
          fontSize: '16px',
          color: '#32325d',
          padding: '10px 12px',
        },
      }
    }
    
    // Create an instance of the idealBank Element.
    const idealBank = elements.create('idealBank', options);
    
    // Add an instance of the idealBank Element into
    // the `ideal-bank-element` <div>.
    idealBank.mount('#ideal-bank-element');

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

    The iDEAL Bank Element emits the customer’s selected bank as it changes. If you would like to perform additional logic with the bank value (such as requiring the field for form validation, for example), you can listen to the change event:

    idealBank.on('change', function(event) {
      var bank = event.value;
      // Perform any additional logic here...
    });
    idealBank.on('change', ({value}) => {
      const bank = value;
      // Perform any additional logic here...
    });

    The change event also contains a few other helpful properties:

    elementType
    string
    idealBank, the name of the Element.
    empty
    Boolean
    true if the value is empty.
    complete
    Boolean
    true if the value has been picked by the customer.
    complete can be used to progressively disclose the next parts of your form or to enable form submission.
    value
    string
    The iDEAL bank that the customer picked from the Element. The full list of banks can be found in the iDEAL guide.

    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 resulting source is used to redirect the customer for payment authorization (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: 'ideal',
        amount: 1099,
        currency: 'eur',
        owner: {
          name: document.querySelector('input[name="name"]').value,
        },
        // Specify the URL to which the customer should be redirected
        // after paying.
        redirect: {
          return_url: 'https://shop.example.com/crtA6B28E1',
        },
      };
    
      // Call `stripe.createSource` with the idealBank Element and
      // additional options.
      stripe.createSource(idealBank, sourceData).then(function(result) {
        if (result.error) {
          // Inform the customer that there was an error.
          var errorElement = document.getElementById('error-message');
          errorElement.textContent = error.message;
        } else {
          // Redirect the customer to the authorization URL.
          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: 'ideal',
        amount: 1099,
        currency: 'eur',
        owner: {
          name: document.querySelector('input[name="name"]').value,
        },
        // Specify the URL to which the customer should be redirected
        // after paying.
        redirect: {
          return_url: 'https://shop.example.com/crtA6B28E1',
        },
      };
    
      // Call `stripe.createSource` with the idealBank Element and
      // additional options.
      const {source, error} = await stripe.createSource(idealBank, sourceData);
    
      if (error) {
        // Inform the customer that there was an error.
        const errorElement = document.getElementById('error-message');
        errorElement.textContent = error.message;
      } else {
        // Redirect the customer to the authorization URL.
        stripeSourceHandler(source);
      }
    });

    The stripe.createSource method takes two arguments:

    • element, the Element containing the 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 iDEAL guide for more information on errors.

    Optional: Providing a custom statement descriptor

    iDEAL requires a statement descriptor before the customer is redirected to authenticate the payment. By default, your Stripe account’s statement descriptor is used (you can review this in the Dashboard). You can provide a custom descriptor by specifying statement_descriptor when creating a source.

    var sourceData = {
      type: 'ideal',
      amount: 1099,
      currency: 'eur',
      // Specify a custom statement descriptor.
      statement_descriptor: 'ORDER AT11990',
      owner: {
        name: document.querySelector('input[name="name"]').value,
      },
      redirect: {
        return_url: 'https://shop.example.com/crtA6B28E1',
      },
    };
    const sourceData = {
      type: 'ideal',
      amount: 1099,
      currency: 'eur',
      // Specify a custom statement descriptor.
      statement_descriptor: 'ORDER AT11990',
      owner: {
        name: document.querySelector('input[name="name"]').value,
      },
      redirect: {
        return_url: 'https://shop.example.com/crtA6B28E1',
      },
    };

    Providing a custom statement descriptor within a subsequent charge request has no effect.

    Step 4: Redirect the customer to authorize payment

    The last step is to redirect the customer to the URL specified in the Source.

    function stripeSourceHandler(source) {
      // Redirect the customer to the authorization URL.
      document.location.href = source.redirect.url;
    }
    const stripeSourceHandler = (source) => {
      // Redirect the customer to the authorization URL.
      document.location.href = source.redirect.url;
    }

    More details about having the customer authorize payment can be found in the iDEAL guide.

    Next steps

    Congrats! You now have a custom payment form to create ideal sources. You can continue with Step 2 of the iDEAL guide to learn more about having the customer authorize the payment, and charging the source.