Pix Decoder
Decode Brazilian Pix BR Code (text starting with 0002...) extracting key, amount, beneficiary, city and identifier.
- Key
- Beneficiary
- City
- Amount
- Identifier (txid)
- CRC16
How does the BR Code work?
Pix leans on the EMV-QR Code standard, assembled from TLV fields. Each field has a 2-digit ID, a 2-digit length, and the value.
Among the most common fields you'll find: 00 (version), 26 (Pix key inside subtags), 52 (category), 53 (currency, where 986 = BRL), 54 (optional amount), 58 (BR), 59 (name), 60 (city), 62 (txid) and 63 (CRC16 of the preceding bytes).
The CRC check confirms integrity.
PIX BR Code: the EMVCo standard adapted by the Brazilian Central Bank
The PIX BR Code is the payload format behind every PIX copy-and-paste string and every PIX QR Code in Brazil. It is not a proprietary format invented by the Banco Central do Brasil (BACEN). Instead, BACEN adopted the international EMVCo Merchant-Presented Mode (MPM) QR Code Specification and profiled it with PIX-specific rules in the Manual de Padroes para Iniciacao do Pix. The QR Code symbology itself follows ISO/IEC 18004, while the payload encoding follows the EMVCo MPM v1.1 specification.
In practice this means that a PIX payload is a plain ASCII string of digits and uppercase letters, identical in structure to QR payments used in India, Singapore and other countries that adopted EMVCo MPM. The difference is the merchant-account container that identifies the payment scheme as BR.GOV.BCB.PIX and carries the PIX key (CPF, CNPJ, email, phone or random EVP key). For developers, decoding a BR Code is a deterministic parsing exercise with no hidden state: every byte of the string maps to a labelled field.
TLV structure: how to decode a payload byte by byte
EMVCo MPM uses TLV (Tag-Length-Value) encoding. Each field starts with a 2-digit numeric tag, followed by a 2-digit decimal length (number of characters in the value, not bytes), and then the literal value. The reader walks the string from left to right, reads 4 characters of header, jumps length characters, and starts the next field. Some tags (notably 26-29 and 62) are templates whose value is itself a sequence of TLV sub-fields.
Example of a minimal static PIX payload (line breaks added for clarity, real payload has none):
00 02 01 26 36 00 14 BR.GOV.BCB.PIX 01 14 12345678901234567890 52 04 0000 53 03 986 58 02 BR 59 13 FULANO DE TAL 60 08 SAO PAULO 62 07 05 03 *** 63 04 A1B2
Reading this: tag 00 length 02 value 01 means "Payload Format Indicator = 01". Tag 26 length 36 means a 36-character merchant-account template follows, which is itself parsed recursively. Tag 63 always closes the payload with the 4-character CRC16 checksum.
Main fields: PFI, Merchant Account (26-29), Amount (54), CRC16 (63)
00Payload Format Indicator (PFI) - mandatory, always01for EMVCo v1.01Point of Initiation Method -11for static QR (reusable),12for dynamic QR (single-use). Optional in static payloads.26-29Merchant Account Information - template. For PIX, BACEN uses tag26with sub-field00=BR.GOV.BCB.PIX(Globally Unique Identifier),01= PIX key, and optionally02= additional info or25= URL for dynamic QR.52Merchant Category Code (MCC) - ISO 18245; typically0000for person-to-person PIX.53Transaction Currency - ISO 4217 numeric code, always986(BRL).54Transaction Amount - decimal with dot, e.g.100.50. Omit to create an open-value QR.58Country Code - ISO 3166-1 alpha-2, alwaysBR.59Merchant Name - up to 25 ASCII characters, no accents.60Merchant City - up to 15 ASCII characters.62Additional Data Field Template - sub-field05is the TxID (transaction reference), critical for reconciliation.63CRC16 - 4 uppercase hex characters, mandatory last field.
Static vs dynamic PIX (cobranca imediata and com vencimento)
A static PIX BR Code is generated once and may be reused by many payers - it is the classic merchant sticker at a checkout counter. The amount may be fixed or open; the TxID is usually a fixed string like *** meaning "no specific reference". The entire payload is self-contained: the payer's bank reads the key and amount directly from the string and initiates a PIX transfer.
Dynamic PIX BR Codes are single-use and carry tag 26 sub-field 25 with a URL pointing to a JWS payload hosted by the recipient's payment service provider (PSP). The payer's app fetches that URL, validates the JWS signature, and only then displays the amount and TxID. BACEN defines two flavours: PIX Cobranca Imediata (immediate billing) and PIX Cobranca com Vencimento (due date), the latter supporting interest, fines and discounts encoded server-side.
CRC16/CCITT-FALSE: why it exists and how to validate
The last field of every BR Code is a 6304XXXX sequence where XXXX is the CRC-16/CCITT-FALSE checksum computed over the entire payload string, including the literal 6304 header itself. Parameters: polynomial 0x1021, initial value 0xFFFF, no input or output reflection, no final XOR. The result is rendered as 4 uppercase hexadecimal characters.
The CRC exists to detect transcription errors (a digit dropped during copy-paste, an OCR mistake, a corrupted QR scan). It is not a cryptographic signature - anyone can recompute it - but every PIX-capable bank app refuses to process a payload whose CRC does not match. Validating CRC on the server side before storing or forwarding a BR Code is a basic sanity check that catches the vast majority of malformed payloads.
Developer use cases
- ERP and billing integration - read BR Codes returned by your PSP API and assert that key, amount and TxID match what your system requested.
- Charge generation - build payloads programmatically for invoices, then validate the round-trip by decoding your own output.
- Reconciliation - extract the TxID from tag
62.05and link it back to your internal order ID. - Anti-fraud - decode payloads pasted by users before forwarding to a payment flow; flag mismatches between displayed amount and actual
54value. - Debugging QA - confirm that a third-party QR Code generator follows the EMVCo MPM rules and BACEN constraints (length limits, charset, MCC).
FAQ
Is the BR Code encrypted? No. It is plain ASCII TLV. Anything written into a static payload is visible to anyone who scans it.
Why is my CRC always wrong? The CRC must be computed including the 6304 literal. Forgetting those 4 bytes is the most common bug. Also confirm you are using CRC-16/CCITT-FALSE, not the plain CCITT or XMODEM variant.
Can the merchant name contain accents? No. Tag 59 is restricted to ASCII characters; remove diacritics before encoding.
What is the maximum payload length? The QR Code itself is bounded by ISO/IEC 18004 capacity. In practice PIX BR Codes are kept under ~300 characters for static and ~500 for dynamic, comfortably inside QR version 10-15 at error correction level M.
Sources: BACEN Manual de Padroes para Iniciacao do Pix (v2.9.0), Manual do BR Code v2.0.0, EMVCo Merchant-Presented Mode QR Code Specification v1.1, ISO/IEC 18004 (QR Code symbology), ISO 4217 (currency codes), ISO 3166-1 (country codes), ISO 18245 (MCC).
Decode a Pix BR Code
Every Pix QR Code hides a string underneath, the so-called BR Code. It always opens with "0002..." and packs the charge's data into a format nobody reads by eye. This tool unpacks that string and lays out the contents in a readable way.
Each field shows up on its own: the Pix key, the amount (if one was set), the payee's name, the city and the transaction identifier. Use it to check a QR before you pay. It also helps when debugging a payments integration, or simply to satisfy the curiosity of seeing what a BR Code holds.
Everything happens in your browser, so the code you paste travels to no server. You paste the BR Code, read the data right there, and work with the ease of knowing nothing left your machine.
Read more on this
Related Tools
JWT Decoder
Decode and inspect JWT (JSON Web Tokens). View the header, payload and verify expiration. Processed 100% in the browser — the token never leaves your device.
User-Agent Parser
Parse User-Agent strings and identify browser, version, operating system and device type. Perfect for debugging access logs.
Cron Parser (describe expression)
Paste a cron expression and see in plain text when it will fire (e.g. "every day at 9am" for `0 9 * * *`). Lists the next N runs. Everything in your browser.