Überblick
Tall3 ist eine mandantenfähige SaaS-Plattform für Autohäuser und Showrooms in Saudi-Arabien, die jeweils einen eigenen Shop auf der Plattform haben. Das Backend ist eine Laravel-Anwendung, die stancl/tenancy für die Mandantenfähigkeit nutzt, kombiniert mit einem Next.js-Frontend.
Ich habe etwa zwei Monate als freiberuflicher Backend-Entwickler an Tall3 gearbeitet, an einer bestehenden Produktionsplattform, die ich nicht von Grund auf gebaut habe. Meine Arbeit umfasste die Entwicklung von REST-APIs, mandantenspezifische Funktionen, eine selbst gehostete WhatsApp-Integration und das Backend, mit dem Mandanten ihre eigene Domain mit ihrem Shop verbinden können.
Zentrale Ingenieurbeiträge
- Eigene Mandanten-Domains (Cloudflare for SaaS): Entwurf und Aufbau des Backends zur Verbindung der eigenen Domain eines Mandanten mit seinem Shop. Dabei werden ein Domainkauf über das Zahlungsgateway N-Genius, die Cloudflare-Produkte Registrar und SSL for SaaS, asynchrones Status-Polling und dynamisches CORS pro Domain koordiniert. Unten ausführlich beschrieben.
- WhatsApp-Integration (selbst gehostet, Evolution API): Nachdem ich die offizielle WhatsApp Business API geprüft und verworfen hatte, habe ich die WhatsApp-Anbindung auf einem selbst gehosteten Gateway aufgebaut: QR-basierte Kontoverbindung, Sitzungsverwaltung für mehrere Nummern, mandantenspezifische Transaktionsbenachrichtigungen (Bestellbestätigungen, OTP) und eine Marketing-Kampagnen-Engine mit CSV-Empfängerimport, Nachrichtenvorlagen, getaktetem Versand und Live-Verfolgung von Fortschritt und Fehlern.
- Backend-Arbeit an der Plattform: Entwicklung und Pflege von REST-APIs und mandantenspezifischen Funktionen in der bestehenden Codebasis, Integration der Gemini API für KI-gestützte Funktionen, Werkzeuge, die neuen Mandanten die Datenmigration von Konkurrenzplattformen erleichtern, sowie Arbeiten an Redis-Caching und Performance-Korrekturen.
Eigene Mandanten-Domains
Der aufwendigste Teil der Backend-Arbeit bei Tall3: Ein Mandant kann eine echte Domain kaufen, und sie liefert sofort seinen bestehenden Shop aus. theirbrand.com zeigt dieselbe Seite wie seine normale Seite unter tall3.com/cars/{tenantId}, mit funktionierendem SSL-Zertifikat und ohne manuelle DNS-Arbeit durch irgendjemanden.
Der Ablauf koordiniert ein Zahlungsgateway, zwei getrennte Cloudflare-Produkte sowie das Laravel-Backend und das Next.js-Frontend:
- Ein Mandant sucht eine Domain und wählt sie aus. Das Backend erstellt eine Checkout-Session bei N-Genius, dem Zahlungsgateway der Plattform, und der Mandant wird zum Bezahlen auf eine gehostete Checkout-Seite weitergeleitet.
- Sobald die Zahlung bestätigt ist, registriert das Backend die Domain über die Registrar-API von Cloudflare. Das ist eine asynchrone Operation, daher fragt ein geplanter Job sie bis zum Abschluss ab.
- Die Registrierung legt automatisch eine neue DNS-Zone an. Das Backend trägt die Einträge ein, die zurück auf die Infrastruktur von Tall3 zeigen.
- Die Domain wird anschließend als Cloudflare-„Custom Hostname” in der eigenen Zone von Tall3 registriert. Das ist der Schritt, der ihr tatsächlich ein Zertifikat verschafft, ebenfalls asynchron und per Polling abgefragt.
- Sobald sie aktiv ist, wird der Verkehr für die neue Domain am Cloudflare-Edge terminiert und an einen gemeinsamen Fallback-Origin mit dem Next.js-Frontend weitergeleitet, einen Server ohne eigene domainspezifische Konfiguration.
- Da die bestehende Mandantenfähigkeit der Plattform nur ihre eigenen Subdomains auflöst, ruft das Frontend einen dedizierten Backend-Endpunkt auf, um den unbekannten Hostnamen einem Mandanten zuzuordnen, und rendert dann den Shop dieses Mandanten.
- Da dieser Shop nun auf einer Domain außerhalb von Tall3 läuft, erlaubt das Backend dafür dynamisch CORS. Geprüft wird gegen die Tabelle der aktiven, bezahlten Domains statt gegen einen Platzhalter.
Keiner der asynchronen Cloudflare-Endpunkte sendet einen Webhook, daher benachrichtigt nichts das Backend, wenn eine Registrierung oder ein Zertifikat fertig ist. Ein Hintergrundjob fragt beide jede Minute ab, mit begrenztem exponentiellem Backoff, und schreibt jedes Ergebnis in einen Zustandsautomaten tenant_domains.status (pending_payment → registering → registered_pending_dns → configuring_dns → provisioning_ssl → active, mit den Zweigen failed/action_required). Er setzt korrekt dort fort, wo eine Domain stehen geblieben ist, selbst wenn die App seit der letzten Prüfung neu gestartet wurde.
Technischer Stack
| Komponente | Technologien |
|---|---|
| Backend | PHP, Laravel |
| Multi-Tenancy | stancl/tenancy |
| Domains & SSL | Cloudflare Registrar, Cloudflare for SaaS (Custom Hostnames) |
| Zahlungen | N-Genius (gehostetes Zahlungsgateway) |
| Messaging | Evolution API (selbst gehostetes WhatsApp-Gateway) |
| Caching | Redis |
| KI | Gemini API |
| Containerisierung | Docker |
| Frontend | Next.js |
Live-Plattform
Plattform ansehen: tall3.com
Tall3 ist eine proprietäre Plattform, zu der ich als Freelancer beigetragen habe. Diese Fallstudie beschreibt meine Beiträge, ohne vertraulichen Code, Zugangsdaten oder Mandantendaten offenzulegen.