/stripe-guides

How to enable SEPA Direct Debit in Stripe?

Learn how to enable SEPA Direct Debit in Stripe with this step-by-step guide covering account setup, dashboard settings, integration, testing, and going live.

Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.

Book a free consultation

How to enable SEPA Direct Debit in Stripe?

How to Enable SEPA Direct Debit in Stripe: A Comprehensive Tutorial

 

Step 1: Create a Stripe Account

 

Before enabling SEPA Direct Debit, you need to have a Stripe account. If you don't have one yet, follow these steps:

  • Go to stripe.com and click on "Start now" or "Create account"
  • Enter your email address, create a password, and provide the required business information
  • Complete the verification process by providing necessary documents as requested by Stripe
  • Ensure your business is located in a SEPA-supported country (EU member states, UK, Switzerland, etc.)

 

Step 2: Enable SEPA Direct Debit in Your Stripe Dashboard

 

To activate SEPA Direct Debit as a payment method in your Stripe account:

  • Log in to your Stripe Dashboard at dashboard.stripe.com
  • Navigate to "Settings" > "Payment methods"
  • Find "SEPA Direct Debit" in the list of payment methods
  • Toggle the switch to enable it
  • Complete any additional verification steps if prompted by Stripe

 

Step 3: Set Up Your Account Details

 

SEPA Direct Debit requires specific business information:

  • In your Stripe Dashboard, go to "Settings" > "Business settings"
  • Ensure your business name, address, and legal entity information are correct
  • Verify that your bank account details are properly configured
  • Make sure you've provided your IBAN (International Bank Account Number)
  • Check that your business identifier (VAT ID or company registration number) is added

 

Step 4: Install Stripe Library in Your Project

 

To implement SEPA Direct Debit in your application, you'll need to install the Stripe library:

For Node.js:


npm install stripe

For PHP:


composer require stripe/stripe-php

For Python:


pip install stripe

For Ruby:


gem install stripe

 

Step 5: Initialize Stripe in Your Code

 

After installing the library, initialize it with your secret key:

For Node.js:


const stripe = require('stripe')('sk_test_your_secret_key');

For PHP:


require\_once 'vendor/autoload.php';
\Stripe\Stripe::setApiKey('sk_test_your_secret_key');

For Python:


import stripe
stripe.api_key = 'sk_test_your_secret\_key'

For Ruby:


require 'stripe'
Stripe.api_key = 'sk_test_your_secret\_key'

 

Step 6: Create a Payment Intent for SEPA Direct Debit

 

To collect a SEPA Direct Debit payment, create a PaymentIntent specifying the payment method as SEPA Direct Debit:

For Node.js:


const paymentIntent = await stripe.paymentIntents.create({
  amount: 1000, // Amount in cents
  currency: 'eur', // SEPA requires EUR
  payment_method_types: ['sepa\_debit'],
  metadata: {
    order\_id: '6735',
  }
});

For PHP:


$paymentIntent = \Stripe\PaymentIntent::create([
  'amount' => 1000, // Amount in cents
  'currency' => 'eur', // SEPA requires EUR
  'payment_method_types' => ['sepa\_debit'],
  'metadata' => [
    'order\_id' => '6735',
  ]
]);

 

Step 7: Implement SEPA Direct Debit Elements on the Frontend

 

Add the necessary HTML elements to your page:


By providing your IBAN and confirming this payment, you are authorizing [Your Company Name] and Stripe, our payment service provider, to send instructions to your bank to debit your account. You are entitled to a refund from your bank under the terms and conditions of your agreement with your bank.

Include Stripe.js in your page:



 

Step 8: Initialize Stripe Elements and Create the IBAN Element

 


const stripe = Stripe('pk_test_your_publishable_key');
const elements = stripe.elements();

// Create an IBAN Element
const ibanElement = elements.create('iban', {
  supportedCountries: ['SEPA'],
  placeholderCountry: 'DE',
  style: {
    base: {
      color: '#32325d',
      fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
      fontSize: '16px',
      '::placeholder': {
        color: '#aab7c4'
      }
    },
    invalid: {
      color: '#fa755a'
    }
  }
});

// Mount the IBAN Element to the DOM
ibanElement.mount('#iban-element');

// Handle validation errors
ibanElement.on('change', (event) => {
  const displayError = document.getElementById('error-message');
  if (event.error) {
    displayError.textContent = event.error.message;
  } else {
    displayError.textContent = '';
  }
});

 

Step 9: Handle Form Submission and Create a Payment Method

 


const form = document.getElementById('payment-form');

form.addEventListener('submit', async (event) => {
  event.preventDefault();
  
  const nameInput = document.getElementById('name');
  const email = document.getElementById('email').value;
  
  // Create a PaymentMethod for sepa\_debit
  const result = await stripe.createPaymentMethod({
    type: 'sepa\_debit',
    sepa\_debit: ibanElement,
    billing\_details: {
      name: nameInput.value,
      email: email
    }
  });
  
  if (result.error) {
    // Show error to your customer
    const errorElement = document.getElementById('error-message');
    errorElement.textContent = result.error.message;
  } else {
    // Send PaymentMethod ID to your server
    const paymentMethodId = result.paymentMethod.id;
    confirmPayment(paymentMethodId);
  }
});

 

Step 10: Confirm the Payment on Your Server

 

Create a server endpoint to confirm the payment:

For Node.js:


app.post('/confirm-payment', async (req, res) => {
  const { paymentMethodId, paymentIntentId } = req.body;
  
  try {
    const paymentIntent = await stripe.paymentIntents.confirm(paymentIntentId, {
      payment\_method: paymentMethodId
    });
    
    res.send({ success: true, paymentIntent });
  } catch (error) {
    res.send({ error: error.message });
  }
});

