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.
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
Berechtigungen (CASL)
| Action | Subject | Wirkung | Keycloak-Rolle |
|---|---|---|---|
view | FE_TransactionAccount, TransactionAccount | Liste/Detail aufrufbar | — |
create/update/delete | TransactionAccount | Pflegen | APP_SPEAMCORE_CREATE/UPDATE/DELETE_TRANSACTION_ACCOUNT |
view | TransactionAccountType | Auswahl im Anlage-Form | APP_SPEAMCORE_VIEW_TRANSACTION_ACCOUNT_TYPE |
view | TransactionAccountBalance | Saldo-Sub-Liste | APP_SPEAMCORE_VIEW_TRANSACTION_ACCOUNT_BALANCE |
view | Transaction | Buchungs-Sub-Liste | APP_SPEAMCORE_VIEW_TRANSACTION |
view | FinapiConfig | finAPI-Overview-Modal | APP_SPEAMCORE_VIEW_FINAPI_CONFIG |
view | PleoConfig | Pleo-Overview-Modal | APP_SPEAMCORE_VIEW_PLEO_CONFIG |
view/create/update/delete | PayPalConfig | PayPal-Anbindung im Integrations-Manager (Test = create) | — |
Schritt-für-Schritt-Anleitung
Eigenes Konto anlegen (z. B. neues Bankkonto)
- Buchhaltungskonten (
/transaction-accounts) → + Neu. displayNamepflegen (z. B. „Sparkasse Geschaeftskonto").transactionAccountTypeIdwählen — beim manuellen Anlegen werden nur die Typen mitsupportsManualEntryangeboten: Bargeld (CASH), Bankkonto (BANK) und Sonstige (OTHER).PAYPAL,CREDIT_CARDund Pleo entstehen nicht manuell, sondern über die Anbindungen (Integrations-Manager).isExternal = false(eigenes Konto).currencypflegen (DefaultEUR).status = activesetzen, damit das Konto in Listen erscheint.- Beim Speichern mit
transactionAccountType.code = BANKlegt der Backend-Hook automatisch einBankAccountan und verknuepft es polymorph (parentType = BankAccount,parentId = bankAccount.id).
finAPI-Bank-Sync anstossen
- In der Liste den Button finAPI-Konten klicken —
FinapiOverviewModalöffnet sich. - finAPI-Bank auswählen → Konten werden importiert und als TransactionAccount mit
externalId = "finapi:<accountId>"angelegt. lastSyncAtwird 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):
| Wert | Bedeutung |
|---|---|
XS2A | PSD2-Banking-API (offizielle Schnittstelle der Bank). |
FINTS_SERVER | FinTS/HBCI-Server. |
WEB_SCRAPER | Web-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 = trueaus finAPI-Sicht. - Geblacklistete Konten erscheinen weder im Konto-Auswahl-Modal noch im Cockpit.
- Aktivieren oder Entfernen über
POST /api/finapi/blacklistundDELETE /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
paymentsEnabledseparat scharfgeschaltet. Mechanik: PayPal-Zahlungsannahme.
- In der Konten-Liste Integrations-Manager → PayPal öffnen (
PayPalOverviewModal→PayPalConnectionSetup). - Zugangsdaten der PayPal-REST-App eintragen:
clientId,clientSecret, Umgebung (live/sandbox). - Verbindung testen (
POST /api/paypal-configs/test) — prüft die Credentials, ohne sie zu speichern. - Speichern. Optional Zahlungsannahme aktivieren (
paymentsEnabled), Gebührensatz und Konten hinterlegen.
| Feldname | Pflicht | Datentyp | Wirkung beim Ausfuellen | Voraussetzung |
|---|---|---|---|---|
clientId | ja | String | Client-ID der PayPal-REST-App | PayPal-REST-App vorhanden |
clientSecret | ja | String (write-only) | Secret der REST-App — verschlüsselt gespeichert, nie wieder ausgegeben | — |
environment | ja | live / sandbox | wählt die PayPal-Basis-URL | — |
isActive | nein | Boolean | aktiviert den Reporting-Sync (steuert den Cron-Job) | — |
paymentsEnabled | nein | Boolean | schaltet die Zahlungsannahme (Orders API) frei → Bezahlseite + Webhook | gültige Credentials |
feeRatePercent | nein | Decimal (Default 2.49) | PayPal-Gebührensatz in % für den exakten Aufschlag-Gross-up | — |
feeFixed | nein | Decimal (Default 0.35) | fixe PayPal-Gebühr je Transaktion (Gross-up) | — |
feeAccountId | nein | UUID → Account | SKR-Aufwandskonto, gegen das PayPal-Gebühren beim Reporting-Sync gebucht werden | view:Account |
transactionAccountId | auto | UUID | Haupt-PayPal-TransactionAccount (beim Anlegen automatisch erstellt) | — |
payoutBankAccountId | nein | UUID | Bankkonto, auf dem PayPal-Auszahlungen landen | — |
webhookId | nein | String | PayPal-Webhook-Abo-ID — Grundlage der Signaturprüfung eingehender Webhooks | — |
syncFromDate | nein | Datum | erstes Datum, das der Reporting-Backfill abdeckt | — |
lastSyncAt | read-only | DateTime | Zeitpunkt 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:
- + Neu mit
isExternal = true. - Entweder
customerIdodersupplierIdsetzen — verknuepft das Konto mit dem Kunden bzw. Lieferanten. transactionAccountTypeIdmit CodeDEBTOR/CREDITOR(sofern angelegt).

