Swiss QR Bill

GRATIS CON POSSIBILITÀ DI UPGRADE
Da GFB Consulting | Aggiornamento לפני חודשיים | Business Software
Health Check

N/A

Torna a tutti i tutorial (1)

Generating a Swiss QR pay slip with Python (or any other language)

The following is a quick tutorial on how to generate a Swiss QR pay slip using this API with Python, although in principle any other programming language that supports socket calls could be used. For it we’ll be using the Python requests library, which if you don’t already have can easily be downloaded with pip by typing either pip install requests or python -m pip install requests, and can be imported by placing the following directive at the top of your script:

import requests
Serialize your data for sending

The API uses a JSON formatted representation of the bill to generate the final file, and there are two ways to put this together, either by string concatonation or serialization. As a String, our JSON file would end up looking like this:

{
   "qrType":"SPC",
   "version":"0200",
   "codingType":"1",
   "account":"CH4431999123000889012",
   "amount":"199.95",
   "currency":"CHF",
   "dueDate":"",
   "referenceType":"QRR",
   "reference":"210000000003139471430009017",
   "unstructuredMsg":"Abonnement für 2020",
   "trailer":"EPD",
   "alternativeSchema":[ "", "" ],
   "creditor":{
      "name":"Robert Schneider AG",
      "addressType":"K",
      "address1":"Rue du Lac 1268/2/22",
      "address2":"2501 Biel",
      "postcode":"",
      "location":"",
      "country":"CH"
   },
   "ultimateCreditor":{
      "name":"",
      "addressType":"",
      "address1":"",
      "address2":"",
      "postcode":"",
      "location":"",
      "country":""
   },
   "ultimateDebitor":{
      "name":"Pia-Maria Rutschmann-Schnyder",
      "addressType":"K",
      "address1":"Grosse Marktgasse 28",
      "address2":"9400 Rorschach",
      "postcode":"",
      "location":"",
      "country":"CH"
   }
}

In this tutorial we’re going to use serialization which is supported by pretty much all languages and Python is no exception.

To do this we’re going to create two classes to hold our bill data, before sending, the first we’ll create we’ll call Actor, which represents the parties in the transaction, the creditor, who is issuing the bill, the ultimateDebitor, who is being billed, and potentially also the ultimateCreditor, which is presently not in use by the QR Bill standard, but it is generally good practice to include an empty reference to it. This class will look like this:

class Actor:
    name = ""
    addressType = ""
    address1 = ""
    address2 = ""
    postcode = ""
    location = ""
    country = ""

    def toJSON(self):
        return dict (
            name = self.name,
            addressType = self.addressType,
            address1 = self.address1,
            address2 = self.address2,
            postcode = self.postcode,
            location = self.location,
            country = self.country,
        )

Next, we’ll add one for the bill itself, which we’ll call QRBill, in which you’ll see it includes Actor objects, as well as a few default values:

class QRBill:
    qrType = "SPC"
    version = "0200"
    codingType = "1"
    account = ""
    amount = ""
    currency = ""
    dueDate = ""
    referenceType = "NON"
    reference = ""
    unstructuredMsg = ""
    trailer = ""
    billInfo = ""
    alternativeSchema = ["", ""]
    creditor = Actor()
    ultimateCreditor = Actor()
    ultimateDebitor = Actor()

    def toJSON(self):
        return dict(
            qrType = self.qrType,
            version = self.version,
            codingType = self.codingType,
            account = self.account,
            amount = self.amount,
            currency = self.currency,
            dueDate = self.dueDate,
            referenceType = self.referenceType,
            reference = self.reference,
            unstructuredMsg = self.unstructuredMsg,
            trailer = self.trailer,
            alternativeSchema = self.alternativeSchema,
            creditor = self.creditor.toJSON(),
            ultimateCreditor = self.ultimateCreditor.toJSON(),
            ultimateDebitor = self.ultimateDebitor.toJSON()
            )

You’ll note I’ve included toJSON() methods in each, who’s purpose is to convert the object into a JSON object when it comes to making our API call.

