Vorbereitung fuer Stripe Billing (Zahlungseinzug) + bestehendes Dolibarr des Kunden (Rechnungsstellung/Buchhaltung) statt eines eigenen Rechnungs- systems oder eines zusaetzlichen ERP nur fuer Kaffeeliste - Begruendung in docs/billing.md. - Neue Tabelle tenant_billing (plan_code, subscription_status, sowie bereits vorbereitete, noch ungenutzte Felder fuer Stripe/Dolibarr-IDs). - app/billing.php: billing_plans() als einzige Quelle der Tarifstufen (synchron mit preise.php), billing_required_plan_code() anhand aktiver Teilnehmerzahl, billing_check_tenant() vergleicht gebuchten mit benoetigtem Tarif - rein informativ, kein Enforcement, solange Stripe nicht angebunden ist. - Neue Mandanten starten automatisch auf plan_code='free' bei der Registrierung. - mandant-einstellungen.php zeigt Owner/Admin ihren aktuellen Tarif und Teilnehmerstand, mit Hinweis bei Bedarf einer hoeheren Stufe. - Back-Office zeigt zusaetzlich zur Mandantenliste den gebuchten und (falls abweichend) den tatsaechlich benoetigten Tarif. Live getestet: Tarifgrenzen (10/25/50/150) mit einem Mandanten unter und einem ueber dem Freikontingent geprueft, UI in Mandant-Einstellungen und Back-Office verifiziert. Alle M8-Isolations-/Rollenmatrix-Tests weiterhin gruen. Phase 2 (Stripe) und Phase 3 (Dolibarr-Sync) folgen, sobald Test-Keys beziehungsweise Sandbox-Zugang vorliegen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
4.4 KiB
Preis- und Abrechnungslogik
Stand: 2026-07-16
Geplante Architektur (mit dem Kunden abgestimmt): Stripe Billing für den Zahlungseinzug, bestehendes Dolibarr für Rechnungsstellung/Buchhaltung. Kein eigenes Rechnungssystem, kein zusätzliches ERP nur für Kaffeeliste – siehe Begründung unten.
Warum diese Aufteilung
Drei getrennte Probleme:
- Rechnung erzeugen – löst Dolibarr (bereits im Einsatz für ein anderes Business des Kunden), fortlaufend nummeriert, GoBD-konform.
- Geld tatsächlich einziehen – der eigentlich schwierige Teil (wiederkehrende Belastung, Fehlschlag-Wiederholung, Zahlungsmittel- Verwaltung). Weder ein selbstgebautes System noch Dolibarr allein lösen das; ein Zahlungsanbieter mit Abo-Logik schon.
- Tarif-/Nutzungsstand verwalten – das übernimmt Kaffeeliste selbst, da die Teilnehmerzahl je Mandant ohnehin schon vorhanden ist.
Empfehlung: Stripe Billing statt Mollie, weil eine echte Abo-Logik mit automatischem Stufenwechsel gebraucht wird (Stripes Billing-Produkt ist dafür ausgereifter als Mollies Subscriptions-API); Mollie ist bei SEPA-Lastschrift günstiger, aber weniger auf SaaS-Abos zugeschnitten.
Phase 1: Datenmodell und Tariflogik (umgesetzt, keine externen Zugänge nötig)
Umgesetzte Dateien:
database/migrations/0014_saas_tenant_billing.sql
app/billing.php
app/saas-auth.php (Init bei Registrierung)
mandant-einstellungen.php (Anzeige "Abo & Tarif")
app/platform-admin.php, backoffice.php (Tarif-Spalte im Back-Office)
- Neue Tabelle
tenant_billing:plan_code,subscription_status,stripe_customer_id,stripe_subscription_id,current_period_end,dolibarr_thirdparty_id(letztere beide vorbereitet für Phase 2/3, noch ungenutzt). billing_plans()ist die einzige Quelle für die Tarifstufen (free/basic/plus/pro/enterprise), synchron mit den Preisen aufpreise.php.billing_required_plan_code()errechnet anhand der aktiven Teilnehmerzahl die günstigste ausreichende Stufe.billing_check_tenant()vergleicht gebuchten mit benötigtem Tarif; rein informativ – kein Enforcement, kein Sperren bei Überschreitung. Solange Stripe nicht angebunden ist, wird bei Bedarf manuell umgestellt (Hinweistext verweist auf Kontakt per E-Mail).- Neue Mandanten starten automatisch mit
plan_code = 'free'. - Owner/Admin sehen ihren aktuellen Tarif und die aktive Teilnehmerzahl
unter „Abo & Tarif" auf
mandant-einstellungen.php; bei Bedarf einer höheren Stufe erscheint ein Hinweis. - Das Back-Office (
backoffice.php) zeigt zusätzlich zur Mandantenliste den gebuchten Tarif und, falls abweichend, den tatsächlich benötigten Tarif – der Betreiber sieht auf einen Blick, wer manuell hochgestuft werden müsste.
Live getestet: Tarifgrenzen-Berechnung (10/25/50/150) mit einem Mandanten knapp unter und einem mit 12 Teilnehmern (über dem Freikontingent, korrekt als „basic" erkannt) geprüft; UI-Anzeige in Mandant-Einstellungen und Back-Office live verifiziert. Alle bestehenden M8-Isolationstests und der Rollen-Matrix-Test bleiben unverändert grün.
Phase 2: Stripe-Anbindung (noch offen)
Wartet auf Stripe-Test-API-Keys vom Kunden. Geplanter Umfang:
- Stripe Checkout zum Abschließen/Wechseln eines bezahlten Tarifs.
- Webhook-Endpunkt für
checkout.session.completed,customer.subscription.updated/.deleted,invoice.paid/.payment_failed, dertenant_billingaktuell hält. - Stripe Customer Portal für Zahlungsmittel-Verwaltung/Kündigung durch den Kunden selbst.
- Automatischer Stufenwechsel: Sobald
billing_check_tenant()einen höheren Bedarf erkennt, Wechsel der Stripe-Subscription auslösen (mit Proration) statt nur anzuzeigen.
Phase 3: Dolibarr-Anbindung (noch offen)
Wartet auf Zugang zu einer Dolibarr-Sandbox/Testinstanz (bewusst nicht direkt gegen die produktive Instanz des Kunden, um deren bestehende Buchhaltungsdaten nicht zu gefährden). Geplanter Umfang:
- Bei jedem erfolgreichen Stripe-Zahlungsereignis (
invoice.paid) über die Dolibarr-REST-API eine Rechnung im bestehenden Dolibarr des Kunden anlegen (dolibarr_thirdparty_idverknüpft den Mandanten mit dem Dolibarr-Kunden). - Stripe bleibt alleiniger Zahlungsweg; Dolibarr wird nur als Buchhaltungs- Spiegel befüllt, nicht selbst zum Auslösen von Zahlungen verwendet.
- Erst nach erfolgreichem Test gegen die Sandbox gegen die produktive Dolibarr-Instanz freigeben.