Webseite oder WordPress gehackt? Notfall-Leitfaden vom Profi: was jetzt zu tun ist, welche Fehler alles schlimmer machen, wie Sie sich künft...
Läuft Ihre Webanwendung, Ihr Kundenportal oder Ihr selbst entwickeltes ERP auf PHP? Dann müssen Sie für die E-Rechnung nicht gleich die Software wechseln. Für PHP gibt es ausgereifte Open-Source-Bibliotheken, die sich per Composer einbinden lassen. Die eigentliche Arbeit steckt meist woanders: in den Rechnungsdaten Ihrer Anwendung.
Dieser Artikel zeigt, welche Bibliotheken infrage kommen, wie der Code aussieht und was Sie vor dem Einbau prüfen sollten.
Warum das Thema jetzt ansteht
Ab dem 1. Januar 2027 müssen Unternehmen mit mehr als 800.000 € Vorjahresumsatz im inländischen B2B-Geschäft E-Rechnungen ausstellen. Ab dem 1. Januar 2028 gilt das auch für die übrigen Unternehmen. Empfangen können müssen Unternehmen E-Rechnungen schon seit dem 1. Januar 2025.
Ein normales PDF ist keine E-Rechnung. Gefordert sind strukturierte Daten, die eine Software ohne Abtippen weiterverarbeiten kann. Ob und ab wann die Pflicht für Ihr Unternehmen gilt und welche Ausnahmen greifen, klären Sie bitte mit Ihrer Steuerberatung.
ZUGFeRD oder XRechnung?
XRechnung ist eine reine XML-Datei. Ohne passendes Anzeigeprogramm ist sie für Menschen kaum lesbar, bei Rechnungen an öffentliche Auftraggeber aber der übliche Weg.
ZUGFeRD ist ein PDF mit eingebetteter XML-Datei. Der Empfänger kann die Rechnung wie gewohnt ansehen, seine Software liest die Daten aus dem Anhang. Im Geschäft mit anderen Unternehmen ist das oft der einfachste Einstieg. ZUGFeRD ist ab Version 2.0.1 zulässig, die Profile MINIMUM und BASIC WL reichen als Rechnung aber nicht aus.
Technisch liegt beiden dieselbe europäische Norm zugrunde, die EN 16931.
Welche PHP-Bibliotheken infrage kommen
| Bibliothek | Formate | PHP | Einschätzung |
|---|---|---|---|
| horstoeko/zugferd | ZUGFeRD, Factur-X, XRechnung (nur CII-Syntax) | ab 7.3 | Weit verbreitet und ausgereift, wird weiter gepflegt |
| horstoeko/invoicesuite | ZUGFeRD, Factur-X, XRechnung (CII und UBL) | ab 8.2 | Offizieller Nachfolger, noch in Version 0.0.x |
| josemmo/einvoicing | EN 16931, UBL und CII, Peppol | siehe Projektseite | Interessant, wenn UBL oder Peppol im Vordergrund stehen |
Wir haben die E-Rechnung in einem PHP-Kundenprojekt bereits mit einer Bibliothek von horstoeko umgesetzt.
Unsere Einschätzung, Stand November 2026: Der Autor von horstoeko/zugferd empfiehlt für neue Projekte ausdrücklich InvoiceSuite. Bestehende Anwendungen müssen laut Projektseite nicht sofort wechseln. Wir würden bei einem neuen Projekt mit aktuellem PHP zuerst InvoiceSuite prüfen. Wer ältere PHP-Versionen betreibt oder eine seit Jahren breit eingesetzte Bibliothek bevorzugt, ist mit horstoeko/zugferd gut bedient. Für Laravel gibt es zusätzlich das Paket horstoeko/zugferd-laravel.
Prüfen Sie vor der Entscheidung die aktuelle Version und Dokumentation. Die Bibliotheken entwickeln sich schnell weiter.
So sieht der Code aus
Das Beispiel nutzt horstoeko/zugferd und orientiert sich an der Dokumentation der Bibliothek. Installiert wird die Bibliothek wie jedes andere Composer-Paket:
composer require horstoeko/zugferd
Eine Rechnung über 10 Stunden zu je 90 € netto:
<?php
use horstoeko\zugferd\ZugferdDocumentBuilder;
use horstoeko\zugferd\ZugferdProfiles;
use horstoeko\zugferd\codelists\ZugferdCountryCodes;
use horstoeko\zugferd\codelists\ZugferdCurrencyCodes;
use horstoeko\zugferd\codelists\ZugferdInvoiceType;
use horstoeko\zugferd\codelists\ZugferdUnitCodes;
use horstoeko\zugferd\codelists\ZugferdVatCategoryCodes;
use horstoeko\zugferd\codelists\ZugferdVatTypeCodes;
$rechnung = ZugferdDocumentBuilder::createNew(ZugferdProfiles::PROFILE_EN16931);
// Kopfdaten
$rechnung->setDocumentInformation(
'RE-2027-0001',
ZugferdInvoiceType::INVOICE,
new DateTime('2027-01-15'),
ZugferdCurrencyCodes::EURO
);
$rechnung->setDocumentSupplyChainEvent(new DateTime('2027-01-10')); // Leistungsdatum
// Verkäufer
$rechnung->setDocumentSeller('Muster Software GmbH');
$rechnung->addDocumentSellerTaxRegistration('VA', 'DE123456789');
$rechnung->setDocumentSellerAddress('Musterstraße 1', '', '', '10115', 'Berlin', ZugferdCountryCodes::GERMANY);
// Käufer
$rechnung->setDocumentBuyer('Beispiel AG');
$rechnung->setDocumentBuyerAddress('Beispielweg 2', '', '', '60311', 'Frankfurt', ZugferdCountryCodes::GERMANY);
// Zahlungsziel
$rechnung->addDocumentPaymentTerm('Zahlbar innerhalb von 14 Tagen', new DateTime('2027-01-29'));
// Rechnungsposition
$rechnung->addNewPosition('1');
$rechnung->setDocumentPositionProductDetails('Softwareentwicklung');
$rechnung->setDocumentPositionNetPrice(90.00);
$rechnung->setDocumentPositionQuantity(10, ZugferdUnitCodes::REC20_HOUR);
$rechnung->addDocumentPositionTax(ZugferdVatCategoryCodes::STAN_RATE, ZugferdVatTypeCodes::VALUE_ADDED_TAX, 19);
$rechnung->setDocumentPositionLineSummation(900.00);
// Steuer: Basisbetrag, Steuerbetrag, Steuersatz
$rechnung->addDocumentTax(ZugferdVatCategoryCodes::STAN_RATE, ZugferdVatTypeCodes::VALUE_ADDED_TAX, 900.00, 171.00, 19.0);
// Summen: Brutto, Zahlbetrag, Netto, Zuschläge, Rabatte, Steuerbasis, Steuer
$rechnung->setDocumentSummation(1071.00, 1071.00, 900.00, 0.0, 0.0, 900.00, 171.00);
$rechnung->writeFile(__DIR__ . '/RE-2027-0001.xml');
Das Beispiel ist bewusst kurz gehalten und nicht für den Produktivbetrieb gedacht. Vor allem müssen die Summen aus Ihren echten Rechnungsdaten kommen und zusammenpassen. Und je nach Profil und Fall sind weitere Angaben nötig: Für eine XRechnung gehören zum Beispiel die Käuferreferenz, etwa die Leitweg-ID, sowie Kontakt- und elektronische Adressdaten dazu.
Aus der XML-Datei wird eine ZUGFeRD-Rechnung, indem Sie sie an das PDF anhängen, das Ihre Anwendung ohnehin schon erzeugt:
use horstoeko\zugferd\ZugferdDocumentPdfMerger;
$pdf = new ZugferdDocumentPdfMerger(__DIR__ . '/RE-2027-0001.xml', __DIR__ . '/RE-2027-0001.pdf');
$pdf->generateDocument();
$pdf->saveDocument(__DIR__ . '/RE-2027-0001-zugferd.pdf');
Ihr bisheriges Rechnungslayout kann also bleiben.
Wie das Ergebnis aussieht, können Sie direkt ausprobieren: In unserer E-Rechnungs-Demo erzeugen Sie eine Musterrechnung mit dieser Bibliothek und laden PDF und XML herunter.
Prüfen, bevor die erste Rechnung rausgeht
Dass eine Datei erzeugt wird, heißt noch nicht, dass sie gültig ist. Die Bibliothek bringt deshalb zwei Prüfungen mit:
ZugferdXsdValidatorprüft nur den Aufbau der XML-Datei.ZugferdKositValidatorprüft zusätzlich die Geschäftsregeln mit dem Prüfwerkzeug der KoSIT, der Koordinierungsstelle für IT-Standards. Das Prüfwerkzeug ist eine Java-Anwendung. Sie brauchen also Java auf dem Server oder eine eigene laufende Instanz des Prüfwerkzeugs, die Sie per HTTP ansprechen.
Am besten bauen Sie die Prüfung in Ihre automatisierten Tests ein. Testen Sie dabei alle Fälle, die bei Ihnen wirklich vorkommen: verschiedene Steuersätze, Rabatte, Gutschriften, Teil- und Schlussrechnungen sowie Kunden im Ausland.
Wo die eigentliche Arbeit steckt
Der Bibliotheksaufruf ist selten das Problem. Diese vier Fragen entscheiden über den Aufwand:
- Sind die Daten strukturiert vorhanden? Stehen USt-IdNr., Leistungsdatum, Einheit und Steuersatz sauber in der Datenbank oder nur als Text in der PDF-Vorlage?
- Stimmen die Beträge? Eine E-Rechnung wird nachgerechnet. Rundet Ihre Anwendung je Position anders als in der Summe, fällt das jetzt auf.
- Gibt es Sonderfälle? Gutschriften, Stornorechnungen, Abschlagsrechnungen und steuerfreie Leistungen brauchen eigene Codes und Angaben.
- Was passiert nach dem Erzeugen? Versand, Archivierung und die Übergabe an die Buchhaltung müssen mit dem neuen Format klarkommen.
Prüfen Sie auch den Empfang. Eine Anwendung, die Eingangsrechnungen verarbeitet, muss die strukturierten Daten lesen können. Dafür gibt es in der Bibliothek eigene Reader, zum Beispiel ZugferdDocumentPdfReader.
Häufige Fragen
Brauche ich dafür eine neue Software? Nicht unbedingt. Läuft Ihre Anwendung auf PHP und liegen die Rechnungsdaten sauber vor, lässt sich die E-Rechnung in vielen Fällen nachrüsten. Ob das bei Ihnen zutrifft, zeigt ein Blick in Code und Daten.
Reicht es, ein PDF per E-Mail zu schicken? Innerhalb der Übergangsfristen und unter den gesetzlichen Bedingungen ist das noch möglich. Danach reicht es im inländischen B2B-Geschäft nicht mehr. Maßgeblich ist, wann die Pflicht für Ihr Unternehmen beginnt.
Geht das auch mit Laravel?
Ja. Die genannten Bibliotheken sind normale Composer-Pakete, und für Laravel gibt es zusätzlich horstoeko/zugferd-laravel.
Kann ich meine alte PHP-Version behalten? horstoeko/zugferd verlangt in der aktuellen Version mindestens PHP 7.3, InvoiceSuite mindestens PHP 8.2. Unabhängig von der E-Rechnung sollte eine Anwendung aber auf einer PHP-Version laufen, die noch Sicherheitsupdates bekommt.
Fazit
Mit PHP ist die E-Rechnung gut machbar, und Ihre bestehende Anwendung kann oft bleiben. Prüfen Sie zuerst Ihre Rechnungsdaten und Sonderfälle, dann fällt auch die Wahl der Bibliothek leichter.
Sie möchten wissen, wie viel Aufwand das bei Ihrer Anwendung ist? Wir sehen uns das mit Ihnen an und bauen die Anbindung und Schnittstellen auf Wunsch auch ein. Das Erstgespräch ist kostenlos und dauert ca. 30 Minuten.