How to Decode a Payment QR
Decoding is the inverse of generation: split the ASCII payload into TLV objects, check lengths, then verify CRC-16. Do this before you treat a scanned merchant QR as payment instructions. This decoder runs locally in the browser.
Start from the raw string, not the pixels
Cameras give you a bitstream; wallets and this site care about the decoded alphanumeric payload. If two scanners disagree, compare the strings, not the images. A smudged sticker can yield a truncated string that still looks like a QR.
Walk TLV left to right
Each object is a two-digit tag, a two-digit length, then exactly that many characters of value. Nested templates (26–51, 62, 64) repeat the same rule inside the value. If a length overruns the remainder of the string, stop — the payload is malformed even if a CRC was appended.
You should see Tag 00 first with value 01 for current MPM. Tag 01 should be 11 or 12. Tag 63 should be last. Anything after the CRC is unexpected.
CRC is an integrity check, not authentication
CRC-16/CCITT-FALSE over the payload through the 6304 prefix detects accidental edits and many generator bugs. It does not prove who created the QR. A fraudster can compute a valid CRC on a malicious MAI just as easily as a merchant can.
If CRC fails, do not try to “fix” the last four hex digits by hand unless you regenerated the whole string. Wrong CRC plus a plausible merchant name is a classic overlay-sticker attack.
Wrong versus right checks
Wrong: Tag 53 = INR. Right: Tag 53 = 356. Wrong: Tag 01 = 11 together with a locked Tag 54 that the cashier cannot change. Right: static 11 without amount, or dynamic 12 with Tag 54. Wrong: two MAI templates with conflicting GUIDs and no documented scheme. Right: the template IDs your acquirer listed.
Worked decode of a static sample
Take 00020101021126360014A000000677010111011300660000000005204581253033565802IN5910EMVQRHUB6007DELHI6304A13F. After splitting you get format 01, POI 11, MCC 5812, currency 356, country IN, name EMVQRHUB, city DELHI. Confirm CRC against the same string. If your decoder reports a different name, a length was misread.
When to refuse the payment
Refuse or escalate when CRC fails, Tag 00 is missing, country/currency pair is nonsense (for example country TH with currency 356 and no documented reason), merchant name is blank, or the GUID is a well-known test AID used as if it were production.
Use the Common EMV QR Errors guide on this academy for CRC failures, POI conflicts, and TLV length mismatches. Then re-generate from the EMV studio rather than patching bytes.
Official spec versus this page
EMVCo publishes the QR Code Specification for Payment Systems (EMV QRCPS). This page restates the operational checks developers hit in tools. It is not a substitute for the specification and EMV QR Hub is not affiliated with EMVCo.
Photograph plus string
When a shop asks for help, take a photo and also copy the decoded text. Photos compress; strings do not. Debug from the string.
Next steps after a valid decode
If CRC and tags look right but nobody can pay, you have an interoperability problem. Jump to that article rather than recomputing CRC.
Pixels lie; the ASCII payload does not
Two cameras can disagree on a smudged sticker. Compare strings, not images. When a shop asks for help, photograph the code and copy the decoded text. Photos compress; strings do not. Debug from the string in /decode/. If the string is truncated, the symbol is a camera/print problem, not a CRC-polynomial problem.
Walk TLV left to right: two-digit tag, two-digit length, value, nested templates inside 26–51 and 62. Tag 00 first (01), Tag 01 is 11 or 12, Tag 63 last. Overrun or leftover characters: malformed. CRC is integrity, not authentication — a valid checksum on an overlay still pays the overlay’s MAI.
Worked static decode you can repeat
Paste a studio-generated static payload. Confirm CRC valid, POI 11, Tag 53 numeric, no Tag 54, Tag 59/60 readable, MAI tree present. Then flip the last CRC nibble and confirm invalid. Then change Tag 53 to INR in a hex editor (and fix length if needed) to see a semantic fail that still checksums if you are careless. That trio is the core lab.
When CRC and tags look right but nobody can pay, you have interoperability (GUID/membership) or a physical scan issue. Jump to those articles rather than recomputing CRC. Official spec versus this page: emvco.com wins; we show original decoder output.
Refuse versus warn
Payment-time decode should refuse malformed TLV, CRC invalid, Tag 63 not last, missing MAI, missing mandatory identity tags, and alphabetic Tag 53. Laboratory decode may show a partial tree. Do not ship laboratory leniency in a wallet. This site’s decoder is a lab tool with clear verdicts so engineers can see why a string is bad.
Next steps after a valid decode: if you are generating, print at deploy size and scan from queue distance. If you are investigating a live shop, check the standee against the stored payload hash. Operator: Pankaj Kalra, not affiliated with EMVCo.
Support ticket template
Ask for: raw payload, app name, expected merchant, amount on receipt, photo of standee. Decode locally; do not ask customers to email production strings to a public inbox. Redact MAI in screenshots if policy requires.
Accessibility and glare
If older customers struggle to scan, check print contrast and size before blaming TLV. Decode the string from a staff phone scan; if that string is truncated, fix the symbol. If the string is full and CRC valid, move to wallet interoperability.
