QR-RECHNUNG SCHWEIZ – API

Zur Vereinfachung und Harmonisierung des Zahlungsverkehrs wird in der Schweiz die QR-Rechnung eingeführt. Seit dem 30. Juni 2020 ist es möglich, QR-Rechnungen zu verwenden. Bis zum 30. September 2022 ist ein Parallelbetrieb der verschiedenen EZ-Systeme vorgesehen. Ab dem 1. Oktober 2022 kann nur noch die QR-Rechnung verwendet werden. Bei etlichen Systemen besteht also dringender Handlungsbedarf.

Rechnung oder Code kostenlos generieren lassen

Die Implementierung der QR-Rechnung in bestehende Applikationen ist nicht immer ohne Weiteres möglich. Setzt man als Entwickler die Generierung der QR-Rechnung selber um, so ist das zudem u.U. mit erheblichem Aufwand für Recherche und Programmierung verbunden. LivingTech stellt daher interessierten Entwicklern eine kostenlose API zur Generierung der QR-Rechnung zur Verfügung. Hier finden Sie Beispiel der generierten Daten.

Nutzung – code snippets

using System;
using System.Linq;
using System.Web;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Collections.Generic;
using Newtonsoft.Json;

static void Main(string[] args)
{
    // Configuration
    Dictionary<string, string> myRequestConfiguration = new Dictionary<string, string>();
    myRequestConfiguration.Add("Account", "CH4431999123000889012");
    myRequestConfiguration.Add("CreditorName", "Muster AG");
    myRequestConfiguration.Add("CreditorAddress1", "Hauptstrasse 1");
    myRequestConfiguration.Add("CreditorAddress2", "8000 Zürich");
    myRequestConfiguration.Add("CreditorCountryCode", "CH");
    myRequestConfiguration.Add("DebtorName", "LivingTech GmbH");
    myRequestConfiguration.Add("DebtorAddress1", "Dörflistrasse 10");
    myRequestConfiguration.Add("DebtorAddress2", "8057 Zürich");
    myRequestConfiguration.Add("DebtorCountryCode", "CH");
    myRequestConfiguration.Add("Amount", "1.50");
    myRequestConfiguration.Add("ReferenceNr", "21000000000313947143000901");
    myRequestConfiguration.Add("UnstructuredMessage", "Mitteilung zur Rechnung");
    myRequestConfiguration.Add("Currency", "CHF");
    myRequestConfiguration.Add("QrOnly", "false");
    myRequestConfiguration.Add("Format", "PDF");
    myRequestConfiguration.Add("Language", "DE");

    // Call function to create invoice
    byte[] myByteResult = generateQrInvoice(myRequestConfiguration);

    // Work with binary data
    if(myByteResult != null)
    {
        // ...
    }
}

protected byte[] generateQrInvoice(Dictionary<string, string> myRequestConfiguration)
{
    // Main configuration
    string myEndpointUrl = "http://qrbillservice.livingtech.ch";
    string myEndpointPath = "/api/qrinvoice/create/";
    string myApiKey = "mySecretApiKey";

    // GET parameters
    string myGetParams = $"?{string.Join("&", myRequestConfiguration.Select(myDict => $"{HttpUtility.UrlEncode(myDict.Key)}={HttpUtility.UrlEncode(myDict.Value)}"))}";

    // HttpClient
    HttpClient myHttpClient = new HttpClient();
    myHttpClient.BaseAddress = new Uri(myEndpointUrl);
    myHttpClient.DefaultRequestHeaders.Add("APIKEY", myApiKey);
    myHttpClient.DefaultRequestHeaders.Accept.Clear();
    myHttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    try
    {
        // Perform request
        HttpResponseMessage myResponse = myHttpClient.GetAsync(myEndpointPath + myGetParams).Result;

        // Check status
        if (myResponse.IsSuccessStatusCode)
        {
            // Read and parse JSON
            string myJsonBody = myResponse.Content.ReadAsStringAsync().Result;
            var myJsonObject = Newtonsoft.Json.Linq.JObject.Parse(myJsonBody);

            // Check if error
            if (myJsonObject["isSuccessed"].ToString().ToLower() == "true")
            {
                if (myJsonObject["base64Image"] != null && !String.IsNullOrEmpty(myJsonObject["base64Image"].ToString()))
                {
                    // Convert base64 string to byte array
                    byte[] myByteArray = Convert.FromBase64String(myJsonObject["base64Image"].ToString());

                    // E.g. save file
                    using (FileStream myFileStream = System.IO.File.Create(HttpContext.Current.Server.MapPath("~/App_Data/" + Guid.NewGuid().ToString() + ".pdf")))
                    {
                        myFileStream.Write(myByteArray, 0, myByteArray.Length);
                    }

                    // Return data
                    return myByteArray;
                }
                else
                {
                    throw new Exception("no data provided");
                }
            }
            else
            {
                throw new Exception(myJsonObject["Message"].ToString());
            }
        }
        else
        {
            throw new Exception("status code " + myResponse.StatusCode);
        }
    }
    catch (Exception ex)
    {
        // Handle exception
        Console.WriteLine("Error: " + ex.Message);
        return null;
    }
}
// Configuration
$myConfiguration = [
    "Account" => "CH4431999123000889012",
    "CreditorName" => "Muster AG",
    "CreditorAddress1" => "Hauptstrasse 1",
    "CreditorAddress2" => "8000 Zürich",
    "CreditorCountryCode" => "CH",
    "DebtorName" => "LivingTech GmbH",
    "DebtorAddress1" => "Dörflistrasse 10",
    "DebtorAddress2" => "8057 Zürich",
    "DebtorCountryCode" => "CH",
    "Amount" => "1.50",
    "ReferenceNr" => "21000000000313947143000901",
    "UnstructuredMessage" => "Mitteilung zur Rechnung",
    "Currency" => "CHF",
    "QrOnly" => "false",
    "Format" => "PDF",
    "Language" => "DE",
];

// Call function to create invoice
$myFile = generateQrInvoice($myConfiguration);

// Work with binary data
if($myFile != null) {
    // ...
}

