Zum Hauptinhalt springen

Buchhaltungskonten (TransactionAccounts)

Zweck

TransactionAccount ist das operative Verrechnungskonto in SpeamCore. Pro Konto wird gepflegt, ob es ein eigenes Konto oder ein externes Debitoren-/Kreditoren-Konto ist (isExternal), aus welchem System es synchronisiert wird (TransactionAccountType — z. B. BANK, PAYPAL, CREDIT_CARD, CASH) und wie es in der Hierarchie haengt (parentTransactionAccountId). TransactionAccounts sind der Anbindungspunkt für finAPI-Bank-Sync und Pleo-Kreditkarten-Sync und der Bezug für alle Transaktionen.

**TransactionAccount vs. Account vs. BankAccount** — drei Modelle, die im Sprachgebrauch leicht verwechselt werden: - **`TransactionAccount`** (`/transaction-accounts`) — diese Seite. Operatives Verrechnungskonto, Hierarchie, finAPI-/Pleo-Anbindung. - **`Account`** ([/accounts](/accounts)) — Buchhaltungs-Stammdaten (Kontenrahmen-Konto wie SKR03 „1200 Bank"). - **`BankAccount`** — physische Bankverbindung (IBAN/BIC). Wird über Polymorph-Parent vom `TransactionAccount` referenziert, wenn `TransactionAccountType.code = BANK`.

Wenn ein Anwender nach „Bankkonto" sucht, fuehren Sie ihn auf Bankkonten und Zuweisungen und ggf. von dort nach /transaction-accounts/:id (Sub-Konto) oder /accounts (Buchhaltungssicht).

Voraussetzungen

- Berechtigung `view:TransactionAccount` und `create:TransactionAccount`. - Mindestens ein gepflegter `TransactionAccountType` (siehe [/transaction-account-types](/transaction-account-types)). - Für finAPI-Sync: Berechtigung `view:FinapiConfig` und konfigurierter finAPI-Provider. - Für Pleo-Sync: Berechtigung `view:PleoConfig` und konfigurierter Pleo-Tenant.

Berechtigungen (CASL)

ActionSubjectWirkungKeycloak-Rolle
viewFE_TransactionAccount, TransactionAccountListe/Detail aufrufbar
create/update/deleteTransactionAccountPflegenAPP_SPEAMCORE_CREATE/UPDATE/DELETE_TRANSACTION_ACCOUNT
viewTransactionAccountTypeAuswahl im Anlage-FormAPP_SPEAMCORE_VIEW_TRANSACTION_ACCOUNT_TYPE
viewTransactionAccountBalanceSaldo-Sub-ListeAPP_SPEAMCORE_VIEW_TRANSACTION_ACCOUNT_BALANCE
viewTransactionBuchungs-Sub-ListeAPP_SPEAMCORE_VIEW_TRANSACTION
viewFinapiConfigfinAPI-Overview-ModalAPP_SPEAMCORE_VIEW_FINAPI_CONFIG
viewPleoConfigPleo-Overview-ModalAPP_SPEAMCORE_VIEW_PLEO_CONFIG
view/create/update/deletePayPalConfigPayPal-Anbindung im Integrations-Manager (Test = create)

Schritt-für-Schritt-Anleitung

Eigenes Konto anlegen (z. B. neues Bankkonto)

  1. Buchhaltungskonten (/transaction-accounts) → + Neu.
  2. displayName pflegen (z. B. „Sparkasse Geschaeftskonto").
  3. transactionAccountTypeId wählen — beim manuellen Anlegen werden nur die Typen mit supportsManualEntry angeboten: Bargeld (CASH), Bankkonto (BANK) und Sonstige (OTHER). PAYPAL, CREDIT_CARD und Pleo entstehen nicht manuell, sondern über die Anbindungen (Integrations-Manager).
  4. isExternal = false (eigenes Konto).
  5. currency pflegen (Default EUR).
  6. status = active setzen, damit das Konto in Listen erscheint.
  7. Beim Speichern mit transactionAccountType.code = BANK legt der Backend-Hook automatisch ein BankAccount an und verknuepft es polymorph (parentType = BankAccount, parentId = bankAccount.id).
Beim Anlegen eines manuellen Kontos erscheint der Hinweis **„Konto manuell anlegen?"**: Bei einem manuellen Konto müssen **alle Umsätze von Hand** erfasst werden — aufwendig und fehleranfällig. Empfohlen wird stattdessen eine **automatische Kontenverbindung** (Bank via finAPI, PayPal, Pleo) über **„Automatische Verbindung einrichten (empfohlen)"** (öffnet den Integrations-Manager). Mit **„Trotzdem manuell anlegen"** legen Sie das Konto dennoch von Hand an.

finAPI-Bank-Sync anstossen

  1. In der Liste den Button finAPI-Konten klicken — FinapiOverviewModal öffnet sich.
  2. finAPI-Bank auswählen → Konten werden importiert und als TransactionAccount mit externalId = "finapi:<accountId>" angelegt.
  3. lastSyncAt wird vom Sync-Job automatisch aktualisiert.

Banking-Schnittstelle pro Verbindung (seit Juni 2026)

Jede finAPI-Bank-Verbindung (FinapiBankConnection) hält jetzt die genutzte Banking-Schnittstelle (bankingInterface):

WertBedeutung
XS2APSD2-Banking-API (offizielle Schnittstelle der Bank).
FINTS_SERVERFinTS/HBCI-Server.
WEB_SCRAPERWeb-Scraping der Banking-Oberfläche (Fallback).

Der Dashboard-Alert zu finAPI-Verbindungen unterscheidet seitdem nach Schnittstellen-Typ — so ist erkennbar, ob z. B. eine wartungsanfälligere Web-Scraping-Verbindung erneuert werden muss, statt alle Verbindungen pauschal zu melden.

finAPI-Blacklist (Welle 141)

Für Bank-Verbindungen, die permanent ausgeschlossen werden sollen (z. B. nicht mehr aktive Privatkonten, die finAPI weiterhin auflistet, oder spezielle Sub-Konten):

  • Auf der finAPI-Konto-Auswahl gibt es einen Blacklist-Toggle pro Bank-Connection.
  • Geblacklistete Connections werden vom Sync-Job defensiv übersprungen — auch wenn isActive = true aus finAPI-Sicht.
  • Geblacklistete Konten erscheinen weder im Konto-Auswahl-Modal noch im Cockpit.
  • Aktivieren oder Entfernen über POST /api/finapi/blacklist und DELETE /api/finapi/blacklist/:id (Admin-Berechtigung).

Vorteil gegenüber „nur deaktivieren": Auch ein versehentlicher Re-Sync legt die Connection nicht erneut an. Sinnvoll bei finAPI-Demo-Konten oder veralteten Bankverbindungen, die nicht mehr im SpeamCore-Cockpit auftauchen sollen.

finAPI-Re-Auth (Welle 132)

Beim Verlust der finAPI-Autorisierung (Banken haben regelmäßige Re-Auth-Pflicht) erscheint im Header der App-Startseite ein Re-Auth-Banner mit der Liste der betroffenen Konten. Jedes Konto-Bandwurmkartet bietet einen „Neu autorisieren"-Button — der Aufruf läuft jetzt über die neue Web Form 2.0-Task-Engine (statt der alten, in finAPI entfernten bankConnectionUpdate-Route). Quelle: BE-Fix 3f0387b8.

Pleo-Kreditkarten-Sync

Analog über den Button Pleo-Konten (PleoOverviewModal). Pflichtkonto vom Typ CREDIT_CARD, Sub-Konten pro Karten-Inhaber werden als Children unter parentTransactionAccountId angelegt.

PayPal anbinden (Integrations-Manager)

Über den Integrations-Manager (Button in der Konten-Liste, IntegrationsManagerModal) wird die PayPal-Anbindung (PayPalConfig) eingerichtet. Sie hat zwei Funktionen, die sich eine Config teilen:

  • Reporting-Sync — holt PayPal-Transaktionen, Gebühren und Auszahlungen über die Transaction-Search-API ins System (Cron 4×/Tag: 03:00, 09:00, 14:00, 19:00). Beim Anlegen der Config entsteht automatisch ein PayPal-TransactionAccount („PayPal").
  • Zahlungsannahme (Orders API v2) — Voraussetzung für die öffentliche Bezahlseite; wird über paymentsEnabled separat scharfgeschaltet. Mechanik: PayPal-Zahlungsannahme.
  1. In der Konten-Liste Integrations-ManagerPayPal öffnen (PayPalOverviewModalPayPalConnectionSetup).
  2. Zugangsdaten der PayPal-REST-App eintragen: clientId, clientSecret, Umgebung (live/sandbox).
  3. Verbindung testen (POST /api/paypal-configs/test) — prüft die Credentials, ohne sie zu speichern.
  4. Speichern. Optional Zahlungsannahme aktivieren (paymentsEnabled), Gebührensatz und Konten hinterlegen.
FeldnamePflichtDatentypWirkung beim AusfuellenVoraussetzung
clientIdjaStringClient-ID der PayPal-REST-AppPayPal-REST-App vorhanden
clientSecretjaString (write-only)Secret der REST-App — verschlüsselt gespeichert, nie wieder ausgegeben
environmentjalive / sandboxwählt die PayPal-Basis-URL
isActiveneinBooleanaktiviert den Reporting-Sync (steuert den Cron-Job)
paymentsEnabledneinBooleanschaltet die Zahlungsannahme (Orders API) frei → Bezahlseite + Webhookgültige Credentials
feeRatePercentneinDecimal (Default 2.49)PayPal-Gebührensatz in % für den exakten Aufschlag-Gross-up
feeFixedneinDecimal (Default 0.35)fixe PayPal-Gebühr je Transaktion (Gross-up)
feeAccountIdneinUUID → AccountSKR-Aufwandskonto, gegen das PayPal-Gebühren beim Reporting-Sync gebucht werdenview:Account
transactionAccountIdautoUUIDHaupt-PayPal-TransactionAccount (beim Anlegen automatisch erstellt)
payoutBankAccountIdneinUUIDBankkonto, auf dem PayPal-Auszahlungen landen
webhookIdneinStringPayPal-Webhook-Abo-ID — Grundlage der Signaturprüfung eingehender Webhooks
syncFromDateneinDatumerstes Datum, das der Reporting-Backfill abdeckt
lastSyncAtread-onlyDateTimeZeitpunkt des letzten erfolgreichen Sync-Laufs

Eingehende PayPal-Webhooks erreichen den öffentlichen Endpunkt POST /api/webhooks/paypal; sie werden anhand der webhookId signaturgeprüft und idempotent verarbeitet (kein Doppelbuchen).

<KIHinweis titel="Zwei verschiedene „PayPal-Gebührenkonten" nicht verwechseln"> feeAccountId (hier) ist das Aufwandskonto, gegen das der Reporting-Sync die von PayPal einbehaltene Gebühr bucht. Davon getrennt ist paypalSurchargeAccountId aus den Rechnungsausgang-Einstellungen — das Erlöskonto für die an den Kunden weitergegebene Gebühr (separate Zusatzrechnung). Beides kann, muss aber nicht zugleich genutzt werden.

Externes Debitoren-/Kreditoren-Konto

Für Buchungen gegen Kunden- oder Lieferanten-Konten:

  1. + Neu mit isExternal = true.
  2. Entweder customerId oder supplierId setzen — verknuepft das Konto mit dem Kunden bzw. Lieferanten.
  3. transactionAccountTypeId mit Code DEBTOR / CREDITOR (sofern angelegt).

Listenansicht — transaction-accounts

Toolbar (Detail-Seite)

Schlanke Toolbar oben rechts:

IconAktion (aria-label)CASLWirkung
ZurückgehenZurück zur Liste.
🏠Zur Startseite gehenSpringt auf das Dashboard / /.
⏮/◀/▶/⏭PaginationNavigation durch die gefilterte Liste — Massen-Bearbeitung ohne Liste-Sprung.

Wie auf jeder Detail-Seite verfuegbar — siehe Floating-Quickbar:

  • KAL. (Mini-Kalender)
  • ZEIT (Persoenliche Wochen-Arbeitszeit)
  • ARBEIT (Eigene bevorstehende Aufträge)

UI-Elemente

Komponente: TransactionAccountForm

Auto-Save-Form mit Feldern aus transactionAccountFieldsConfig.ts. Felder werden in Gruppen geclustert (accountTypeAndExternal, currencyAndStatus).

Komponente: FinapiOverviewModal

Listet alle in finAPI verfuegbaren Bankverbindungen und erlaubt Import als TransactionAccount. Berechtigung view:FinapiConfig erforderlich.

Komponente: PleoOverviewModal

Analog für Pleo-Kreditkarten. Berechtigung view:PleoConfig erforderlich.

Selector: TransactionAccountSelector

Auswahl-Dropdown in anderen Modulen (z. B. Transaktions-Form, Cockpit). Filter typischerweise auf status = active und isExternal.

Felder und Eingaben

FeldnamePflichtDatentypWirkung beim AusfuellenVoraussetzung
displayNameneinString (255)Anzeigename in Liste, Reports und Selectors. Falls leer, wird ein abgeleiteter Name aus parent-Daten gebildet.
transactionAccountTypeIdja (disabled nach Anlage)UUIDKlassifiziert das Konto (BANK, PAYPAL, CREDIT_CARD, CASH, ...). Steuert Sync-Verhalten und Polymorph-Parent.view:TransactionAccountType, mind. ein TransactionAccountType angelegt.
isExternaljaBoolean (Select intern/extern)false: eigenes Konto. true: Debitoren-/Kreditoren-Konto für Kunden/Lieferanten. Filter in Cockpit und Reports.
currencyjaString (3)Waehrungscode (EUR/USD/GBP/CHF). Default EUR. Saldo wird in dieser Waehrung gefuehrt.
statusjaENUM (active, inactive, pending)Steuert Sichtbarkeit in Auswahllisten und Sync-Aktivität.
parentTransactionAccountIdneinUUIDVerweis auf Eltern-Konto für Hierarchie (z. B. Pleo-Master mit Karten als Children).view:TransactionAccount.
customerIdneinUUIDVerknuepft externes Debitoren-Konto mit Kunde.isExternal = true, view:Customer.
supplierIdneinUUIDVerknuepft externes Kreditoren-Konto mit Lieferant.isExternal = true, view:Supplier.
externalIdneinString (100)Externe System-ID (z. B. finapi:28709411). Wird vom Sync-Prozess gesetzt.
lastSyncAtnein (read-only)DateTimeZeitpunkt des letzten erfolgreichen Sync-Laufs. Wird vom Job geschrieben.
parentType / parentIdnein (auto)PolymorphVerweist auf physische Entitaet (z. B. BankAccount). Beim Anlegen mit type=BANK automatisch von beforeCreate-Hook gesetzt.
defaultOffsetAccountIdneinUUID → AccountFallback-SKR-Konto für die Allocation-Engine. Liefert 10 Punkte im Score (z. B. „Pleo Geldtransit contra → 1361"). Sichtbar nur bei Top-Level-Konten (kein Parent).view:Account
clearingAccountIdneinUUID → AccountVerrechnungskonto für Cash-Advance-Clearing (z. B. 1200 Bank für Pleo-Aufladungen). Nur bei Top-Level-Konten.view:Account
fundingAccountIdneinUUID → AccountKonto, das die Karte mit Geld versorgt (z. B. der Pleo-Main-Account als Funding-Quelle). Nur bei Top-Level-Konten.view:Account

Hinweis (Welle 129): Die alte Currency-Spalte ist im Formular disabled und wird in Listen-Karten ausgeblendet — der Wert kommt zwingend aus dem Sync, manuelle Pflege war fehleranfällig. Anlage/Änderung geschieht nur noch über das Provider-API.

Zahlungskonten-Verknüpfung & 2-stufiger Geldtransit (seit Juni 2026)

Damit Bank-/Dienstleister-Bewegungen DATEV-konform gebucht werden, bekommt jedes Top-Level-Zahlungskonto ein Bilanzkonto (defaultOffsetAccountId) und optional ein Verrechnungs-/Geldtransitkonto (clearingAccountId).

Verknüpfung (Auto-Vorschlag)

Über den 🔗-Button (auch Schritt 2 des DATEV-Kontenabgleich-Wizards) schlägt SpeamCore die passenden SKR-Konten je Zahlungskonto vor:

  • GET /transaction-accounts/link-suggestions — Heuristik per Token-Abgleich aus dem Kontenrahmen (z. B. „Pleo" → 1030/1363).
  • POST /transaction-accounts/apply-links — übernimmt die Zuordnungen.
  • Gruppierung: Konten mit identischem Ziel (gleiches Bilanz-/Verrechnungskonto, z. B. alle Pleo-Karten → 1030/1363) werden zu einer Zeile zusammengefasst; angewandt wird trotzdem je Konto.

2-stufiger Geldtransit

Ist ein Verrechnungskonto (clearingAccountId) gesetzt, bucht der Booking-Service einen Geldtransfer (z. B. Bank → Pleo-Wallet) zweistufig über das Transitkonto, sodass dieses am Ende auf 0 steht:

Soll 1363 (Transit) / Haben 1200 (Bank) — Geld verlässt die Bank
Soll 1030 (Pleo) / Haben 1363 (Transit) — Geld kommt im Wallet an

Ohne clearingAccountId wird einstufig direkt Soll 1030 / Haben 1200 gebucht. Typische Konten: 1030 Pleo-Saldo, 1363 Pleo-Transit, 1201 PayPal-Saldo, 1361 PayPal-Transit.

Settlement-Perioden (PayPal/Pleo)

Sammel-Auszahlungen eines Zahlungsdienstleisters dienen als Perioden-Grenzen: alle Einzelbewegungen zwischen zwei Auszahlungen bilden eine Settlement-Periode. Im Transaktions-Cockpit zeigt ein aufklappbares Panel diese Periode mit Saldo-Check (Σ Bewegungen ≈ Auszahlungsbetrag), gespeist aus GET /transactions/:id/settlement-group.

Workflows und Zustaende

Wiederverwendbare Konzepte

Verknuepfungen zu anderen Modulen

  • TransaktionenTransaction.transactionAccountFromId und Transaction.transactionAccountToId referenzieren TransactionAccounts. Sub-Liste /transaction-accounts/:id/transactions zeigt Buchungen pro Konto.
  • Transaktions-Cockpit — Cockpit-Sicht mit Filter auf TransactionAccount und Live-Saldo.
  • Match-Vorschlaege — Vorschläge werden pro Konto erzeugt.
  • Konten-Typen — Pflicht-Stammdaten für transactionAccountTypeId.
  • Kunden / Lieferanten — externe Konten via customerId/supplierId.
  • Konten (Account) — Kontenrahmen-Konto, oft als Gegenkonto bei Buchungen referenziert.
  • Niederlassungen — primary/secondary Bank-Account-Verknuepfung wirkt auf TransactionAccounts vom Typ BANK.

Häufige Fehler und Lösungen

FehlerLösung
transactionAccountTypeId nicht änderbarPer Design — Type ist nach Anlage immutable. Neues Konto anlegen, alte Buchungen zuordnen.
Konto erscheint nicht im Cockpitstatus != active oder isExternal = true (Cockpit zeigt nur eigene Konten).
lastSyncAt veraltetSync-Job prüfen; finAPI/Pleo-Credentials abgelaufen.
Doppelte Konten nach finAPI-Re-ImportVorhandene Konten werden über externalId deduplicated — prüfen, ob externalId korrekt gesetzt ist.
Sub-Konten ohne Eltern-VerknuepfungparentTransactionAccountId manuell setzen.

API/Schnittstellen

MethodeEndpointZweckCASL
GET/api/transaction-accountsListe mit Tree-Aware-Paginationview TransactionAccount
POST/api/transaction-accountsAnlegen (triggert beforeCreate-Hook bei type=BANK)create TransactionAccount
GET/api/transaction-accounts/:idDetailview TransactionAccount
PATCH/api/transaction-accounts/:idÄndernupdate TransactionAccount
DELETE/api/transaction-accounts/:idSoft-Delete (paranoid)delete TransactionAccount
GET/api/transaction-account-balancesSaldo-Sub-Listeview TransactionAccountBalance
GET`/api/transactions?filter=transactionAccountFromIdtoId`Buchungs-Sub-Liste
GET/api/transaction-accounts/link-suggestionsKonto-Verknüpfungs-Vorschläge (Bilanz-/Verrechnungskonto)view TransactionAccount
POST/api/transaction-accounts/apply-linksVerknüpfungen übernehmenupdate TransactionAccount
GET/api/paypal-configsPayPal-Anbindungen auflistenview PayPalConfig
POST/api/paypal-configsPayPal-Anbindung anlegencreate PayPalConfig
PATCH/api/paypal-configs/:idPayPal-Anbindung ändernupdate PayPalConfig
POST/api/paypal-configs/testCredentials testen (ohne Speichern)create PayPalConfig
POST/api/paypal-configs/:id/syncReporting-Sync manuell anstoßenupdate PayPalConfig
POST/api/webhooks/paypalPayPal-Webhooks (öffentlich, signaturgeprüft)

Versionshinweise

  • 2026-06-22 (Drift): Manuelle Konten auf supportsManualEntry-Typen begrenzt (Bargeld/Bankkonto/Sonstige) dokumentiert — PayPal/Kreditkarte/Pleo nur über die Anbindungen; Warnhinweis „Konto manuell anlegen?" mit Empfehlung zur automatischen Verbindung. Verifiziert an TransactionAccountListPage.tsx.
  • 2026-06-22: PayPal-Anbindung (PayPalConfig) im Integrations-Manager dokumentiert — Reporting-Sync (Cron 4×/Tag) und Zahlungsannahme (paymentsEnabled, Orders API v2), Gebührensatz/-konto, Webhook (/api/webhooks/paypal) und Abgrenzung feeAccountId vs. paypalSurchargeAccountId. Verweise auf Bezahlseite und Konzept. Verifiziert an paypalConfig.model.ts, paypalConfig.router.ts, paypalWebhook.router.ts.
  • 2026-06-12: Zahlungskonten-Verknüpfung (link-suggestions/apply-links, Gruppierung identischer Ziele), 2-stufiger Geldtransit über clearingAccountId und Settlement-Perioden (PayPal/Pleo, settlement-group) dokumentiert. Verifiziert an transactionAccount.model.ts, paymentAccountLinkSuggestion.service.ts, booking.service.ts, transactionSettlementGroup.service.ts.
  • 2026-06-09: bankingInterface (XS2A / FINTS_SERVER / WEB_SCRAPER) pro finAPI-Bank-Verbindung dokumentiert; Dashboard-Alert unterscheidet jetzt nach Schnittstellen-Typ. Verifiziert an finapiBankConnection.model.ts.
  • 2026-05-21 (Welle 141): finAPI-Blacklist für permanent ausgeschlossene Bank-Connections (isActive-unabhängig). Sync-Job überspringt geblacklistete Konten defensiv. Re-Auth läuft über Web Form 2.0 statt der entfernten bankConnectionUpdate-Route. Quelle: BE-Commits 6ab091a8, c93bdcd7, 8add54ad, 3f0387b8.

Frühere Versionen

  • 2026-05-16 (Welle 129): Neue Felder clearingAccountId, fundingAccountId, defaultOffsetAccountId für die Anbindung an die Allocation-Proposal-Engine (Account-Default-Signal). Form-UX: Currency-Feld komplett aus dem Formular entfernt (kommt aus Sync), klarere Labels, Beispiel-Placeholders, vollständige SKR-Liste (kein Filter mehr), interne Bankkonten + PleoCard-Parents im Picker sichtbar.

Frühere Versionen

  • 2026-04-30: Initiale Veroeffentlichung mit FE-Tiefe und Cluster-Verlinkung.