PHP · Packagist

XRechnung in PHP. One Composer require, valid XML.

No Mustang, no local Schematron, no JRE in CI. composer require normbill/xrechnung — generate, validate, parse. If KoSIT fails, the path is invoice.buyer_reference, not an XPath.

Get API keyPackagist

composer require → valid XML

composer require normbill/xrechnung
use Normbill\Xrechnung\NormbillClient;

$nb = new NormbillClient(getenv('NORMBILL_API_KEY'));
$result = $nb->generate([
    'format'  => 'xrechnung-3.0',
    'invoice' => [
        'number'          => 'INV-2026-0001',
        'issue_date'      => '2026-06-15',
        'due_date'        => '2026-07-15',
        'buyer_reference' => '04011000-1234512345-06',
        'seller' => [
            'name'    => 'Muster Lieferant GmbH',
            'vat_id'  => 'DE123456789',
            'address' => ['country' => 'DE', 'city' => 'Berlin', 'postal_code' => '10115'],
            'contact' => ['name' => 'Billing', 'phone' => '+49 30 1234567', 'email' => 'billing@lieferant.example'],
        ],
        'buyer' => [
            'name'    => 'Beispiel Kunde AG',
            'address' => ['country' => 'DE', 'city' => 'Hamburg', 'postal_code' => '20095'],
            'contact' => ['email' => 'ap@kunde.example'],
        ],
        'payment' => ['iban' => 'DE89370400440532013000'],
        'lines'   => [
            ['name' => 'Beratungsleistung', 'qty' => 10, 'unit_price' => 100, 'vat' => 19],
        ],
    ],
]);

$result['xml'] is KoSIT-validated XRechnung 3.0. XRechnung API · Docs

No Java, no local Schematron

KoSIT runs on our side. Your CI needs ext-curl. PHP ≥ 8.1. No Mustang, no JRE, no pinned Schematron packs.

horstoeko / xrechnung-kit vs API

horstoeko and xrechnung-kit are right if you want to own the XML. The API is right if your SaaS issues invoices for tenants and you do not want to pin KoSIT updates yourself. OSS library vs API for XRechnung.

Generate / Validate / Parse

The same three endpoints as REST, on NormbillClient:

  • generate(array $request) — JSON → validated XML
  • validate(string $content) — check XML you already have. Free within fair use.
  • parse(string $content) — receiving mandate: XML → invoice array

TypeScript counterpart

npm i @normbill/xrechnung — the same contract in TypeScript. REST stays the language the clients wrap.

Pricing with no sales call

Free: 50/month, KoSIT, test and live keys, no card. Paid from €19. Same surface as the XRechnung API.

Pricing · Get API key

Spotted something?

Bug, missing feature, wrong validation result — tell us. The page you're on is attached automatically; email optional.