Integrate iDEAL Payments Using Stripe Web Elements

Tutorial Scope 

In this tutorial, you learn how to integrate iDEAL payments with Stripe Web Elements to collect payment method details and create a payment source in Stripe for payment processing. After that, you can create a Chargebee subscription along with the payment information collected. This process includes the following steps:

  1. Setting up Stripe Web Elements
  2. Collect payment method details
  3. Mount iDEAL element in Stripe Web Elements
  4. Create a payment source (Sources)
  5. Create a Chargebee subscription using the Chargebee Subscriptions API 


Before trying out this tutorial, you need to set up the following:

  • A Chargebee account. Sign up  for a free trial if you don't have one
  • Plans configured in Chargebee 
  • Your Chargebee test site's API key 

Also, refer to the following Stripe help topics for more information on payment setups:

Learn about payment methods 
Accept an iDEAL payment 
Configure and enable Stripe and iDEAL in the Chargebee application 

Client-Side Implementation 

Step 1: Set up recurring payments with Single Euro Payments Area (SEPA)

By default, the Single Euro Payments Area (SEPA) is not automatically enabled in the Stripe API, therefore If you want to accept recurring direct debit payments using SEPA, you must specify it in the Stripe API. To do that, follow the instruction here  as well as how to set up iDEAL payments with Sources  in Stripe documentation.


Setting up SEPA is a mandatory step for recurring payments, so make sure that you set up parameters specific to SEPA during your Chargebee integration.

Step 2: Set up Stripe

Install Stripe to use their official libraries for access to the Stripe API:

# Install via npm
npm install --save stripe

Step 3: Collect payment method details

Payment method details are collected on the client side with Stripe Elements. In this step, you learn how to set up Single Euro Payments Area (SEPA), integrate Stripe.js and mount it on your checkout page.


Always load Stripe.js directly from  to ensure PCI compliance.

3.1 Include Stripe.js on your checkout page

Create a checkout page (checkout.html) and include Stripe.js in it.

  • php
  • Ruby
  • Java
# checkout.html
    <script src=""></script>

3.2 Create a Stripe Elements instance

Create a Stripe Elements instance on your checkout page.

  • php
  • Ruby
  • Java
var stripe = Stripe('{stripe_API_key}');
var elements = stripe.elements();

3.3 Add and configure an idealBank Element

On your checkout page, create a payment form that includes a placeholder (container) for idealBank element by creating empty DOM nodes with a unique ID.

  • php
  • Ruby
  • Java
<form id="payment-form">
    <div class="form-row">
      <label for="accountholder-name">
      <input id="accountholder-name"  name="accountholder-name">

    <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="ideal-bank-element">
        iDEAL Bank
      <div id="ideal-bank-element">
        <!-- A Stripe Element will be inserted here. -->

    <button>Submit Payment</button>

    <!-- Used to display form errors. -->
    <div id="error-message" role="alert"></div>

3.4. Create and mount an idealBank element

Once your payment form is loaded, create an instance of an idealBank element and mount it on the Element container of your checkout page.

  • php
  • Ruby
  • Java
var options = {
  // Custom styling can be passed to options when creating an Element
  style: {
    base: {
      padding: '10px 12px',
      color: '#32325d',
      fontSize: '16px',
      '::placeholder': {
        color: '#aab7c4'

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

You can customize Stripe Elements in order to maintain the style consistency of your site, this can ensure that your customers have a seamless checkout experience.

Server-Side Implementation 

Step 4: Create a Source

Create a payment source (Source) and specify the currency as euro as well as the amount to collect. Source can be a bank account, an ACH transfer, or an iDEAL payment. Source is a method that handles bank payments, for details, see Stripe API Reference - Sources .

  • iDEAL only supports Euro.

  • The authorized amount must be the same as the charged amount.

  • The user must provide a redirect URL for payment processing.

4.1 Create a source using Stripe SDK

  • php
  • Ruby
  • Java
async function genIdealSource() {
    return stripe.sources.create({
        type: "ideal",
        currency: "eur",
        amount: 9900,
        owner: {
            email: "[email protected]",
            address: {
                country: "NL"
        redirect: {return_url: baseUrl+"authorizedPayment"}

app.get('/sourceRedirect', async (req, res) => {
    genIdealSource().then((response) => {
        // res.redirect(response.redirect.url);

If you choose to directly send the response to the client side, you will receive a 200 response along with source information from Stripe. However, if you choose to directly send the redirected request from the server-side, you will receive 3xx response at your client-side instead.

4.2 Set up an event listener to contact the server-side API for creating a Source

Create an event listener to contact the backend for creating a Source.

  • php
  • Ruby
  • Java
form.addEventListener('submit', function (event) {
            .then((response) => {
                // response is 3xx, implement lines 6-8
                // if(response.redirected){ 
                //     window.location.href = response.url;
                // }
                // response is 200, then implement 10-12
                if(response.url !== undefined){
                    window.location.href = response.url;
            .catch(error => console.log(error));

You must provide your own redirection logic as per the status of the response. If the response is 3xx, then the redirect flag will be set to true, in this case, implement lines 6-8 in the code above. However, if the response is 200, then it means the redirect URL is present, in this case, implement lines 10-12.

Create A Subscription 

Pass the ID of the successfully authorized payment_method[type] and payment_method[gateway_account_id] to Chargebee's Create a Subscription API  to create a subscription.


When you create a subscription using the Chargebee API, you must make sure that the correct values are also included in payment_method[type] and payment_method[gateway_account_id]. The value for payment_method[gateway_account_id] is your Stripe gateway account ID, whereas the value for payment_method[type] is ideal. For payment_method[tmp_token] , the value is your authorized source ID.

Sample request to create a subscription in Chargebee

curl https://{site-name} \
-u {site_api_key}:\
-d plan_id=6-"month-plan" \
-d auto_collection="on" \
-d customer[first_name]="John" \
-d customer[last_name]="Doe" \
-d customer[email]="[email protected]" \
-d billing_address[first_name]="John" \
-d billing_address[last_name]="Doe" \
-d billing_address[line1]="PO Box 9999" \
-d billing_address[city]="Walnut" \
-d billing_address[state]="California" \
-d billing_address[zip]="91789" \
-d billing_address[country]="FR" \
-d payment_method[type]="ideal" \
-d payment_method[gateway_account_id]="{your_gateway_account_id}" \
-d payment_method[tmp_token]="{authorized_source_id}"


You have successfully integrated iDEAL payments using Stripe Elements, and create a Chargebee subscription with the payment information collected.