Nordlet

← Blog

Jak integrovat cloudové účetní API do platformy SaaS

Praktický průvodce vývojem multi-tenantní účetní integrace, která zvládne OAuth, webhooky, daňová pravidla a párování bez poškození hlavní účetní knihy.

Nordlet Team · · 13 min. čtení

Většina týmů, které se rozhodnou "přidat účetnictví" do svého produktu SaaS, začíná tím, že propojí HTTP klient s koncovým bodem poskytovatele a odešle fakturu. V demu to funguje. Rozbije se to ve chvíli, kdy zákazník propojí dvě účetní organizace, kdy webhook dorazí dvakrát a kdy se obnovovací token (refresh token) uprostřed požadavku obmění a ztratí. Odolná verze této práce není pouhý klient. Je to integrační vrstva.

Tato vrstva musí spravovat připojení tenantů, ukládání a obměnu tokenů, účetní pravidla specifická pro daného poskytovatele, mapování záznamů, počáteční a přírůstkovou synchronizaci, příjem webhooků s opakovanými pokusy a deduplikací, limity požadavků (rate limits), správu verzí a auditní stopu, kterou si váš tým podpory dokáže přečíst ve dvě ráno. Tento článek provádí touto architekturou a rozhodnutími, na kterých záleží nejvíce.

Užitečný mentální model:

Produkt SaaS → služba účetní integrace → adaptér poskytovatele (nebo jednotné API) → asynchronní synchronizace a párování

Účetní systém zůstává zdrojem pravdy pro položky hlavní účetní knihy (general ledger): účty, daňové kódy, zaúčtované transakce a interní účetní doklady (journal entries). Vaše platforma SaaS udržuje stabilní identifikátory napříč systémy, stav synchronizace, metadata mapování a provozní protokol auditu.

Co "cloudové účetní API" v tomto kontextu skutečně obnáší

Tento pojem obvykle označuje API hostované účetní platformy, jako je QuickBooks Online, Xero, Sage, Zoho Books nebo regionální systém. Může také znamenat jednotné účetní API (unified accounting API), které sjednocuje několik poskytovatelů pod jedno rozhraní.

Stojí za to být přesní, protože implementace se liší podle účelu. Čtení faktur pro účely reportingu není totéž jako vytváření faktur na základě aktivity v SaaS, účtování vydaných faktur, synchronizace zákazníků a produktů, zápis účetních dokladů nebo spouštění skutečné obousměrné synchronizace. Než se dotknete nějakého koncového bodu, ujasněte si, co vlastně stavíte.

Pro tento text je důležité ještě jedno rozdělení. Platební API přesouvá peníze. Bankovní API stahuje data o účtech. Fakturační API může vytvářet dokumenty, aniž by zpřístupnilo hlavní účetní knihu. Zabudovaná účetní kniha (embedded ledger) je opět něco jiného: společnost SaaS vlastní samotný účetní engine. Právě sem patří Nordlet. Namísto připojování vašeho produktu k externím knihám zákazníka poskytuje Nordlet platformám a tržištím skutečné podvojné účetnictví, neměnnou účetní knihu připravenou pro audit, zpracování DPH v EU a výplaty přímo v jejich vlastním produktu, a to prostřednictvím návrhu založeného na API se silně typovanými SDK a webhooky. Pokud jste tržiště, které se rozhoduje, zda integrovat zákazníkův účetní systém, nebo vést účetnictví sami, je to zásadní křižovatka, ke které se ještě vrátíme.

Multi-tenancy: každé připojení omezte hned dvakrát

V produktu SaaS se jedna aplikace připojuje k mnoha zákaznickým organizacím. Každé připojení musí být omezeno jak tenantem SaaS, tak identifikátorem organizace u poskytovatele, jako je ID tenanta v Xero nebo ID oblasti (realm ID) v QuickBooks.

Nezakládejte připojení pouze na ID uživatele OAuth. Jeden uživatel může autorizovat několik účetních organizací a jednu organizaci mohou v průběhu času propojit různí uživatelé. Pokud to uděláte špatně, nakonec zaúčtujete fakturu jednoho zákazníka do knih jiného zákazníka, a z takové chyby se už potichu nevzpamatujete.

