💡 Praxis-Beispiel: Sehen Sie sich unsere Dynamics 365 Case Study an – dort zeigen wir, wie wir X-Rechnung, ZUGFeRD und PDF-Rechnungen automatisch verarbeiten und direkt in Microsoft Dynamics 365 Finance & Operations buchen.
📋 Inhaltsverzeichnis
- 1. Das Problem: Manuelle Rechnungsprüfung bindet viel Zeit
- 2. Die Lösung: KI-gestützte Automatisierung
- 3. Wirtschaftlichkeit: mit eigenen Zahlen rechnen
- 4. Technische Architektur (Intrexx + n8n + Claude)
- 5. Implementierung (Schritt-für-Schritt)
- 6. Code-Beispiele (Groovy, n8n, Claude Prompt)
- 7. FAQ
⏱️ Lesezeit: 13 Minuten
Das Problem: Manuelle Rechnungsprüfung bindet viel Zeit
Kennen Sie das? Ihre Buchhaltung verbringt täglich viel Zeit mit manueller Rechnungsprüfung:
- Rechnung aus E-Mail herunterladen
- PDF öffnen, Betrag, Datum, Rechnungsnummer ablesen
- Daten in ERP/Buchhaltungs-Software eintippen
- Rechnung mit Bestellung abgleichen (falls vorhanden)
- Bei Unstimmigkeiten: E-Mail an Lieferanten
- Rechnung archivieren (GoBD-konform)
Die Lösung: KI-gestützte Automatisierung
Stellen Sie sich vor:
- Rechnung kommt per E-Mail rein
- KI extrahiert automatisch: Betrag, Datum, Rechnungsnummer, Lieferant, USt-ID
- KI validiert: Betrag > 0? Datum plausibel? USt-ID korrekt?
- KI prüft Duplikate: Wurde diese Rechnung schon erfasst?
- Confidence Score > 90%? → Auto-Approve + E-Mail an Prüfer
- Confidence Score < 90%? → Manuelle Prüfung + Felder sind schon vorausgefüllt
Was macht die KI konkret?
Die KI liest Betrag, Datum, Rechnungsnummer und Lieferant aus, validiert die USt-ID und prüft auf Duplikate. Der Mensch prüft nur noch Abweichungen und Rechnungen mit niedrigem Confidence Score.
Wirtschaftlichkeit: mit eigenen Zahlen rechnen
Ob sich die automatische Rechnungsprüfung lohnt, hängt von Rechnungsvolumen, Anteil strukturierter Rechnungen, Prüfaufwand und Fehlerkosten in Ihrem Betrieb ab. Pauschale Kennzahlen helfen dabei wenig; belastbarer ist eine Rechnung mit den eigenen Zahlen.
Der ROI-Rechner liefert dafür eine erste Spanne mit offengelegten Annahmen. Eine belastbare Zahl für Ihren Betrieb ergibt der Pilot mit Ihrem eigenen Ablauf.
Technische Architektur (Intrexx + n8n + Claude)
┌─────────────────────────────────────────────────────────┐
│ EINGANGSRECHNUNG (E-Mail/Upload) │
└────────────────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ INTREXX (Low-Code) │
│ • PDF-Upload via Drag-&-Drop │
│ • Datenbank-Eintrag erstellt (Status: "Neu") │
│ • afterSave-Trigger feuert Groovy Hook │
└────────────────────────┬────────────────────────────────┘
│
│ Groovy Hook sendet:
│ - PDF (Base64)
│ - Invoice ID
│ - Supplier Name (falls bekannt)
▼
┌─────────────────────────────────────────────────────────┐
│ n8n WEBHOOK NODE │
│ • Empfängt Request von Intrexx │
│ • Validiert API-Key │
└────────────────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ n8n: BASE64 → BINARY NODE │
│ • PDF dekodieren │
└────────────────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ CLAUDE VISION API (OCR + EXTRAKTION) │
│ Prompt: │
│ "Extrahiere aus dieser Rechnung: │
│ 1. Rechnungsnummer │
│ 2. Rechnungsbetrag (Brutto in EUR) │
│ 3. Rechnungsdatum (Format: YYYY-MM-DD) │
│ 4. Lieferant (Firma) │
│ 5. USt-ID │
│ 6. Confidence Score (0-100%) │
│ │
│ Antwort als JSON." │
└────────────────────────┬────────────────────────────────┘
│
│ Response:
│ {
│ "invoice_number": "RE-2026-001",
│ "amount": 1234.56,
│ "date": "2026-01-10",
│ "supplier": "Baustoff GmbH",
│ "vat_id": "DE123456789",
│ "confidence": 96
│ }
▼
┌─────────────────────────────────────────────────────────┐
│ n8n: VALIDATION NODE │
│ • Betrag > 0? │
│ • Datum in Vergangenheit < 90 Tage? │
│ • Rechnungsnummer nicht leer? │
│ • USt-ID-Format korrekt (DE + 9 Ziffern)? │
└────────────────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ n8n: DUPLIKATE-CHECK NODE │
│ • Query Intrexx DB: Gibt es schon Rechnung mit │
│ gleicher Rechnungsnummer? │
│ • Gibt es Rechnung mit gleichem Betrag + Lieferant │
│ + Datum (±3 Tage)? │
└────────────────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ n8n: IF NODE (Confidence) │
│ Confidence > 90% && Keine Duplikate? │
│ ├─ JA: Status = "Auto-Approved" │
│ └─ NEIN: Status = "Manuelle Prüfung" │
└────────────────────────┬────────────────────────────────┘
│
│ Callback an Intrexx REST API
│ (Extrahierte Daten + Status)
▼
┌─────────────────────────────────────────────────────────┐
│ INTREXX REST API HANDLER │
│ • Datenbank-Update: │
│ - invoice_number = "RE-2026-001" │
│ - amount = 1234.56 │
│ - invoice_date = "2026-01-10" │
│ - supplier_name = "Baustoff GmbH" │
│ - vat_id = "DE123456789" │
│ - ai_confidence = 96 │
│ - processing_status = "Auto-Approved" │
│ • Workflow-Trigger: E-Mail an Prüfer │
└────────────────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ USER NOTIFICATION │
│ E-Mail: "Rechnung RE-2026-001 geprüft (Auto-Approved)"│
│ Link: https://intrexx.firma.de/invoices/1234 │
└─────────────────────────────────────────────────────────┘
Technologie-Stack
| Komponente | Technologie | Funktion |
|---|---|---|
| Frontend + DB | Intrexx | Upload-Formular, Datenbank, User-Interface |
| Workflow-Engine | n8n | Orchestrierung (Claude API, Validierung, Callback) |
| KI-Engine | Claude Vision API | OCR + Datenextraktion aus PDF |
| Integration Layer | Webhooks (HTTPS + API-Key) | Intrexx ↔ n8n Kommunikation |
| Archivierung | Intrexx DMS (GoBD-konform) | PDF/A-Export, 10 Jahre Aufbewahrung |
Implementierung (Schritt-für-Schritt)
Woche 1: Setup & Foundation
Tag 1-2: Intrexx Datenbank + UI
- Datenbank-Tabelle
invoiceserstellen:- id (Primary Key)
- invoice_number (VARCHAR 50)
- amount (DECIMAL 10,2)
- invoice_date (DATE)
- supplier_name (VARCHAR 200)
- vat_id (VARCHAR 20)
- invoice_pdf (FILE)
- processing_status (VARCHAR 50)
- ai_confidence (INT 0-100)
- created_at, updated_at (DATETIME)
- Upload-Formular bauen (Drag-&-Drop für PDF)
- Übersichts-Seite (Tabelle mit allen Rechnungen)
- Detail-Seite (einzelne Rechnung anzeigen + PDF-Preview)
Tag 3: n8n Setup
- n8n installieren (Docker oder Cloud)
- Ersten Webhook erstellen (Test mit Postman)
- Claude API-Key in n8n hinterlegen
Tag 4-5: Intrexx Groovy Hook
- afterSave-Event Handler in Intrexx
- Groovy Script schreiben (PDF → Base64 → n8n Webhook)
- Error-Handling (Try-Catch, Logging)
Woche 2: n8n Workflow + KI-Integration
Tag 6-7: n8n Workflow bauen
- Webhook Node (Empfang von Intrexx)
- Function Node (Base64 → Binary)
- Claude Vision Node (OCR + Extraktion)
- Function Node (JSON-Parsing + Validierung)
- IF Node (Confidence > 90%?)
Tag 8: Duplikate-Check
- HTTP Request Node (Intrexx REST API Query)
- Function Node (Duplikate-Logik: Rechnungsnummer + Betrag+Datum)
- IF Node (Duplikat gefunden?)
Tag 9-10: Callback an Intrexx
- HTTP Request Node (Intrexx REST API Update)
- Error-Trigger Node (bei Fehlern: Slack/E-Mail Alert)
- Testing (10 Test-Rechnungen durchlaufen lassen)
Woche 3: Testing, Optimierung, Rollout
Tag 11-12: User Acceptance Testing
- 50 echte Rechnungen durchlaufen lassen
- Fehleranalyse (welche Rechnungen hatten Confidence <90%?)
- Prompt-Optimierung (Claude Prompt anpassen für bessere Extraktion)
Tag 13: GoBD-Archivierung
- PDF/A-Konvertierung in Intrexx aktivieren
- Audit-Log (wer hat wann welche Rechnung validiert?)
- Backup-Strategie testen
Tag 14-15: Training & Rollout
- User-Training (Buchhaltung): Wie funktioniert das System?
- Dokumentation schreiben (Prozess-Diagramm, FAQ)
- Go-Live: System für alle Mitarbeiter freischalten
✅ Ziel nach der Implementierung: System ist live. Erste Rechnungen werden automatisch verarbeitet. Buchhaltung spart ab Tag 1 Zeit.
Code-Beispiele (Groovy, n8n, Claude Prompt)
1. Intrexx Groovy Hook (afterSave)
// ==========================================
// Intrexx Event Handler: afterSave
// Trigger: Rechnung wurde hochgeladen
// ==========================================
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
def invoiceFile = g_record.getFile("invoice_pdf")
if (invoiceFile == null) {
g_log.error("Keine Rechnung gefunden für ID: ${g_record.getIntegerValue('id')}")
return
}
// PDF zu Base64 konvertieren
def invoiceBase64 = invoiceFile.getBytes().encodeBase64().toString()
// n8n Webhook URL (aus Intrexx Config)
def n8nWebhookUrl = "https://n8n.your-company.de/webhook/invoice-check"
def apiKey = "YOUR_SECRET_API_KEY"
// Payload erstellen
def payload = [
invoice_id: g_record.getIntegerValue("id"),
pdf_base64: invoiceBase64,
supplier_name: g_record.getStringValue("supplier_name") ?: "",
upload_timestamp: new Date().format("yyyy-MM-dd'T'HH:mm:ss'Z'")
]
try {
def connection = new URL(n8nWebhookUrl).openConnection()
connection.setRequestMethod("POST")
connection.doOutput = true
connection.setRequestProperty("Content-Type", "application/json")
connection.setRequestProperty("X-API-Key", apiKey)
connection.setConnectTimeout(5000) // 5 Sek.
connection.setReadTimeout(30000) // 30 Sek.
def writer = new OutputStreamWriter(connection.outputStream, "UTF-8")
writer.write(JsonOutput.toJson(payload))
writer.flush()
writer.close()
def responseCode = connection.responseCode
if (responseCode == 200) {
def response = connection.inputStream.text
def json = new JsonSlurper().parseText(response)
g_record.setValue("processing_status", "In Verarbeitung")
g_record.setValue("n8n_workflow_id", json.workflow_id ?: "")
g_log.info("n8n Workflow gestartet für Invoice ID: ${g_record.getIntegerValue('id')}")
} else {
g_log.error("n8n HTTP Error ${responseCode} für Invoice ID: ${g_record.getIntegerValue('id')}")
g_record.setValue("processing_status", "Fehler beim Senden")
}
} catch (Exception e) {
g_log.error("n8n Request fehlgeschlagen: ${e.message}")
g_record.setValue("processing_status", "Fehler: ${e.message}")
}
2. Claude Vision Prompt (in n8n)
// n8n Node: Claude Vision API Call
{
"model": "claude-3-7-sonnet-20250219",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "application/pdf",
"data": "{{ $json.pdf_base64 }}"
}
},
{
"type": "text",
"text": `Du bist ein Experte für Rechnungsprüfung.
Extrahiere aus dieser Rechnung folgende Daten:
1. **Rechnungsnummer** (z.B. RE-2026-001, Inv-12345, etc.)
2. **Rechnungsbetrag** (Brutto in EUR, nur die Zahl)
3. **Rechnungsdatum** (Format: YYYY-MM-DD)
4. **Lieferant** (Firmenname)
5. **USt-ID** (Format: DE + 9 Ziffern, z.B. DE123456789)
6. **Confidence Score** (0-100%): Wie sicher bist du bei der Extraktion?
WICHTIG:
- Wenn ein Feld nicht gefunden werden kann: null
- Betrag ohne € Symbol, nur Zahl (z.B. 1234.56)
- Datum im ISO-Format (YYYY-MM-DD)
- Confidence Score: 100% = absolut sicher, 50% = unsicher
Antwort als JSON (ohne Erklärung):
{
"invoice_number": "...",
"amount": 1234.56,
"date": "2026-01-10",
"supplier": "Firma XY GmbH",
"vat_id": "DE123456789",
"confidence": 95
}`
}
]
}
]
}
3. n8n Duplikate-Check (Function Node)
// n8n Function Node: Duplikate-Check
const extractedData = $input.first().json;
const invoiceNumber = extractedData.invoice_number;
const amount = extractedData.amount;
const date = extractedData.date;
const supplier = extractedData.supplier;
// Intrexx REST API abfragen (vorherige Node hat Datenbank-Abfrage gemacht)
const existingInvoices = $('Intrexx_Query').all();
let isDuplicate = false;
let duplicateReason = "";
// Check 1: Rechnungsnummer exakt gleich
for (const invoice of existingInvoices) {
if (invoice.json.invoice_number === invoiceNumber) {
isDuplicate = true;
duplicateReason = `Duplikat: Rechnungsnummer ${invoiceNumber} existiert bereits (ID: ${invoice.json.id})`;
break;
}
}
// Check 2: Betrag + Lieferant + Datum (±3 Tage) gleich
if (!isDuplicate) {
const invoiceDate = new Date(date);
for (const invoice of existingInvoices) {
const existingDate = new Date(invoice.json.invoice_date);
const daysDiff = Math.abs((invoiceDate - existingDate) / (1000 * 60 * 60 * 24));
if (
invoice.json.amount === amount &&
invoice.json.supplier_name === supplier &&
daysDiff <= 3
) {
isDuplicate = true;
duplicateReason = `Duplikat-Verdacht: Gleicher Betrag (${amount}€) vom gleichen Lieferanten (${supplier}) am ${date} (±3 Tage)`;
break;
}
}
}
return {
...extractedData,
is_duplicate: isDuplicate,
duplicate_reason: duplicateReason
};
Häufig gestellte Fragen (FAQ)
Bei strukturierten Rechnungen (Standard-Layouts wie DATEV, Lexware) liest Claude Vision Betrag, Datum und Rechnungsnummer in der Regel zuverlässig aus.
Bei unstrukturierten Rechnungen (handschriftliche Notizen, Scans schlechter Qualität) ist die Trefferquote geringer. Eine belastbare Genauigkeit zeigt erst ein Test mit Ihren eigenen Dokumenten.
Best Practice: 4-Augen-Prinzip – KI extrahiert, Mensch validiert bei Confidence Score <90%.
Beim Eigenbau mit der Claude Vision API fallen API-Kosten nach Nutzung an (Preisliste von Anthropic).
Kommerzielle Lösungen wie DocuWare, ABBYY FlexiCapture oder Candis rechnen meist pro Rechnung oder Nutzer ab; die Preise nennen die Hersteller.
Zusätzlich beim Eigenbau:
- Intrexx-Lizenz: nach Herstellerangebot (wird aber meist schon für andere Use Cases genutzt und fällt dann anteilig an)
- n8n: Open Source, selbst gehostet ohne Lizenzgebühr
- Entwicklung: Aufwand nach Umfang
Ob sich der Eigenbau lohnt, hängt vom Rechnungsvolumen ab. Eine erste Schätzung liefert der ROI-Rechner.
Die KI extrahiert nur Daten – GoBD-konforme Archivierung macht Intrexx (DMS-Modul).
Anforderungen GoBD:
- Unveränderbarkeit: PDF/A-Konvertierung
- Versionierung: Audit-Log bei Änderungen
- Nachvollziehbarkeit: Wer hat wann was gemacht?
- 10 Jahre Aufbewahrung: Backup-Strategie
Intrexx erfüllt alle Punkte:
- PDF/A-Export (automatisch bei Upload)
- Datenbank-Trigger für Audit-Logs
- Rechte-Management (nur Finance darf löschen)
- Automatisches Backup (täglich)
Optional: Zertifizierte Archiv-Systeme (d.velop d3, ELO) via Intrexx-Integration anbinden.
Claude Vision unterstützt 100+ Sprachen (Englisch, Französisch, Spanisch, Italienisch, Polnisch, Türkisch, etc.).
Genauigkeit: Bei häufigen Sprachen höher als bei seltenen; testen Sie mit Ihren eigenen Rechnungen.
Best Practice: Prompt in Englisch schreiben, Output-Sprache auf Deutsch forcieren.
Beispiel:
Extract invoice data from this document (language: French).
Return all values in German. Amount in EUR (convert if needed).
Bei häufigen Fremdsprachen-Rechnungen:
- Separate n8n-Workflows pro Sprache (optimierte Prompts)
- Auto-Detection via Language-Detection-Node (Zeile 1 der Rechnung analysieren)
3-Stufen-Duplikate-Check:
1) Rechnungsnummer-Abgleich
SQL-Query in Intrexx: SELECT COUNT(*) WHERE invoice_number = ?
2) Betrag + Lieferant + Datum-Kombination
Gleicher Betrag am gleichen Tag vom gleichen Lieferant = 95% Duplikat
3) Semantic Search mit Embeddings
Claude erzeugt Vektor-Repräsentation der Rechnung, Similarity-Check gegen
alle Rechnungen der letzten 12 Monate, Threshold >0.92 = Duplikat-Warnung
Umsetzung in n8n:
3 IF-Nodes, bei Duplikat-Verdacht: Status "Manuelle Prüfung" +
E-Mail an Finance + Link zu beiden Rechnungen im UI.
🚀 Bereit für automatische Rechnungsprüfung?
Ich setze solche Systeme für Unternehmen um, die Rechnungen automatisch auslesen und für die Buchung vorbereiten wollen.
Nächster Schritt: Kostenloses Gespräch (45 Minuten)
Gespräch vereinbarenWeiterführende Artikel: