Skip to content

How QRIS Works — A Visual Guide

Think of a QRIS code as a shopping receipt packed into a QR image. Just like a receipt lists items, prices, and the merchant name, a QRIS code stores the same information in a machine-readable format.

The Secret Language: Tag-Length-Value

A QRIS code uses a pattern called TLV (Tag-Length-Value). Every piece of information is stored in the same three-part structure:

Real Example

The raw QRIS string starts with these characters: 000201

Breaking it down:

PartWhat it saysMeaning
00This is tag 00The "Payload Format Indicator"
02The value is 2 characters longLength of the data
01The value is 01Version 1 of the EMVCo format

So 000201 means: "This QRIS code follows format version 01."


Anatomy of a QRIS Code

A QRIS code is a sequence of TLV blocks, one after another:

🏷️ Header Information

TagNameWhat it does
00Payload Format IndicatorAlways 01. Marks this as a payment QR code.
01Point of Initiation Method11 = Static (customer types the amount themselves) • 12 = Dynamic (merchant sets the amount)

🏪 Merchant Information

TagNameWhat it does
2651Merchant Account TemplatesContains nested TLV with payment provider details (like DANA, GoPay, OVO). Each template has its own sub-tags (see below).
52Merchant Category Code (MCC)A 4-digit code describing the business type. 5411 = restaurant, 5411 = grocery store.
59Merchant NameThe business name (e.g., "Toko Berkah Jaya").
60Merchant CityCity where the merchant operates.
61Postal CodeZIP or postal code (optional).

💰 Payment Details

TagNameWhat it does
53Transaction CurrencyCurrency code. 360 = Indonesian Rupiah (IDR).
54Transaction AmountThe payment amount. Only present on dynamic QRIS codes.
55Tip or Convenience Indicator01 = ask customer for tip • 02 = fixed fee added • 03 = percentage fee added
56Convenience Fee (Fixed)A flat fee in Rupiah (e.g., 2000 = Rp2.000 fee).
57Convenience Fee (%)A percentage fee (e.g., 250 = 2.50% fee).

🌍 Location & Miscellaneous

TagNameWhat it does
58Country CodeID for Indonesia.
62Additional DataExtra info like bill numbers or references (contains nested TLV).

✅ Integrity Check

TagNameWhat it does
63CRC ChecksumA 4-character "fingerprint" that detects accidental corruption. Always appears last.

Static vs Dynamic QRIS

Static (11)Dynamic (12)
Has amount (tag 54)?No — customer enters amountYes — amount is pre-set
Reusable?Yes — same QR code foreverNo — new code per transaction
Used byWarung, street vendors, small shopsPayment terminals, e-commerce, apps

Merchant Account Templates (Tags 26–51)

These tags contain nested TLV — a TLV inside a TLV. Think of it like a folder inside a filing cabinet:

Common sub-tags inside merchant account templates:

Sub-TagNameExample
00Globally Unique Identifier (GUID)ID.DANA.WWW0115 identifies DANA as the provider
01Merchant Account Number / PANThe merchant's account number with that provider
02Merchant IDAlternative ID for the merchant
03Merchant CriteriaAdditional routing information

Common Payment Providers

GUID PrefixProvider Name
ID.DANA.WWWDANA
ID.GOPAY.WWWGoPay
ID.OVO.WWWOVO
ID.SHOPEEPAY.WWWShopeePay
ID.LINKAJA.WWWLinkAja
ID.BNI.WWWBNI
ID.BRI.WWWBRI
ID.MANDIRI.WWWMandiri
ID.BCA.WWWBCA

The CRC "Fingerprint"

The CRC (Cyclic Redundancy Check) is like a seal on an envelope. It ensures nobody accidentally changes the QRIS data.

If any character in the QRIS string gets altered, the CRC won't match, and the system knows the code is corrupted.


Converting Static to Dynamic


Complete Example

Here's a full QRIS string broken down into its TLV parts:

String: 00020101021126190015ID.DANA.WWW01155204541153033605802ID
        5922Toko Berkah Jaya6010Surabaya6304C8C0

00 02 01          → Format version 01
01 02 11          → Static QRIS (customer enters amount)
26 19 0015ID.DANA.WWW0115  → Merchant account: DANA
52 04 5411        → Category: Restaurant
53 03 360         → Currency: IDR
58 02 ID          → Country: Indonesia
59 22 Toko Berkah Jaya  → Merchant name
60 10 Surabaya  → City
63 04 C8C0        → CRC checksum

Last updated: