💳 feat(stripe): add SEPA Direct Debit payment option

- Add sepa_debit to payment_method_types for credit purchases
- Add sepa_debit to subscription checkout sessions
- Handle payment_intent.processing webhook for SEPA status tracking
- Add blueprint article analyzing payment options (Stripe vs LSV+/FinTS)

SEPA offers lower fees (0.8% vs 1.5%+€0.25) for DACH customers.
Payments are confirmed 3-14 days after checkout (bank processing).
This commit is contained in:
Till-JS 2026-02-16 12:05:19 +01:00
parent 0e8f6f134e
commit b5d7524c77
4 changed files with 543 additions and 3 deletions

View file

@ -69,13 +69,26 @@ export class StripeWebhookController {
});
// Handle relevant events
// Note: SEPA Direct Debit payments are not instant - they go through:
// 1. checkout.session.completed (payment_status may be 'unpaid' for SEPA)
// 2. payment_intent.processing (SEPA is being processed by banks)
// 3. payment_intent.succeeded (3-14 days later when bank confirms)
// Credits are only added on payment_intent.succeeded for safety.
switch (event.type) {
// Credit purchases via Checkout Session
case 'checkout.session.completed':
await this.handleCheckoutSessionCompleted(event.data.object as Stripe.Checkout.Session);
break;
// Credit purchases
// Payment processing (SEPA: bank is processing the debit)
case 'payment_intent.processing':
this.logger.log('Payment processing (SEPA in progress)', {
paymentIntentId: (event.data.object as Stripe.PaymentIntent).id,
});
// Purchase stays in 'pending' status until succeeded
break;
// Credit purchases - payment confirmed
case 'payment_intent.succeeded':
await this.handlePaymentSucceeded(event.data.object as Stripe.PaymentIntent);
break;

View file

@ -185,7 +185,7 @@ export class StripeService {
const session = await stripe.checkout.sessions.create({
customer: options.customerId,
mode: 'payment',
payment_method_types: ['card'],
payment_method_types: ['card', 'sepa_debit'],
line_items: [
{
price_data: {

View file

@ -139,7 +139,7 @@ export class SubscriptionsService {
const session = await this.stripe.checkout.sessions.create({
customer: stripeCustomerId,
mode: 'subscription',
payment_method_types: ['card'],
payment_method_types: ['card', 'sepa_debit'],
line_items: [
{
price: stripePriceId,