Keycloak × Stripe: Unsichtbares Marktplatz-Onboarding mit ereignisgesteuerter Architektur aufbauen

5 min read• By Stephane Segning Lambou
Blog
Erfahren Sie, wie Sie ein nahtloses Marktplatz-Onboarding durch die Integration von Keycloak und Stripe Connect mit reaktivem Kotlin und AMQP aufbauen.

Das Onboarding auf Marktplätzen ist oft eine fragmentierte Erfahrung: Benutzer erstellen ein Konto, durchlaufen zusätzliche Registrierungsschritte und verknüpfen Zahlungsfunktionen manuell. Jeder zusätzliche Schritt erhöht die Reibung.

In diesem Artikel zeigen wir, wie wir Keycloak und Stripe Connect integriert haben, um große Teile des Onboarding-Prozesses zu automatisieren. Mithilfe einer ereignisgesteuerten Architektur, eines reaktiven Kotlin-Backends und zuverlässigem AMQP-Messaging werden neue Benutzer automatisch systemübergreifend bereitgestellt – für ein nahtloses Onboarding-Erlebnis ohne zusätzliche Benutzerinteraktion.

Warum dieser Ansatz? Unsere Kernprinzipien

Bevor wir in das „Wie“ eintauchen, lassen Sie uns das „Warum“ untersuchen. Unser Architekturdesign wurde von vier Schlüsselprinzipien für unseren Marktplatz geleitet:

  • Mühelose Benutzererfahrung (User Experience): Unser Ziel war es, Reibungspunkte zu eliminieren. Die Registrierung und die Vorbereitung auf Zahlungen sollten sich wie eine einzige, fließende und natürliche Aktion anfühlen.

  • Unerschütterliche Markenkonsistenz (Whitelabeling): Obwohl wir leistungsstarke Drittanbieter-Tools wie Stripe Connect nutzen, sollten unsere Nutzer immer das Gefühl haben, sich in der Umgebung unserer eigenen Plattform zu bewegen.

  • Unbeugsame Sicherheit: Betrachten Sie Keycloak als unseren vertrauenswürdigen Wächter – es ist unsere zentrale "Source of Truth" (Quelle der Wahrheit) für Identität und Autorisierung.

  • Architektonische Flexibilität: Wir haben ein modulares System aufgebaut, in dem Komponenten aktualisiert oder ausgetauscht werden können, ohne dass größere Generalüberholungen erforderlich sind.

Diese Kernprinzipien haben uns ganz natürlich zu einem ereignisgesteuerten (event-driven) Modell geführt, bei dem die identitätsbezogenen Aktionen von Keycloak nahtlos zahlungsspezifische Prozesse auslösen.

Das Gesamtbild: Eine detaillierte User Journey & Backend-Magie

Um den „unsichtbaren“ Aspekt wirklich zu verstehen, lassen Sie uns eine typische Benutzerregistrierung nachverfolgen und beobachten, wie die Frontend-Erfahrung und die Backend-Prozesse über drei verschiedene Phasen hinweg fehlerfrei miteinander tanzen.

Phase 1: Benutzerregistrierung & Event-Emission

In dieser ersten Phase interagieren die Benutzer mit dem Frontend und dem Keycloak-Authentifizierungssystem. Dies gipfelt darin, dass Keycloak das entscheidende USER_CREATED-Event ausgibt.

/User-Registration-&-Event-Emission
1graph TD
2U[User] -->|"1- Initiates Signup"| F[Next.js Frontend]
3F -->|2- Redirects for Authentication| KC["Keycloak (Auth/Register)"]
4KC -->|3- User Completes Registration| F
5F -->|4- Receives JWT & Logs In| U
6KC -->|5- Emits USER_CREATED Event| W[Keycloak Webhook Plugin]
7W -->|6- Publishes AMQP Message| MQ[AMQP Message Broker]
phase 1 image DE

Erklärung:

  1. Benutzer kommt an: Der Benutzer startet den Registrierungsprozess über unser Next.js-Frontend.

  2. Auth-Weiterleitung: Das Frontend leitet sicher zu Keycloak für die Authentifizierung/Registrierung weiter.

  3. Keycloak-Magie: Der Benutzer schließt seine Registrierung auf den Standardseiten von Keycloak ab.

  4. Zurück zur App: Keycloak leitet den Benutzer mit einem JWT für den Login zurück zu unserem Frontend.

  5. Keycloak-Event: Keycloak generiert intern ein USER_CREATED-Event, wenn die Registrierung erfolgreich war.

  6. Webhook & AMQP: Unser Keycloak-Webhook-Plugin lauscht auf dieses Event und sendet es als AMQP-Nachricht an einen Broker.

Phase 2: Asynchrone Backend-Verarbeitung

Diese Phase beschreibt den Weg des Events vom Message Broker zum Payment Service sowie dessen Interaktion mit Stripe und unserer Datenbank, um das Zahlungskonto bereitzustellen.

// language: mermaid // title: /Asynchronous-Backend-Processing // copy: true // lines: true // maxLines: 10 graph TD MQ[AMQP Message Broker] -->|7- Payment Service Consumes Event| PS["Payment Service (Spring Boot Kotlin)"] PS -->|8- Calls Stripe API to Create Account| S[Stripe] S -->|Stripe Account ID| PS PS -->|9- Saves KeycloakUser ID : StripeAccount ID Mapping| DB[DynamoDB]
Phase 2 image DE

Erklärung:

  1. Service lauscht: Unser Payment Service überwacht und verarbeitet das USER_CREATED-Event aus der AMQP-Warteschlange.

  2. Erstellung des Stripe-Kontos: Unter Verwendung der Benutzerinformationen aus dem Event erstellt der Payment Service über die Stripe-API ein neues Stripe-Connect-Konto.

  3. Datenhaltung: Das System speichert die neue Stripe-Account-ID in DynamoDB und verknüpft sie direkt mit der Keycloak-User-ID.

Phase 3: Anschließende Einrichtung der Benutzerzahlungen

Diese letzte Phase zeigt, wie Benutzer ihre Zahlungsdaten über die Frontend-Oberfläche vervollständigen. Dies baut nahtlos auf den Vorarbeiten des Backends auf, um ein konsistentes Markenerlebnis zu gewährleisten.

/Subsequent-User-Payment-Setup
1graph TD
2U[User] -->|10- Navigates to Payment Setup Section| F[Next.js Frontend]
3F -->|11- Frontend Requests Payment Status API Call| PS[Payment Service]
4PS -->|12- Fetches Stripe Account ID| DB[DynamoDB]
5DB -->|Stripe Account ID| PS
6PS -->|Returns Stripe Account ID| F
7F -->|13- Embeds Stripe Elements Guided Onboarding within UI| S[Stripe via Frontend]

Phase 3 DE

Erklärung:

  1. Benutzer erkundet & konfiguriert: Wenn er bereit ist, besucht der Benutzer den Bereich für die Zahlungseinrichtung in unserem Frontend.

  2. Frontend prüft Status: Das Frontend sendet eine sichere API-Anfrage an den Payment Service, um den Status der Zahlungskonfiguration zu überprüfen.

  3. Backend liefert: Der Payment Service ruft die zuvor erstellte Stripe-Account-ID aus der DynamoDB ab.

  4. Geführtes Onboarding: Unter Verwendung der Stripe-Account-ID implementiert unser Next.js-Frontend Stripe Elements, um den Benutzer durch die verbleibenden Schritte (wie Bankverbindung und KYC) innerhalb unserer gebrandeten UI zu führen. Der Benutzer bleibt während des gesamten Prozesses in unserer Anwendung.

Dieser phasenweise Ansatz bedeutet: Wenn die Benutzer bereit sind, sich um die Zahlungen zu kümmern, ist der Großteil der Einrichtungsarbeit hinter den Kulissen bereits erledigt, was eine reibungslose und effiziente Erfahrung schafft.

Keycloaks Event-Superkraft: Die Webhook- und AMQP-Brücke

Der Schlüssel zu unserer Hintergrundmagie liegt in Keycloaks leistungsstarkem Event-System, das Benachrichtigungen für verschiedene Aktionen im Lebenszyklus eines Benutzers ausgibt. Das Keycloak-Webhook-Plugin ist so konfiguriert, dass es diese spezifischen Ereignisse erfasst.

Wenn ein Event wie USER_CREATED eintritt, führt das Plugin keinen direkten, blockierenden HTTP-Aufruf an unseren Payment Service aus. Stattdessen wandelt es die Event-Daten in eine Nachricht um und veröffentlicht sie auf einem AMQP-Broker (wie RabbitMQ).

Warum AMQP? Eine strategische Entscheidung für Robustheit:

  • Entkopplung: Keycloak läuft unabhängig, ohne die Netzwerkadresse oder den Verfügbarkeitsstatus des Payment Service kennen zu müssen.

  • Resilienz: Wenn der Payment Service ausfällt, warten die Nachrichten sicher im AMQP-Broker und werden automatisch verarbeitet, sobald der Dienst wieder läuft – es gehen keine Events verloren.

  • Skalierbarkeit: Mehrere Instanzen des Payment Service können aus derselben Warteschlange konsumieren, was die horizontale Skalierung extrem einfach macht.

Der grundlegende Ablauf für diese Event-Weiterleitung ist elegant und einfach:

/The-Webhook-and-AMQP-Bridge
1graph TD
2KC[Keycloak: Event Occurs] --> Plugin[Webhook Plugin]
3Plugin -- Publishes Event --> AMQP[AMQP Message Broker]
4AMQP -- Delivers Message --> PS[Payment Service: AMQP Consumer]
5PS --> Logic[Processes Event]

 The Webhook and AMQP Bridge DE

Automatisierung von Stripe Connect: Die Kernlogik

Da die Keycloak-Events zuverlässig über AMQP fließen, übernimmt unser Payment Service die Rolle des Orchestrators für die Verwaltung der Stripe-Connect-Konten.

Szenario 1: Benutzererstellung oder -aktualisierung

Wenn ein USER_CREATED-Event (oder ein USER_UPDATED-Event, falls wir Änderungen synchronisieren) eintrifft:

  1. Der Payment Service empfängt die Event-Daten aus der AMQP-Warteschlange.

  2. Er extrahiert die relevanten Benutzerdaten (wie die Keycloak-User-ID und die E-Mail-Adresse) aus dem Event-Payload.

  3. Er ruft die Stripe-API auf, um ein neues Connect-Konto zu erstellen (in der Regel ein Express-Konto) und füllt die Informationen aus Keycloak und den Marktplatz-Standardeinstellungen vorab aus.

  4. Nach erfolgreicher Erstellung speichert er die Stripe-Account-ID sicher in der DynamoDB, gemappt auf die Keycloak-User-ID.

Dieser optimierte Prozess sorgt für eine effiziente und nahtlose Integration:

/User Creation or Update
1sequenceDiagram
2 participant KPlugin as Keycloak Webhook via AMQP
3 participant PaySvc as Payment Service
4 participant StripeAPI as Stripe
5 participant DB as DynamoDB
6 KPlugin->>PaySvc: USER_CREATED Event
7 activate PaySvc
8 PaySvc->>StripeAPI: Create Connect Account (User Details)
9 activate StripeAPI
10 StripeAPI-->>PaySvc: Stripe Account ID
11 deactivate StripeAPI
12 PaySvc->>DB: Save (KeycloakUserID, StripeAccountID)
13 activate DB
14 DB-->>PaySvc: Confirmation
15 deactivate DB
16 deactivate PaySvc
Scenario 1

Szenario 2: Benutzerlöschung

Wenn ein USER_DELETED-Event empfangen wird:

  1. Der Payment Service fragt DynamoDB ab, um die entsprechende Stripe-Account-ID des Benutzers anhand seiner Keycloak-User-ID abzurufen.

  2. Wenn ein Konto gefunden wird, ruft er die Stripe-API auf, um das Connect-Konto zu löschen oder zu deaktivieren (basierend auf Compliance-Anforderungen und Datenrückhalterichtlinien).

  3. Schließlich entfernt er den Mapping-Eintrag aus der DynamoDB, um einen sauberen und konsistenten Zustand zu wahren.

Der Ablauf für die Löschung ist ebenso präzise:

