Wie uns Stripe hilft, das bestmögliche Buchungserlebnis bereitzustellen

Wer bei Psychofit einen Termin bucht, wählt einen Slot, bezahlt und hat den Termin. Dazwischen liegen eine Reservierung, ein Stripe-Checkout und ein Webhook. All das haben wir selbst gebaut. Seit Februar 2026 läuft es ohne Calendly. Stripe ist seit unserer ersten Zahlung im März 2024 unser einziger Zahlungsdienstleister.
Dieser Beitrag erzählt, warum wir es so gebaut haben und welche Entscheidungen im Betrieb wichtig wurden. Er richtet sich an alle, die Ähnliches vorhaben, und an alle, die wissen wollen, was nach dem Klick auf „Jetzt bezahlen" passiert.
Wer wir sind
Psychofit bietet niedrigschwellige psychologische Online-Beratung für Selbstzahler:innen in Deutschland. Das ist psychologische Beratung, keine Psychotherapie und keine Kassenleistung. Gegründet haben Psychofit zwei Personen, die Plattform bauen wir selbst. Die Beratung übernehmen Psycholog:innen mit mindestens Bachelorabschluss aus unserem Partnernetzwerk, unter Supervision approbierter Psychotherapeut:innen. Seit 2023 finanzieren wir uns vollständig ohne Fremdkapital.
Wir wollen das beste Angebot dieser Art in Deutschland sein. Worauf wir diesen Anspruch stützen, steht in unserem Preisversprechen, wofür wir das tun, in Mission und Vision. Der Anlass sind die langen Wartezeiten auf einen Therapieplatz. Die aktuellen Preise finden Sie auf unserer Preisseite.
Die Vorgeschichte: Stripe ja, Calendlys Zahlung nein
Unsere ersten Zahlungen liefen 2024 über Stripe Payment Links, verlinkt in den Terminbestätigungen von Calendly. Calendlys eingebaute Zahlung haben wir nicht genutzt, weil sie Karte und PayPal nicht nebeneinander anbieten konnte.
Calendly hat das in der eigenen Community mehrfach bestätigt. Im November 2023 hieß es dort, dass über die Stripe-Anbindung nur mit Karte bezahlt werden kann (Calendly Community, November 2023). Im Februar und März 2024 folgte die Antwort, dass pro Termintyp entweder Stripe oder PayPal angebunden werden kann, nicht beides (Februar 2024, März 2024). Apple Pay und Google Pay kamen zur Stripe-Anbindung von Calendly erst im Juni 2025 dazu (Calendly Community, Juni 2025).
Payment Links lösten das für uns: ein Bezahlformular mit allen Zahlungsarten, die wir in Stripe freigeschaltet hatten. Noch im Januar 2026 haben wir Calendlys Zahlung ein zweites Mal ausprobiert und sind wieder bei derselben Wahl gelandet, Karte oder PayPal. Live geschaltet haben wir sie nie.
| Zeitpunkt | Was passiert ist |
|---|---|
| März 2024 | Erste Zahlung über Stripe Payment Links, verlinkt in den Calendly-Bestätigungen |
| Januar 2026 | Zweiter Versuch mit Calendlys eingebauter Zahlung, nie live geschaltet |
| Februar 2026 | Calendly abgelöst: eigenes Buchungssystem, bezahlt wird direkt im Custom Checkout auf psychofit.de |
Warum Calendly ganz raus ist
Mit Calendly endete die Buchung auf einer fremden Seite. Damit riss auch unsere Messung ab, ob aus einem Besuch eine Buchung wurde. Im Februar 2026 haben wir das geändert.
Der Umbau war ein einzelner Commit am 14. Februar 2026: 55 Dateien, 1.350 Zeilen dazu, 4.517 Zeilen weg. Allein der Webhook, der Calendly-Termine in unsere Datenbank übersetzte, hatte 1.009 Zeilen. Seitdem gehören Verfügbarkeit, Slot-Berechnung, Reservierung und Buchung uns und der Checkout läuft auf psychofit.de.
Der Checkout auf unserer eigenen Seite
Unser Anspruch ist das beste Buchungserlebnis, das wir bauen können. Deshalb läuft der ganze Weg vom Slot bis zur Bestätigung auf psychofit.de.
Während der Entwicklung haben wir zuerst den eingebetteten Stripe Checkout getestet. Am 20. Februar 2026 schrieb uns Stripes Produktteam, fragte nach Feedback zu dieser Integration und stellte eine neue einbettbare Variante vor. Das war der Anstoß, genauer hinzusehen. Live gegangen sind wir Ende Februar 2026 direkt mit Custom Checkout, dem Payment Element und der Appearance API. Für unsere Kund:innen ging es also ohne Zwischenschritt von den Payment Links zum eigenen Checkout.
Für die Kundin heißt das: kein Sprung zu einem anderen Anbieter mitten in der Buchung, Psychofit-Farben, ein Dunkelmodus und beim nächsten Termin eine gespeicherte Karte, wenn sie das beim ersten Mal selbst ausgewählt hat.
Der eingebettete Checkout blieb als Rückfall im Code, umschaltbar über einen Schalter im Admin-Bereich. Wäre etwas schiefgegangen, wäre er einen Klick entfernt gewesen.
Sechs Zahlungsarten, alle über Stripe
Bei uns kann man mit Kreditkarte (Visa, Mastercard), Apple Pay, Google Pay, Klarna, SEPA-Lastschrift und PayPal bezahlen. Welche Arten erscheinen, schalten wir im Stripe-Dashboard, nicht im Code. Genutzt werden alle davon, bunt gemischt. Karte und PayPal in einem Formular: Genau das ging bei Calendly nicht.
Sieben Entscheidungen aus dem Betrieb
1. Drei Schichten gegen Doppelbuchung
Zwei Menschen dürfen nie denselben Termin bekommen. Dafür prüfen wir dreimal.
Zuerst vergleicht die Reservierung den Slot mit bestehenden Buchungen, laufenden Reservierungen und den Pufferzeiten der beratenden Person. Die letzte Wahrheit ist eine Eindeutigkeitsregel in der Datenbank auf beratende Person und Startzeit. Kommt trotzdem eine zweite Reservierung durch, lehnt die Datenbank sie ab. Wir unterscheiden dann, ob dieselbe Person doppelt geklickt hat oder ob jemand anderes schneller war. Im ersten Fall gilt einfach ihre bestehende Reservierung.
Die dritte Schicht betrifft das Verlassen der Seite. Wer den Buchungsschritt schließt, gibt den Slot per sendBeacon sofort wieder frei. Dieses Signal feuert aber auch, wenn die Seite während der Zahlung wechselt. Hat die Reservierung schon eine Stripe-Session, geben wir sie deshalb nicht frei.
2. Zwei Lebensdauern für eine Reservierung
Eine Reservierung hält fünf Minuten, solange die Kundin noch auswählt. Sobald es eine Stripe-Session gibt, verlängern wir auf 35 Minuten, passend zur Ablaufzeit der Session (expires_at).
Ohne diese Verlängerung würde ein Aufräum-Job die Reservierung löschen, während die Kundin noch bezahlt, und der Webhook fände danach nichts mehr.
3. Metadata als Ausfallsicherung
Jede Checkout-Session trägt in ihrer Metadata die Angaben, mit denen wir die Buchung notfalls auch ohne unsere Reservierung anlegen können: beratende Person, Termintyp und Startzeit. Ist die Reservierung beim Eintreffen des Webhooks trotzdem weg, baut der Webhook daraus eine Ersatz-Reservierung.
Scheitert auch das, bekommt das Team sofort eine Alarm-Mail mit den Zahlungsdaten. Eine Zahlung ohne Buchung darf nicht still im Log verschwinden. Stripe erlaubt 500 Zeichen pro Metadata-Wert, Freitexte kürzen wir deshalb bewusst auf 450.
4. Idempotenz über die Buchung, nicht über Event-IDs
Stripe kann denselben Webhook mehr als einmal schicken (Stripe-Doku zu Webhooks). Vor dem Anlegen prüfen wir deshalb, ob es zur Session schon eine Buchung gibt, und die Reservierung trägt die Session-ID als eindeutigen Wert. Einen eigenen Speicher für verarbeitete Events brauchen wir dadurch nicht.
Bei der Erstattung nach einer Paketkündigung schicken wir Stripe zusätzlich einen Idempotenzschlüssel pro Paket mit und das Paket wird geschlossen, bevor das Geld zurückgeht. Eine wiederholte Anfrage kann so weder doppelt erstatten noch ein Guthaben stehen lassen.
5. Der gezahlte Betrag ist die Wahrheit
Wir speichern den Betrag, den Stripe tatsächlich abgebucht hat (amount_total), und nicht den Listenpreis. Rabatte, Aktionen und der ermäßigte Tarif sorgen dafür, dass beides oft auseinanderliegt. Bei einem Sitzungspaket wies unsere Auswertung einmal 199 € aus, obwohl 159,20 € geflossen waren. Seitdem zählt nur, was wirklich bezahlt wurde.
6. Ein aufgebrauchter Rabattcode lässt keine Buchung scheitern
Bei Stripe schließen sich ein automatisch gesetzter Rabattcode (discounts) und das Feld, in das Kund:innen selbst einen Code eingeben (allow_promotion_codes), gegenseitig aus. Wir setzen je nach Fall das eine oder das andere.
Ist ein automatisch gesetzter Code im Moment der Buchung schon aufgebraucht oder abgelaufen, lehnt Stripe die Session ab. Wir erkennen diesen Fehler und legen die Session zum regulären Preis neu an. Die Kundin sieht den tatsächlichen Betrag vor dem Bezahlen und die Buchung hängt nicht an einem Rabatt.
7. Erstattungen: täglicher Abgleich statt Webhook
Erstattungen lösen wir im Stripe-Dashboard aus, ein täglicher Abgleich holt sie in unsere Datenbank. Einen Webhook haben wir dafür bewusst nicht gebaut. Er bräuchte pro Umgebung ein eigenes Abo im Dashboard, getrennt für Test und Live, und ein vergessenes Abo fällt niemandem auf. Der Abgleich läuft mit dem Schlüssel, den wir ohnehin haben, und holt auch ältere Erstattungen nach.
Drei Dinge haben wir dabei gelernt:
- Stripe einmal nach allen Erstattungen des Zeitraums fragen, nicht einmal pro Buchung. Sonst läuft der Job in sein Zeitlimit.
- Laufbetrieb und Nachholen trennen. Die letzten 14 Tage kommen immer zuerst, ältere Erstattungen bis zu einem Jahr zurück danach in kleinen Portionen.
- Die Gesamtsumme von der Zahlung lesen (
amount_refunded) und nicht die einzelne Erstattung. Sonst würden zwei Teilerstattungen je für sich gegen den vollen Betrag geprüft und keine erreicht ihn.
Warum Stripe bei uns sichtbar ist
Im Footer jeder Seite steht das Badge „Powered by Stripe" und im Checkout verlinken wir auf Stripe. Ein Bezahlformular braucht Vertrauen und Stripe nimmt uns viel ab: die Zahlungsarten, den Schutz der Kartendaten, die Bestätigung durch die Bank per 3D Secure und die Erstattungen. So bleibt mehr Zeit für das, worum es bei Psychofit geht: gute Beratung.
Wir haben nie mit einem anderen Zahlungsdienstleister gearbeitet und haben es auch nicht vor.
Alle Angaben in diesem Artikel wurden sorgfältig recherchiert, erfolgen jedoch ohne Gewähr. Preise, Wartezeiten und gesetzliche Regelungen können sich ändern. Stand: September 2026.
