Naar de inhoud

Voor ontwikkelaars

Uw SaaS koppelen aan de boekhouding: klanten, concepten, webhooks

Laatst gecontroleerd SUPPORTED WITH LIMITATIONS

Vertaling van de Engelse versie, die als eerste wordt bijgehouden. Regelgevende uitspraken verwijzen naar de genoemde bronnen en hun leesdatum.

Een SaaS-product met KRONENWERK aan de boekhouding koppelen betekent vier dingen: één klant aanmaken per betalend account, voor elke factureerbare gebeurtenis een transactie en een factuurconcept openen met een Idempotency-Key die van uw eigen record is afgeleid, invoice.issued, invoice.paid en payment.recorded ontvangen op een webhook-endpoint, en afstemmen met GET /reports/outstanding. De API reikt geen facturen uit en registreert geen betalingen; dat doet een persoon in het product, en de events vertellen uw systeem wat er is gebeurd. Dat is de eerlijke vorm van de integratie, en deze pagina laat ze stap voor stap zien.

Wat de integratie wel en niet kan automatiseren

De API van KRONENWERK maakt herstelbare records aan en leest de boekhouding. Ze voert de onomkeerbare handelingen niet uit — een factuur uitreiken, een betaling registreren, annuleren — omdat elk daarvan iets verbruikt dat niet ongedaan kan worden gemaakt of geld in het grootboek verplaatst. Voor een SaaS-backend is dat een beperking die u moet kennen voordat u ontwerpt.

Uw gebeurtenisWat uw app doetWat er in het product gebeurtWat terugkomt
Account registreert zich of stapt over naar een betaald planPOST /customersDe klant verschijnt in de stamgegevens met een relatienummer201 met de id en het number van de klant
Contract of order wordt overeengekomenPOST /transactionsEen transactie (een opdracht met een fase en een vervaldatum) verschijnt op het bord van de onderneming201 met een number zoals V2026-0481
Factureringsperiode vervalt voor een B2B-accountPOST /invoices/draftsEen concept wacht op regels en uitreiking door een persoon201 met het concept; later invoice.issued
Klant betaalt (kaart, overschrijving)Niets op de APIDe betaling wordt in het product geregistreerd: handmatig, of gekoppeld vanuit de aangesloten bankrekeningpayment.recorded en, wanneer de vordering is vereffend, invoice.paid
Terugbetaling of geschil maakt een factuur ongedaanNiets op de APIEen persoon reikt een volledige correctie uitinvoice.cancelled met vermelding van de creditnota
Controle bij maandafsluitingGET /reports/outstanding, GET /invoices?status=OPENVandaag openstaande vorderingen en schulden; de openstaande facturen

De API maakt deel uit van het Enterprise-plan; het volledige oppervlak staat op de pagina over de boekhoud-API. De bedrijfskant van het voeren van de boekhouding van een abonnementsbedrijf — uitgestelde omzet, btw op digitale diensten, meerdere valuta's — wordt besproken in boekhouding voor SaaS en een app koppelen aan de boekhouding.

Patroon 1: één klant per betalend account, idempotent aangemaakt

Maak de KRONENWERK-klant aan wanneer een account een betalende klant wordt, niet bij de registratie, en gebruik uw eigen accountidentificator in de Idempotency-Key. Een nieuwe poging na een verloren antwoord geeft dan de aangemaakte klant terug in plaats van een duplicaat, en een dubbele klant is de fout die niemand opmerkt tot een factuur naar het verkeerde record gaat.

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"
  }'

Naam, straat, postcode en plaats zijn verplicht — EN 16931 voert een adres in onderdelen, en een klant zonder straat is er een aan wie geen factuur kan worden geadresseerd. Land, btw-nummer en valuta zijn optioneel; een ontbrekend land valt terug op dat van de onderneming zelf. Sla de teruggegeven id op bij uw account. Het btw-nummer is belangrijker dan het lijkt: bij de uitreiking controleert KRONENWERK het in VIES en leidt het daaruit het btw-oordeel af (bijvoorbeeld verlegging voor een zakelijke klant in een ander EU-land). Vraag het op bij het afrekenen.

