
Bun.js + Stripe Webhooks + Drizzle: Zahlungen ohne Duplikate
Stripe-Webhooks mit Bun.js sicher verarbeiten: Signaturprüfung, PostgreSQL-Event-Ledger, Idempotenz und transaktionssichere Geschäftslogik.
Bun liest den Raw Body, das Stripe SDK prüft die Signatur und PostgreSQL speichert die Event-ID vor der Geschäftslogik. Ein Duplikat wird im Ledger erkannt und als No-op beendet.
Warum ein Webhook kein normaler Callback ist
Stripe kann Zustellung wiederholen, Events in anderer Reihenfolge liefern oder nach einem temporären Serverfehler erneut senden.
01
Stripe sendet ein signiertes Event
Der Payload enthält Stripe-Signature. Vor der Prüfung darf JSON nicht vertraut werden.
02
Bun prüft den Raw Body
request.text() statt request.json() lesen: Parsing kann signierte Bytes verändern.
03
Das Ledger erkennt Duplikate
Eine eindeutige event.id verhindert doppelte Geschäftsoperationen.
04
Eine Transaktion ändert die Domain
Payment-Status oder Entitlement ändern und Event atomar als verarbeitet markieren.
Die doppelte Zustellung stoppt bei Idempotency; der Business-Job läuft erst nach der Prüfung.
Screenshot des Abschnitts architectureSchritt 1: SDK und Secrets
SDK installieren
bun add stripe drizzle-orm postgres
bun add -d drizzle-kitSecrets konfigurieren
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
DATABASE_URL=postgres://app:app@localhost:5432/paymentsDas Secret der Stripe CLI und das Production-Secret sind verschieden.
Event-Ledger anlegen
export const stripeEvents = pgTable("stripe_events", {
id: text("id").primaryKey(),
type: text("type").notNull(),
processedAt: timestamp("processed_at", { withTimezone: true }),
receivedAt: timestamp("received_at", { withTimezone: true }).defaultNow().notNull(),
});Der Primary Key ist die letzte Schutzschicht gegen Duplikate.
Schritt 2: Raw Body signieren
Rufe request.json() nicht vor constructEvent auf. Nach dem Parsing können die Bytes vom signierten Payload abweichen.
import Stripe from "stripe";
const stripe = new Stripe(Bun.env.STRIPE_SECRET_KEY!);
export async function verifyStripeRequest(request: Request) {
const signature = request.headers.get("stripe-signature");
if (!signature) throw new Response("Missing signature", { status: 400 });
const rawBody = await request.text();
return stripe.webhooks.constructEvent(rawBody, signature, Bun.env.STRIPE_WEBHOOK_SECRET!);
}constructEvent prüft HMAC-Signatur und Zeitfenster. Alles andere ablehnen.
Schritt 3: idempotenter Drizzle-Handler
Füge das Event zuerst ein. Ein Conflict bedeutet eine erneute Zustellung — die Geschäftslogik darf nicht erneut laufen.
export async function processEvent(event: Stripe.Event) {
const inserted = await db.insert(stripeEvents).values({ id: event.id, type: event.type }).onConflictDoNothing().returning();
if (inserted.length === 0) return { duplicate: true };
await db.transaction(async (tx) => {
if (event.type === "checkout.session.completed") {
const session = event.data.object as Stripe.Checkout.Session;
// Bestellung auf paid setzen, z. B. mit tx.update(...).
}
await tx.update(stripeEvents).set({ processedAt: new Date() }).where(eq(stripeEvents.id, event.id));
});
return { duplicate: false };
}Schritt 4: Endpoint und Retry-Policy
Gib 2xx erst zurück, wenn das Event geprüft und verarbeitet wurde oder schon im Ledger steht. Bei einem temporären Datenbankfehler muss Stripe mit 500 erneut senden.
export async function POST(request: Request) {
try {
const event = await verifyStripeRequest(request);
await processEvent(event);
return new Response("ok", { status: 200 });
} catch (error) {
console.error("stripe webhook failed", error);
return new Response("retry", { status: 500 });
}
}Langsame Jobs nach dem Commit in eine Queue stellen; keine unbegrenzten Network Calls im Webhook-Request.
Lokal mit der Stripe CLI testen
Events weiterleiten
stripe listen --forward-to http://localhost:3000/api/stripe/webhookEvent auslösen
stripe trigger checkout.session.completedDuplikat prüfen
Dasselbe Event zweimal senden: eine Geschäftsänderung und danach { duplicate: true }. Signaturprüfung niemals in CI deaktivieren.
Production-Checkliste
Signatur und Zeitstempel prüfen
Frontend-Daten oder Event-Typ allein beweisen keine Zahlung.
Payload schützen
JSON nur für Audit speichern, Zugriffe begrenzen und Secrets aus Logs entfernen.
Webhook-Secrets rotieren
Separate Secrets pro Umgebung und definierte Rotation verwenden.
Fehler überwachen
Auf 5xx, steigende Duplikate und unverarbeitete Ledger-Zeilen alarmieren.
FAQ
Nicht vor der Signaturprüfung. Zuerst request.text() lesen, mit dem Stripe SDK prüfen und erst dann Event-Daten verwenden.
In der Regel 200, weil es bereits verarbeitet wurde. Bei einem temporären Datenbankfehler 500 zurückgeben, damit Stripe erneut zustellt.
Fazit
Beschreiben Sie die Aufgabe — die ersten 15 Minuten der Beratung sind kostenlos.
Verwandte Artikel

AI Assistant Entwicklung Kosten 2026: RAG, Knowledge Base, Integrationen und Support
Praktischer Leitfaden zu Kosten fuer AI Assistants: RAG, Knowledge Base, Channels, Tool Use, Guardrails, Evaluations, Monitoring und Support.

KI fur Landingpage-Entwicklung: wo sie Launches beschleunigt und wo sie Conversion schadet
Eine praxisnahe Analyse zur Nutzung von KI fur Landingpages: v0, Webflow AI, Builder.io, Framer-ahnliche Builder, UX-Generierung, Copy, SEO, Personalisierung, A/B-Tests, Template-Risiken, Accessibility, Security und technischer Schuldenaufbau.

AI SEO / GEO im Jahr 2026: Ihre nächsten Kunden sind nicht Menschen — sondern Agents
Suche verschiebt sich von Klicks zu Antworten. Bots und AI-Agents crawlen, zitieren, empfehlen — und kaufen zunehmend. Erfahren Sie, was AI SEO / GEO bedeutet, warum klassisches SEO nicht mehr reicht und wie PAS7 Studio Marken im agentischen Web sichtbar macht.

Der leistungsstärkste Chip von Apple? M5 Pro und M5 Max brechen Rekorde
Eine Analyse zu Apple M5 Pro und M5 Max im März 2026. Wir zeigen, warum diese Chips als die stärksten professionellen Laptop-SoCs von Apple gelten können, wie sie sich gegen M4 Pro, M4 Max, M1 Pro, M1 Max schlagen und was der Vergleich mit aktuellen Intel- und AMD-Chips zeigt.
Professionelle Entwicklung für Ihr Geschäft
Wir erstellen moderne Web-Lösungen und Bots für Unternehmen. Erfahren Sie, wie wir Ihnen helfen können, Ihre Ziele zu erreichen.