Now we’ve build our scaffolding, we can easily instantiatiate our QRBill object thus:

# Create your QRBill object for your request
bill = QRBill()
bill.account = "CH4431999123000889012"
bill.amount = "199.95"
bill.currency = "CHF"

# Set and attach creditor to QRBill object
creditor = Actor()
creditor.addressType = "K"
creditor.name = "Robert Schneider AG"
creditor.address1 = "Rue du Lac 1268/2/22"
creditor.address2 = "2501 Biel"
creditor.country = "CH"
bill.creditor = creditor

# more bill data
bill.referenceType = "QRR";
bill.reference = "210000000003139471430009017";
bill.trailer = "EPD";
bill.unstructuredMsg ="Abonnement für 2020";

# Set and attach debtor to QRBill object
debtor = Actor()
debtor.addressType = "K"
debtor.name = "Pia-Maria Rutschmann-Schnyder"
debtor.address1 = "Grosse Marktgasse 28"
debtor.address2 = "9400 Rorschach"
debtor.country = "CH"
bill.ultimateDebitor = debtor

With this we can easily generate our JSON string by calling str(bill.toJSON()).

Choosing our output

First we want to create some settings for our call, principally the base URL for the API and your RapidAPI key:

BASE_URL = 'https://swiss-qr-bill.p.rapidapi.com'
RAPID_API_KEY = 'YOUR_API_KEY' # Don't forget to replace this with your actual key

Now the important settings - these are:

LANGUAGE = "en"

This denotes the language you want your bill to be in. Four languages are presently supported by the API. These are:

  • English (“en”)
  • German (“de”)
  • French (“fr”)
  • italian (“it”)
FORMAT = "png"

This denotes the output format of the bill. Presently this can be:

  • Portable Network Graphics or PNG (“png”).
  • Adobe Acrobat Document or PDF (“pdf”).
  • Scalable Vector Graphics format or SVG (“svg”).
SIZE = "a4"

This denotes the output size of the bill. Presently this can be:

  • A4 Page format (“a4”). This produces a standard A4 page, with the QR Bill slip at the bottom.
  • QR code (“qr”). This produces only the QR code image.
  • QR Bill slip (“slip”). Like the A4 format above, it produces the QR Bill slip, but truncates the output so only the bottom part with the payment slip is outputted.
Calling the API

Now we can call the API, using the request library we imported earlier:

# Make your request
headers = {
    'Content-type': 'application/json',
    'Accept': '*/*',
    'X-RapidAPI-Key': RAPID_API_KEY,
    'X-RapidAPI-Host': 'swiss-qr-bill.p.rapidapi.com'
    }
path = '/qrbill/generate/language/' + LANGUAGE + '/format/' + FORMAT + '/size/' + SIZE
response = requests.post(BASE_URL + path, data=str(bill.toJSON()), headers=headers)

As you can see, we add the path to the base URL, which is formatted with out output settings, that we defined earlier and the Json is passed as the POST data, returning us a response object.

Handling our response

Now we have our response we can check if it all went well, which we can do by checking if the HTTP response code is 200. In this example, we’re going to save it as a file, and as you’ll note the FORMAT value also happens to be the same as the file extension that you’ll want to use. Finally we clean up the response object.

# If the request is successful
if response.status_code == 200:
    with open(f"qr_bill." + FORMAT, "wb") as f:
        f.write(response.content)
    print ("File saved!")
else:
    print("Upps! An error occured!")

response.close()
Troubleshooting and final thoughts

There are multiple reasons why the call may fail. Most common of these is that you’ve submitted an invalid QRBill JSON object, which will raise a HTTP 500 error.

Equally possible is the data may be invalid as it does not conform to the QR Bill standard, which will typically return a HTTP 400 error. In this case you can use the /qrbill/validate API call on your QR Bill and if it finds complience errors, it’ll return a list of problems with it.

Overall, while this tutorial works with Python, the basic logic can easily be impremented in pretty much any programming language. Java, Node.js, Golang, Kotlin, C# or any of the other languages listed on the endpoints screen can be easily adapted to utilize the API.