Patroon 2: een transactie per order, met uw identificatoren erin

Een transactie in KRONENWERK is een werkeenheid met een titel, een klant, een fase uit de eigen workflow van de onderneming en een vervaldatum — een order, een project, een abonnementsperiode. Ze bevat geen geld, en precies daarom is ze het juiste record voor "er is iets factureerbaars gebeurd" voordat iemand heeft beslist wat de factuur zal zeggen. Zet uw provideridentificatoren in de beschrijving, zodat de persoon die later de factuur uitreikt het Stripe-abonnement of de order in één zoekopdracht terugvindt.

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"
  }'

Alleen title is verplicht. stage mag een fasesleutel uit de workflow van de onderneming noemen; als ze wordt weggelaten, begint de transactie waar de workflow begint. Het antwoord bevat id, number, title, stage, customer, dueOn, archived en createdAt. GET /transactions?search=sub_1Q… vindt ze terug. Merk op dat dit geen grootboekboeking is: er wordt niets geboekt tot een factuur wordt uitgereikt of een betaling in het product wordt geregistreerd.

Patroon 3: een factuurconcept voor elke B2B-factureringsgebeurtenis

Voor zakelijke klanten die een echte factuur nodig hebben — een XRechnung voor een Duitse overheidsklant, een Peppol-document voor een Belgische, een Factur-X voor een Franse — start u een concept wanneer de factureringsperiode vervalt. Het concept bevat het nummeringsvoorstel van de verkoper en de betalingsvoorwaarden van de klant; een persoon voegt de regels toe en reikt het uit, en op dat moment wordt het gestructureerde bestand gegenereerd en gevalideerd. Waarom de grens bij het concept ligt, wordt uitgelegd op de pagina over de factuur-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…" }'

Gebruik de factuuridentificator van de provider als sleutel: één Stripe-factuur, één KRONENWERK-concept, hoe vaak de webhook die het in gang zette ook wordt afgeleverd. Als uw product consumenten factureert in plaats van ondernemingen, hebt u misschien helemaal geen concept per betaling nodig; een periodiek overzicht dat in het product wordt afgehandeld, past vaak beter, en of een verkoop aan een consument in een bepaald land een individuele factuur vereist, vereist professionele bevestiging.

Patroon 4: luister naar de webhooks, verifieer, ontdubbel, antwoord snel

Registreer een HTTPS-endpoint op poort 443 in het product en abonneer u op invoice.issued, invoice.paid, invoice.cancelled en payment.recorded. Elke aflevering bevat KRONENWERK-Signature: t=<seconds>,v1=<hex> — een HMAC-SHA256 over de tijdstempel, een punt en de ruwe body — en een stabiele event-id in KRONENWERK-Event-Id en Idempotency-Key. De body is een plat JSON-object waarvan de waarden strings zijn, met gesorteerde sleutels, waarin event en id altijd aanwezig zijn.

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"}

De verwerkingsregels zijn dezelfde die Stripe voor zijn eigen webhooks documenteert, en om dezelfde redenen: verifieer de handtekening tegen de ruwe body voordat u parset, weiger een tijdstempel buiten uw tolerantie (de eigen verifier van KRONENWERK gebruikt vijf minuten), registreer de event-id en sla alles over wat u al hebt gezien, vertrouw niet op de volgorde, en geef snel een 2xx terug en doe het werk in een wachtrij. De aflevering is at-least-once met nieuwe pogingen; redirects worden als mislukking behandeld. De volledige beschrijving staat op webhooks.

Patroon 5: afstemmen met het rapport van openstaande posten

