Die Abrechnung in digitalen Produkten und Dienstleistungen war lange Zeit fest in der Hand des Backends. Klassische Zahlungssysteme setzen auf sichere geheime Schlüssel, Webhooks und synchronisierten Status zwischen Server und Frontend, um Transaktionen abzuwickeln. Doch dieses Modell bringt Komplexität mit sich, die sowohl für Entwickler als auch für Endnutzer hinderlich sein kann. Unser Ziel war es, die Abrechnung auf eine völlig neue Ebene zu heben und das gesamte Zahlungserlebnis direkt im Frontend zu ermöglichen – eine sogenannte 'backendlose' Abrechnung. Die Vorstellung dahinter ist verlockend: Entwickler sollten Zahlungen, Upgrades, Downgrades und Paywalls mit minimalem Setup und ohne komplizierte Serverlogik handhaben können.
Im Folgenden erläutern wir den Weg, den wir dabei eingeschlagen haben, die Herausforderungen, denen wir begegnet sind, und warum wir schlussendlich einige der eigenen Konzepte wieder hinterfragten. Am Anfang stand die Erkenntnis, dass viele unserer Nutzer noch nie zuvor mit Stripe oder ähnlichen Payment Anbietern gearbeitet hatten. Stripe stellt klare Richtlinien auf: Es gibt geheime Schlüssel für sensible Operationen und sogenannte Publishable Keys, die nur unsensible Tasks vom Frontend aus abwickeln. Wir wollten von Anfang an Weg von der separaten Backend-Schicht und hin zu einer Lösung, bei der Entwickler sogar Zahlungsvorgänge über das Frontend auslösen können. Unsere erste Idee war die Einführung eines eigenen "Publishable Keys", mit dem Entwickler etwa Zahlungslinks generieren oder checken konnten, ob ein Nutzer über eine gültige Abo-Lizenz verfügt.
Das klang zunächst vielversprechend, denn einfache Operationen wie das Abrufen von Feature-Zugängen können ja theoretisch nicht missbraucht werden. Doch schon sehr bald wurde klar, dass dieser Ansatz an seine Grenzen stieß. Zum einen funktionierte er nur mit ausgewählten Schnittstellen; komplexere Konzepte wie das Tracking von Nutzung, etwa für Gebrauchsmengen-Abrechnung, waren weiterhin nur über geheime Schlüssel möglich. Das führte bei Entwicklern zu Verwirrung: Welche Endpunkte sind mit welchem Schlüssel zu nutzen? Dies erhöhte die Fehleranfälligkeit der Integration maßgeblich. Ein weiteres, besonders dramatisches Problem lag beim automatischen Wiederkauf: Wenn ein Nutzer bereits einmal ein Upgrade gekauft hatte, sollte das System automatisch weitere Käufe abwickeln können.
Dieses Szenario ist jedoch mit publik zugänglichen Schlüsseln grundsätzlich nicht umsetzbar, denn es bedarf einer sicheren Verifizierung des Kunden, die nur das Backend gewährleisten kann. Auch wenn dieses initiale Feature vielen den Start erleichterte, wurde es rasch obsolet. In der Praxis musste der „Publishable Key“-Ansatz oft entfernt oder stark angepasst werden, was wiederum Frust bei unseren Anwendern auslöste. Dennoch besteht der Ansatz noch in unserer Dokumentation und sorgt dort immer wieder für Missverständnisse. Das nächste Kapitel unseres Projekts wandte sich dem vielversprechenden Konzept der Server Actions zu, inspiriert von modernen Frameworks wie Next.
js. Server Actions bieten die Möglichkeit, vom Frontend aus Funktionen aufzurufen, die sicher auf dem Server laufen und dabei Umgebungsvariablen wie geheime Schlüssel nutzen können. Das klingt ideal, denn so können Entwickler im Frontend „normale“ Funktionen verwenden, ohne sich um Routing oder Sicherheit zu sorgen. Anfangs wirkte die Nutzererfahrung sogar fast magisch. Doch beim genaueren Hinsehen offenbarte sich ein gravierender Sicherheitsmangel: Server Actions sind standardmäßig öffentlich und nicht authentifiziert.
Wenn man also beispielsweise einen Kundenidentifikator (customer_id) in den Request einbaute, konnte theoretisch jede beliebige Person mit dieser ID auf deren Ressourcen zugreifen. Böswillige Akteure hätten so Upgrades durchführen, Nutzungsdaten manipulieren oder andere kritische Aktionen unter fremdem Namen durchführen können. Dies war eine bedrohliche Schwachstelle, die unseren hohen Sicherheitsansprüchen nicht genügen konnte. Davon wollten wir uns jedoch nicht entmutigen lassen, denn die Entwicklererfahrung der Server Actions war unvergleichlich. Also suchten wir nach einer Lösung, die diese Sicherheitslücke zuverlässig verschließt, ohne die einfache Bedienbarkeit aufzugeben.
Unser Weg führte uns zu einer eigens implementierten Verschlüsselungslösung für den customer_id-Parameter. Die Idee war simpel aber wirkungsvoll: Die Kundendaten werden bereits serverseitig in einem Provider-Komponentenverschlüsselt und als verschlüsselter Wert an die Client-Komponenten weitergegeben. Das Benutzerfrontend erhielt so nur einen verschlüsselten Token, der den Kunden identifizierte. Bei jedem Server Action Aufruf übergab der Client diesen verschlüsselten Wert zurück, der beim Server wieder entschlüsselt wurde, um die tatsächliche Kunden-ID sicher und verborgen zu erhalten. Dieser Mechanismus wirkte im Grunde wie eine eigene Authentifizierungsstufe, quasi eine individuell generierte Signatur, die den Zugang zu sensiblen Aktionen authentifizierte.
Diese Lösung ermöglichte es uns, alle gängigen Anwendungsfälle aus dem Frontend heraus abzudecken: sichere Upgrades, Downgrades, Nutzungserfassung und noch vieles mehr, ganz ohne Backend-Routing-Setup. Der Nutzen dieser Verschlüsselungslösung war groß und beeindruckend. Allerdings stellte sich auch heraus, dass sie nur mit Frameworks funktionierte, die Server Actions unterstützen. Da der Markt sich dynamisch verändert und etwa SPAs (Single Page Applications) auf Basis von Vite und anderen modernen Tools wieder stark an Bedeutung gewinnen, wurde klar, dass diese Lösung nicht universell anwendbar war. Unterschiede in der Implementierung und Framework-Beschränkungen erschweren die breite Nutzung.
Dies brachte uns zu der Überlegung, dass man vielleicht gar nicht versuchen sollte, ganz ohne Backend-Routen auszukommen. Stattdessen wäre ein Konzept besser, das Backend- und Frontend-Handling in einem sauberen Standard zu vereinheitlichen und so die Einrichtung für Entwickler zu vereinfachen. Andere Anbieter wie Take Better Auth oder Polar verwenden genau diesen Ansatz. Sie bieten standardisierte Backends mit lediglich wenigen Zeilen Code an, was Installation und Wartung sehr übersichtlich macht. Gleichzeitig sorgen sie für maximale Sicherheit, weil kritische Aktionen serverseitig authentifiziert bleiben.
Dieser Mittelweg kann das beste aus zwei Welten bieten: einfache Entwicklererfahrung kombiniert mit robuster Sicherheit. Dass wir versuchen wollten, das Backend komplett zu eliminieren, war am Ende zwar ein ambitionierter, aber vielleicht nicht der beste Weg für diese Art von Anwendung. Aus unserer Sicht ist klar, dass die Zukunft der Abrechnungssysteme in flexiblen Architekturen liegt, die sowohl moderne Frontend-Techniken unterstützen, als auch bewährte Sicherheitskonzepte für den Server integrieren. Vollständig backendlose Lösungen mögen in manchen Szenarien funktionieren, gerade im Kontext einfachster Aufgaben, aber bei der Handhabung von sensiblen Zahlungsvorgängen und Nutzeridentitäten braucht es klare Authentifizierungsschritte, die sich nicht umgehen lassen. Die beste Nutzererfahrung wird deshalb erreicht, wenn Developer-Tools es schaffen, Sicherheitspraktiken zu automatisieren und zu vereinfachen, anstatt sie komplett abzuschaffen.
Mit unseren Erfahrungen hoffen wir Entwickler weltweit praktische Anregungen zu geben und den Diskurs rund um Entwicklererlebnis und Sicherheit in der digitalen Zahlungswelt mit voranzutreiben. Es ist spannend zu beobachten, wie die Branche immer neue Wege findet, technische Herausforderungen zu meistern und gleichzeitig den Einstieg und die Integration für Entwickler so angenehm wie möglich zu gestalten. Ob uns der komplette Verzicht auf das Backend tatsächlich noch gelingen wird, bleibt offen. Für den Moment liegt der Fokus darauf, die Balance zwischen Usability und Sicherheit weiter zu optimieren und native, robuste Lösungen für die breite Entwicklergemeinschaft bereitzustellen.