První architektonické rozhodnutí: přímý konektor, jednotné API, nebo zabudovaná účetní kniha

Přímé integrace s poskytovateli

Přímá integrace vám poskytuje největší kontrolu: funkce specifické pro daného poskytovatele, vlastní pole, zpracování chyb, frekvenci synchronizace, uchovávání dat a strukturu nákladů. Cena za to je však reálná. Každý poskytovatel přináší vlastní tok OAuth, datové schéma, specifika, limity požadavků, chování webhooků, certifikaci a průběh údržby.

Jednotná účetní API

Jednotné API nabízí jedno rozhraní napříč několika účetními systémy a normalizuje entity, jako jsou zákazníci, faktury, dodavatelé, účty, platby a produkty. Může zkrátit dobu počátečního vývoje. Neodstraňuje však složitost integrace a předpokládat opak je častou chybou.

Než se zavážete k tomuto kroku, zeptejte se: Kteří poskytovatelé a operace jsou podporováni? Fungují zápisy, nebo jen čtení? Jsou zápisy synchronní, nebo se řadí do fronty? Jsou pole specifická pro daného poskytovatele dostupná přes průchozí vrstvu (passthrough)? Jsou data cachována a jak jsou čerstvá? Kdo řeší výpadky poskytovatele a změny API? Je cenotفěno za volání, za propojený účet, za záznam, nebo formou poplatku platformě? Můžete exportovat svá mapování a čistě se odpojit? Pojem "jednotné" málokdy znamená "stejná funkčnost napříč všemi poskytovateli".

Zabudovaná účetní kniha (Embedded ledger)

Pokud hlavním úkolem vaší platformy je vést účetnictví pro vaše uživatele, nikoliv jej pouze zrcadlit v jejich stávajících knihách, zabudovaná účetní kniha mění situaci. Tržiště s tisíci prodejců nebo produkt SaaS, který potřebuje mít v sobě zabudované dodržování předpisů pro DPH v EU připravené pro audit a compliance pro jednotlivé země, udělá lépe, když bude vlastníkem účetního engine, než když bude zapojovat $N$ externích konektorů. To je pozice Nordletu: skutečné účetní knihy jako API, neměnné podvojné účetnictví, DPH pro jednotlivé země s ověřením VIES a generováním registru i.SAF, export SEPA a reportní exporty v XLSX, PDF nebo JSON, a to vše uvnitř vašeho produktu namísto pokladny třetí strany.

Pravidlo pro rozhodování, které používám:

Situace Nejvhodnější volba
Vaší zákaznické základně dominuje jeden účetní poskytovatel; klíčové je chování specifické pro daného poskytovatele Přímý konektor
Široké pokrytí poskytovatelů a rychlost uvedení na trh jsou důležitější než kontrola Jednotné API
Jste platforma nebo tržiště, které potřebuje vést a vlastnit účetnictví, včetně DPH v EU a auditních stop Zabudovaná účetní kniha (Nordlet)
Smíšená realita Hybridní: jednotné API pro běžné toky, přímé konektory pro strategické poskytovatele

Doporučená integrační architektura

Izolujte integraci od základní podnikové logiky

Nerozptylujte volání poskytovatele napříč fakturací, objednávkami, předplatným a reportingem. Vytvořte vyhrazenou integrační službu, která bude obsahovat adaptéry poskytovatelů, správu připojení OAuth, kanonické modely, mapování ID, synchronizační úlohy a fronty, koncové body webhooků, zpracování opakovaných pokusů a selhání (dead-letter handling), protokoly auditu a nástroje pro párování. Tím zabráníte tomu, aby název pole z Xero nebo QuickBooks prosákl do vašeho doménového modelu.

Definujte úzký kanonický model

Modelujte pouze ty pracovní postupy, které podporujete. Typické objekty: zákazník, položka produktu nebo služby, faktura, řádek faktury, platba, dobropis, dodavatel, účet, daňová sazba, měna, účetní doklad.

