Ein SaaS-Produkt mit KRONENWERK an die Buchhaltung anzubinden bedeutet vier Dinge: je zahlendem Konto einen Kunden anlegen, für jedes abrechenbare Ereignis einen Vorgang und einen Rechnungsentwurf mit einem aus Ihrem eigenen Datensatz abgeleiteten Idempotency-Key eröffnen, invoice.issued, invoice.paid und payment.recorded an einem Webhook-Endpunkt empfangen und mit GET /reports/outstanding abstimmen. Die API stellt keine Rechnungen aus und erfasst keine Zahlungen; das tut eine Person im Produkt, und die Ereignisse teilen Ihrem System mit, was geschehen ist. Das ist die ehrliche Gestalt der Integration, und diese Seite zeigt sie Schritt für Schritt.
Was die Integration automatisieren kann und was nicht
Die KRONENWERK-API legt wiederherstellbare Datensätze an und liest die Bücher. Sie führt die unumkehrbaren Handlungen nicht aus – eine Rechnung ausstellen, eine Zahlung erfassen, stornieren –, weil jede davon etwas verbraucht, das sich nicht zurückholen lässt, oder Geld im Hauptbuch bewegt. Für ein SaaS-Backend ist das eine Randbedingung, die Sie kennen sollten, bevor Sie entwerfen.
| Ihr Ereignis | Was Ihre App tut | Was im Produkt geschieht | Was zurückkommt |
|---|---|---|---|
| Konto registriert sich oder wechselt auf einen bezahlten Plan | POST /customers | Der Kunde erscheint in den Stammdaten mit einer Partnernummer | 201 mit id und number des Kunden |
| Vertrag oder Bestellung wird vereinbart | POST /transactions | Ein Vorgang (ein Auftrag mit Phase und Fälligkeitsdatum) erscheint auf dem Board des Unternehmens | 201 mit number wie V2026-0481 |
| Abrechnungszeitraum eines B2B-Kontos wird fällig | POST /invoices/drafts | Ein Entwurf wartet auf Positionen und die Ausstellung durch eine Person | 201 mit dem Entwurf; später invoice.issued |
| Kunde zahlt (Karte, Überweisung) | Nichts auf der API | Die Zahlung wird im Produkt erfasst: manuell oder aus dem verbundenen Bankkonto zugeordnet | payment.recorded und, wenn die Forderung ausgeglichen ist, invoice.paid |
| Erstattung oder Reklamation macht eine Rechnung rückgängig | Nichts auf der API | Eine Person stellt eine vollständige Korrektur aus | invoice.cancelled mit Nennung der Gutschrift |
| Prüfung zum Monatsende | GET /reports/outstanding, GET /invoices?status=OPEN | — | Heute offene Forderungen und Verbindlichkeiten; die offenen Rechnungen |
Die API ist Teil des Enterprise-Plans; die gesamte Schnittstelle steht auf der Seite zur Buchhaltungs-API. Die betriebswirtschaftliche Seite der Buchführung eines Abonnementunternehmens – passive Rechnungsabgrenzung, Umsatzsteuer auf digitale Dienstleistungen, mehrere Währungen – wird in Buchhaltung für SaaS und Eine App mit der Buchhaltung verbinden behandelt.
Muster 1: ein Kunde je zahlendem Konto, idempotent angelegt
Legen Sie den KRONENWERK-Kunden an, wenn ein Konto zum zahlenden Kunden wird, nicht bei der Registrierung, und verwenden Sie Ihre eigene Kontokennung im Idempotency-Key. Ein Wiederholungsversuch nach einer verlorenen Antwort liefert dann den angelegten Kunden zurück statt eines Duplikats – und ein doppelter Kunde ist der Fehler, den niemand bemerkt, bis eine Rechnung an den falschen Datensatz geht.
curl -X POST https://kronenwerk.org/api/extern/v1/customers \
-H "Authorization: Bearer greif_live_…" \
-H "Idempotency-Key: account-88213" \
-H "Content-Type: application/json" \
-d '{
"name": "Beispiel GmbH",
"email": "billing@example.de",
"street": "Musterstraße 1",
"postalCode": "10115",
"city": "Berlin",
"country": "DE",
"vatId": "DE123456789",
"currency": "EUR"
}'
Name, Straße, Postleitzahl und Ort sind Pflicht – die EN 16931 führt eine Adresse in Einzelteilen, und an einen Kunden ohne Straße lässt sich keine Rechnung adressieren. Land, USt-IdNr. und Währung sind optional; ein fehlendes Land wird mit dem des eigenen Unternehmens vorbelegt. Speichern Sie die zurückgegebene id zu Ihrem Konto. Die USt-IdNr. ist wichtiger, als sie aussieht: Bei der Ausstellung prüft KRONENWERK sie gegen VIES und leitet daraus das Steuerurteil ab (zum Beispiel Reverse Charge für einen Unternehmerkunden in einem anderen EU-Land). Erheben Sie sie im Checkout.
Muster 2: ein Vorgang je Bestellung, mit Ihren Kennungen darin
Ein Vorgang in KRONENWERK ist eine Arbeitseinheit mit Titel, Kunde, einer Phase aus dem eigenen Workflow des Unternehmens und einem Fälligkeitsdatum – eine Bestellung, ein Projekt, ein Abonnementzeitraum. Er trägt kein Geld, und genau deshalb ist er der richtige Datensatz für „etwas Abrechenbares ist passiert“, bevor jemand entschieden hat, was auf der Rechnung stehen wird. Schreiben Sie Ihre Anbieterkennungen in die Beschreibung, damit die Person, die später die Rechnung ausstellt, das Stripe-Abonnement oder die Bestellung mit einer einzigen Suche findet.
curl -X POST https://kronenwerk.org/api/extern/v1/transactions \
-H "Authorization: Bearer greif_live_…" \
-H "Idempotency-Key: sub_1Q…-2026-09" \
-H "Content-Type: application/json" \
-d '{
"title": "Team plan, September 2026 — Beispiel GmbH",
"customerId": "3f2b…",
"description": "Stripe subscription sub_1Q…, invoice in_1Q…, 12 seats",
"dueOn": "2026-09-30"
}'
Nur title ist Pflicht. stage kann einen Phasenschlüssel des Unternehmens-Workflows nennen; fehlt er, beginnt der Vorgang dort, wo der Workflow beginnt. Die Antwort enthält id, number, title, stage, customer, dueOn, archived und createdAt. GET /transactions?search=sub_1Q… findet ihn wieder. Beachten Sie, dass dies keine Buchung im Hauptbuch ist: Nichts wird gebucht, bis im Produkt eine Rechnung ausgestellt oder eine Zahlung erfasst wird.
Muster 3: ein Rechnungsentwurf für jedes B2B-Abrechnungsereignis
Für Geschäftskunden, die eine ordentliche Rechnung brauchen – eine XRechnung für einen deutschen öffentlichen Auftraggeber, ein Peppol-Dokument für einen belgischen, eine Factur-X für einen französischen –, starten Sie einen Entwurf, wenn der Abrechnungszeitraum fällig wird. Der Entwurf trägt den Nummerierungsvorschlag des Verkäufers und die Zahlungsbedingungen des Kunden; eine Person fügt die Positionen hinzu und stellt ihn aus, und die strukturierte Datei wird in diesem Moment erzeugt und validiert. Warum die Grenze beim Entwurf gezogen wird, erklärt die Seite zur Rechnungs-API.
curl -X POST https://kronenwerk.org/api/extern/v1/invoices/drafts \
-H "Authorization: Bearer greif_live_…" \
-H "Idempotency-Key: in_1Q…" \
-H "Content-Type: application/json" \
-d '{ "customerId": "3f2b…" }'
Verwenden Sie die Rechnungskennung des Anbieters als Schlüssel: eine Stripe-Rechnung, ein KRONENWERK-Entwurf, egal wie oft der auslösende Webhook zugestellt wird. Wenn Ihr Produkt Verbraucher statt Unternehmen abrechnet, brauchen Sie möglicherweise gar keinen Entwurf je Zahlung; eine periodische Zusammenfassung, die im Produkt bearbeitet wird, passt oft besser, und ob ein Verkauf an Verbraucher in einem bestimmten Land eine Einzelrechnung erfordert, erfordert fachliche Bestätigung.
Muster 4: Webhooks empfangen, prüfen, deduplizieren, schnell antworten
Registrieren Sie im Produkt einen HTTPS-Endpunkt auf Port 443 und abonnieren Sie invoice.issued, invoice.paid, invoice.cancelled und payment.recorded. Jede Zustellung trägt KRONENWERK-Signature: t=<seconds>,v1=<hex> – ein HMAC-SHA256 über den Zeitstempel, einen Punkt und den rohen Body – sowie eine stabile Ereignis-ID in KRONENWERK-Event-Id und Idempotency-Key. Der Body ist ein flaches JSON-Objekt, dessen Werte Zeichenketten sind, mit sortierten Schlüsseln, wobei event und id immer vorhanden sind.
POST /hooks/kronenwerk HTTP/1.1
Content-Type: application/json; charset=utf-8
KRONENWERK-Event: invoice.paid
KRONENWERK-Event-Id: 0d3c…
KRONENWERK-Delivery: 61af…
KRONENWERK-Attempt: 1
Idempotency-Key: 0d3c…
KRONENWERK-Signature: t=1788768000,v1=9f2c…
User-Agent: KRONENWERK-Webhooks/1
{"amountDueMinor":"0","buyerName":"Beispiel GmbH","currency":"EUR","documentType":"INVOICE","dueDate":"2026-09-17","event":"invoice.paid","grossMinor":"105910","id":"0d3c…","invoiceId":"7a90…","issueDate":"2026-09-03","netMinor":"89000","number":"2026-0042","paidOn":"2026-09-10","paymentState":"PAID","taxMinor":"16910"}
Die Verarbeitungsregeln sind dieselben, die Stripe für seine eigenen Webhooks dokumentiert, und aus denselben Gründen: Prüfen Sie die Signatur gegen den rohen Body, bevor Sie parsen, lehnen Sie einen Zeitstempel außerhalb Ihrer Toleranz ab (der eigene Verifizierer von KRONENWERK verwendet fünf Minuten), protokollieren Sie die Ereignis-ID und überspringen Sie alles, was Sie schon gesehen haben, verlassen Sie sich nicht auf die Reihenfolge, und antworten Sie schnell mit 2xx und erledigen Sie die Arbeit in einer Warteschlange. Die Zustellung erfolgt mindestens einmal mit Wiederholungen; Weiterleitungen werden als Fehler behandelt. Die vollständige Beschreibung steht unter Webhooks.
Muster 5: Abstimmung mit dem Bericht über offene Posten
GET /reports/outstanding beantwortet die Frage „was ist heute in jeder Richtung offen“ aus derselben Übersicht, die das Dashboard des Inhabers anzeigt, sodass Ihre Zahl und dessen Zahl nicht auseinanderlaufen können.
{
"asOf": "2026-09-03",
"currency": "EUR",
"booksOpen": true,
"receivables": {
"outstanding": { "minor": 4237650, "currency": "EUR" },
"due": { "minor": 1105910, "currency": "EUR" },
"overdue": { "minor": 318400, "currency": "EUR" },
"count": 23
},
"payables": {
"outstanding": { "minor": 812000, "currency": "EUR" },
"due": { "minor": 0, "currency": "EUR" },
"overdue": { "minor": 0, "currency": "EUR" },
"count": 4
}
}
Die beiden Seiten werden getrennt ausgewiesen und niemals saldiert: Geld, das einem Unternehmen geschuldet wird, und Geld, das es schuldet, werden an verschiedenen Tagen fällig, und eine einzige Zahl wäre genau dann beruhigend, wenn sie es nicht sein sollte. Für eine Sicht je Rechnung blättern Sie durch GET /invoices?status=OPEN und vergleichen outstanding und overdue mit Ihrem eigenen Abrechnungsstand. Eine Abweichung bedeutet meist eine Zahlung, die die Bank erreicht hat, aber im Produkt noch nicht zugeordnet wurde, oder eine Rechnung, die Ihr Webhook-Handler verloren hat – das Protokoll der Ereignis-IDs sagt Ihnen, welches von beiden.
Beispielablauf für ein über Stripe abgerechnetes Abonnement
- Stripe sendet
customer.subscription.created. Ihr Handler prüft es, dedupliziert anhand der Stripe-Ereignis-ID und ruftPOST /customersmitIdempotency-Key: account-<id>auf, falls für das Konto noch kein KRONENWERK-Kunde existiert. Speichern Sie die zurückgegebeneid. - Ihr Handler ruft
POST /transactionsmitIdempotency-Key: sub_<id>-<period>auf, schreibt die Kennungen des Abonnements und der Stripe-Rechnung indescriptionund das Ende des Zeitraums indueOn. - Für B2B-Konten ruft Ihr Handler
POST /invoices/draftsmitIdempotency-Key: in_<id>auf. - Eine Person in der Finanzabteilung öffnet den Entwurf, fügt anhand der Beschreibung des Vorgangs die Position für den Zeitraum hinzu und stellt ihn aus. KRONENWERK berechnet das Steuerurteil, prüft die USt-IdNr., validiert die strukturierte Datei, verbraucht die Nummer und sendet
invoice.issuedan Ihren Endpunkt. Speichern SienumberundinvoiceIdzur Stripe-Rechnung. - Stripe zieht die Kartenzahlung ein und zahlt auf das Bankkonto des Unternehmens aus. Die Bankanbindung (Enable Banking für europäische Banken, Plaid für kanadische und US-Banken) zeigt die Auszahlung; eine Person ordnet sie der Rechnung zu oder erfasst die Zahlung manuell.
payment.recordedundinvoice.paiderreichen Ihren Endpunkt. - Erstattet Stripe die Belastung, stellt eine Person im Produkt eine Korrektur aus;
invoice.cancelledkommt mitcancelledByNumberan, und Sie hängen die Gutschriftsnummer an die Erstattung. - Zum Monatsende vergleichen Sie
GET /reports/outstandingmit Ihren eigenen offenen Forderungen.
Fallstricke
- Idempotenzschlüssel aus Zeit oder Zufall ableiten
- Ein Schlüssel, der sich beim Wiederholungsversuch ändert, schützt nichts. Leiten Sie ihn aus dem Datensatz ab, den Sie spiegeln – Konto-ID, Abonnement-ID plus Zeitraum, Rechnungs-ID des Anbieters –, sodass ein Wiederholungsversuch dieselbe Operation bedeutet. Ein anderer Body unter demselben Schlüssel antwortet mit
409 IDEMPOTENZ_KONFLIKT, was ein Fehler in Ihrem Code ist, kein vorübergehender Fehler. - Entwürfe anlegen, bevor der Kunde existiert
- Stripe garantiert keine Ereignisreihenfolge;
invoice.paidkann vorcustomer.subscription.createdeintreffen. Ermitteln Sie zuerst den KRONENWERK-Kunden, legen Sie ihn idempotent an, falls er fehlt, und erstellen Sie dann den Entwurf. - Ein Schlüssel, eine Firma
- Ein KRONENWERK-API-Schlüssel ist für seine gesamte Lebensdauer an genau eine Firma gebunden. Ein SaaS mit mehreren Rechtsträgern (etwa einer deutschen GmbH und einer französischen SAS) braucht je Rechtsträger einen Schlüssel und muss jedes Konto an den richtigen leiten; siehe Mehrere Firmen, mehrere Währungen.
invoice.issuedals „versendet“ behandeln- Es bedeutet, dass ein validiertes Dokument existiert und eine Nummer verbraucht wurde. Die Zustellung – E-Mail, Peppol über den verbundenen Access-Point-Anbieter oder ein nationales System – ist ein separater Schritt im Produkt und wird auf der API nicht gemeldet.
- Das Ratenlimit ignorieren
- Das Budget beträgt 240 Anfragen je Schlüssel, aufgefüllt mit etwa zwei pro Sekunde. Ein Monatsend-Job, der tausend Entwürfe in einem Schwung anlegt, trifft auf
429mitRetry-After; beachten Sie den Header und verteilen Sie die Arbeit. Details unter Grenzen. - Gegen den Live-Schlüssel testen
- Verwenden Sie während der Entwicklung einen
greif_test_-Schlüssel; er funktioniert gegen denselben Host im Testmodus für die Firma, die ihn erstellt hat.GET /memeldetenvironmentalsSANDBOXoderPRODUCTION, sodass eine Startprüfung sich weigern kann, einen Test-Build mit einem Live-Schlüssel auszuführen. - Formatierte Beträge speichern
- Beträge sind auf der API ganzzahlige Nebeneinheiten mit Währungscode und in Webhook-Bodys Zeichenketten aus Nebeneinheiten. Parsen Sie nirgendwo „1.059,10 €“; es gibt nichts zu parsen.
So geht KRONENWERK damit um
MIT EINSCHRÄNKUNGEN UNTERSTÜTZT Alles hier Gezeigte läuft auf der API, wie sie heute existiert, im Enterprise-Plan (Preise): idempotentes Anlegen von Kunden, Vorgängen und Rechnungsentwürfen; signierte Webhooks für Ausstellung, Zahlung, Stornierung, Einkäufe und Zahlungen; der Bericht über offene Posten und seitenweises Lesen von Rechnungen. Die Einschränkungen sind die durchgehend genannten: keine Ausstellung, keine Zahlungserfassung, keine Stornierung und kein Datei-Download über die API sowie kein automatischer Import von Stripe-Zahlungen. Wenn Ihre Integration eine Abrechnungsschleife ohne Menschen braucht, ist die API von KRONENWERK nicht das Richtige. Wenn die Bücher einer Firma widerspiegeln sollen, was Ihr Produkt verkauft hat, wobei die rechtlichen Schritte von einer Person nach den Regeln des Landes vorgenommen werden, ist dies der vorgesehene Weg. Die zugehörigen Produktseiten sind Buchhaltung, Rechnungen und Automatisierung; der Vergleich von Buchhaltungswerkzeugen mit API steht unter Buchhaltungssoftware mit API.
Häufig gestellte Fragen
Kann ich eine Stripe-Zahlung über die API erfassen?
Nein. Die API erfasst keine Zahlungen. Auszahlungen erreichen die Bücher über die Bankanbindung, oder eine Person erfasst die Zahlung; payment.recorded und invoice.paid erreichen dann Ihren Endpunkt.
Was ist ein „Vorgang“ (transaction) auf der API?
Eine Arbeitseinheit mit Titel, optionalem Kunden, einer Phase aus dem Workflow der Firma und einem Fälligkeitsdatum – eine Bestellung oder ein Abonnementzeitraum. Es ist keine Buchung im Hauptbuch.
Brauche ich für jede Verbraucherzahlung einen Entwurf?
Oft nicht. Entwürfe sind für Kunden gedacht, die eine einzelne, strukturierte Rechnung brauchen. Ob Verkäufe an Verbraucher in einem bestimmten Land eine solche erfordern, ist eine Frage, die fachliche Bestätigung erfordert.
Wie sollte ich Idempotenzschlüssel ableiten?
Aus Ihren eigenen stabilen Kennungen: Konto-ID für Kunden, Abonnement-ID plus Zeitraum für Vorgänge, Rechnungs-ID des Anbieters für Entwürfe. Schlüssel dürfen bis zu 200 Zeichen lang sein.
Wie teste ich, ohne die Live-Bücher zu berühren?
Erstellen Sie einen greif_test_-Schlüssel. Er funktioniert gegen dieselbe API im Testmodus für die Firma, die ihn erstellt hat, und GET /me meldet "environment", damit Ihr Build es prüfen kann.
Quellen
- KRONENWERK developer documentation — gelesen am
- Stripe — Receive Stripe events in your webhook endpoint (duplicates, ordering, signatures) — gelesen am
- Stripe — Idempotent requests — gelesen am