Guide · API REST

Générer des QR-factures suisses à partir d'un modèle Word

Votre facture reste un modèle Word. La section paiement vient des données : une entrée qrbills avec créancier, débiteur, montant, monnaie et référence, et l'API dessine la QR-facture sur le PDF rendu, sur la dernière page ou sur une page à part. QR-IBAN avec référence QR, ou IBAN avec référence créancier ou sans référence.

Pourquoi ne pas dessiner la section paiement vous-même

  • La QR-facture a des dimensions fixes, des polices, des textes en quatre langues et un Swiss QR Code au contenu exact ; une version maison est rejetée par les banques.
  • Mise en page de la facture et section paiement issues de deux outils : un changement dans l'un casse l'autre.
  • Une bibliothèque PDF ne connaît pas la spécification SIX ; un modèle Word ne sait pas dessiner la section.

La requête

L'entrée qrbills porte le contenu sous forme de chaîne JSON dans l'enveloppe. Le modèle n'a besoin d'aucun espace réservé pour la section ; placement NEW_PAGE_AT_END ajoute une page, LAST_PAGE la dessine au bas de la dernière page.

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

Depuis .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);

La réponse

Le PDF revient avec la section paiement composée après le rendu. Le transport JSON renvoie filename, content, format et warnings. Un contenu qui échoue à la validation, ou le format DOCX, renvoie le document sans la section et un avertissement QR_BILL qui en donne la raison ; la requête elle-même réussit.

Le résultat

Dernière page de la facture de référence rendue : la section paiement QR suisse avec code QR, récépissé et informations de paiement
La section paiement que l'API ajoute à la facture de référence, à partir du même modèle et de la même requête. Modèle, requête et PDF attendu : exemple publié

Ce que XGenerate ne fait pas

La section paiement est composée sur le PDF après le rendu ; une sortie DOCX n'en porte pas et signale un avertissement QR_BILL, de même qu'un contenu qui échoue à la validation, au lieu de faire échouer la requête. Seule la première entrée qrbills est dessinée.

Essayez-le sur votre propre modèle

Envoyez-nous un fichier Word que vous utilisez aujourd'hui. Nous le rendons avec vos données et vous renvoyons le PDF avec le modèle adapté, pour que votre évaluation ne dépende pas de nous.

Demander une démo

Guides associés