Zachovejte rozdíly, které ovlivňují účetnictví. Neslučujte koncepty jako koncept (draft) versus schváleno versus zaúčtováno, částky včetně daně versus bez daně, dobropisy versus záporné faktury, přiřazení platby versus existence platby nebo číslo faktury pro zákazníka versus ID objektu u poskytovatele. Každý záznam by měl obsahovat ID v SaaS, ID u poskytovatele, název poskytovatele a verzi API, indikátor zdroje pravdy, stav, časová razítka, čas poslední synchronizace, externí referenci a stav chyby nebo párování.

Udržujte explicitní mapovací tabulky

Mapujte tenanta SaaS na účetní organizaci, zákazníka SaaS na kontakt u poskytovatele, produkt SaaS na položku nebo účet u poskytovatele, fakturu SaaS na fakturu u poskytovatele, platbu SaaS na platbu u poskytovatele, daňovou kategorii na daňový kód a účetní kategorii na účet v hlavní knize.

Nikdy nepoužívejte jména nebo e-maily jako trvalé identifikátory. Jména se mění, existují duplicity a dva zákazníci mohou sdílet jeden e-mail. Uložte neměnné ID poskytovatele a zachovejte původní ID v SaaS.

Přidejte stavové stroje (State machines)

Poskytněte připojení explicitní stavy: nepřipojeno, autorizace čeká na vyřízení, připojeno, počáteční synchronizace čeká na vyřízení, probíhá synchronizace, v pořádku, omezeno limitem požadavků, vyžadována reautorizace, poskytovatel nedostupný, odpojeno, trvale selhalo. Záznamům přiřaďte vlastní stavy: čeká na vyřízení, odesláno, potvrzeno, selhalo s možností opakování, selhalo a vyžaduje zásah uživatele, spárováno, zjištěn konflikt. Binární příznak "připojeno / nepřipojeno" neříká vašemu týmu podpory nic užitečného.

OAuth a onboarding připojení

Použijte tok autorizačního kódu (authorization code flow). Zákazník klikne na tlačítko Připojit, váš server vytvoří krátkodobou autorizační transakci, zákazník se autentizuje u poskytovatele a udělí oprávnění (scopes), vyměníte kód za tokeny, zjistíte autorizovanou organizaci, uložíte připojení k příslušnému tenantovi a zařadíte do fronty počáteční synchronizaci.

Zpětné volání (callback) pečlivě ověřte: porovnejte parametr state s transakcí na straně serveru, zkontrolujte přesnou adresu pro přesměrování (redirect URI), vydavatele od poskytovatele a kontext tenanta. RFC 9700, OAuth 2.0 Security Best Current Practice, formalizuje aktuální doporučení: používejte PKCE u toků s autorizačním kódem, vyhněte se implicitním a heslovým grantům a používejte přesnou shodu URI pro přesměrování.

Vyžadujte oprávnění s nejnižšími potřebnými právy (least-privilege scopes). Pokud nepotřebujete zapisovat, použijte práva pouze pro čtení. Modely oprávnění se mění, takže nekopírujte staré příklady. Dokumentace k OAuth od Xero uvádí, že široká účetní oprávnění jsou nahrazována granulárními, přičemž nové aplikace dostávají granulární oprávnění od března 2026 a široká oprávnění mají zůstat k dispozici do září 2027.

Ukládejte tokeny pouze na straně serveru. Nikdy je nevystavujte v JavaScriptu v prohlížeči, mobilním klientům, front-end logům, analytickým nástrojům ani chybovým hlášením pro zákazníky. Šifrujte je v klidovém stavu (at rest), redigujte je z logů a uchovávejte metadata pro každé připojení: zašifrované přístupové a obnovovací tokeny, dobu platnosti, ID organizace u poskytovatele, udělená oprávnění, čas vydání, poslední úspěšné obnovení a stav odvolání.

Obměna obnovovacích tokenů (Refresh-token rotation) je místem, kde produkce selhává

Odpověď na obnovení může vrátit nový obnovovací token. Nejnovější hodnotu musíte uložit atomicky, jinak zákazníka zablokujete. Podle častých dotazů pro vývojáře Xero produkuje každé obnovení nový obnovovací token, obnovovací tokeny vydrží až 60 dní a existuje 30minutová lhůta pro opakování pokusu se stávajícím tokenem v případě ztráty odpovědi. QuickBooks Online radí vývojářům ukládat nejnovější obnovovací token z nejaktuálnější odpovědi: obnovovací tokeny platí až 100 dní a hodnota se může obměňovat až každých 24 hodin.

