So fügst du deiner App Zahlungen hinzu: Checkout, Abos und Webhooks
Der einfachste Weg, Zahlungen in deine App einzubauen, ist Stripe: Nimm einen Zahlungslink, wenn du nur einen „Jetzt kaufen“-Button brauchst und Bestellungen von Hand abwickeln kannst, Stripe Checkout, wenn deine App wissen muss, wer bezahlt hat, und automatisch reagieren soll, und Checkout im Abo-Modus plus das Kundenportal von Stripe für wiederkehrende Abrechnung. In allen Fällen außer dem einfachsten brauchst du außerdem einen Webhook, also einen Server-Endpunkt, den Stripe aufruft, wenn eine Zahlung erfolgreich war. Teste alles mit den Testschlüsseln und Testkarten von Stripe, bevor du auf Live-Schlüssel umstellst.
Dieser Leitfaden erklärt jede Option, den Webhook-Teil, den die meisten Anleitungen auslassen, und was du prüfen solltest, bevor du echtes Geld annimmst. Die Angaben zu Stripe stammen aus der eigenen Dokumentation von Stripe, Stand September 2026.
Warum überhaupt einen Zahlungsdienstleister nutzen
Erhebe Kartennummern niemals über deine eigenen Formulare. Der Umgang mit rohen Kartendaten bringt dich in den Geltungsbereich von PCI DSS (dem Sicherheitsstandard der Kartenbranche) und ist ein ernstes Haftungsrisiko. Ein Zahlungsdienstleister wie Stripe hostet das Zahlungsformular, speichert die Karte, übernimmt die Bankauthentifizierung und teilt deiner App das Ergebnis mit. Deine App sieht nur: „Kunde X hat für Y bezahlt“.
Dieser Leitfaden nutzt Stripe, weil es weit verbreitet, gut dokumentiert und von den meisten KI-App-Baukästen unterstützt wird. Es gibt andere Anbieter, und manche agieren als „Merchant of Record“ und übernehmen die Umsatzsteuer für dich. Wenn dir die steuerliche Compliance Sorgen macht, lohnt sich ein Vergleich mit diesem Modell.
Die drei Wege, Zahlungen mit Stripe anzunehmen
| Option | Code nötig | Deine App weiß, wer bezahlt hat? | Geeignet für |
|---|---|---|---|
| Zahlungslinks | Keiner | Nur mit zusätzlichem Webhook | Ein paar feste Produkte, Spenden, Nachfrage testen |
| Checkout (einmalig) | Serverseitiger Code, um eine Sitzung zu erstellen | Ja, über Webhook | Shops, bezahlte Downloads, einmalige Käufe |
| Checkout (Abo) | Serverseitiger Code plus Webhook-Verarbeitung | Ja, über Webhook | SaaS, Mitgliedschaften, alles Wiederkehrende |
Zahlungslinks
Ein Zahlungslink ist eine von Stripe gehostete Zahlungsseite, die du ohne Code im Stripe-Dashboard erstellst. Du erhältst eine URL, die du hinter einen Button in deiner App legen, per E-Mail teilen oder als QR-Code zeigen kannst. Laut der Dokumentation von Stripe können Zahlungslinks ein Produkt, ein Abo oder eine Spende anbieten, und du kannst Kunden wählen lassen, was sie zahlen, oder die Anzahl der Käufe begrenzen.
Der Haken: Deine App erfährt nicht automatisch, dass ein bestimmter angemeldeter Nutzer bezahlt hat. Für eine Spendenseite oder einen kleinen Shop, bei dem du Bestellungen anhand der E-Mail-Benachrichtigungen von Stripe von Hand erfüllst, ist das in Ordnung. Für „Zahle, um die Pro-Funktionen freizuschalten“ ist es das nicht.
Stripe Checkout
Checkout ist eine Zahlungsseite, die dein Server bei Bedarf für einen bestimmten Kauf erstellt. Dein Server teilt Stripe mit, was gekauft wird (und optional, welcher Kunde kauft), Stripe liefert eine URL zurück, und du schickst den Kunden dorthin. Laut der Dokumentation von Stripe unterstützt Checkout sowohl einmalige Zahlungen als auch Abos, als vollständig von Stripe gehostete Seite, als in deine Website eingebettete Seite oder als eingebettetes Formular.
Der Ablauf:
- Der Kunde klickt in deiner App auf Kaufen.
- Dein Server erstellt mit deinem geheimen Schlüssel eine Checkout-Sitzung und verknüpft sie per ID mit deinem Nutzer oder deiner Bestellung.
- Der Kunde wird zu Stripe weitergeleitet und zahlt.
- Stripe leitet ihn zu deiner Erfolgsseite zurück.
- Stripe sendet ein Ereignis
checkout.session.completedan deinen Webhook, und dein Server markiert die Bestellung als bezahlt oder schaltet den Zugang frei.
Schritt 2 muss auf dem Server passieren, weil dafür dein geheimer Schlüssel nötig ist. Das ist der Hauptgrund, warum Checkout ein Backend braucht.
Abos
Abos nutzen Checkout im Abo-Modus mit einem wiederkehrenden Preis, den du in Stripe anlegst. Die erste Zahlung funktioniert wie oben beschrieben. Danach passieren Verlängerungen, fehlgeschlagene Karten, Upgrades und Kündigungen über die Zeit, oft wenn der Kunde gar nicht in deiner App ist, daher erfährt deine App davon nur über Webhooks.
Damit Kunden ihr Abo selbst verwalten können, bietet Stripe ein gehostetes Kundenportal. Laut der Dokumentation von Stripe können Kunden dort Zahlungsmethoden und Rechnungsdaten aktualisieren, Abos ändern oder kündigen sowie Rechnungen ansehen und herunterladen. Du konfigurierst es im Stripe-Dashboard und ergänzt einen Button „Abrechnung verwalten“, der den Kunden dorthin schickt. So sparst du dir den Bau dieser Oberflächen.
Webhooks: der Teil, den du nicht auslassen darfst
Ein Webhook ist eine HTTP-Anfrage, die Stripe an deinen Server schickt, wenn etwas passiert. (Die allgemeine Idee erklärt was ein Webhook ist.) Der Leitfaden von Stripe zur Erfüllung ist eindeutig: Du darfst dich bei der Erfüllung von Bestellungen nicht allein auf die Erfolgsseite verlassen, weil ein Kunde zahlen und danach die Verbindung verlieren kann, bevor diese Seite lädt. Für Abos und verzögerte Zahlungsmethoden sind Webhooks Pflicht.
Ereignisse, die du behandeln solltest
| Ereignis | Was es bedeutet | Was deine App tut |
|---|---|---|
checkout.session.completed | Checkout ist abgeschlossen | Bestellung als bezahlt markieren oder Zugang starten |
checkout.session.async_payment_succeeded | Eine verzögerte Methode (etwa eine Lastschrift) wurde später bestätigt | Jetzt erfüllen |
checkout.session.async_payment_failed | Diese verzögerte Zahlung ist fehlgeschlagen | Kunden informieren; nicht erfüllen |
invoice.paid | Eine Abozahlung war erfolgreich, auch Verlängerungen | Zugang verlängern |
invoice.payment_failed | Eine Verlängerung ist fehlgeschlagen | Nutzer warnen; Stripe kann erneut versuchen |
customer.subscription.updated | Tarif geändert oder Kündigung geplant | Tarif des Nutzers aktualisieren |
customer.subscription.deleted | Abo beendet | Bezahlten Zugang entfernen |
Regeln für einen korrekten Webhook-Handler
Diese stammen direkt aus der Webhook-Dokumentation von Stripe, und KI-generierte Handler vergessen manchmal eine davon:
- Signatur prüfen. Jedes Ereignis enthält einen Header
Stripe-Signature. Dein Handler prüft ihn mit dem Signaturgeheimnis des Endpunkts (es beginnt mitwhsec_). Ohne diese Prüfung könnte jemand deinem Server ein gefälschtes „Zahlung erfolgreich“ schicken. - Den rohen Anfragekörper verwenden. Signaturprüfungen schlagen fehl, wenn dein Framework den Körper vorher parst oder verändert.
- Schnell mit 2xx antworten, langsamere Arbeit danach erledigen. Zeitüberschreitungen zählen als Fehler.
- Duplikate behandeln. Stripe kann dasselbe Ereignis mehrfach zustellen. Speichere verarbeitete Ereignis-IDs, oder mache die Erfüllung so, dass sie zweimal ausgeführt werden kann.
- Reihenfolge nicht voraussetzen. Stripe garantiert nicht, dass Ereignisse in der Reihenfolge ihres Auftretens eintreffen.
- Mit Wiederholungen rechnen. Im Live-Modus versucht Stripe fehlgeschlagene Zustellungen bis zu drei Tage lang erneut, ein kurzer Ausfall verliert also keine Zahlungen. Dein Handler muss aber mit verspäteten Ereignissen umgehen können.
Webhooks brauchen eine öffentliche HTTPS-Adresse, deshalb funktionieren sie meist erst, wenn deine App veröffentlicht ist. Für Entwickler kann die CLI von Stripe Ereignisse an einen lokalen Rechner weiterleiten.
Ein Prompt, der den ganzen Ablauf abdeckt
Füge einen einmaligen Kauf mit Stripe Checkout für das „Pro-Paket“ hinzu (Preis-ID in STRIPE_PRICE_ID). Erstelle die Checkout-Sitzung auf dem Server mit STRIPE_SECRET_KEY aus den Geheimnissen und füge die ID des angemeldeten Nutzers zur Sitzung hinzu. Füge einen Endpunkt POST /api/stripe/webhook hinzu, der die Signatur mit STRIPE_WEBHOOK_SECRET anhand des rohen Anfragekörpers prüft, checkout.session.completed verarbeitet und diesen Nutzer als Inhaber des Pro-Pakets markiert. Mache ihn sicher, falls dasselbe Ereignis zweimal ankommt. Erfolgs- und Abbruchseiten. Gib den geheimen Schlüssel niemals an den Browser weiter.
Für Abos ergänze: „Verwende den Abo-Modus mit STRIPE_PRICE_ID. Verarbeite invoice.paid, invoice.payment_failed, customer.subscription.updated und customer.subscription.deleted. Füge einen Button Abrechnung verwalten hinzu, der das Kundenportal von Stripe öffnet.“
Testmodus
Stripe trennt Sandbox (Test) und Live-Umgebung mit getrennten Schlüsseln. Sandbox-Schlüssel beginnen mit pk_test_, sk_test_ oder rk_test_; Live-Schlüssel beginnen mit pk_live_, sk_live_ oder rk_live_. Testtransaktionen bewegen kein Geld.
Nützliche Testkarten aus der Testdokumentation von Stripe (beliebiges zukünftiges Ablaufdatum, beliebige dreistellige Prüfnummer):
| Kartennummer | Ergebnis |
|---|---|
4242 4242 4242 4242 | Zahlung gelingt |
4000 0000 0000 0002 | Karte wird abgelehnt |
4000 0000 0000 3220 | Erfordert 3D-Secure-Authentifizierung, dann gelingt sie |
Teste mindestens:
- Eine erfolgreiche Zahlung schaltet das Richtige für den richtigen Nutzer frei
- Eine abgelehnte Karte zeigt eine klare Meldung und schaltet nichts frei
- Wenn der Kunde direkt nach der Zahlung den Browser-Tab schließt, erhält er trotzdem Zugang (das beweist, dass der Webhook funktioniert, nicht nur die Erfolgsseite)
- Ein Abbruch auf der Stripe-Seite bringt den Nutzer zurück in deine App, ohne dass etwas abgebucht wird
- Bei Abos: im Kundenportal kündigen und prüfen, dass der Zugang dann endet, wie er soll
Livegang
- Aktiviere dein Stripe-Konto mit deinen Geschäfts- und Bankdaten.
- Tausche die Live-Schlüssel in den Geheimnissen deiner App aus. Stripe empfiehlt eingeschränkte Schlüssel mit nur den Rechten, die deine Integration braucht, statt eines uneingeschränkten geheimen Schlüssels.
- Lege einen Live-Webhook-Endpunkt an, der auf deine veröffentlichte App zeigt. Er hat ein eigenes Signaturgeheimnis, das sich vom Testgeheimnis unterscheidet, aktualisiere es.
- Erstelle Produkte und Preise im Live-Modus neu; Test-IDs existieren dort nicht.
- Mache einen echten kleinen Kauf und erstatte ihn zurück.
Bewahre jeden Schlüssel in den Geheimnissen deines Projekts auf, niemals im Code oder im Chat. Unsere Sicherheits-Checkliste behandelt Schlüssel und die Webhook-Prüfung ausführlicher.
Steuern, Erstattungen und Papierkram
Zahlungen bringen Pflichten mit sich, die Code nicht löst. Das ist keine Steuerberatung; kläre es mit einer Steuerberaterin oder einem Steuerberater.
- Umsatzsteuer, MwSt. und GST. Je nachdem, wo du und deine Kunden sitzen, musst du dich eventuell registrieren, Steuern berechnen und abführen. Stripe Tax kann Steuern beim Checkout berechnen und einziehen, überwachen, wo deine Umsätze eine Pflicht auslösen könnten, und bei Registrierung und Meldung helfen. Die Verantwortung bleibt aber bei dir. Merchant-of-Record-Anbieter sind eine Alternative, die mehr davon übernimmt.
- Erstattungen und Rückbuchungen. Lege deine Erstattungsrichtlinie vor dem Start fest und veröffentliche sie auf deiner Website. Rückbuchungen (Chargebacks) kommen vor; bewahre Nachweise darüber auf, was gekauft und geliefert wurde.
- Quittungen und Rechnungen. Stripe kann Quittungen per E-Mail verschicken; Unternehmen brauchen unter Umständen ordentliche Rechnungen.
- Gebühren. Jeder Anbieter berechnet Gebühren pro Transaktion. Schau auf die aktuelle Preisseite des Anbieters, statt dich auf Zahlen aus Artikeln zu verlassen.
Welches Setup zu deiner App passt
- Spenden oder ein paar Produkte: Zahlungslinks. Siehe wie du eine Spenden-Website für Non-Profits baust.
- Ein Shop mit Warenkorb: Checkout mit Positionen und Webhook. Siehe wie du einen Online-Shop baust.
- SaaS oder Mitgliedschaften: Checkout im Abo-Modus, Webhooks und das Kundenportal. Siehe wie du ein SaaS-MVP baust und wie du ein SaaS-Produkt preist.
- Ein Marktplatz, der an Verkäufer auszahlt: Ein anderes, stärker reguliertes Setup (Stripe Connect oder ähnlich). Plane es separat.
Zahlungen in Mythex einbauen
Zahlungen in Apps, die du auf Mythex baust, nutzen dein eigenes Stripe-Konto und deine eigenen Schlüssel; es gibt keine Ein-Klick-Verbindung „Stripe verbinden“ für deine App. Der übliche Ablauf:
- Hol dir Stripe-Test-Schlüssel.
- Füge
STRIPE_SECRET_KEY(und später das Webhook-Geheimnis) zu den Projektgeheimnissen hinzu, über/secrets, die Projekteinstellungen oder die Geheimnis-Karte, die der Agent zeigt, wenn er einen Schlüssel braucht. - Bitte den Agenten um Checkout mit einem Prompt wie dem oben.
- Teste in der Vorschau mit Testkarten. Veröffentliche, bevor du den Webhook registrierst, denn er braucht deine öffentliche URL.
- Nach dem Umstellen auf Live-Schlüssel veröffentlichst du erneut, damit die Live-App sie übernimmt.
Siehe Zahlungen mit Stripe annehmen und Webhooks in deinem Backend verarbeiten in der Dokumentation.
Fragen
Was ist der einfachste Weg, Zahlungen in einer App anzunehmen?
Ein Stripe-Zahlungslink braucht keinen Code: Du erstellst ihn im Stripe-Dashboard und verlinkst ihn aus deiner App. Wenn deine App wissen muss, wer bezahlt hat, und etwas automatisch freischalten soll, verwende stattdessen Stripe Checkout mit einem Webhook.
Brauche ich einen Webhook, um Zahlungen anzunehmen?
Wenn deine App auf eine Zahlung reagieren muss, etwa ein Konto freischalten, eine Bestellung als bezahlt markieren oder eine Verlängerung verarbeiten, dann ja. Laut der Dokumentation von Stripe reicht die Erfolgsseite allein nicht, weil ein Kunde zahlen und diese Seite nie erreichen kann. Für Abos sind Webhooks ohnehin nötig.
Wie teste ich Zahlungen ohne echtes Geld?
Verwende die Sandbox-API-Schlüssel (Test) von Stripe und seine Testkartennummern, zum Beispiel 4242 4242 4242 4242 mit einem beliebigen zukünftigen Ablaufdatum und einer beliebigen dreistelligen Prüfnummer. Testtransaktionen bewegen kein echtes Geld.
Übernimmt Stripe Umsatzsteuer und MwSt. für mich?
Stripe Tax kann Steuern beim Checkout berechnen und einziehen und überwachen, wo du dich möglicherweise registrieren musst. Die Verantwortung für deine steuerlichen Pflichten bleibt aber bei dir. Kläre deine Situation mit einer Steuerberaterin oder einem Steuerberater.