/User Deletion
1sequenceDiagram
2 participant KPlugin as Keycloak Webhook via AMQP
3 participant PaySvc as Payment Service
4 participant StripeAPI as Stripe
5 participant DB as DynamoDB
6 KPlugin->>PaySvc: USER_DELETED Event
7 activate PaySvc
8 PaySvc->>DB: Get StripeAccountID for KeycloakUserID
9 activate DB
10 DB-->>PaySvc: Stripe Account ID (or null)
11 deactivate DB
12 alt Stripe Account ID Found
13 PaySvc->>StripeAPI: Delete Connect Account (StripeAccountID)
14 activate StripeAPI
15 StripeAPI-->>PaySvc: Confirmation
16 deactivate StripeAPI
17 PaySvc->>DB: Delete Mapping (KeycloakUserID)
18 activate DB
19 DB-->>PaySvc: Confirmation
20 deactivate DB
21 end
22 deactivate PaySvc
scenario2

Unter der Haube: Der Payment Service (Spring Boot Kotlin)

Unser Payment Service ist eine Spring Boot-Anwendung, die in Kotlin geschrieben ist und Coroutines für effiziente asynchrone Operationen nutzt. Dieser nicht-blockierende Ansatz ist essenziell für die Verarbeitung von I/O-gebundenen Aufgaben wie AMQP-Messaging, DynamoDB-Zugriffen und Stripe-API-Aufrufen – was eine optimale Performance und Reaktionsfähigkeit garantiert.

AMQP-Event-Listener: Der dedizierte Consumer

Im Herzen unseres Dienstes überwacht der KeycloakEventListener die zugewiesene AMQP-Warteschlange auf eingehende

/KeycloakEventListener
1@Component
2class KeycloakEventListener(
3 private val paymentAccountOrchestrator: PaymentAccountOrchestrator
4) {
5 @RabbitListener(queues = ["\\\\${app.amqp.keycloak-events-queue}"]) // Configured queue name
6 suspend fun handleKeycloakEvent(eventMessage: KeycloakEventPayload) { // Assuming deserialized payload
7 logger.info("Received Keycloak event: ${eventMessage.type} for user ${eventMessage.details.userId}")
8 when (eventMessage.type) {
9 "USER_CREATED" -> paymentAccountOrchestrator.createAccountForUser(eventMessage.details.userId)
10 "USER_DELETED" -> paymentAccountOrchestrator.deleteAccountForUser(eventMessage.details.userId)
11 // Handle USER_UPDATED if necessary for syncing profile changes
12 else -> logger.warn("Unhandled Keycloak event type: ${eventMessage.type}")
13 }
14 }
15}

Kern-Logik des Services (Vereinfachtes createAccountForUser): Der Konto-Alchemist

Diese Methode kapselt die wesentliche Logik für die Erstellung eines Stripe-Kontos, einschließlich einer wichtigen Idempotenzprüfung, um Duplikate zu verhindern:

/createAccountForUser
1@Service
2class PaymentAccountOrchestrator(
3 private val stripeService: StripeService, // Robust wrapper for all Stripe API calls
4 private val userRepository: UserRepository // Our DynamoDB repository for user-Stripe mappings
5) {
6 suspend fun createAccountForUser(keycloakUserId: String) {
7 // Idempotency check: Crucial to avoid recreating existing accounts
8 if (userRepository.findStripeAccountId(keycloakUserId) != null) {
9 logger.info("Stripe account mapping already exists for Keycloak user: $keycloakUserId. Skipping creation.")
10 return
11 }
12 // Build the request for an Express account with sensible defaults
13 val accountCreationRequest = StripeAccountCreateRequest(
14 type = "express",
15 country = "DE", // Example default country (e.g., for a German marketplace)
16 email = "user-$keycloakUserId@example.com" // Placeholder; ideally fetched from Keycloak user details
17 // Add other required capabilities (e.g., card_payments, transfers) as needed
18 )
19 val stripeAccount = stripeService.createAccount(accountCreationRequest)
20 userRepository.saveStripeMapping(keycloakUserId, stripeAccount.id)
21 logger.info("Successfully created Stripe account ${stripeAccount.id} for Keycloak user $keycloakUserId.")
22 }
23 // ... Implement other core methods like deleteAccountForUser to complete the lifecycle
24}