V praxi: používejte zámek obnovení pro každé připojení, vyměňte obnovovací token atomicky, řešte přechodná selhání koncového bodu tokenu pomocí opakovaných pokusů, zobrazte jasný stav reautorizace a nikdy neobnovujte token při každém volání API, pokud platný přístupový token stále zbývá.

Počáteční synchronizace

Počáteční synchronizaci spusťte jako úlohu na pozadí. Neblokujte jí zpětné volání OAuth ani uživatelské rozhraní.

Robustní posloupnost: načtěte metadata organizace, získejte účty, daňové sazby, měny, kontakty a položky, uložte ID poskytovatele a mapování, importujte pouze historické období, které produkt potřebuje, zařaďte závislé záznamy do fronty v pořadí závislostí, zaznamenejte kontrolní bod (checkpoint) a označte připojení jako v pořádku až po ověření.

Pořádí závislostí je důležité. Faktura může vyžadovat, aby nejprve existoval kontakt, položka, výnosový účet, daňový kód a měna. Nevytvářejte slepě duplicity. Porovnávejte podle uloženého externího ID, reference zadané zákazníkem, definovaného pravidla párování nebo explicitního kroku výběru uživatelem v nejednoznačných případech.

Přírůstková synchronizace

Webhooky považujte za signály, nikoli za autoritativní záznamy

Webhook obvykle říká, že se něco změnilo. Ověřte podpis, zaznamenejte surovou událost, rychle vraťte požadovanou úspěšnou odpověď, deduplikujte, zařaďte do fronty následné načtení, stáhněte aktuální objekt od poskytovatele, aplikujte aktualizaci transakčně, aktualizujte kontrolní bod a přesměrujte selhání k opakovanému pokusu nebo k párování. Tím se vyřeší neúplná datová payload a události dorazící v nesprávném pořadí.

Pravidla poskytovatelů se liší, takže neslibujte jedno univerzální chování. Webhooky Xero nesou podpis HMAC-SHA256 v hlavičce x-xero-signature, vyžadují HTTPS, opakují pokusy s klesající frekvencí až po dobu 24 hodin, po opakovaném selhání mohou být deaktivovány a mohou uchovávat události až 31 dní pro opětovné přehrání po obnovení. QuickBooks Online ověřuje pomocí HMAC-SHA256 a ověřovacího tokenu, očekává HTTP 200 do tří sekund a opakuje pokusy podle pevného harmonogramu, který nakonec přejde v intervaly šesti hodin, přičemž Intuit doporučuje asynchronní zpracování.

Deduplikace a idempotence

Doručení alespoň jednou (at-least-once) je normální. Očekávejte duplicitní webhooky, opakované pokusy po vypršení časového limitu, kdy zápis ve skutečnosti uspěl, přeuspořádané události a duplicitní kliknutí uživatelů. Použijte ID události poskytovatele, pokud je k dispozici, jedinečný klíč události v trvalém úložišti, ID operace vygenerované před každým zápisem, databázová omezení jedinečnosti, sémantiku upsert a dotaz pro párování po nejednoznačných časových limitech.

Nepředpokládejte, že každé účetní API nabízí nativní idempotenční klíče. Pokud poskytovatel takový klíč nemá, uložte interní klíč operace a před opakovaným pokusem zkontrolujte, zda očekávaný vzdálený objekt již neexistuje. Vzory ze správy idempotentních požadavků ve Stripe a obecné doporučení pro idempotenci webhooků se zde dají dobře uplatnit.

Polling a detekce změn

