How to Automate Accounts Payable with n8n and AI (German Mittelstand Guide)
Step-by-step guide to AP automation for German Mittelstand using n8n workflows, AI invoice extraction, E-Rechnung processing, and DATEV integration.
Summary
German Mittelstand companies can automate 80% of accounts payable processing using n8n orchestration, AI-powered invoice extraction, E-Rechnung intake, and DATEV export: without enterprise ERP budgets.
Definition
Accounts payable automation for the German Mittelstand combines invoice intake (email, portal, E-Rechnung), AI-powered data extraction, approval routing, and ERP/DATEV export, orchestrated by workflow tools like n8n without requiring SAP or enterprise AP platforms.
Why n8n for Mittelstand AP
Enterprise AP solutions (Basware, Tipalti, Yokoy) cost €50K+ annually and assume SAP/Oracle backends. German Mittelstand companies: 50 to 500 employees, €10M–€100M revenue: need automation that connects to DATEV, Lexware, or SevDesk without six-figure contracts.
n8n provides:
- Self-hosted data control (GDPR, GoBD)
- Visual workflow builder finance teams can modify
- 400+ integrations including email, Slack, HTTP, databases
- AI node support for Claude/GPT extraction
- One-time setup cost, low ongoing fees
Architecture Overview
Invoice Intake → Format Detection → Extraction → Validation → Approval → Export
↓ ↓ ↓ ↓ ↓ ↓
Email/IMAP XRechnung/ZUGFeRD AI/OCR Rules Engine Slack DATEV CSV
Supplier Portal PDF scan Claude PO Match Email Lexware API
Step 1: Invoice Intake Workflow
Create an n8n workflow triggered by email (IMAP) or webhook:
{
"nodes": [
{
"name": "Email Trigger",
"type": "n8n-nodes-base.emailReadImap",
"parameters": {
"mailbox": "rechnungen@company.de",
"downloadAttachments": true
}
},
{
"name": "Detect Format",
"type": "n8n-nodes-base.code",
"parameters": {
"jsCode": "const items = $input.all();\nreturn items.map(item => {\n const filename = item.binary?.attachment_0?.fileName || '';\n const mime = item.binary?.attachment_0?.mimeType || '';\n let format = 'unknown';\n if (mime === 'application/xml' || filename.endsWith('.xml')) format = 'xrechnung';\n else if (mime === 'application/pdf') format = 'pdf';\n return { json: { ...item.json, format, filename } };\n});"
}
}
]
}
Route by format: XML → direct parsing, PDF → AI extraction, ZUGFeRD → embedded XML extraction first, fallback to AI.
Step 2: AI Invoice Extraction
For PDF invoices without structured data, use Claude with structured output:
// n8n Code node - call Claude API
const pdfBase64 = items[0].binary.attachment_0.data;
const response = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: {
'x-api-key': $env.ANTHROPIC_API_KEY,
'anthropic-version': '2023-06-01',
'content-type': 'application/json'
},
body: JSON.stringify({
model: 'claude-sonnet-4-20250514',
max_tokens: 2000,
messages: [{
role: 'user',
content: [
{
type: 'document',
source: { type: 'base64', media_type: 'application/pdf', data: pdfBase64 }
},
{
type: 'text',
text: `Extract invoice data as JSON with fields:
rechnungsnummer, rechnungsdatum, faelligkeitsdatum,
lieferant_name, lieferant_ustid, nettobetrag, ust_betrag,
bruttobetrag, waehrung, positionen (array of beschreibung, menge, einzelpreis, steuersatz).
Return ONLY valid JSON.`
}
]
}]
})
});
const extracted = JSON.parse(response.content[0].text);
return [{ json: extracted }];
Set confidence thresholds: auto-approve extractions above 95% field match against vendor master data. Route lower confidence to human review.
Step 3: Validation Rules
Before approval, validate extracted data:
| Rule | Action on Fail |
|---|---|
| USt-IdNr. format valid (DE + 9 digits) | Flag for review |
| USt-IdNr. matches vendor master | Block until verified |
| Duplicate Rechnungsnummer + Lieferant | Reject as duplicate |
| PO number match (if required) | Route to procurement |
| Amount within PO tolerance (±5%) | Route to manager |
| Bank details changed from last invoice | Require dual approval |
// Validation code node
const invoice = $input.first().json;
const vendor = await $('PostgreSQL').execute({
query: 'SELECT * FROM vendors WHERE ust_id = $1',
params: [invoice.lieferant_ustid]
});
const errors = [];
if (!vendor) errors.push('Unknown vendor USt-IdNr.');
if (vendor && vendor.default_iban !== invoice.lieferant_iban) {
errors.push('IBAN changed from vendor master');
}
const duplicate = await $('PostgreSQL').execute({
query: 'SELECT id FROM invoices WHERE number = $1 AND vendor_id = $2',
params: [invoice.rechnungsnummer, vendor?.id]
});
if (duplicate.length) errors.push('Duplicate invoice');
return [{ json: { ...invoice, validation_errors: errors, status: errors.length ? 'review' : 'approved' } }];
Step 4: Approval Routing
Use n8n Switch node for approval matrix:
- < €500: Auto-approve if validation passes
- €500–€5,000: Slack approval to department head
- €5,000–€25,000: Email + Slack to finance manager
- > €25,000: Sequential approval (FM → CFO)
{
"name": "Approval Router",
"type": "n8n-nodes-base.switch",
"parameters": {
"rules": {
"rules": [
{ "value": "={{ $json.bruttobetrag }}", "operation": "smallerEqual", "output": 0, "value2": 500 },
{ "value": "={{ $json.bruttobetrag }}", "operation": "smallerEqual", "output": 1, "value2": 5000 },
{ "value": "={{ $json.bruttobetrag }}", "operation": "smallerEqual", "output": 2, "value2": 25000 }
]
}
}
}
Wait for approval via n8n Wait node with webhook callback from Slack interactive buttons.
Step 5: DATEV Export
Generate DATEV-compatible CSV (EXTF Buchungsstapel):
const invoice = $input.first().json;
const datevRow = [
'11000', // Umsatz
'H', // Soll/Haben
'EUR', // Währung
'', // Kurs
'', // Basisumsatz
'', // WKZ Basis
invoice.nettobetrag.toFixed(2).replace('.', ','), // Netto
'8400', // Gegenkonto (Aufwand)
'0000', // BU-Schlüssel
formatDate(invoice.rechnungsdatum), // Belegdatum
invoice.rechnungsnummer, // Belegnummer
'', // Belegtext
'1', // Postensperre
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''
].join(';');
await writeFile(`/exports/datev_${Date.now()}.csv`, datevRow);
Upload to DATEV Unternehmen online via DATEVconnect API or manual import: depending on your DATEV package.
Step 6: E-Rechnung Processing
For XRechnung/ZUGFeRD, skip AI extraction when structured XML is available:
# External Python service called via n8n HTTP node
from lxml import etree
def parse_xrechnung(xml_bytes):
ns = {'cbc': 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2',
'cac': 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2'}
root = etree.fromstring(xml_bytes)
return {
'rechnungsnummer': root.find('.//cbc:ID', ns).text,
'rechnungsdatum': root.find('.//cbc:IssueDate', ns).text,
'lieferant_name': root.find('.//cac:AccountingSupplierParty/cac:Party/cac:PartyName/cbc:Name', ns).text,
'lieferant_ustid': root.find('.//cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID', ns).text,
'bruttobetrag': float(root.find('.//cbc:TaxInclusiveAmount', ns).text),
'nettobetrag': float(root.find('.//cbc:TaxExclusiveAmount', ns).text),
}
Structured extraction is faster, cheaper, and more accurate than AI: always prefer XML when available.
Monitoring and Metrics
Track in n8n or connected Grafana:
| Metric | Target |
|---|---|
| Auto-processing rate | >80% of invoices |
| AI extraction accuracy | >95% field-level |
| Average processing time | under 5 minutes |
| Duplicate detection rate | 100% |
| DATEV export errors | under 1% |
Common Pitfalls
- Running n8n cloud without self-hosting for sensitive invoice data (GDPR concern)
- No vendor master data maintenance: AI extraction cannot validate unknown vendors
- Skipping IBAN change detection: primary fraud vector in AP
- Manual DATEV CSV without automated upload: creates second bottleneck
- Over-automating first invoice from new vendors: always require human review
Business Outcomes
Mittelstand companies implementing this stack process invoices in under 5 minutes versus 15–20 minutes manually, reduce AP headcount needs by 1–2 FTE, achieve 99%+ duplicate detection, and maintain GoBD-compliant audit trails through n8n execution logs.
Related: E-Rechnung 2025 Guide · E-Rechnung integration
Need help connecting your finance systems?
Fynteq connects E-Rechnung, DATEV, Stripe, ERP and bank workflows for German SMEs and growing digital businesses. Frankfurt-based, fixed-scope implementation.
Frequently Asked Questions
Related articles
DATEV Integration with Stripe: A Technical Guide for German Companies
Technical guide to integrating Stripe payment data with DATEV: webhook sync, Buchungsstapel export, tax mapping, GoBD compliance, and reconciliation automation.
E-Rechnung 2025: What Every German B2B Company Must Do Now
Practical guide to E-Rechnung compliance in Germany: XRechnung, ZUGFeRD, Peppol, DATEV integration, and what B2B companies must implement before the mandate expands.
How to Automate Payment Reconciliation
Learn how to automate payment reconciliation: matching provider settlements to internal records, exception handling, and finance-ready reporting for SaaS and FinTech.
Finance integration insights
Practical guides on E-Rechnung, DATEV, Stripe, reconciliation and finance automation for teams in Germany.
By downloading, you agree to our privacy policy. We use your email to send the PDF and follow up on related services. Or contact info@fynteq.com.