Toolbar (Detail-Seite)
Schlanke Toolbar oben rechts:
| Icon | Aktion (aria-label) | CASL | Wirkung |
|---|---|---|---|
| ← | Zurückgehen | — | Zurück zur Liste. |
| 🏠 | Zur Startseite gehen | — | Springt auf das Dashboard / /. |
| ⏮/◀/▶/⏭ | Pagination | — | Navigation durch die gefilterte Liste — Massen-Bearbeitung ohne Liste-Sprung. |
Globale Floating-Drawer (links)
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
| Feldname | Pflicht | Datentyp | Wirkung beim Ausfuellen | Voraussetzung |
|---|---|---|---|---|
displayName | nein | String (255) | Anzeigename in Liste, Reports und Selectors. Falls leer, wird ein abgeleiteter Name aus parent-Daten gebildet. | — |
transactionAccountTypeId | ja (disabled nach Anlage) | UUID | Klassifiziert das Konto (BANK, PAYPAL, CREDIT_CARD, CASH, ...). Steuert Sync-Verhalten und Polymorph-Parent. | view:TransactionAccountType, mind. ein TransactionAccountType angelegt. |
isExternal | ja | Boolean (Select intern/extern) | false: eigenes Konto. true: Debitoren-/Kreditoren-Konto für Kunden/Lieferanten. Filter in Cockpit und Reports. | — |
currency | ja | String (3) | Waehrungscode (EUR/USD/GBP/CHF). Default EUR. Saldo wird in dieser Waehrung gefuehrt. | — |
status | ja | ENUM (active, inactive, pending) | Steuert Sichtbarkeit in Auswahllisten und Sync-Aktivität. | — |
parentTransactionAccountId | nein | UUID | Verweis auf Eltern-Konto für Hierarchie (z. B. Pleo-Master mit Karten als Children). | view:TransactionAccount. |
customerId | nein | UUID | Verknuepft externes Debitoren-Konto mit Kunde. | isExternal = true, view:Customer. |
supplierId | nein | UUID | Verknuepft externes Kreditoren-Konto mit Lieferant. | isExternal = true, view:Supplier. |
externalId | nein | String (100) | Externe System-ID (z. B. finapi:28709411). Wird vom Sync-Prozess gesetzt. | — |
lastSyncAt | nein (read-only) | DateTime | Zeitpunkt des letzten erfolgreichen Sync-Laufs. Wird vom Job geschrieben. | — |
parentType / parentId | nein (auto) | Polymorph | Verweist auf physische Entitaet (z. B. BankAccount). Beim Anlegen mit type=BANK automatisch von beforeCreate-Hook gesetzt. | — |
defaultOffsetAccountId | nein | UUID → Account | Fallback-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 |
clearingAccountId | nein | UUID → Account | Verrechnungskonto für Cash-Advance-Clearing (z. B. 1200 Bank für Pleo-Aufladungen). Nur bei Top-Level-Konten. | view:Account |
fundingAccountId | nein | UUID → Account | Konto, 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
- Buchhaltungskonten — Querschnitt zu Account / TransactionAccount / BankAccount.
- Bankkonten und Zuweisungen — physische Bankverbindung (BankAccount) und ihre Zuordnung zu Niederlassungen, Kunden, Lieferanten.
- Polymorpher Parent-Pattern —
parentType/parentIdzu BankAccount/PayPalAccount. - Berechtigungen verstehen (CASL)
Verknuepfungen zu anderen Modulen
- Transaktionen —
Transaction.transactionAccountFromIdundTransaction.transactionAccountToIdreferenzieren TransactionAccounts. Sub-Liste/transaction-accounts/:id/transactionszeigt 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
| Fehler | Lösung |
|---|---|
transactionAccountTypeId nicht änderbar | Per Design — Type ist nach Anlage immutable. Neues Konto anlegen, alte Buchungen zuordnen. |
| Konto erscheint nicht im Cockpit | status != active oder isExternal = true (Cockpit zeigt nur eigene Konten). |
lastSyncAt veraltet | Sync-Job prüfen; finAPI/Pleo-Credentials abgelaufen. |
| Doppelte Konten nach finAPI-Re-Import | Vorhandene Konten werden über externalId deduplicated — prüfen, ob externalId korrekt gesetzt ist. |
| Sub-Konten ohne Eltern-Verknuepfung | parentTransactionAccountId manuell setzen. |
API/Schnittstellen
| Methode | Endpoint | Zweck | CASL |
|---|---|---|---|
GET | /api/transaction-accounts | Liste mit Tree-Aware-Pagination | view TransactionAccount |
POST | /api/transaction-accounts | Anlegen (triggert beforeCreate-Hook bei type=BANK) | create TransactionAccount |
GET | /api/transaction-accounts/:id | Detail | view TransactionAccount |
PATCH | /api/transaction-accounts/:id | Ändern | update TransactionAccount |
DELETE | /api/transaction-accounts/:id | Soft-Delete (paranoid) | delete TransactionAccount |
GET | /api/transaction-account-balances | Saldo-Sub-Liste | view TransactionAccountBalance |
GET | `/api/transactions?filter=transactionAccountFromId | toId` | Buchungs-Sub-Liste |
GET | /api/transaction-accounts/link-suggestions | Konto-Verknüpfungs-Vorschläge (Bilanz-/Verrechnungskonto) | view TransactionAccount |
POST | /api/transaction-accounts/apply-links | Verknüpfungen übernehmen | update TransactionAccount |
GET | /api/paypal-configs | PayPal-Anbindungen auflisten | view PayPalConfig |
POST | /api/paypal-configs | PayPal-Anbindung anlegen | create PayPalConfig |
PATCH | /api/paypal-configs/:id | PayPal-Anbindung ändern | update PayPalConfig |
POST | /api/paypal-configs/test | Credentials testen (ohne Speichern) | create PayPalConfig |
POST | /api/paypal-configs/:id/sync | Reporting-Sync manuell anstoßen | update PayPalConfig |
POST | /api/webhooks/paypal | PayPal-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 anTransactionAccountListPage.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 AbgrenzungfeeAccountIdvs.paypalSurchargeAccountId. Verweise auf Bezahlseite und Konzept. Verifiziert anpaypalConfig.model.ts,paypalConfig.router.ts,paypalWebhook.router.ts. - 2026-06-12: Zahlungskonten-Verknüpfung (
link-suggestions/apply-links, Gruppierung identischer Ziele), 2-stufiger Geldtransit überclearingAccountIdund Settlement-Perioden (PayPal/Pleo,settlement-group) dokumentiert. Verifiziert antransactionAccount.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 anfinapiBankConnection.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 entferntenbankConnectionUpdate-Route. Quelle: BE-Commits6ab091a8,c93bdcd7,8add54ad,3f0387b8.
Frühere Versionen
- 2026-05-16 (Welle 129): Neue Felder
clearingAccountId,fundingAccountId,defaultOffsetAccountIdfü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.