Kombinujte webhooky s pravidelným dotazováním (pollingem). Webhooky bývají deaktivované, zpožděné, ztracené kvůli nesprávné konfiguraci nebo omezené na určité objekty. Xero podporuje hlavičku If-Modified-Since pro změny po určitém časovém razítku UTC, ale jeho dokumentace varuje, že ne každá změna aktualizuje UpdatedDateUTC, takže některé částečně zaplacené transakce a pole kontaktů se v tomto filtru neobjeví. Sledování změn (Change Data Capture) v QuickBooks Online sleduje změny za předchozích 30 dní, omezuje odpovědi na 1 000 objektů, vrací smazané entity se stavem Deleted a nejlépe funguje s kratšími okny dotazování.

Ukládejte kontrolní bod pro každého poskytovatele a tenanta a používejte překrývající se okna. Vyžádejte si změny z doby mírně předcházející poslednímu kontrolnímu bodu a poté proveďte deduplikaci podle ID poskytovatele a verze úprav. To chrání před nepřesnostmi hodin a částečnými selháními.

Účetní integrita dat

Právě tato část odlišuje fungující integraci od té důvěryhodné.

Daňové chování není zaměnitelné. Dokumentace Xero uvádí, že faktury, dobropisy a objednávky se ve výchozím nastavení řídí cenami bez daně, pokud je hodnota LineAmountTypes nenastavená, zatímco účtenky a bankovní transakce se ve výchozím nastavení řídí cenami včetně daně a ruční účetní doklady nemají žádnou daň ve výchozím stavu. Použijte pole TaxType, nikoli název daňové sazby. Nikdy nepředpokládejte, že "20% DPH" jednoznačně identifikuje daňový kód; může se lišit podle země, typu transakce, data platnosti a konfigurace organizace. Zde se ruční řešení DPH pro více zemí EU prodraží, a právě zde si zabudovaná účetní kniha s předem připravenou compliance pro jednotlivé země obhájí své místo.

Pro peníze používejte desetinnou aritmetiku nebo aritmetiku s pevnou řádovou čárkou, nikdy binární plovoucí řádovou čárku (binary floating point). Ukládejte kód měny a přesnost, jednotkovou částku, množství, slevu, částku daně, čistou částku, hrubou částku a směnný kurz. Jasně se rozhodněte, zda odesíláte částky na úrovni řádků a necháte poskytovatele spočítat součty, nebo odešlete předem spočítaný součet. Jejich míchání vytváří zaokrouhlovací nesrovnalosti, které váš účetní jistě odhalí.

Na účty hlavní knihy se odkazujte pomocí ID nebo kódu poskytovatele, nikoli podle zobrazovaného názvu. Před zápisem ověřte, že účty, daňové kódy, zákazníci, položky a měna jsou aktivní a podporované. Neúspěšný zápis faktury je obvykle problém mapování nebo konfigurace, nikoli přechodná chyba API, takže uživatelské rozhraní by mělo vysvětlit nápravu namísto zobrazení hlášení "synchronizace selhala".

Nepředpokládejte ekvivalenci objektů. "Platba" může znamenat příjem, přiřazení, vklad, bankovní transakci nebo účetní doklad. "Předplatné" v SaaS nemusí čistě odpovídat "faktuře" v účetnictví. Než si vyberete objekt API, definujte účetní událost, kterou chcete reprezentovat. Podívejte se do dokumentace k platbám Xero, jak jeden poskytovatel tento koncept modeluje.

Limity požadavků a správa verzí

Limity jsou obvykle omezeny na tenanta, organizaci, aplikaci nebo jejich kombinaci. Podle častých dotazů k limitům Xero: pět souběžných požadavků na tenanta, 60 za minutu na tenanta, 5 000 za den na tenanta a 10 000 za minutu napříč aplikací, přičemž k dispozici jsou hlavičky zbývajícího limitu a Retry-After při chybách 429. QuickBooks Online uvádí 500 požadavků za minutu a 10 za sekundu na ID oblasti, přičemž koncový bod pro dávkové zpracování podporuje až 30 operací na jeden požadavek.

Zaveďte omezování požadavků pro jednotlivé tenanty, globální throttling, exponenciální ustupování s náhodnou odchylkou (jitter), respektování hlavičky Retry-After, omezenou souběžnost, stránkování a metriky chyb 429 a zbývající kvóty. Nepoužívejte neomezenou paralelitu pro importy; jeden velký zákazník může vyhladovět všechny ostatní úlohy u daného tenanta.