Die Frontend-Erfahrung: Whitelabeling in Aktion

Wie in der gesamten User Journey bereits hervorgehoben, wird der Endnutzer akribisch davor geschützt, rohe Stripe-Seiten zu sehen. Nach der initialen, stillen Kontoerstellung im Hintergrund passiert Folgendes:

  1. Unser Next.js-Frontend ruft die Stripe-Account-ID des Benutzers sicher ab (über die geschützte API unseres Backends).

  2. Es nutzt dann strategisch Stripe Elements oder andere eingebettete UIs, die von Stripe.js bereitgestellt werden, um alle weiteren erforderlichen Informationen zu sammeln (z. B. Bankdaten für Auszahlungen oder Identifikationsdokumente für die KYC/KYB-Compliance).

Entscheidend ist, dass dieser gesamte Datenerfassungsprozess innerhalb der UI unserer Anwendung stattfindet. Das bewahrt eine nahtlose Markenkonsistenz und bietet eine geführte, vertraute Benutzererfahrung.Dieser akribische Ansatz ist die Essenz unseres „Whitelabeling“-Ziels: die Nutzung der mächtigen Backend-Zahlungsverarbeitung von Stripe, ohne Kompromisse bei unserer sorgfältig gestalteten Frontend-User-Experience einzugehen.

Das Ergebnis: Nahtlos, sicher und flexibel

Unsere ereignisgesteuerte, entkoppelte Architektur erfüllt unsere ursprünglichen Designprinzipien:

  • Mühelose UX: Die Benutzerregistrierung löst die automatische Erstellung des Zahlungskontos aus, wodurch Reibungsverluste minimiert werden und eine reaktionsschnelle Plattform entsteht.

  • Markenkonsistenz: Das Frontend behält die vollständige Kontrolle über die Stripe-Interaktionspunkte, sodass alle Touchpoints des Nutzers innerhalb unserer gebrandeten UI verbleiben.

  • Robuste Sicherheit: Keycloak fungiert als zentraler Gatekeeper für das Identitäts- und Zugriffsmanagement, während alle sensiblen Zahlungsoperationen sicher auf der Serverseite abgewickelt werden.

  • Außergewöhnliche Flexibilität: Die AMQP-Brücke hält Keycloak und den Payment Service lose gekoppelt. Alle Stripe-Interaktionen sind im Payment Service gekapselt, was zukünftige Änderungen oder einen Wechsel des Anbieters vereinfacht.

Dieser Ansatz des „unsichtbaren Onboardings“ optimiert die erste Benutzererfahrung und sorgt dafür, dass sich unsere Plattform von Anfang an polierter, professioneller und intuitiver anfühlt.

Abschließende Gedanken

Seien wir ehrlich – das Verknüpfen von Identitätsmanagement mit Zahlungssystemen ist ein bisschen so, als würde man versuchen, einer Katze beizubringen, die Steuererklärung zu machen. Aber wir haben es geknackt! Indem wir Keycloak und unsere asynchrone Architektur ihren Tanz aufführen lassen (denken Sie an Fred Astaire trifft auf Distributed Computing), haben wir etwas erschaffen, das so reibungslos läuft, als würden Ihre Zahlungen von Ninja-Buchhaltern verarbeitet. Klar, das Ganze einzurichten hat ungefähr so viel Spaß gemacht, wie Code zu debuggen, der von einem koffeingetriebenen Eichhörnchen geschrieben wurde, aber die Ergebnisse sind es wert. Wir haben das, was leicht eine Erfahrung auf dem Niveau eines Straßenverkehrsamtes hätte werden können, in etwas so Unsichtbares verwandelt, dass Harry Potters Tarnumhang dagegen wie Amateurenwerk aussieht. Jetzt können Nutzer unserer Plattform schneller beitreten, als Sie „Blockchain“ sagen können – und das will was heißen!

© 2026 adorsys. Alle Rechte vorbehalten.
Certificate TopCompany Kununu
Certificate ISO 27001
Certificate ISO 9001