QR Platba generator: the SPD string format explained
A Czech QR Platba code is not a special kind of QR code. It is an ordinary QR code containing one line of text in a format called SPD, short payment descriptor. Once you have seen the format there is no mystery left, and you can generate one from anything that can draw a QR code.
The whole format in one line
SPD*1.0*ACC:CZ2806000000000168540115*AM:1250.00*CC:CZK*X-VS:20260141*MSG:FAKTURA 2026-0141
That is a complete, valid payment code. Read it as: the header SPD, the version
1.0, then any number of KEY:value pairs, all joined with asterisks. Encode
that string as a QR code and every Czech banking app will open a prefilled payment.
The fields
| Key | Meaning | Notes |
|---|---|---|
| ACC | Account, as IBAN | The only mandatory field. Optionally IBAN+BIC. |
| AM | Amount | Decimal point, two places, no thousands separator. |
| CC | Currency | Three letters, CZK or EUR. |
| MSG | Message for the recipient | Up to 60 characters. |
| X-VS | Variabilní symbol | Up to 10 digits. |
| X-SS | Specifický symbol | Up to 10 digits. |
| X-KS | Konstantní symbol | Up to 10 digits. |
| RN | Recipient name | Up to 35 characters. |
| DT | Due date | YYYYMMDD. |
| RF | Payer reference | Up to 16 digits. |
| X-URL | Link to the invoice | Optional, not shown by every app. |
Only ACC is strictly required. Everything else is a convenience, and every field you fill
in is one field the customer cannot get wrong.
The rules that trip people up
-
The account goes in as an IBAN. Not the Czech
prefix-number/bankform. Convert it once and store the IBAN. - No spaces in the IBAN. Strip them before encoding. A space inside the value is the most common reason a code scans but the app refuses it.
- Asterisks are the separator, so no field value may contain one. If your invoice numbers use asterisks, they cannot go in the message.
- Uppercase and ASCII for the message. The spec allows more, but banking apps vary in how they handle diacritics. Strip accents and uppercase it and it works everywhere.
-
Amount is optional. Leave
AMout for a donation or a tip jar code and the payer types their own amount.
Which error correction level to use
QR codes carry redundant data so they still scan when part of the code is damaged. There are four levels: L recovers about 7% of the code, M about 15%, Q about 25% and H about 30%. Higher recovery means a physically denser code for the same payload.
For a payment code printed on paper, M is the right default. It survives a fold, a coffee ring and mediocre thermal printing without inflating the code. Use Q or H only if the code is going somewhere genuinely hostile, like a sticker on a machine, or if you are placing a logo over the middle of it.
Sizing it for print
A QR code is a grid of modules and the scanner needs each module to be a clean, distinct square. Two numbers matter:
- Module size. Aim for at least 0.4 mm per module in print, which on a 203 dpi thermal printer means 3 dots or more. Below that the dots bleed into each other and the code stops reading.
- Quiet zone. Four modules of blank space on every side. This is not optional padding, it is part of the specification, and cropping it is the second most common reason a code fails.
On an invoice that gives you a code around 25 to 35 mm square. Bigger looks confident and costs nothing. On a 58 mm thermal roll you have about 40 mm to work with, so keep the payload short: fewer fields means a lower QR version, which means fatter modules at the same physical size.
Generating one without a service
You do not need an API for this, and you should not send your bank account number to one. A QR encoder is a few hundred lines: encode the bytes, add Reed-Solomon error correction, lay the codewords into the matrix, try all eight masks and keep the one with the lowest penalty score. The generator linked below has one written from scratch, so the code is produced in your browser and the string never leaves your device.
Free QR Platba generator, built into the invoice tool
Set the QR content to QR Platba, enter your IBAN, the variable symbol and the message, and the code is built from the invoice total automatically. Choose the error correction level, print it on an invoice or a thermal receipt, and nothing is uploaded anywhere.
Open the generatorWritten by Oliver Žaigla, a developer in Prague who wrote the QR encoder behind this tool. If it was useful, buy me a coffee. If you need one of these built properly, write to oliver@zaigla.com.