Ukotvěte nebo explicitně spravujte verze API. QuickBooks Online ve výchozím nastavení používá minoritní verzi 75, není-li uvedena žádná jiná. Centralizujte verze v konfiguračních souborech, spouštějte testy kontraktů nad sandboxovými prostředími, sledujte poznámky k vydání a zacházejte s neznámými poli v odpovědích tak, aby byla zpětně kompatibilní. Sandboxová prostředí nereprodukují každou produkční podmínku, takže před spuštěním otestujte odpojení, opětovné připojení, odvolaný souhlas, vypršelé tokeny, limity požadavků a úpravy na straně poskytovatele.

Co bych postavil jako první

Pokud bych s tím začínal zítra, postupoval bych v tomto pořadí:

  1. Definujte přesný účetní pracovní postup: které události a objekty čtete nebo zapisujete.
  2. Zvolte strategii poskytovatele: přímá, jednotná, zabudovaná nebo hybridní.
  3. Vytvořte model připojení s vymezením na tenanta, obsahující ID organizace u poskytovatele, oprávnění, stav a metadata tokenů.
  4. Implementujte OAuth pomocí toku s autorizačním kódem, PKCE, ověřením stavu, oprávněními s nejnižšími právy a ukládáním tokenů na straně serveru.
  5. Sestavte jeden adaptér poskytovatele za stabilním interním rozhraním.
  6. Vytvořte mapování ID na základě neměnných ID poskytovatele.
  7. Nejprve implementujte čtení; před jakýmkoli zápisem importujte číselníky a referenční data.
  8. Přidejte úlohu počáteční synchronizace se stránkováním, omezováním požadavků, kontrolními body a řazením závislostí.
  9. Implementujte jeden úzký zápis (vytvoření faktury) až po ověření mapování zákazníků, položek, daní a účtů.
  10. Zajistěte, aby zápisy odolávaly opakovaným pokusům (retry-safe) pomocí interních ID operací, omezení jedinečnosti a kontrol vzdáleného stavu.
  11. Přidejte podepsané webhooky, které rychle potvrdí příjem a zpracují se asynchronně.
  12. Přidejte polling a párování, aby webhooky sloužily jako akcelerátor, nikoli jako jediný zdroj pravdy.
  13. Záměrně otestujte stavy selhání.
  14. Přidejte nástroje pro podporu a audit, díky nimž budou selhání vysvětlitelná a opravitelná.
  15. Postupně rozšiřujte pokrytí objektů.

FAQ

Mám použít jednotné API, nebo vytvořit přímé konektory?

Přímý konektor použijte v případě, že vašim zákazníkům dominuje jeden poskytovatel nebo je klíčové chování specifické pro daného poskytovatele. Jednotné API zvažte tehdy, když je širší pokrytí a rychlost důležitější než kontrola. Pokud vaší skutečnou potřebou je vést účetnictví sami namísto synchronizace do zákazníkova systému, ani jedno neodpovídá na vaši otázku – podívejte se raději na zabudovanou účetní knihu, jako je Nordlet.

Jsou webhooky pro udržení synchronizace dostatečné?

Ne. Webhooky bývají deaktivované, zpožděné nebo ztracené a jejich datová payload může být neúplná nebo v nesprávném pořadí. Považujte je za signály o změně, následně stáhněte aktuální objekt a doplňte je pravidelným dotazováním (pollingem) a párováním.

Jak zabránit tomu, aby selhání obnovovacího tokenu zablokovalo zákazníky?

Uložte nejnovější obnovovací token atomicky při každém obnovení, použijte zámek pro každé připojení, opakujte přechodná selhání koncového bodu tokenu a zobrazte jasný stav reautorizace. 30minutová lhůta u Xero pomáhá, ale před chybami vás zachrání právě atomické uložení.

Mohu párovat záznamy podle jména zákazníka nebo e-mailu?

Ne jako trvalý identifikátor. Jména se mění, objevují se duplicity a dva zákazníci mohou sdílet stejný e-mail. Uložte neměnné ID poskytovatele a uchovávejte vedle něj vlastní ID v SaaS.

Další doporučená četba