In den meisten Architekturdiagrammen ist eine Zahlung ein einzelner Pfeil vom Shop zu „Stripe“ oder „Adyen“. In Produktion ist sie eine Kette von Beteiligten mit zwei Zeitachsen: was passiert, während der Kunde auf der Checkout-Seite wartet, und was Minuten oder Tage später per Webhook eintrifft. Die meisten Zahlungsbugs leben in der Lücke dazwischen.
Dieser Guide zeichnet eine Kartenzahlung aus Sicht der Entwickler beim Händler: die Beteiligten, den Happy Path, warum das Ergebnis im Browser nicht die maßgebliche Quelle ist, was nach der Autorisierung passiert, und ein Diagramm, das zeigt, wo sich Geld und Bestellstatus ändern. Er ist anbieterneutral; Stripe und Adyen dienen nur als Beispiele dafür, wie Payment Service Provider die Details dokumentieren.
Die Beteiligten
| Beteiligter | Rolle bei einer Kartenzahlung |
|---|---|
| Kunde | Der Karteninhaber, der im Browser oder in einer App zahlt |
| Checkout-Frontend | Deine Checkout-Seite mit den Kartenfeldern deines Payment Service Providers (PSP) |
| Payments-Backend | Dein Service, der Zahlungen anlegt und den Bestellstatus verantwortet |
| PSP | Das Gateway, an das du dich anbindest: API, Kartenfelder, 3-D Secure, Webhooks, Reports |
| Acquirer | Die Bank, die Kartenzahlungen für den Händler annimmt; oft über den PSP vermittelt |
| Kartennetzwerk | Leitet Autorisierung und Clearing zwischen Acquirer und Issuer weiter |
| Issuer | Die Bank des Karteninhabers: authentifiziert ihn, genehmigt oder lehnt ab, reserviert den Betrag |
Der Happy Path
- Der Kunde wählt Bezahlen. Das Frontend bittet dein Backend, den Checkout für eine Bestellung zu starten.
- Das Backend legt beim PSP eine Zahlung an, mit Betrag, Währung, Bestell-ID und einem Idempotency-Key, und gibt das Client-Token des PSP an das Frontend weiter.
- Das Frontend erfasst die Kartendaten in den Feldern des PSP, meist iframes oder ein SDK. So geht die Kartennummer direkt vom Browser zum PSP und berührt deine Server nie.
- Der Issuer entscheidet über 3-D Secure. EMVCo beschreibt zwei Flows: Im Frictionless Flow genehmigt der Issuer auf Basis einer Risikobewertung, ohne den Kunden etwas zu fragen; im Challenge Flow bestätigt der Kunde, etwa mit einem Einmalcode oder in einer Banking-App. In manchen Regionen wird so die starke Kundenauthentifizierung erfüllt.
- Der PSP sendet die Autorisierung über den Acquirer und das Kartennetzwerk an den Issuer, der genehmigt und den Betrag reserviert.
- Das Frontend zeigt das Ergebnis. „Danke“ anzuzeigen ist in Ordnung, aber es ist nicht der Moment zum Versenden.
- Der PSP schickt einen Webhook, der meldet, dass die Zahlung autorisiert wurde. Dein Backend verifiziert ihn und aktualisiert die Bestellung.
- Das Backend führt das Capture der Zahlung aus, wenn die Bestellung versendet wird, bei digitalen Gütern sofort.
- Der PSP zahlt aus, gebündelt und abzüglich Gebühren, und ein Abgleichs-Job ordnet Auszahlungen den Bestellungen zu.
Die Kartenfelder sind für die Compliance wichtig. Wenn eine E-Commerce-Seite nur das Zahlungsformular eines PSP einbettet und selbst keine Kartendaten speichert, verarbeitet oder überträgt, kann sie für PCI DSS SAQ A statt des viel längeren SAQ A-EP infrage kommen. Unter PCI DSS v4.0.1 verlangt das zusätzlich, die Seite vor bösartigen Skripten zu schützen, wie der PCI Security Standards Council erklärt. Kläre den richtigen Fragebogen mit deinem Acquirer.
Warum der Browser nicht die maßgebliche Quelle ist
Der Kunde kann den Tab während 3-D Secure schließen, die Verbindung verlieren, nachdem der Issuer genehmigt hat, oder im falschen Moment neu laden. Wenn dein Bestellstatus davon abhängt, dass der Browser sich zurückmeldet, bleiben manche bezahlten Bestellungen unbezahlt und manche fehlgeschlagenen sehen bezahlt aus. Maßgeblich sind die Webhooks des PSP oder seine API. Behandle sie wie jeden anderen Nachrichtenstrom:
- Prüf die Signatur. PSPs signieren Webhook-Requests, Stripe zum Beispiel in einem
Stripe-Signature-Header und Adyen mit HMAC-Signaturen. Lehn alles ab, was sich nicht verifizieren lässt. - Schnell antworten, später verarbeiten. Stripes Webhook-Guide verlangt eine 2xx-Antwort vor jeder komplexen Logik. Leg das verifizierte Event in eine Queue und antworte.
- Rechne mit Duplikaten. Endpunkte können dasselbe Event mehrmals erhalten. Speichere verarbeitete Event-IDs und überspring Wiederholungen.
- Verlass dich nicht auf die Reihenfolge. Stripe garantiert nach eigener Aussage keine Zustellung in der Reihenfolge, in der Events erzeugt wurden. Passt ein Event nicht zum aktuellen Status, hol die Zahlung über die API des PSP.
- Rechne mit Wiederholungen. Stripe wiederholt fehlgeschlagene Zustellungen im Live-Modus bis zu drei Tage lang mit exponentiellem Backoff; ein langsamer Endpunkt bekommt dasselbe Event also später noch einmal.
Dieselbe Disziplin gilt in die andere Richtung. Schick bei jedem Request, der eine Zahlung anlegt oder ändert, einen Idempotency-Key mit und verwende ihn wieder, wenn du nach einem Timeout erneut sendest, damit ein Retry nicht doppelt abbucht. Keys leben nicht ewig: Stripe kann sie nach 24 Stunden entfernen, Adyen bewahrt sie 7 bis 14 Tage auf.
Nach der Autorisierung: Capture, Erstattungen, Chargebacks und Auszahlungen
- Die Autorisierung reserviert, das Capture bewegt Geld. Eine Autorisierung verfällt, wenn du sie nicht einziehst. Bei Online-Kartenzahlungen beträgt das Fenster meist etwa eine Woche; Stripe listet es pro Kartenmarke und danach, wer die Zahlung ausgelöst hat. Zieh vor Ablauf ein, sonst wird die Reservierung freigegeben.
- Ein Capture kann trotzdem scheitern. Adyen dokumentiert seltene Fälle, in denen das Kartennetz ein Capture ablehnt, nachdem der PSP es angenommen hat; deine Bestellstatus brauchen also auch dafür einen Pfad.
- Erstattungen sind neue Vorgänge auf einer eingezogenen Zahlung. Sie laufen asynchron und kommen ebenfalls als Webhooks an.
- Chargebacks kommen vom Issuer, manchmal Wochen später, wenn ein Karteninhaber eine Zahlung beanstandet. Manche Netzwerke beginnen mit einer Anfrage; beantworte sie, sonst kann daraus ein schwer zu gewinnender Chargeback werden.
- Auszahlungen brauchen einen Abgleich. Ordne jede Auszahlung den Zahlungen, Erstattungen, Gebühren und Chargebacks zu, die sie abrechnet, anhand der Auszahlungs- oder Settlement-Reports des PSP.
Das Diagramm
Diagramminhalt
- Customer
- Acquirer, card network, issuer
- Payment service provider
- Merchant systems · no raw card data
- Checkout web app
- Payments API
- Webhook handler
- Orders + payments
- Payment events
- Reconciliation job
- 1 Pay
- 2 Start checkout
- 3 Create payment, later capture
- 4 Card details (hosted fields)
- 5 3-D Secure, authorization
- 6 Webhook: authorized
- 7 Verified event
- 8 Update order
- orders, payments
- match payouts
- payout reports, daily
So liest du es:
- Durchgezogene Kanten sind der Checkout selbst: bezahlen (1), Checkout starten (2), Zahlung anlegen (3), Kartendaten aus den Feldern des PSP an den PSP senden (4) sowie 3-D Secure und Autorisierung zwischen PSP und Kartennetzwerk (5).
- Gestrichelte Kanten passieren später: der Webhook (6), das verifizierte Event in der Queue (7) und die Payments-API, die die Bestellung aktualisiert (8). Der nächtliche Abgleichs-Job liest die Auszahlungsreports des PSP und ordnet sie den Bestellungen zu.
- Der Rahmen markiert die Systeme des Händlers. Keine rohen Kartendaten gelangen hinein; die Kartennummer geht aus den Feldern des PSP direkt an den PSP.
So zeichnest du einen Zahlungsflow
- Nummeriere die Schritte. Zahlungen sind Abfolgen; Nummern machen die Reihenfolge lesbar, ohne eigenes Sequenzdiagramm.
- Trenne Synchrones von Asynchronem. Durchgezogen für den Checkout-Request, gestrichelt für Webhooks, Queues und Batch-Jobs.
- Markiere die Grenze der Kartendaten. Zeig, welche Komponenten Kartennummern sehen können. Mit Hosted Fields sollte keine deiner eigenen das tun.
- Zeig, wo sich der Bestellstatus ändert. Eine Komponente sollte ihn verantworten, gespeist von verifizierten Events, nicht vom Browser.
- Benenne die Geldvorgänge. Autorisierung, Capture, Erstattung und Auszahlung sind verschiedene Ereignisse mit verschiedenem Timing; beschrifte sie.
- Zeichne die Fehlerfälle, auf die es ankommt: Timeout beim Anlegen (mit demselben Idempotency-Key wiederholen), doppelter Webhook (deduplizieren), abgebrochene 3-D-Secure-Challenge (Bestellung verfallen lassen), abgelaufene Autorisierung (neu autorisieren oder stornieren).
Eine Sequenzansicht desselben Flows findest du im Anwendungsfall Zahlungsflow-Diagramm. Für die Event-Seite siehe den Guide ereignisgesteuerte Architektur als Diagramm, und für das Security-Review die Datenflussdiagramme für die Bedrohungsmodellierung.
In Archboard nachbauen
- Melde dich mit Google oder GitHub an und leg ein Diagramm an.
- Füge einen Person-Node aus dem C4-Modell-Pack für den Kunden hinzu und zwei Externes System-Nodes aus dem C4-Modell-Pack: einen für den Payment Service Provider, einen für Acquirer, Kartennetzwerk und Issuer.
- Füge einen Rahmen aus dem Basis-Pack für die Händlersysteme hinzu und setz vier Container-Nodes aus dem C4-Modell-Pack hinein: die Checkout-Web-App, die Payments-API, den Webhook-Handler und den Abgleichs-Job.
- Füge im Rahmen Postgres aus dem Daten-Pack für Bestellungen und Zahlungen hinzu und eine Warteschlange aus dem Daten-Pack für Zahlungs-Events.
- Nummeriere die Kanten der Reihe nach, stell die Kanten für Webhook, Queue und Abgleich gestrichelt dar und füge einen Markdown-Block aus dem Basis-Pack hinzu, der die Linienstile erklärt.
Das Beispiel nutzt 11 Diagramm-Nodes und bleibt damit im Free-Plan.
FAQ
Was ist der Unterschied zwischen einem Payment Gateway und einem Payment Processor? Das Gateway ist die Schnittstelle, mit der deine Systeme sprechen: API, Kartenfelder, Webhooks. Der Processor bewegt die Transaktion durch die Kartennetzwerke. Viele PSPs bieten beides an, zusammen mit einer Acquiring-Beziehung.
Darf ich eine Bestellung als bezahlt markieren, wenn der Browser meldet, dass die Zahlung geklappt hat? Zeig dem Kunden eine Bestätigung, aber ändere den Bestellstatus nur aufgrund eines verifizierten Webhooks oder einer Prüfung über die API des PSP.
Warum erst autorisieren und später einziehen? Damit nur berechnet wird, was auch versendet wird. Die Reservierung sichert den Betrag; das Capture bewegt ihn, wenn du lieferst. Behalte den Ablauf der Autorisierung im Blick.
Muss ich mit Webhooks umgehen, die in falscher Reihenfolge ankommen? Ja. Mach den Handler idempotent, führ die Bestellung als Zustandsautomaten, der unmögliche Übergänge ablehnt, und hol im Zweifel die aktuelle Zahlung vom PSP.
Macht mich der Einsatz von Hosted Fields PCI-konform? Er verkleinert den Umfang; er beseitigt ihn nicht. Du füllst trotzdem einen Selbstbewertungsfragebogen aus und schützt die Checkout-Seite. Frag deinen Acquirer, welcher Fragebogen gilt.