Billing Phase 3: Dolibarr-Rechnungssynchronisation

Bei erfolgreicher Stripe-Zahlung (invoice.paid) wird automatisch ein
Dolibarr-Kunde ermittelt/angelegt und eine validierte Rechnung als
Buchhaltungsspiegel erzeugt. Dolibarr-Fehler blockieren die
Stripe-Webhook-Verarbeitung nicht, sondern landen im Audit-Log zur
manuellen Nachbearbeitung. Getestet gegen die produktive
Dolibarr-Instanz des Kunden (kein Sandbox verfuegbar) mit einem
rechtebeschraenkten API-Key und einem nicht validierten Test-Datensatz.
This commit is contained in:
2026-07-17 10:35:01 +02:00
parent 80da042cae
commit 73d599f85b
3 changed files with 275 additions and 34 deletions
+66 -32
View File
@@ -147,43 +147,77 @@ klicken, wenn `billing_check_tenant()` einen höheren Bedarf anzeigt).
- Von Test- auf Live-API-Keys wechseln, sobald ein echter Stripe-Account
mit Bankverbindung eingerichtet ist.
## Phase 3: Dolibarr-Anbindung (noch offen)
## Phase 3: Dolibarr-Anbindung (umgesetzt)
**Korrektur (2026-07-16):** Der Kunde betreibt nur eine einzige
Dolibarr-Instanz, und das ist die produktive für sein anderes Business
keine separate Sandbox verfügbar. Der ursprüngliche Plan „erst gegen
Sandbox testen" ist damit hinfällig; stattdessen wird sicher **innerhalb**
der einen produktiven Instanz getestet:
**Ausgangslage:** Der Kunde betreibt nur eine einzige Dolibarr-Instanz,
und das ist die produktive für sein anderes Business keine separate
Sandbox verfügbar (Dolibarr 23.0.3, `https://verwaltung.ctb-it.de`).
Der ursprüngliche Plan „erst gegen Sandbox testen" wurde daher ersetzt
durch sicheres Testen **innerhalb** der einen produktiven Instanz.
- **Eigener, rechtebeschränkter API-Key**: Der Kunde legt einen
dedizierten Dolibarr-Benutzer/API-Key nur mit den für die Integration
nötigen Rechten an (Thirdparty + Invoice lesen/erstellen), statt seinen
bestehenden Admin-Key zu nutzen. Begrenzt den Schaden, falls der Key
je kompromittiert wird.
- **Test nur über Entwurfs-Rechnungen (Draft)**: Dolibarr-Rechnungen im
Entwurfsstatus haben noch keine fortlaufende, GoBD-relevante
Rechnungsnummer und lassen sich rückstandsfrei löschen. Die
Integration wird gegen einen eindeutig benannten Test-Kunden
(z. B. „TEST Kaffeeliste Integration") getestet; die dabei erzeugte
Entwurfs-Rechnung wird **nicht validiert**, sondern nach Prüfung der
Feldinhalte über die API wieder gelöscht.
- Erst wenn dieser Test erfolgreich war, wird der Live-Betrieb
freigeschaltet (echte Stripe-`invoice.paid`-Events lösen dann echte
Rechnungserstellung bei echten Kunden aus).
Umgesetzte Dateien:
Geplanter Umfang der Anbindung selbst bleibt unverändert:
```text
app/dolibarr.php
stripe-webhook.php (invoice.paid ruft dolibarr_sync_invoice_paid())
```
- Bei jedem erfolgreichen Stripe-Zahlungsereignis (`invoice.paid`) über
die Dolibarr-REST-API eine Rechnung im bestehenden Dolibarr des Kunden
anlegen (`dolibarr_thirdparty_id` verknüpft den Mandanten mit dem
Dolibarr-Kunden).
- `app/dolibarr.php`: minimaler REST-Client nach demselben Muster wie
`app/stripe.php` (PHP-Streams, kein SDK). `dolibarr_find_or_create_thirdparty()`
legt bei Erstkontakt einen Dolibarr-Kunden für den Mandanten an
(`Kaffeeliste - <Mandantenname>`, E-Mail des Owners) und cached die
Dolibarr-Kunden-ID in `tenant_billing.dolibarr_thirdparty_id`.
`dolibarr_create_and_validate_invoice()` legt eine Rechnung mit einer
Freitext-Position an (kein eigenes Dolibarr-Produkt pro Tarif nötig),
fügt die Position hinzu und validiert die Rechnung sofort (vergibt die
permanente, fortlaufende Nummer). `tva_tx = 0` durchgängig, da
Kleinunternehmer nach § 19 UStG.
- `stripe-webhook.php`: `invoice.paid` löst jetzt zusätzlich zum
Audit-Log-Eintrag `dolibarr_sync_invoice_paid()` aus. Ein Fehlschlag
dort (Netzwerk, Dolibarr down, ungültige Daten) wird **nicht** an
Stripe als Fehler zurückgemeldet Stripe hat das Geld bereits
erfolgreich eingezogen, das ist unabhängig vom Dolibarr-Spiegel. Der
Fehler landet stattdessen als `billing.dolibarr_invoice_failed` im
Mandanten-Audit-Log (sichtbar sowohl unter „Protokoll" in
Mandant-Einstellungen als auch im Back-Office) zur manuellen
Nachbearbeitung.
- Rechnungen werden **automatisch validiert** (nicht als Entwurf für
manuelle Prüfung liegen gelassen) bewusste Entscheidung des Kunden,
um den Prozess vollautomatisch zu halten.
- Das automatische **Erfassen der Zahlung** in Dolibarr (Rechnung als
bezahlt markieren) ist bewusst **nicht** umgesetzt erfordert
Kenntnis der Bankkonto-/Zahlungsart-IDs der Dolibarr-Instanz. Rechnungen
erscheinen offen und werden vom Kunden manuell abgeglichen.
- Stripe bleibt alleiniger Zahlungsweg; Dolibarr wird nur als Buchhaltungs-
Spiegel befüllt, nicht selbst zum Auslösen von Zahlungen verwendet.
**Offen, bevor programmiert werden kann:**
### Live getestet
- Dolibarr-Basis-URL und der neue, rechtebeschränkte API-Key.
- Dolibarr-Version (API-Feldnamen unterscheiden sich leicht je Version).
- Ob pro Kaffeeliste-Tarif ein eigenes Dolibarr-Produkt angelegt wird
oder eine einzelne generische Rechnungsposition mit Freitext-
Beschreibung + Betrag aus Stripe genügt.
- **Verbindung/Lesezugriff**: `GET /status`, `/thirdparties`,
`/invoices` gegen die echte Instanz erfolgreich geprüft (Version,
Erreichbarkeit, Rechte des API-Keys).
- **Schreibzugriff (mit expliziter Freigabe des Kunden)**: ein eindeutig
benannter Test-Kunde („TEST Kaffeeliste Integration") sowie eine
Entwurfs-Rechnung mit Position wurden über die API angelegt und die
Struktur verifiziert (`status: 0` = Entwurf, `ref: (PROVx)` = noch
keine permanente Nummer, korrekter Betrag, korrekte Verknüpfung).
**Nicht validiert** der Kunde hat die beiden Testdatensätze danach
manuell in der Dolibarr-Oberfläche gelöscht (der beschränkte API-Key
hat kein Lösch-Recht, `DELETE` liefert `403`).
- **Bewusst nicht live getestet**: der eigentliche `validate()`-Aufruf,
der die permanente Rechnungsnummer vergibt das hätte einen
unlöschbaren Testeintrag in der produktiven Buchhaltung hinterlassen.
Auf Wunsch des Kunden ist die erste echte Stripe-Zahlung nach dem
Go-Live der erste echte Test dieses Schritts. Das Risiko ist durch die
fehlertolerante Webhook-Verarbeitung begrenzt (siehe oben).
- Alle bestehenden Regressionstests (Golden Master, M8-Isolation,
M8-Rollenmatrix, HTTP-Smoke mit 36 Seiten) weiterhin grün.
### Für den Produktivbetrieb noch zu tun
- Nach dem ersten echten `invoice.paid`-Ereignis in Produktion das
Mandanten-Audit-Log prüfen (`billing.dolibarr_invoice_created` bzw.
`billing.dolibarr_invoice_failed`), um den `validate()`-Aufruf einmal
scharf zu bestätigen.
- Zahlungserfassung in Dolibarr (Rechnung als bezahlt markieren) als
möglicher Ausbau, sobald Bankkonto-/Zahlungsart-IDs bekannt sind.