Połączenie produktu SaaS z księgowością w KRONENWERK oznacza cztery rzeczy: utworzenie jednego klienta na każde płacące konto, otwarcie transakcji i szkicu faktury dla każdego zdarzenia rozliczeniowego z nagłówkiem Idempotency-Key wyprowadzonym z własnego rekordu, odbieranie zdarzeń invoice.issued, invoice.paid i payment.recorded na punkcie końcowym webhooków oraz uzgadnianie stanu za pomocą GET /reports/outstanding. API nie wystawia faktur ani nie rejestruje płatności; robi to osoba w produkcie, a zdarzenia informują Państwa system o tym, co się wydarzyło. Taki jest uczciwy kształt tej integracji i ta strona pokazuje go krok po kroku.
Co integracja może, a czego nie może zautomatyzować
API KRONENWERK tworzy rekordy odwracalne i odczytuje księgi. Nie wykonuje czynności nieodwracalnych — wystawienia faktury, zarejestrowania płatności, anulowania — ponieważ każda z nich zużywa coś, czego nie da się cofnąć, albo przesuwa pieniądze w księdze. Dla back-endu SaaS jest to ograniczenie, które warto znać, zanim zaprojektują Państwo integrację.
| Państwa zdarzenie | Co robi Państwa aplikacja | Co dzieje się w produkcie | Co wraca |
|---|---|---|---|
| Konto rejestruje się lub przechodzi na plan płatny | POST /customers | Klient pojawia się w danych podstawowych z numerem partnera | 201 z id i number klienta |
| Uzgodniono umowę lub zamówienie | POST /transactions | Transakcja (zlecenie z etapem i terminem) pojawia się na tablicy firmy | 201 z number, np. V2026-0481 |
| Nadchodzi okres rozliczeniowy konta B2B | POST /invoices/drafts | Szkic czeka na pozycje i wystawienie przez osobę | 201 ze szkicem; później invoice.issued |
| Klient płaci (karta, przelew) | Nic w API | Płatność jest rejestrowana w produkcie: ręcznie albo dopasowana z podłączonego rachunku bankowego | payment.recorded oraz, gdy należność zostanie rozliczona, invoice.paid |
| Zwrot lub spór odwraca fakturę | Nic w API | Osoba wystawia pełną korektę | invoice.cancelled ze wskazaniem faktury korygującej |
| Kontrola na koniec miesiąca | GET /reports/outstanding, GET /invoices?status=OPEN | — | Otwarte na dziś należności i zobowiązania; otwarte faktury |
API jest częścią planu Enterprise; cała jego powierzchnia jest opisana na stronie API księgowego. Biznesowa strona prowadzenia ksiąg w firmie subskrypcyjnej — przychody rozliczane w czasie, VAT od usług cyfrowych, wiele walut — jest omówiona w artykułach księgowość dla SaaS i łączenie aplikacji z księgowością.
Wzorzec 1: jeden klient na płacące konto, tworzony idempotentnie
Klienta w KRONENWERK proszę tworzyć w chwili, gdy konto staje się klientem płacącym, a nie przy rejestracji, i używać własnego identyfikatora konta w nagłówku Idempotency-Key. Ponowienie po utraconej odpowiedzi zwróci wtedy klienta, który został utworzony, a nie duplikat — a zduplikowany klient to błąd, którego nikt nie zauważa, dopóki faktura nie trafi do niewłaściwego rekordu.
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"
}'
Nazwa, ulica, kod pocztowy i miejscowość są wymagane — EN 16931 przenosi adres w częściach, a klient bez ulicy to taki, do którego nie da się zaadresować żadnej faktury. Kraj, numer VAT i waluta są opcjonalne; brakujący kraj przyjmuje domyślnie kraj własnej firmy. Zwrócone id proszę zapisać przy swoim koncie. Numer VAT znaczy więcej, niż się wydaje: przy wystawianiu KRONENWERK sprawdza go w VIES i na jego podstawie wyprowadza rozstrzygnięcie podatkowe (np. odwrotne obciążenie dla klienta biznesowego z innego kraju UE). Proszę zbierać go przy zakupie.
Wzorzec 2: transakcja na każde zamówienie, z Państwa identyfikatorami
Transakcja w KRONENWERK to jednostka pracy z tytułem, klientem, etapem z własnego przepływu pracy firmy i terminem — zamówienie, projekt, okres subskrypcji. Nie niesie żadnych pieniędzy i właśnie dlatego jest właściwym rekordem dla „wydarzyło się coś do zafakturowania”, zanim ktokolwiek zdecydował, co będzie na fakturze. Identyfikatory dostawcy proszę umieścić w opisie, aby osoba, która później wystawi fakturę, znalazła subskrypcję Stripe lub zamówienie jednym wyszukaniem.
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"
}'
Wymagany jest tylko title. stage może wskazywać klucz etapu z przepływu pracy firmy; pominięty sprawia, że transakcja zaczyna tam, gdzie zaczyna się przepływ. Odpowiedź zawiera id, number, title, stage, customer, dueOn, archived i createdAt. GET /transactions?search=sub_1Q… odnajduje ją ponownie. Proszę pamiętać, że nie jest to zapis księgowy: nic nie zostaje zaksięgowane, dopóki w produkcie nie zostanie wystawiona faktura lub zarejestrowana płatność.
Wzorzec 3: szkic faktury na każde zdarzenie rozliczeniowe B2B
Dla klientów biznesowych, którzy potrzebują prawidłowej faktury — XRechnung dla niemieckiego nabywcy publicznego, dokumentu Peppol dla belgijskiego, Factur-X dla francuskiego — proszę rozpocząć szkic, gdy nadchodzi okres rozliczeniowy. Szkic niesie propozycję numeracji sprzedawcy i warunki płatności klienta; osoba dodaje pozycje i wystawia go, a plik ustrukturyzowany jest generowany i walidowany w tym momencie. Dlaczego granica przebiega właśnie na szkicu, wyjaśnia strona API fakturowania.
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…" }'
Jako klucza proszę użyć identyfikatora faktury dostawcy: jedna faktura Stripe, jeden szkic KRONENWERK, niezależnie od tego, ile razy dostarczony zostanie webhook, który go wywołał. Jeśli Państwa produkt rozlicza konsumentów, a nie firmy, szkic na każdą płatność może w ogóle nie być potrzebny; okresowe zestawienie obsługiwane w produkcie często pasuje lepiej, a to, czy sprzedaż konsumencka w danym kraju wymaga indywidualnej faktury, wymaga potwierdzenia przez specjalistę.
Wzorzec 4: nasłuchiwanie webhooków, weryfikacja, deduplikacja, szybka odpowiedź
Proszę zarejestrować w produkcie punkt końcowy HTTPS na porcie 443 i zasubskrybować invoice.issued, invoice.paid, invoice.cancelled oraz payment.recorded. Każda dostawa niesie KRONENWERK-Signature: t=<seconds>,v1=<hex> — HMAC-SHA256 obliczony ze znacznika czasu, kropki i surowej treści — oraz stabilny identyfikator zdarzenia w KRONENWERK-Event-Id i Idempotency-Key. Treść to płaski obiekt JSON, którego wartości są łańcuchami, klucze posortowane, a event i id zawsze obecne.
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"}
Zasady obsługi są te same, które Stripe dokumentuje dla własnych webhooków, i z tych samych powodów: weryfikacja podpisu względem surowej treści przed parsowaniem, odrzucenie znacznika czasu spoza tolerancji (własny weryfikator KRONENWERK stosuje pięć minut), zapisanie identyfikatora zdarzenia i pominięcie wszystkiego, co już widziano, niepoleganie na kolejności oraz szybkie zwrócenie 2xx i wykonanie pracy w kolejce. Dostarczanie jest typu at-least-once z ponowieniami; przekierowania są traktowane jako niepowodzenia. Pełny opis znajduje się na stronie webhooki.
Wzorzec 5: uzgadnianie z raportem należności otwartych
GET /reports/outstanding odpowiada na pytanie „ile jest dziś należne w każdą stronę” z tego samego przeglądu, który renderuje pulpit właściciela, więc Państwa liczba i jego liczba nie mogą się różnić.
{
"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
}
}
Obie strony są raportowane osobno i nigdy nie są kompensowane: pieniądze należne firmie i pieniądze, które firma jest winna, stają się wymagalne w różnych dniach, a jedna liczba uspokajałaby dokładnie w tym momencie, w którym nie powinna. Dla widoku per faktura proszę przejść stronami przez GET /invoices?status=OPEN i porównać outstanding oraz overdue z własnym stanem rozliczeń. Rozbieżność zwykle oznacza płatność, która dotarła do banku, ale nie została jeszcze dopasowana w produkcie, albo fakturę, którą Państwa handler webhooków zgubił — dziennik identyfikatorów zdarzeń pokaże, które z nich zaszło.
Przykładowa sekwencja dla subskrypcji rozliczanej przez Stripe
- Stripe wysyła
customer.subscription.created. Państwa handler weryfikuje je, deduplikuje po identyfikatorze zdarzenia Stripe i wywołujePOST /customerszIdempotency-Key: account-<id>, jeśli dla konta nie istnieje jeszcze klient KRONENWERK. Zwróconeidzostaje zapisane. - Handler wywołuje
POST /transactionszIdempotency-Key: sub_<id>-<period>, umieszczając identyfikatory subskrypcji i faktury Stripe wdescription, a koniec okresu wdueOn. - Dla kont B2B handler wywołuje
POST /invoices/draftszIdempotency-Key: in_<id>. - Osoba z działu finansów otwiera szkic, dodaje pozycję za okres na podstawie opisu transakcji i wystawia fakturę. KRONENWERK oblicza rozstrzygnięcie podatkowe, sprawdza numer VAT, waliduje plik ustrukturyzowany, zużywa numer i wysyła
invoice.issuedna Państwa punkt końcowy.numberiinvoiceIdzostają zapisane przy fakturze Stripe. - Stripe pobiera płatność kartą i wypłaca środki na rachunek bankowy firmy. Połączenie bankowe (Enable Banking dla banków europejskich, Plaid dla banków kanadyjskich i amerykańskich) pokazuje wypłatę; osoba dopasowuje ją do faktury albo rejestruje płatność ręcznie.
payment.recordediinvoice.paiddocierają na Państwa punkt końcowy. - Jeśli Stripe zwraca obciążenie, osoba wystawia korektę w produkcie; przychodzi
invoice.cancelledzcancelledByNumber, a Państwo dołączają numer faktury korygującej do zwrotu. - Na koniec miesiąca porównują Państwo
GET /reports/outstandingz własnymi otwartymi należnościami.
Pułapki
- Wyprowadzanie kluczy idempotencji z czasu lub losowości
- Klucz, który zmienia się przy ponowieniu, niczego nie chroni. Proszę wyprowadzać go z rekordu, który Państwo odwzorowują — identyfikatora konta, identyfikatora subskrypcji z okresem, identyfikatora faktury dostawcy — tak aby ponowienie oznaczało tę samą operację. Inna treść pod tym samym kluczem otrzymuje
409 IDEMPOTENZ_KONFLIKT, co jest defektem w Państwa kodzie, a nie błędem przejściowym. - Tworzenie szkiców, zanim istnieje klient
- Stripe nie gwarantuje kolejności zdarzeń;
invoice.paidmoże nadejść przedcustomer.subscription.created. Najpierw proszę ustalić klienta KRONENWERK, tworząc go idempotentnie, jeśli go brakuje, a dopiero potem utworzyć szkic. - Jeden klucz, jedna firma
- Klucz API KRONENWERK jest przez całe swoje życie związany z dokładnie jedną firmą. SaaS z kilkoma podmiotami prawnymi (np. niemiecką GmbH i francuską SAS) potrzebuje jednego klucza na podmiot i musi kierować każde konto do właściwego; zob. wiele firm, wiele walut.
- Traktowanie
invoice.issuedjako „wysłano” - Oznacza ono, że istnieje zwalidowany dokument i został zużyty numer. Doręczenie — e-mailem, przez Peppol za pośrednictwem podłączonego dostawcy punktu dostępowego lub przez system krajowy — jest osobnym krokiem w produkcie i nie jest raportowane w API.
- Ignorowanie limitu zapytań
- Budżet wynosi 240 zapytań na klucz, uzupełniany w tempie około dwóch na sekundę. Zadanie na koniec miesiąca, które w jednym rzucie tworzy tysiąc szkiców, napotka
429zRetry-After; proszę respektować ten nagłówek i rozłożyć pracę w czasie. Szczegóły na stronie limity. - Testowanie na kluczu produkcyjnym
- Podczas rozwoju proszę używać klucza
greif_test_; działa on na tym samym hoście w trybie testowym dla firmy, która go utworzyła.GET /mezgłaszaenvironmentjakoSANDBOXlubPRODUCTION, więc kontrola przy starcie może odmówić uruchomienia kompilacji testowej z kluczem produkcyjnym. - Przechowywanie kwot sformatowanych
- Kwoty w API to całkowite jednostki mniejsze z kodem waluty, a w treściach webhooków — łańcuchy jednostek mniejszych. Proszę nigdzie nie parsować „1.059,10 €”; nie ma czego parsować.
Jak KRONENWERK to obsługuje
Obsługiwane z ograniczeniami Wszystko, co tu pokazano, działa na API w jego dzisiejszym kształcie, w planie Enterprise (cennik): idempotentne tworzenie klientów, transakcji i szkiców faktur; podpisane webhooki dla wystawienia, płatności, anulowania, zakupów i płatności; raport należności otwartych i stronicowany odczyt faktur. Ograniczenia są te, które wskazano w całym tekście: brak wystawiania, brak rejestrowania płatności, brak anulowania i brak pobierania plików przez API oraz brak automatycznego importu płatności Stripe. Jeśli Państwa integracja potrzebuje pętli rozliczeniowej bez udziału człowieka, API KRONENWERK tym nie jest. Jeśli potrzebuje, aby księgi firmy odzwierciedlały to, co sprzedał Państwa produkt, z krokami prawnymi wykonywanymi przez osobę zgodnie z zasadami danego kraju, to jest zamierzona ścieżka. Powiązane strony produktu to księgowość, faktury i automatyzacja; porównanie narzędzi księgowych z API znajduje się na stronie oprogramowanie księgowe z API.
Najczęściej zadawane pytania
Czy mogę zarejestrować płatność Stripe przez API?
Nie. API nie rejestruje płatności. Wypłaty trafiają do ksiąg przez połączenie bankowe albo osoba rejestruje płatność; następnie payment.recorded i invoice.paid docierają na Państwa punkt końcowy.
Czym jest „transakcja” w API?
Jednostką pracy z tytułem, opcjonalnym klientem, etapem z przepływu pracy firmy i terminem — zamówieniem lub okresem subskrypcji. Nie jest zapisem księgowym.
Czy potrzebuję szkicu na każdą płatność konsumencką?
Często nie. Szkice są przeznaczone dla klientów, którzy potrzebują indywidualnej, ustrukturyzowanej faktury. To, czy sprzedaż konsumencka w danym kraju jej wymaga, jest pytaniem wymagającym potwierdzenia przez specjalistę.
Jak powinienem wyprowadzać klucze idempotencji?
Z własnych stabilnych identyfikatorów: identyfikator konta dla klientów, identyfikator subskrypcji z okresem dla transakcji, identyfikator faktury dostawcy dla szkiców. Klucze mogą mieć do 200 znaków.
Jak testować bez dotykania ksiąg produkcyjnych?
Proszę utworzyć klucz greif_test_. Działa on na tym samym API w trybie testowym dla firmy, która go utworzyła, a GET /me zgłasza "environment", dzięki czemu Państwa kompilacja może to sprawdzić.
Źródła
- KRONENWERK developer documentation — odczytano
- Stripe — Receive Stripe events in your webhook endpoint (duplicates, ordering, signatures) — odczytano
- Stripe — Idempotent requests — odczytano