Leitfaden · REST-API

QR-Rechnungen aus einer Word-Vorlage generieren

Ihre Rechnung bleibt eine Word-Vorlage. Der Zahlteil kommt aus den Daten: ein qrbills-Eintrag mit Zahlungsempfänger, Zahlungspflichtigem, Betrag, Währung und Referenz, und die API zeichnet die QR-Rechnung auf das gerenderte PDF, auf die letzte Seite oder auf eine eigene. QR-IBAN mit QR-Referenz oder IBAN mit Creditor Reference oder ohne.

Warum den Zahlteil nicht selbst zeichnen

  • Die QR-Rechnung hat feste Masse, Schriften, Texte in vier Sprachen und einen Swiss QR Code mit exaktem Inhalt; eine selbstgebaute Version lehnen Banken ab.
  • Rechnungslayout und Zahlteil aus zwei Werkzeugen: eine Änderung im einen bricht das andere.
  • Eine PDF-Bibliothek kennt die SIX-Spezifikation nicht; eine Word-Vorlage kann den Zahlteil nicht zeichnen.

Die Anfrage

Der qrbills-Eintrag trägt den Inhalt als JSON-String im Envelope. Die Vorlage braucht keinen Platzhalter für den Zahlteil; placement NEW_PAGE_AT_END hängt eine Seite an, LAST_PAGE zeichnet ihn unten auf die letzte Seite.

TOKEN=$(curl -sS https://auth.xgenerate.io/realms/xgenerate/protocol/openid-connect/token \
  -d grant_type=client_credentials \
  -d client_id="$XGENERATE_CLIENT_ID" \
  -d client_secret="$XGENERATE_CLIENT_SECRET" | jq -r .access_token)

# The payload is a JSON string inside the envelope; the template needs no placeholder for the slip.
cat > fields.json <<'JSON'
{
  "fields": [
    { "name": "invoice.number", "value": "2026-0042" },
    { "name": "invoice.total",  "value": "CHF 1'234.50" }
  ],
  "qrbills": [
    { "name": "payment",
      "value": "{\"qrIban\": \"CH4431999123000889012\", \"amount\": \"1234.50\", \"currency\": \"CHF\", \"reference\": {\"type\": \"QRR\", \"value\": \"210000000003139471430009017\"}, \"creditor\": {\"name\": \"Alpenblick Consulting AG\", \"street\": \"Bahnhofstrasse\", \"houseNo\": \"10\", \"postalCode\": \"8001\", \"town\": \"Zürich\", \"country\": \"CH\"}, \"debtor\": {\"name\": \"Lumière Logistique SARL\", \"street\": \"Rue de la République\", \"houseNo\": \"12\", \"postalCode\": \"69002\", \"town\": \"Lyon\", \"country\": \"FR\"}, \"language\": \"DE\", \"placement\": \"NEW_PAGE_AT_END\"}" }
  ]
}
JSON

curl -sS https://api.xgenerate.io/v2/documents/generate \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@invoice.docx" \
  -F "fields=@fields.json;type=application/json" \
  -F "format=PDF" \
  -o invoice.pdf

Aus .NET

using System.Net.Http.Json;
using System.Text.Json;

using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new("Bearer", token);

// The QR-bill payload travels as a JSON string inside the envelope.
var payment = JsonSerializer.Serialize(new
{
    qrIban = "CH4431999123000889012",
    amount = "1234.50",
    currency = "CHF",
    reference = new { type = "QRR", value = "210000000003139471430009017" },
    creditor = new { name = "Alpenblick Consulting AG", street = "Bahnhofstrasse", houseNo = "10",
                     postalCode = "8001", town = "Zürich", country = "CH" },
    debtor = new { name = "Lumière Logistique SARL", street = "Rue de la République", houseNo = "12",
                   postalCode = "69002", town = "Lyon", country = "FR" },
    language = "DE",
    placement = "NEW_PAGE_AT_END"
});

var request = new
{
    filename = "invoice.docx",
    content = Convert.ToBase64String(await File.ReadAllBytesAsync("invoice.docx")),
    format = "PDF",
    fields = new
    {
        fields = new[] { new { name = "invoice.number", value = "2026-0042" } },
        qrbills = new[] { new { name = "payment", value = payment } }
    }
};
var response = await http.PostAsJsonAsync(
    "https://api.xgenerate.io/v2/documents/generate", request);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadFromJsonAsync<GenerateResult>();
await File.WriteAllBytesAsync(result!.Filename, Convert.FromBase64String(result.Content));

record GenerateResult(string Filename, string Content, string Format);

Die Antwort

Das PDF kommt mit dem nach dem Rendern aufgesetzten Zahlteil zurück. Der JSON-Transport liefert filename, content, format und warnings. Ein Inhalt, der die Validierung nicht besteht, oder das Format DOCX liefert das Dokument ohne Zahlteil und eine QR_BILL-Warnung mit dem Grund; die Anfrage selbst gelingt.

Das Ergebnis

Letzte Seite der gerenderten Referenzrechnung: der Schweizer QR-Zahlteil mit QR-Code, Empfangsschein und Zahlungsinformationen
Der Zahlteil, den die API an die Referenzrechnung anhängt, aus derselben Vorlage und Anfrage. Vorlage, Anfrage und erwartetes PDF: bereitgestelltes Beispiel

Was XGenerate nicht tut

Der Zahlteil wird nach dem Rendern auf das PDF gesetzt; DOCX-Ausgabe trägt keinen Zahlteil und meldet eine QR_BILL-Warnung, ebenso ein Inhalt, der die Validierung nicht besteht, statt die Anfrage scheitern zu lassen. Nur der erste qrbills-Eintrag wird gezeichnet.

Testen Sie es mit Ihrer eigenen Vorlage

Schicken Sie uns eine Word-Datei, die Sie heute verwenden. Wir rendern sie mit Ihren Daten und senden das PDF zusammen mit der angepassten Vorlage zurück — Ihre Evaluation muss nicht auf uns warten.

Demo anfragen

Verwandte Leitfäden