Skip to main content

A payment QR code is just twelve lines of text

The creator of ibanchecker.cash breaks down the EPC069-12 standard, revealing how payment QR codes are built using simple plain text and strict byte limits.

AI-written
Inewgen
12 Aug 2026Source: Dev.to3 min read (0 views)
Share
A payment QR code is just twelve lines of text

Stock photo for illustration only, not from the actual event

Font size
  • The EPC069-12 standard uses twelve lines of plain text without binary framing or JSON.
  • The entire payload must fit within 331 bytes and supports only the euro currency.
  • Decoding happens completely inside the browser using jsQR with zero image uploads.

If you have paid an invoice in Europe recently, you have likely pointed your banking app at a small square to automatically fill in the payee, IBAN, and amount. Koray Köylü, creator of ibanchecker.cash, spent weeks working on both sides of these squares by generating and reading them, discovering that the format is far simpler than most expect.

The standard is EPC069-12, published by the European Payments Council and marketed in Germany as a GiroCode. There is no binary framing and no JSON; the payload consists of plain text with twelve elements separated by line breaks:

  • 1. Service tag: BCD
  • 2. Version: 002 (making the BIC optional)
  • 3. Character set: 1 for UTF-8
  • 4. Identification: SCT (SEPA Credit Transfer)
  • 5. BIC: COBADEFF
  • 6. Beneficiary name: Who gets paid
  • 7. IBAN: The bank account
  • 8. Amount: Currency glued to the value
  • 9. Purpose: Empty
  • 10. Structured reference: Empty
  • 11. Unstructured reference: Free text
  • 12. Beneficiary to originator: May be absent

Crucial implementation rules dictate that the entire payload must fit within 331 bytes. The name is capped at 70 characters and the reference at 140. Amounts are strictly in euros from 0.01 to 999,999,999.99, error correction must be level M, and there is no digital signature proving who generated the code—something to keep in mind when encountering stickers on parking meters.

Germany technology computer screen code editor

Stock photo for illustration only, not from the actual event

331Bytes max payload limit
12Line elements in code
70Character limit for name

Line 6 represents the beneficiary name. An early bug in Köylü's generator accidentally pulled the bank name instead, causing banking apps to display "Commerzbank" rather than the actual account holder. The developer strongly emphasizes that line 6 must always be the payee, never the bank.

Never miss the latest news?

Subscribe to get news summaries by email - not often enough to be annoying.

โฆษณา

"A payment QR code is just twelve lines of text"

Koray Köylü

The SEPA Credit Transfer (SCT) framework forms the backbone of European cross-border transactions. Structuring payment QR codes as simple plain-text line breaks democratizes implementation for developers, removing heavy software dependencies. However, the absence of cryptographic signatures in the EPC standard highlights the vulnerability of physical QR code stickers, underscoring the need for careful client-side verification.

The updated tool features live code updates as you type, tracking byte progression toward the 331-byte ceiling. Exports include SVG, high-resolution PNG, and vector PDF generated via raw SVG path rendering with zero dependencies. On the decoding side, dropped images are parsed locally via a dynamically imported jsQR module, ensuring user privacy by keeping image data strictly in the browser.

Source: Dev.to

Comments

Leave a Comment
0/2000

Found something wrong in this article? Report an issue with this article