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.
Book a call with an Expert
Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.
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:
Step 2: Enable SEPA Direct Debit in Your Stripe Dashboard
To activate SEPA Direct Debit as a payment method in your Stripe account:
Step 3: Set Up Your Account Details
SEPA Direct Debit requires specific business information:
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:
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:
Step 14: Go Live with Your SEPA Direct Debit Integration
When you're ready to accept real payments:
Step 15: Implement Additional Features (Optional)
Enhance your SEPA Direct Debit integration with these additional features:
// 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']
});
When it comes to serving you, we sweat the little things. That’s why our work makes a big impact.