GET /reports/outstanding beantwoordt de vraag "wat staat er vandaag in elke richting open" op basis van hetzelfde overzicht dat het dashboard van de eigenaar toont, zodat uw cijfer en het hunne niet van elkaar kunnen afwijken.

{
  "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
  }
}

De twee zijden worden afzonderlijk gerapporteerd en nooit gesaldeerd: geld dat aan een onderneming verschuldigd is en geld dat zij verschuldigd is, vervallen op verschillende dagen, en één enkel cijfer zou geruststellend zijn op precies het moment dat het dat niet mag zijn. Voor een overzicht per factuur bladert u door GET /invoices?status=OPEN en vergelijkt u outstanding en overdue met uw eigen factureringsstatus. Een afwijking betekent meestal een betaling die de bank heeft bereikt maar nog niet in het product is gekoppeld, of een factuur die uw webhookhandler heeft laten vallen — het logboek van event-id's vertelt u welke van de twee.

Voorbeeldvolgorde voor een via Stripe gefactureerd abonnement

  1. Stripe stuurt customer.subscription.created. Uw handler verifieert het, ontdubbelt op de Stripe-event-id en roept POST /customers aan met Idempotency-Key: account-<id> als er voor het account nog geen KRONENWERK-klant bestaat. Sla de teruggegeven id op.
  2. Uw handler roept POST /transactions aan met Idempotency-Key: sub_<id>-<period>, zet de identificatoren van het abonnement en de Stripe-factuur in description en het einde van de periode in dueOn.
  3. Voor B2B-accounts roept uw handler POST /invoices/drafts aan met Idempotency-Key: in_<id>.
  4. Een persoon van de financiële afdeling opent het concept, voegt de regel voor de periode toe op basis van de beschrijving van de transactie en reikt het uit. KRONENWERK berekent het btw-oordeel, controleert het btw-nummer, valideert het gestructureerde bestand, verbruikt het nummer en stuurt invoice.issued naar uw endpoint. Sla number en invoiceId op bij de Stripe-factuur.
  5. Stripe int de kaartbetaling en betaalt uit op de bankrekening van de onderneming. De bankkoppeling (Enable Banking voor Europese banken, Plaid voor Canadese en Amerikaanse banken) toont de uitbetaling; een persoon koppelt ze aan de factuur of registreert de betaling handmatig. payment.recorded en invoice.paid bereiken uw endpoint.
  6. Als Stripe de betaling terugbetaalt, reikt een persoon in het product een correctie uit; invoice.cancelled komt binnen met cancelledByNumber, en u koppelt het creditnotanummer aan de terugbetaling.
  7. Bij de maandafsluiting vergelijkt u GET /reports/outstanding met uw eigen openstaande vorderingen.

Valkuilen

Idempotentiesleutels afleiden van tijd of toeval
Een sleutel die bij een nieuwe poging verandert, beschermt niets. Leid ze af van het record dat u spiegelt — account-id, abonnements-id plus periode, factuur-id van de provider — zodat een nieuwe poging dezelfde handeling betekent. Een andere body onder dezelfde sleutel krijgt 409 IDEMPOTENZ_KONFLIKT; dat is een fout in uw code, geen tijdelijke storing.
Concepten aanmaken voordat de klant bestaat
Stripe garandeert de volgorde van events niet; invoice.paid kan vóór customer.subscription.created binnenkomen. Bepaal eerst de KRONENWERK-klant, maak die idempotent aan als hij ontbreekt, en maak dan pas het concept aan.
Eén sleutel, één onderneming
Een API-sleutel van KRONENWERK is voor zijn hele levensduur aan precies één onderneming gebonden. Een SaaS met meerdere juridische entiteiten (bijvoorbeeld een Duitse GmbH en een Franse SAS) heeft één sleutel per entiteit nodig en moet elk account naar de juiste sleutel leiden; zie meerdere ondernemingen, meerdere valuta's.
invoice.issued opvatten als "verzonden"
Het betekent dat er een gevalideerd document bestaat en dat een nummer is verbruikt. De verzending — e-mail, Peppol via de aangesloten toegangspuntaanbieder, of een nationaal systeem — is een afzonderlijke stap in het product en wordt niet op de API gemeld.
De rate limit negeren
Het budget is 240 verzoeken per sleutel, aangevuld met ongeveer twee per seconde. Een maandafsluitingsjob die in één keer duizend concepten aanmaakt, krijgt 429 met Retry-After; respecteer de header en spreid het werk. Details op limieten.
Testen met de live sleutel
Gebruik tijdens de ontwikkeling een greif_test_-sleutel; die werkt tegen dezelfde host in testmodus voor de onderneming die ze heeft aangemaakt. GET /me rapporteert environment als SANDBOX of PRODUCTION, zodat een controle bij het opstarten kan weigeren een testbuild met een live sleutel te draaien.
Opgemaakte bedragen opslaan
Bedragen zijn op de API gehele getallen in kleinste munteenheden met een valutacode, en in webhookbodies strings van kleinste munteenheden. Parse nergens "1.059,10 €"; er valt niets te parsen.

