
Warum wir Payload CMS für unser eigenes CRM gewählt haben — und was wir dabei über TypeScript-native Headless CMS, AWS-Hosting und Next.js-Integration gelernt haben.
Die meisten CMS-Vergleiche bleiben theoretisch. Feature-Tabellen, Preisvergleiche, Architekturdiagramme — aber selten zeigt jemand, wie ein Headless CMS in einem echten Projekt funktioniert, wenn es über Blog-Posts und Landingpages hinausgeht.
Wir bei codehero GmbH haben genau das getan: Wir haben unser eigenes internes CRM-System mit Payload CMS gebaut. Kunden, Kontakte, Projekte, Angebote, Rechnungen mit ZUGFeRD-Standard, Zeiterfassung, Sales-Pipeline — alles in einer Next.js-App mit Payload als Daten-Backend.
In diesem Artikel teilen wir unsere Erfahrungen: Was hat funktioniert, wo mussten wir improvisieren, und warum wir Payload CMS jetzt auch unseren Kunden empfehlen.
Klar, es gibt Hunderte CRM-Systeme. HubSpot, Salesforce, Pipedrive — alle ausgereift, alle funktional. Aber für eine kleine Agentur mit sehr spezifischen Anforderungen bringen sie alle dasselbe Problem mit: Sie lösen 80% der Use Cases, aber die restlichen 20% kosten 80% der Zeit.
Unsere Anforderungen waren speziell:
Kein SaaS-CRM bietet das out of the box. Also haben wir es selbst gebaut — und Payload CMS war die perfekte Grundlage dafür.
Die kurze Antwort: Payload lebt in unserer Next.js-App, nicht daneben.
Wir haben in den letzten Jahren mit Sanity und Strapi (für Kundenprojekte) und headless CMS gearbeitet. Jedes System hat seine Stärken. Aber für ein internes Tool, das wir selbst warten und erweitern, war Payload die logische Wahl:
TypeScript-native Konfiguration — Kein JSON-Schema, kein YAML, kein GUI-Builder. Collections werden als TypeScript-Objekte definiert. Der Compiler fängt Fehler ab, bevor sie in die Datenbank gelangen.
Payload 3.x lebt in Next.js — Kein separater Backend-Server. Das Admin Panel ist eine Route in unserer Next.js-App. Die Payload Local API greift direkt auf die Datenbank zu — ohne HTTP-Overhead, ohne CORS, ohne API-Keys.
Hooks für alles — Before-Change-Hooks berechnen unsere Netto/Brutto-Beträge automatisch. After-Change-Hooks triggern Lambda-Funktionen für PDF-Generierung. Alles deklarativ, alles typsicher.
PostgreSQL — Für ein CRM mit Beziehungen zwischen Kunden, Kontakten, Projekten, Angeboten und Rechnungen ist eine relationale Datenbank die richtige Wahl. Payload unterstützt PostgreSQL nativ über den offiziellen Adapter.
Das System besteht aus 11 Collections und 1 Global:
Kern-Collections:
Finanzen:
Sales:
Infrastruktur:
Global: Firmeneinstellungen — Firmendaten, Bankverbindung, Nummernkreise, MwSt.-Satz — wird von allen Hooks referenziert.
Das Feature, das Payload von anderen Headless CMS unterscheidet, sind die Lifecycle Hooks. Für unser CRM waren sie entscheidend:
Automatische Nummernvergabe:
Jedes Angebot bekommt automatisch eine fortlaufende Nummer (ANG-2026-0001). Der Hook liest den aktuellen Zähler aus den Firmeneinstellungen, vergibt die Nummer und inkrementiert den Zähler — atomar, ohne Race Conditions.
```typescript
export const generateNummer = (type: 'angebot' | 'rechnung') =>
async ({ data, operation, req }) => {
if (operation !== 'create' || data?.nummer) return data
const settings = await req.payload.findGlobal({ slug: 'firmeneinstellungen' })
const prefix = type === 'angebot' ? 'ANG' : 'RE'
const counter = settings.nummernkreise[naechste${type}Nr] || 1
data.nummer = ${prefix}-${new Date().getFullYear()}-${String(counter).padStart(4, '0')}
// Counter inkrementieren...
return data
}
```
Automatische Betragsberechnung:
Ein Before-Change-Hook iteriert über alle Positionen, berechnet Netto, wendet Rabatt an, berechnet MwSt. und Brutto — bei jeder Änderung automatisch.
Fälligkeitsdatum:
Bei Rechnungen wird das Fälligkeitsdatum automatisch aus Rechnungsdatum + Zahlungsziel berechnet. Simple Logik, aber ein Hook spart manuelle Fehler.
PDF-Generierung:
Wenn ein Angebot auf "Gesendet" gesetzt wird, triggert ein After-Change-Hook eine Lambda-Funktion. Die Lambda nutzt die Claude API, um ein professionelles Anschreiben zu generieren, rendert alles als HTML im codehero-CI und konvertiert es mit Puppeteer zu einem A4-PDF.
Ein besonderer Aspekt unseres CRM: ZUGFeRD-konforme Rechnungen. Seit 2025 müssen B2B-Rechnungen in Deutschland strukturierte elektronische Formate unterstützen. ZUGFeRD/Factur-X kombiniert ein visuelles PDF mit einem maschinenlesbaren XML nach EN16931.
Unsere Lösung:
Das Besondere: Wir konnten eine bestehende Lambda wiederverwenden und mussten nur die Seller-Daten konfigurierbar machen. Payload liefert die Daten, die Lambda generiert das PDF, S3 speichert es — alles event-driven.
Ursprünglich hatten wir ECS Fargate + ALB + RDS geplant (~40€/Monat). Dann haben wir uns gefragt: Brauchen wir das wirklich für ein internes Tool?
Die Antwort war nein. Unser Setup:
Geschätzte Kosten: unter 5€/Monat statt 40€. Für ein internes Tool mit ein paar Nutzern absolut ausreichend.
Payload ist mehr als ein CMS. Es ist ein Framework für datengetriebene Anwendungen. Die Kombination aus typed Collections, Hooks, Access Control und Admin Panel macht es zu einer der besten Lösungen für eigene CRM/Backendlösungen — mit dem Vorteil, dass es nativ in Next.js lebt.
Hooks ersetzen Backend-Logik. Was normalerweise Express-Middleware oder API-Handler wären, sind bei Payload deklarative Before/After-Hooks. Das reduziert Boilerplate erheblich.
Self-Hosting ist einfacher als gedacht. Mit Amplify + PostgresSQL ist ein Payload-Deployment in unter 30 Minuten live. Keine Docker-Container, keine VPCs, keine Load Balancer.
Die Community wächst schnell. Payload 3.x hat die Adoption beschleunigt. Die Discord-Community ist aktiv, die Dokumentation ist gut, und die Maintainer reagieren schnell auf Issues.
| Kriterium | Payload CMS | Sanity | Strapi | Directus |
|---|---|---|---|---|
| TypeScript-Support | Erstklassig (native) | Gut (GROQ codegen) | Mittel (v5 besser) | Mittel |
| Next.js-Integration | Nativ (same process) | API + SDK | API | API |
| Self-Hosting | Ja (eigene Infra) | SaaS + Self-Host | Ja | Ja |
| Hooks/Lifecycle | Sehr mächtig | Webhooks | Lifecycle | Flows |
| Access Control | Granular (Feld-Level) | GROQ-basiert | Rollen | Rollen + Policies |
| Eignet sich als App-Backend | Ja | Nein (Content-fokus) | Eingeschränkt | Eingeschränkt |
| Kosten bei Skalierung | Infrastruktur only | Teuer (pro Seat) | Infrastruktur | Infrastruktur |
Für Content-Websites bleibt Sanity eine hervorragende Wahl — wir nutzen es selbst für codehero.solutions. Aber sobald ein Projekt über reines Content Management hinausgeht — CRM, E-Commerce Backend, interne Tools — hat Payload die Nase vorn.
Unser CRM läuft. Angebote werden automatisch nummeriert, Beträge berechnet, PDFs generiert und ZUGFeRD-Rechnungen erstellt. Alles TypeScript, alles in einer Next.js-App, alles auf AWS.
Payload CMS hat sich für uns als das richtige Tool erwiesen — nicht weil es perfekt ist, sondern weil es die richtige Balance zwischen Flexibilität und Struktur bietet. Es gibt uns ein professionelles Admin Panel ohne Custom-UI-Aufwand, typsichere Datenmodelle ohne ORM-Overhead und Hooks für Business-Logik ohne separates Backend.
Wenn Sie ein Projekt planen, das über eine klassische Website hinausgeht — ein Kundenportal, ein internes Tool, ein E-Commerce-Backend — lohnt sich ein Blick auf Payload CMS.
[→ Mehr über unsere Payload CMS Expertise](/payload-agentur)
[→ Projekt mit Payload CMS besprechen](/kontakt)
Wolfgang Müller
CEO & Fullstack-Developer
Kostenloses Erstgespräch — ehrlich, technisch fundiert, unverbindlich. Antwort innerhalb von 24 Stunden.