Webhook-Integration

Einrichtung und Verarbeitung von Webhooks des Zahlungsanbieters für Abonnementereignisse.

Hinweis: Dies sind Beispiel- bzw. Platzhalterinhalte zu Demonstrationszwecken.

Webhooks benachrichtigen Ihre Anwendung, wenn Abrechnungsereignisse eintreten, und sorgen so dafür, dass Ihre App mit Ihrem Zahlungsanbieter synchron bleibt.

Warum Webhooks?

Webhooks sind unverzichtbar für:

  • Echtzeit-Updates – Sofortige Benachrichtigung über Zahlungsereignisse
  • Zuverlässigkeit – Verarbeitet Ereignisse auch dann, wenn Nutzer ihren Browser schließen
  • Sicherheit – Kommunikation von Server zu Server
  • Automatisierung – Automatische Aktualisierung des Abonnementstatus

Webhook-Endpunkt

Ihr Webhook-Endpunkt empfängt Ereignisse vom Zahlungsanbieter:

// app/api/billing/webhook/route.ts
export async function POST(request: Request) {
  const body = await request.text();
  const signature = request.headers.get('stripe-signature');

  // Webhook-Signatur überprüfen
  const event = stripe.webhooks.constructEvent(
    body,
    signature,
    process.env.STRIPE_WEBHOOK_SECRET
  );

  // Ereignis verarbeiten
  await handleBillingEvent(event);

  return new Response('OK', { status: 200 });
}

Häufige Ereignisse

Abonnement erstellt

case 'customer.subscription.created':
  await prisma.subscription.create({
    data: {
      id: event.data.object.id,
      accountId: event.data.object.metadata.accountId,
      status: 'active',
      planId: event.data.object.items.data[0].price.id,
      currentPeriodEnd: new Date(event.data.object.current_period_end * 1000),
    },
  });
  break;

Abonnement aktualisiert

case 'customer.subscription.updated':
  await prisma.subscription.update({
    where: { id: event.data.object.id },
    data: {
      status: event.data.object.status,
      planId: event.data.object.items.data[0].price.id,
      currentPeriodEnd: new Date(event.data.object.current_period_end * 1000),
    },
  });
  break;

Abonnement gelöscht

case 'customer.subscription.deleted':
  await prisma.subscription.update({
    where: { id: event.data.object.id },
    data: {
      status: 'canceled',
      canceledAt: new Date(),
    },
  });
  break;

Zahlung fehlgeschlagen

case 'invoice.payment_failed':
  const subscription = await prisma.subscription.findUnique({
    where: { id: event.data.object.subscription },
  });

  // Benachrichtigung über fehlgeschlagene Zahlung senden
  await sendPaymentFailureEmail(subscription.accountId);
  break;

Webhooks einrichten

Stripe

  1. Lokale Entwicklung (mit der Stripe CLI):
stripe listen --forward-to localhost:3000/api/billing/webhook
  1. Produktion:
  • Gehen Sie zu Stripe Dashboard → Developers → Webhooks
  • Fügen Sie den Endpunkt hinzu: https://yourdomain.com/api/billing/webhook
  • Wählen Sie die Ereignisse aus, die empfangen werden sollen
  • Kopieren Sie das Webhook-Signaturgeheimnis in Ihre .env

Paddle

  1. Konfigurieren Sie die Webhook-URL im Paddle-Dashboard
  2. Fügen Sie das Webhook-Geheimnis zu den Umgebungsvariablen hinzu
  3. Überprüfen Sie die Webhook-Signatur:
const signature = request.headers.get('paddle-signature');
const verified = paddle.webhooks.verify(body, signature);

if (!verified) {
  return new Response('Invalid signature', { status: 401 });
}

Best Practices für die Sicherheit

  1. Signaturen immer überprüfen – Verhindert nicht autorisierte Anfragen
  2. HTTPS verwenden – Verschlüsselt Webhook-Daten bei der Übertragung
  3. Ereignisdaten validieren – Auf Pflichtfelder prüfen
  4. Idempotent verarbeiten – Doppelte Ereignisse sicher verarbeiten
  5. Schnell mit 200 antworten – Den Empfang bestätigen, asynchron verarbeiten

Fehlerbehandlung

async function handleBillingEvent(event: Event) {
  try {
    await processEvent(event);
  } catch (error) {
    // Fehler zur Fehlersuche protokollieren
    console.error('Webhook error:', error);

    // Fehlgeschlagenes Ereignis für erneuten Versuch speichern
    await prisma.failedWebhook.create({
      data: {
        eventId: event.id,
        type: event.type,
        payload: event,
        error: error.message,
      },
    });

    // Fehler werfen, um einen erneuten Versuch des Anbieters auszulösen
    throw error;
  }
}

Webhooks testen

CLI-Tools des Anbieters verwenden

# Stripe
stripe trigger customer.subscription.created

# Bestimmte Szenarien testen
stripe trigger payment_intent.payment_failed

Manuelles Testen

curl -X POST https://your-app.com/api/billing/webhook \
  -H "Content-Type: application/json" \
  -H "stripe-signature: test_signature" \
  -d @test-event.json

Monitoring

Überwachen Sie die Zustellung von Webhooks:

  • Antwortzeiten
  • Erfolgs- und Fehlerquoten
  • Dauer der Ereignisverarbeitung
  • Fehlgeschlagene Ereignisse, die manuelles Eingreifen erfordern

Die meisten Anbieter bieten Dashboards zur Webhook-Überwachung, die Zustellversuche und Fehlschläge anzeigen.