function generateQrInvoice($myRequestConfiguration) {
    // Main configuration
    $myEndpointUrl = "http://qrbillservice.livingtech.ch";
    $myEndpointPath = "/api/qrinvoice/create/";
    $myApiKey = "mySecretApiKey";

    // GET parameters
    $myGetParams = http_build_query($myRequestConfiguration);

    // CURL
    $myCurl = curl_init();
    curl_setopt($myCurl, CURLOPT_URL, $myEndpointUrl . $myEndpointPath . "?" . $myGetParams);
    curl_setopt($myCurl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($myCurl, CURLOPT_HTTPHEADER, array(
        "APIKEY: " . $myApiKey, 
        "Accept: application/json"
    ));

    // Debug only
    curl_setopt($myCurl, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($myCurl, CURLOPT_SSL_VERIFYPEER, false);

    try {
        // Perform request
        $myResponse = curl_exec($myCurl);

        // Check status
        if (!curl_errno($myCurl)) {
            if(curl_getinfo($myCurl, CURLINFO_HTTP_CODE) == 200) {
                // Read and parse JSON
                $myJsonObject  = json_decode($myResponse, true);

                // Check if error
                if($myJsonObject['isSuccessed'] == "true") {
                    if(isset($myJsonObject['base64Image']) && !empty($myJsonObject['base64Image'])) {
                        // E.g. save file
                        file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/output/" . uniqid("", true) . ".pdf", base64_decode($myJsonObject['base64Image']));

                        // Return data
                        return base64_decode($myJsonObject['base64Image']);
                    } else {
                        throw new Exception("no data provided");
                    }
                } else {
                    throw new Exception($myJsonObject["Message"]);
                }
            } else {
                throw new Exception("status code " . curl_getinfo($myCurl, CURLINFO_HTTP_CODE));
            }
        } else {
            throw new Exception(curl_error($myCurl));
        }

        // Close curl
        curl_close($myCurl);
    } catch(Exception $e) {
        // Handle exception
        echo "Error: " . $e->getMessage();
        return null;
    }
}
// Configuration
let myConfiguration  = { 
    "Account" : "CH4431999123000889012",
    "CreditorName" : "Muster AG",
    "CreditorAddress1" : "Hauptstrasse 1",
    "CreditorAddress2" : "8000 Zürich",
    "CreditorCountryCode" : "CH",
    "DebtorName" : "LivingTech GmbH",
    "DebtorAddress1" : "Dörflistrasse 10",
    "DebtorAddress2" : "8057 Zürich",
    "DebtorCountryCode" : "CH",
    "Amount" : "1.50",
    "ReferenceNr" : "21000000000313947143000901",
    "UnstructuredMessage" : "Mitteilung zur Rechnung",
    "Currency" : "CHF",
    "QrOnly" : "false",
    "Format" : "PDF",
    "Language" : "DE"
}

// Call function to create invoice
let myFile = generateQrInvoice(myConfiguration);

// Work with binary data
if(myFile != null) {
    // ...
}

function generateQrInvoice(myRequestConfiguration) {
    // Main configuration
    let myEndpointUrl = "http://qrbillservice.livingtech.ch";
    let myEndpointPath = "/api/qrinvoice/create/";
    let myApiKey = "mySecretApiKey";

    // GET parameters
    let myGetParams = new URLSearchParams(myRequestConfiguration);

    // Perform request
    fetch(myEndpointUrl + myEndpointPath + "?" + myGetParams, {
        method: "GET", 
        mode: "cors", 
        cache: "no-cache", 
        headers: {
            "APIKEY": myApiKey, 
            "Accept": "application/json"
        }
    }).then(function (myResponse) {
        try {
            // Check status
            if(myResponse.status == 200) {
                // Read and parse JSON
                let myJsonObject  = JSON.parse(myResponse);

                // Check if error
                if(myJsonObject["isSuccessed"] == "true") {
                    if("base64Image" in myJsonObject && myJsonObject["base64Image"].trim() != "") {
                        // E.g. send file to client
                        let myBlob = new Blob(atob(myJsonObject["base64Image"]), {type: "application/pdf"});
                        let myBlobUrl = URL.createObjectURL(myBlob);
                        window.open(myBlobUrl);

                        // Return data
                        return atob(myJsonObject["base64Image"]);
                    } else {
                        throw "no data provided";
                    }
                } else {
                    throw myJsonObject["Message"];
                }
            } else {
                throw "status code " . myResponse.status;
            }
        }
        catch(e) {
            // Handle exception
            console.warn("Error: " + e.message, e);
            return null;
        }
    }).catch(function (err) {
        // Handle exception
        console.warn("Error: " + err.message, err);
        return null;
    });
}

Über uns

Die QR-Rechnungs-API ist ein kostenloser Service der LivingTech GmbH. Wir erstellen Webseiten, setzen E-Commerce-Projekte um und entwickeln kundenspezifische Webapplikationen. Alles aus einer Hand – lokal, unkompliziert und fair. Haben Sie Fragen? Melden Sie sich bei uns.

LivingTech

QR-RECHNUNG SCHWEIZ – API

Zur Vereinfachung und Harmonisierung des Zahlungsverkehrs wird in der Schweiz die QR-Rechnung eingeführt. Seit dem 30. Juni 2020 ist es möglich, QR-Rechnungen zu verwenden. Bis zum 30. September 2022 ist ein Parallelbetrieb der verschiedenen EZ-Systeme vorgesehen. Ab dem 1. Oktober 2022 kann nur noch die QR-Rechnung verwendet werden. Bei etlichen Systemen besteht also dringender Handlungsbedarf.

Rechnung oder Code kostenlos generieren lassen

Die Implementierung der QR-Rechnung in bestehende Applikationen ist nicht immer ohne Weiteres möglich. Setzt man als Entwickler die Generierung der QR-Rechnung selber um, so ist das zudem u.U. mit erheblichem Aufwand für Recherche und Programmierung verbunden. LivingTech stellt daher interessierten Entwicklern eine kostenlose API zur Generierung der QR-Rechnung zur Verfügung. Hier finden Sie Beispiel der generierten Daten.

Nutzung – code snippets

using System;
using System.Linq;
using System.Web;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Collections.Generic;
using Newtonsoft.Json;

static void Main(string[] args)
{
    // Configuration
    Dictionary<string, string> myRequestConfiguration = new Dictionary<string, string>();
    myRequestConfiguration.Add("Account", "CH4431999123000889012");
    myRequestConfiguration.Add("CreditorName", "Muster AG");
    myRequestConfiguration.Add("CreditorAddress1", "Hauptstrasse 1");
    myRequestConfiguration.Add("CreditorAddress2", "8000 Zürich");
    myRequestConfiguration.Add("CreditorCountryCode", "CH");
    myRequestConfiguration.Add("DebtorName", "LivingTech GmbH");
    myRequestConfiguration.Add("DebtorAddress1", "Dörflistrasse 10");
    myRequestConfiguration.Add("DebtorAddress2", "8057 Zürich");
    myRequestConfiguration.Add("DebtorCountryCode", "CH");
    myRequestConfiguration.Add("Amount", "1.50");
    myRequestConfiguration.Add("ReferenceNr", "21000000000313947143000901");
    myRequestConfiguration.Add("UnstructuredMessage", "Mitteilung zur Rechnung");
    myRequestConfiguration.Add("Currency", "CHF");
    myRequestConfiguration.Add("QrOnly", "false");
    myRequestConfiguration.Add("Format", "PDF");
    myRequestConfiguration.Add("Language", "DE");

    // Call function to create invoice
    byte[] myByteResult = generateQrInvoice(myRequestConfiguration);

    // Work with binary data
    if(myByteResult != null)
    {
        // ...
    }
}

protected byte[] generateQrInvoice(Dictionary<string, string> myRequestConfiguration)
{
    // Main configuration
    string myEndpointUrl = "http://qrbillservice.livingtech.ch";
    string myEndpointPath = "/api/qrinvoice/create/";
    string myApiKey = "mySecretApiKey";

    // GET parameters
    string myGetParams = $"?{string.Join("&", myRequestConfiguration.Select(myDict => $"{HttpUtility.UrlEncode(myDict.Key)}={HttpUtility.UrlEncode(myDict.Value)}"))}";

    // HttpClient
    HttpClient myHttpClient = new HttpClient();
    myHttpClient.BaseAddress = new Uri(myEndpointUrl);
    myHttpClient.DefaultRequestHeaders.Add("APIKEY", myApiKey);
    myHttpClient.DefaultRequestHeaders.Accept.Clear();
    myHttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    try
    {
        // Perform request
        HttpResponseMessage myResponse = myHttpClient.GetAsync(myEndpointPath + myGetParams).Result;

        // Check status
        if (myResponse.IsSuccessStatusCode)
        {
            // Read and parse JSON
            string myJsonBody = myResponse.Content.ReadAsStringAsync().Result;
            var myJsonObject = Newtonsoft.Json.Linq.JObject.Parse(myJsonBody);

            // Check if error
            if (myJsonObject["isSuccessed"].ToString().ToLower() == "true")
            {
                if (myJsonObject["base64Image"] != null && !String.IsNullOrEmpty(myJsonObject["base64Image"].ToString()))
                {
                    // Convert base64 string to byte array
                    byte[] myByteArray = Convert.FromBase64String(myJsonObject["base64Image"].ToString());

                    // E.g. save file
                    using (FileStream myFileStream = System.IO.File.Create(HttpContext.Current.Server.MapPath("~/App_Data/" + Guid.NewGuid().ToString() + ".pdf")))
                    {
                        myFileStream.Write(myByteArray, 0, myByteArray.Length);
                    }

                    // Return data
                    return myByteArray;
                }
                else
                {
                    throw new Exception("no data provided");
                }
            }
            else
            {
                throw new Exception(myJsonObject["Message"].ToString());
            }
        }
        else
        {
            throw new Exception("status code " + myResponse.StatusCode);
        }
    }
    catch (Exception ex)
    {
        // Handle exception
        Console.WriteLine("Error: " + ex.Message);
        return null;
    }
}
// Configuration
$myConfiguration = [
    "Account" => "CH4431999123000889012",
    "CreditorName" => "Muster AG",
    "CreditorAddress1" => "Hauptstrasse 1",
    "CreditorAddress2" => "8000 Zürich",
    "CreditorCountryCode" => "CH",
    "DebtorName" => "LivingTech GmbH",
    "DebtorAddress1" => "Dörflistrasse 10",
    "DebtorAddress2" => "8057 Zürich",
    "DebtorCountryCode" => "CH",
    "Amount" => "1.50",
    "ReferenceNr" => "21000000000313947143000901",
    "UnstructuredMessage" => "Mitteilung zur Rechnung",
    "Currency" => "CHF",
    "QrOnly" => "false",
    "Format" => "PDF",
    "Language" => "DE",
];

// Call function to create invoice
$myFile = generateQrInvoice($myConfiguration);

// Work with binary data
if($myFile != null) {
    // ...
}

function generateQrInvoice($myRequestConfiguration) {
    // Main configuration
    $myEndpointUrl = "http://qrbillservice.livingtech.ch";
    $myEndpointPath = "/api/qrinvoice/create/";
    $myApiKey = "mySecretApiKey";

    // GET parameters
    $myGetParams = http_build_query($myRequestConfiguration);

    // CURL
    $myCurl = curl_init();
    curl_setopt($myCurl, CURLOPT_URL, $myEndpointUrl . $myEndpointPath . "?" . $myGetParams);
    curl_setopt($myCurl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($myCurl, CURLOPT_HTTPHEADER, array(
        "APIKEY: " . $myApiKey, 
        "Accept: application/json"
    ));

    // Debug only
    curl_setopt($myCurl, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($myCurl, CURLOPT_SSL_VERIFYPEER, false);

    try {
        // Perform request
        $myResponse = curl_exec($myCurl);

        // Check status
        if (!curl_errno($myCurl)) {
            if(curl_getinfo($myCurl, CURLINFO_HTTP_CODE) == 200) {
                // Read and parse JSON
                $myJsonObject  = json_decode($myResponse, true);

                // Check if error
                if($myJsonObject['isSuccessed'] == "true") {
                    if(isset($myJsonObject['base64Image']) && !empty($myJsonObject['base64Image'])) {
                        // E.g. save file
                        file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/output/" . uniqid("", true) . ".pdf", base64_decode($myJsonObject['base64Image']));

                        // Return data
                        return base64_decode($myJsonObject['base64Image']);
                    } else {
                        throw new Exception("no data provided");
                    }
                } else {
                    throw new Exception($myJsonObject["Message"]);
                }
            } else {
                throw new Exception("status code " . curl_getinfo($myCurl, CURLINFO_HTTP_CODE));
            }
        } else {
            throw new Exception(curl_error($myCurl));
        }

        // Close curl
        curl_close($myCurl);
    } catch(Exception $e) {
        // Handle exception
        echo "Error: " . $e->getMessage();
        return null;
    }
}
// Configuration
let myConfiguration  = { 
    "Account" : "CH4431999123000889012",
    "CreditorName" : "Muster AG",
    "CreditorAddress1" : "Hauptstrasse 1",
    "CreditorAddress2" : "8000 Zürich",
    "CreditorCountryCode" : "CH",
    "DebtorName" : "LivingTech GmbH",
    "DebtorAddress1" : "Dörflistrasse 10",
    "DebtorAddress2" : "8057 Zürich",
    "DebtorCountryCode" : "CH",
    "Amount" : "1.50",
    "ReferenceNr" : "21000000000313947143000901",
    "UnstructuredMessage" : "Mitteilung zur Rechnung",
    "Currency" : "CHF",
    "QrOnly" : "false",
    "Format" : "PDF",
    "Language" : "DE"
}

// Call function to create invoice
let myFile = generateQrInvoice(myConfiguration);

// Work with binary data
if(myFile != null) {
    // ...
}

function generateQrInvoice(myRequestConfiguration) {
    // Main configuration
    let myEndpointUrl = "http://qrbillservice.livingtech.ch";
    let myEndpointPath = "/api/qrinvoice/create/";
    let myApiKey = "mySecretApiKey";

    // GET parameters
    let myGetParams = new URLSearchParams(myRequestConfiguration);

    // Perform request
    fetch(myEndpointUrl + myEndpointPath + "?" + myGetParams, {
        method: "GET", 
        mode: "cors", 
        cache: "no-cache", 
        headers: {
            "APIKEY": myApiKey, 
            "Accept": "application/json"
        }
    }).then(function (myResponse) {
        try {
            // Check status
            if(myResponse.status == 200) {
                // Read and parse JSON
                let myJsonObject  = JSON.parse(myResponse);

                // Check if error
                if(myJsonObject["isSuccessed"] == "true") {
                    if("base64Image" in myJsonObject && myJsonObject["base64Image"].trim() != "") {
                        // E.g. send file to client
                        let myBlob = new Blob(atob(myJsonObject["base64Image"]), {type: "application/pdf"});
                        let myBlobUrl = URL.createObjectURL(myBlob);
                        window.open(myBlobUrl);

                        // Return data
                        return atob(myJsonObject["base64Image"]);
                    } else {
                        throw "no data provided";
                    }
                } else {
                    throw myJsonObject["Message"];
                }
            } else {
                throw "status code " . myResponse.status;
            }
        }
        catch(e) {
            // Handle exception
            console.warn("Error: " + e.message, e);
            return null;
        }
    }).catch(function (err) {
        // Handle exception
        console.warn("Error: " + err.message, err);
        return null;
    });
}

API Key anfordern

Erstellen Sie sich mit folgenden Formular einen API-Key. Der Service ist kostenlos (fair use policy) und der Key wird Ihnen umgehend per Mail zugestellt. Happy coding.

API Key anfordern

Erstellen Sie sich mit folgenden Formular einen API-Key. Der Service ist kostenlos (fair use policy) und der Key wird Ihnen umgehend per Mail zugestellt. Happy coding.

Beispiele für Rückgabe

Sie können über Parameter festlegen, welche Art von Rückgabe Sie von der API erwarten. Entweder ein normiertes PDF mit dem vollständigen Einzahlungsschein oder den reinen QR-Code. Die Daten werden jeweils als Base64-kodierter String zurückgegeben.

Einzahlungsschein als PDF

Standardmässig gibt Ihnen die API ein einseitiges PDF-Dokument mit dem QR-Einzahlungsschein am unteren Ende zurück. Dieses Dokument können Sie Ihrer Rechnung anstelle des bisherigen orangen EZ beifügen. Der QR-EZ enthält alle notwendigen Informationen und entspricht den offiziellen Vorgaben.

QR-Code als PNG

Alternativ können Sie sich den Einzahlungsschein auch selber erstellen – oder ganz darauf verzichten. In diesem Fall fordern Sie bei der API lediglich den QR-Code als PNG an. Der Code enthält alle relevanten Zahlungsinformationen und kann vom Enduser in der Banking-App gescannt werden.