Hoe KRONENWERK hiermee omgaat

ONDERSTEUND MET BEPERKINGEN Alles wat hier wordt getoond, draait op de API zoals ze vandaag bestaat, in het Enterprise-plan (prijzen): idempotent aanmaken van klanten, transacties en factuurconcepten; ondertekende webhooks voor uitreiking, betaling, annulering, aankopen en betalingen; het rapport van openstaande posten en gepagineerde factuurlezingen. De beperkingen zijn die welke overal op deze pagina zijn genoemd: geen uitreiken, geen registreren van betalingen, geen annuleren en geen downloaden van bestanden via de API, en geen automatische import van Stripe-betalingen. Als uw integratie een factureringslus zonder mensen nodig heeft, is de API van KRONENWERK dat niet. Als ze nodig heeft dat de boekhouding van een onderneming weerspiegelt wat uw product heeft verkocht, met de juridische stappen gezet door een persoon volgens de regels van het land, dan is dit de bedoelde weg. De bijbehorende productpagina's zijn boekhouding, facturen en automatisering; de vergelijking van boekhoudtools met een API staat op boekhoudsoftware met een API.

Veelgestelde vragen

Kan ik een Stripe-betaling via de API registreren?

Nee. De API registreert geen betalingen. Uitbetalingen bereiken de boekhouding via de bankkoppeling, of een persoon registreert de betaling; payment.recorded en invoice.paid bereiken daarna uw endpoint.

Wat is een "transactie" op de API?

Een werkeenheid met een titel, een optionele klant, een fase uit de workflow van de onderneming en een vervaldatum — een order of een abonnementsperiode. Het is geen grootboekpost.

Heb ik een concept nodig voor elke consumentenbetaling?

Vaak niet. Concepten zijn bedoeld voor klanten die een individuele, gestructureerde factuur nodig hebben. Of verkopen aan consumenten in een bepaald land er een vereisen, is een vraag voor professionele bevestiging.

Hoe leid ik idempotentiesleutels af?

Van uw eigen stabiele identificatoren: account-id voor klanten, abonnements-id plus periode voor transacties, factuur-id van de provider voor concepten. Sleutels mogen tot 200 tekens lang zijn.

Hoe test ik zonder de live boekhouding te raken?

Maak een greif_test_-sleutel aan. Die werkt tegen dezelfde API in testmodus voor de onderneming die ze heeft aangemaakt, en GET /me rapporteert "environment" zodat uw build dat kan controleren.

Bronnen

  1. KRONENWERK developer documentation geraadpleegd op
  2. Stripe — Receive Stripe events in your webhook endpoint (duplicates, ordering, signatures) geraadpleegd op
  3. Stripe — Idempotent requests geraadpleegd op

Begin met integreren

Lees de snelstart Referentie

Lees verder