Anbieter-Registrierung
[admin] [signup]
Self-Service-Registrierung unter https://admin.licensio.io/register. Die Registrierung legt einen kostenfreien Zugang an — keine Kreditkarte, keine Planauswahl, keine Portal-Adresse. Ein neuer Anbieter ist in unter zwei Minuten startklar.
Hinweis: Die öffentliche Marketing-Site unter
https://licensio.io(eigene Next.js-Appapps/marketing, separates Vercel-Deployment, i18n EN/DE mit Flaggen-Dropdown im Header) verlinkt aus Header (Sign up) und Hero (Start for free →) aufhttps://admin.licensio.io/register?lang=<locale>. Die Sprache wird in das Register-Formular übernommen. Die Kontakt-Sektion öffnetmailto:malte@licensio.io.
Sprache auf der Register-Seite: Auflösungsreihenfolge
?lang=en|de(URL-Param) > LocalStoragelicensio_locale> Defaulten. Ein Flaggen-Dropdown oben rechts erlaubt den manuellen Wechsel; die Wahl wird im Admin-LocalStorage gespeichert. Formular-Labels, Buttons und Fehlermeldungen sind übersetzt.
Lebenszyklus nach der Registrierung
- Anbieter + Auth-User + tenant_users-Verknüpfung werden in
/api/registerangelegt (Self-Service-Signup, E-Mail direkt bestätigt). Der Tenant wird auf dem kostenfreien Zugang angelegt (Plan-Wertfree), inkl. akzeptierter AGB-Version + Zeitstempel (terms_accepted_at,terms_version). - Bei der Registrierung wird keine Portal-Subdomain angelegt.
tenants.slugbleibtNULL, bis das Anbieter-Modul aktiviert wird (App Store, später); erst dann wird eine Subdomain gewählt und provisioniert. Bis dahin arbeitet der Anbieter vollständig im Admin. - Welcome-E-Mail an die Registrierungs-Adresse (Resend,
from: noreply@licensio.io): „Willkommen bei licensio.io 🎉" + CTA aufadmin.licensio.io. Best-effort (die Registrierung schlägt nicht fehl, wenn Resend down ist). - Weiterleitung auf
/onboarding. Es gibt keinen Stripe-Checkout auf dem Registrierungs-Pfad — ein Upgrade auf einen kostenpflichtigen Tarif passiert später im Admin unter Einstellungen → Abonnement.
Passwort vergessen / zurücksetzen
/forgot-password(wartungs-ausgenommen): E-Mail-Eingabe →POST /api/auth/forgot-passwordruftsupabase.auth.resetPasswordForEmail(email, { redirectTo: '/reset-password' }). Die Antwort ist immer{ success: true }(kein Info-Leak)./reset-password(wartungs-ausgenommen): wartet auf das Supabase-PASSWORD_RECOVERY-Event, ruft dann clientseitigupdateUser({ password }). Die Recovery-Session kommt automatisch über den E-Mail-Link; kein separater Server-Endpunkt nötig.
Für wen
Neue Anbieter, die mit licensio starten wollen.
Schritt für Schritt
1. Account-Felder ausfüllen
Das Register-Formular fragt genau diese Felder ab — sonst nichts:
- Vorname + Nachname: die ersten beiden Pflichtfelder (eine Zeile, zwei Spalten), gespeichert auf
tenant_users(Migration 096), Anrede in Willkommens- und Login-OTP-Mail. - Firmenname
- E-Mail: primärer Login
- Passwort: min. 8 Zeichen (+ Bestätigung)
- Land des Unternehmens: ein Profilfeld (
tenants.country) für Abrechnungswährung und Compliance. Es legt kein Stripe-Konto an und setzt an dieser Stelle keine Portal-Adresse. - Branche (NACE Rev. 2.1): Pflicht. Zweistufige Auswahl (Sektion A–V → Abteilung, 87 Abteilungen, DE/EN-Labels aus der amtlichen Eurostat-Quelle). Bis zu 3 Branchen, die erste ist die Hauptbranche. Gespeichert in
tenants.industry_codes(Migration 093), serverseitig gegen die Referenztabellenace_divisionsvalidiert. - AGB + Datenschutz akzeptieren (Pflicht-Checkbox)
Es gibt keine Planauswahl, keine Tarif-Karten und kein Shop-/Subdomain-Feld.
2. Absenden
Das Backend (/api/register) führt aus:
- Validierung (Vor-/Nachname nicht leer + max 80, E-Mail-Format, Passwortlänge, Firmenname ≥ 3 Zeichen, unterstütztes Land, mindestens ein gültiger NACE-Branchencode, AGB akzeptiert — siehe
apps/admin/lib/register-validate.ts+validateIndustryCodes) - Cloudflare-Turnstile-Captcha-Prüfung (fail-open solange
TURNSTILE_SECRET_KEYungesetzt ist) - E-Mail-Eindeutigkeitsprüfung
auth.admin.createUser({ email_confirm: true }): Account direkt aktiv ohne Mail-BestätigungtenantsINSERT: Planfree,slug: NULL,industry_codes, Abrechnungswährung aus dem Land abgeleitet, Default-Branding (primary_color: #0070F3,button_style: rounded),terms_accepted_at+terms_versiontenant_usersINSERT mitrole='admin',first_name,last_name- Weiterleitung: mit Anbieter-Absicht auf
/onboarding/provider, sonst/onboarding(dazwischen Post-Register-OTP zur E-Mail-Bestätigung)
Bei Fehlern werden Auth-User + Tenant-Eintrag zurückgerollt.
3. Onboarding-Wizard
Nach erfolgreicher Registrierung führt ein Wizard durch Branding, Stripe Connect und das erste Produkt:
- Willkommen: Überblick über die nächsten Schritte.
- Branding: Firmenname + Primärfarbe (Logo + weitere Farben später im Dashboard)
- Stripe Connect: Klick auf „Stripe verbinden" startet das Express-Onboarding über
/api/stripe/connect/authorize?return=onboarding. Nach dem Stripe-Setup landet man zurück auf/onboarding?step=4&stripe=connected. - Erstes Produkt: Direktlink zur Produkterstellung (oder überspringen)
- Fertig: Überblick „Wie geht's weiter", Link ins Dashboard
Ein Fortschrittsbalken oben + ein Schrittzähler unten zeigen den Fortschritt. Der URL-Parameter ?step=N springt zum jeweiligen Schritt (z. B. nach der Stripe-Connect-Rückkehr).
4. Plan-Gates im Admin
Features, die im aktuellen Plan nicht enthalten sind, werden ausgeblendet statt gesperrt (seit 2026-05-29, kein Lock-Banner / 🔒-Badge / Upgrade-CTA mehr):
- Die Widget- + Domain-Tabs in den Einstellungen sowie die zugehörigen Advanced-Kacheln erscheinen nur, wenn der Plan das Feature hat
- Bulk-Import, API, PrintFarm ebenso: der Nav-Eintrag fehlt ohne das Feature komplett
- Direktes Öffnen einer Feature-Seite ohne Berechtigung → 404 (
notFound()) - Feature-Promotion läuft über Newsletter + App Store (Phase 4), nicht mehr über Lock-Hinweise
Die Sichtbarkeitslogik liegt in apps/admin/lib/plans.ts (isFeatureAvailable + has_*-Flags). apps/admin/components/PlanGate.tsx rendert null, wenn ein Feature fehlt (defensiver Content-Layer, future-proof). Backend-API-Routen prüfen den Plan zusätzlich serverseitig (403).
Häufige Fragen
Welche Felder fragt die Registrierung ab? Firmenname, E-Mail, Passwort, Land des Unternehmens, Branche (NACE Rev. 2.1, Pflicht) und die AGB-Checkbox. Sonst nichts — keine Planauswahl, keine Tarif-Karten, keine Subdomain.
Wann bekomme ich eine Portal-Adresse (<name>.licensio.io)?
Beim Aktivieren des Anbieter-Moduls (App Store, später). Erst dann wird eine Subdomain gewählt und provisioniert. Admin-Aktionen, die einen Portal-Link versenden würden (Kunde einladen, Freischalten, Mail senden, Registrierung erneut senden, Passwort zurücksetzen, Newsletter, Benachrichtigung senden), sind bis dahin deaktiviert.
Kann ich auf einen kostenpflichtigen Tarif upgraden? Ja, später im Admin unter Einstellungen → Abonnement. Die Registrierung startet immer mit dem kostenfreien Zugang.
Werden Daten bei Account-Löschung DSGVO-konform behandelt?
Die Anbieter-Löschung läuft über eine Support-Anfrage. DSGVO Art. 17 wird durch Löschen von tenant_users + tenants erfüllt; Kundendaten in deleted_customers werden anonymisiert archiviert.
Verwandt
- Zugang & Konditionen: was der kostenfreie Zugang enthält
- Erste Schritte: nach der Registrierung
- Branding: das Portal anpassen