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:
+66
-32
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user