And call it from your frontend:


async function confirmPayment(paymentMethodId) {
  const response = await fetch('/confirm-payment', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      paymentMethodId: paymentMethodId,
      paymentIntentId: 'id; ?>' // Pass from your server
    })
  });
  
  const result = await response.json();
  
  if (result.error) {
    // Show error to your customer
    const errorElement = document.getElementById('error-message');
    errorElement.textContent = result.error;
  } else {
    // Success! Show confirmation to your customer
    document.getElementById('payment-form').style.display = 'none';
    document.getElementById('success-message').style.display = 'block';
  }
}

 

Step 11: Handle SEPA Direct Debit Mandate

 

SEPA Direct Debit requires a mandate from the customer. The mandate is automatically generated by Stripe, but you should display it to the customer:


// After successful payment method creation
const mandateAcceptance = document.getElementById('mandate-acceptance');
mandateAcceptance.innerHTML = \`
  By providing your payment information and confirming this payment, you authorize 
  (A) ${result.paymentMethod.sepa_debit.mandate_reference} and Stripe, our payment service provider, 
  to send instructions to your bank to debit your account and (B) your bank to debit your account in 
  accordance with those instructions. As part of your rights, 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.
\`;

 

Step 12: Set Up Webhook Handling for SEPA Direct Debit Events

 

SEPA Direct Debit payments are not instant and require webhook handling:


// Node.js webhook handler example
app.post('/webhook', express.raw({type: 'application/json'}), async (req, res) => {
  const sig = req.headers['stripe-signature'];
  let event;

  try {
    event = stripe.webhooks.constructEvent(req.body, sig, 'whsec_your_webhook\_secret');
  } catch (err) {
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }

  // Handle specific SEPA Direct Debit events
  switch (event.type) {
    case 'payment\_intent.succeeded':
      const paymentIntent = event.data.object;
      console.log('PaymentIntent succeeded:', paymentIntent.id);
      // Update your database, fulfill order, etc.
      break;
      
    case 'payment_intent.payment_failed':
      const failedPayment = event.data.object;
      console.log('Payment failed:', failedPayment.id, failedPayment.last_payment_error?.message);
      // Notify customer, update database, etc.
      break;
      
    case 'charge.succeeded':
      const charge = event.data.object;
      console.log('Charge succeeded:', charge.id);
      break;
      
    default:
      console.log(`Unhandled event type ${event.type}`);
  }

  res.json({received: true});
});

 

Step 13: Test SEPA Direct Debit Integration

 

Before going live, test your integration using Stripe's test mode:

  • Use test IBAN numbers like DE89370400440532013000
  • Test the full payment flow using Stripe's test clock feature to simulate the passing of time
  • Verify webhook delivery using the Stripe CLI or webhook testing tools
  • Test both successful payments and failures using different test IBANs

 

Step 14: Go Live with Your SEPA Direct Debit Integration

 

When you're ready to accept real payments:

  • Switch your API keys from test to live mode in your Stripe Dashboard
  • Update your code to use the live API keys
  • Update your webhook endpoint to use the live webhook secret
  • Perform a real test transaction with a small amount to ensure everything works properly
  • Monitor your Stripe Dashboard for incoming payments and potential issues

 

Step 15: Implement Additional Features (Optional)

 

Enhance your SEPA Direct Debit integration with these additional features:

  • Set up recurring payments using Stripe Subscriptions
  • Implement automatic retry logic for failed payments
  • Create automated email notifications for payment status changes
  • Add a customer portal for managing SEPA mandates and payment methods
  • Implement fraud detection measures specific to SEPA payments

// Example of creating a subscription with SEPA Direct Debit
const subscription = await stripe.subscriptions.create({
  customer: 'cus_customer_id',
  items: [
    { price: 'price_monthly_subscription' },
  ],
  payment\_settings: {
    payment_method_types: ['sepa\_debit'],
    save_default_payment_method: 'on_subscription'
  },
  expand: ['latest_invoice.payment_intent']
});

Want to explore opportunities to work with us?

Connect with our team to unlock the full potential of no-code solutions with a no-commitment consultation!

Book a Free Consultation

Client trust and success are our top priorities

When it comes to serving you, we sweat the little things. That’s why our work makes a big impact.

Rapid Dev was an exceptional project management organization and the best development collaborators I've had the pleasure of working with. They do complex work on extremely fast timelines and effectively manage the testing and pre-launch process to deliver the best possible product. I'm extremely impressed with their execution ability.

CPO, Praction - Arkady Sokolov

May 2, 2023

Working with Matt was comparable to having another co-founder on the team, but without the commitment or cost. He has a strategic mindset and willing to change the scope of the project in real time based on the needs of the client. A true strategic thought partner!

Co-Founder, Arc - Donald Muir

Dec 27, 2022

Rapid Dev are 10/10, excellent communicators - the best I've ever encountered in the tech dev space. They always go the extra mile, they genuinely care, they respond quickly, they're flexible, adaptable and their enthusiasm is amazing.

Co-CEO, Grantify - Mat Westergreen-Thorne

Oct 15, 2022

Rapid Dev is an excellent developer for no-code and low-code solutions.
We’ve had great success since launching the platform in November 2023. In a few months, we’ve gained over 1,000 new active users. We’ve also secured several dozen bookings on the platform and seen about 70% new user month-over-month growth since the launch.

Co-Founder, Church Real Estate Marketplace - Emmanuel Brown

May 1, 2024 

Matt’s dedication to executing our vision and his commitment to the project deadline were impressive. 
This was such a specific project, and Matt really delivered. We worked with a really fast turnaround, and he always delivered. The site was a perfect prop for us!

Production Manager, Media Production Company - Samantha Fekete

Sep 23, 2022