Zahlungen und Offene Posten #
Zahlungseingänge leben in der Tabelle RechnungZe. Die API schreibt
dort direkt - das ist der offizielle EULANDA-Weg: Datenbank-Trigger
pflegen den bezahlten Betrag (paidAmount) und den Saldo (balance)
der Rechnung automatisch. Beide Felder stehen auch im Feld-Glossar der
Rechnung.
Vorzeichen-Konvention (wichtig): Beträge werden 1:1 wie in der Datenbank geführt - ein Zahlungseingang ist negativ. Der Vertrag ist damit glasklar:
grossTotal + Summe aller payment.amounts = 0bedeutet: bezahlt, der offene Posten verschwindet aus/open-items.
So bleiben Teilzahlung, Rückzahlung (positiv), Ausbuchung und Gutschrift-OPs (negativer Saldo) ohne Sonderfälle abbildbar.
Endpunkte #
| Methode | Pfad | Zweck | Scope |
|---|---|---|---|
| GET | /api/v1/invoices/{id}/payments | Zahlungen der Rechnung inkl. paidAmount/balance | payments:read |
| POST | /api/v1/invoices/{id}/payments | Zahlung erfassen | payments:write |
| DELETE | /api/v1/invoices/{id}/payments/{paymentId} | Zahlung löschen | payments:write |
| GET | /api/v1/open-items | Offene-Posten-Liste (?asOf=, ?paymentTerms=, ?customerId=, ?view=dunning) | payments:read |
| POST | /api/v1/invoices/{id}/actions/write-off | Restbetrag ausbuchen | payments:write |
Zahlung erfassen #
Body: amount ist Pflicht (Zahlungseingang negativ), alles andere
optional - date (Default heute), account (Fibu-Geldkonto, Default
1200), statementRef (Kontoauszug), note, currency (Default
Rechnungswährung). Die Antwort enthält den neuen Saldo:
{ "amount": -350.00, "date": "2026-07-18", "statementRef": "AZ-77", "note": "Überweisung" }
{ "id": 81, "invoiceId": 58, "amount": -350.00, "currency": "EUR",
"account": 1200, "paidAmount": 350.00, "balance": 0.00 }
Geschützt beim Löschen: Zahlungen mit Belegreferenz (refType, etwa
aus dem OP-Ausgleich an der Kasse - Ausgleich nur über den
Kassen-Storno) und Zahlungen aus einem SEPA-Lauf (sepaJobId) liefern
409 PAYMENT_PROTECTED.
Offene Posten #
Die Standard-Sicht rechnet mit dem EULANDA-OP-Baustein (cnf_OPs):
je offener Rechnung Saldo, Fälligkeit und der zum Stichtag zu zahlende
Betrag inklusive Skonto (payAmount, discountAmount,
discountPercent). ?asOf= verschiebt den Stichtag für die
Skonto-Rechnung.
Mit ?view=dunning kommt die Mahn-Sicht: Mahnstufe, Mahnkosten,
Überfälligkeit in Tagen, letzte Mahnung/Zahlung und die Anschrift -
die Datenbasis für einen Mahnlauf im Client.
PowerShell:
$h = @{ Authorization = "Bearer $key" }
$base = 'http://localhost:8098/api/v1'
# Offene Posten zum Stichtag, nur ein Kunde
Invoke-RestMethod -Uri "$base/open-items?asOf=2026-07-31&customerId=2" -Headers $h
# Zahlung auf Rechnung 58 erfassen und OP-Liste prüfen
Invoke-RestMethod -Method Post -Uri "$base/invoices/58/payments" -Headers $h `
-ContentType 'application/json' -Body '{"amount":-350.00,"statementRef":"AZ-77"}'
Invoke-RestMethod -Uri "$base/open-items?view=dunning" -Headers $h
curl:
curl.exe -s -H "Authorization: Bearer %KEY%" "http://localhost:8098/api/v1/open-items?asOf=2026-07-31&customerId=2"
curl.exe -s -X POST -H "Authorization: Bearer %KEY%" -H "Content-Type: application/json" ^
-d "{\"amount\":-350.00,\"statementRef\":\"AZ-77\"}" ^
http://localhost:8098/api/v1/invoices/58/payments
curl.exe -s -H "Authorization: Bearer %KEY%" "http://localhost:8098/api/v1/open-items?view=dunning"
Restbetrag ausbuchen #
actions/write-off gleicht den offenen Rest aus (Skonto-Differenzen,
Kleinstbeträge): ohne amount wird der komplette Rest gebucht, note
ohne Angabe trägt den EULANDA-Standardtext. 409 OPEN_ITEM_SETTLED,
wenn nichts offen ist.
{ "note": "Skonto-Differenz ausgebucht" }
Feld-Glossar (payment) #
| API | DB-Spalte | Typ | Hinweis |
|---|---|---|---|
id | RechnungZe.ID | int | |
invoiceId | KopfID | int | |
date | ZeDatum | datetime | Wertstellung |
amount | Betrag | decimal | Zahlungseingang negativ |
currency | Waehrung | string | Default Rechnungswährung |
account | Konto | int | Fibu-Geldkonto (Default 1200) |
statementRef | Auszug | string | Kontoauszug-Nr., max. 20 Zeichen |
note | Bemerkung | string | max. 200 Zeichen |
refType/refId | RefTyp/RefID | string/int | Ursprungsbeleg (z.B. Kassenbeleg), nur lesend |
sepaJobId | DTAJobId | int | SEPA-Lauf, nur lesend |
Fehlercodes #
| Code | Status | Bedeutung |
|---|---|---|
PAYMENT_PROTECTED | 409 | Zahlung ist an Kassenbeleg oder SEPA-Lauf gebunden |
OPEN_ITEM_SETTLED | 409 | Kein offener Saldo - nichts auszubuchen |
VALIDATION_FIELD_INVALID | 422 | amount fehlt/0 oder Datum unlesbar |