Pix payload (BR Code)
The Pix BR Code payload behind a Pix QR Code and "Pix copia e cola".
Validate
- JavaScript library
- Python library
- Go library28 cases fail
- Ruby library23 cases fail
- Rust library25 cases fail
- .NET library29 cases fail
- Erlang library
Validates a Pix BR Code payload against the Manual de Padrões para Iniciação do Pix v2.10.0 and, where the manual is silent, the EMV QRCPS-MPM it builds on. The function checks the form of the key, not whether the key is registered in the DICT.
- Structure: well-formed TLV with every length from
01to99, the payload format indicator000201as the first object, and the CRC-16 (63) as the last top-level object, whole, matching the payload. Eight trailing characters that only look like6304and a checksum (inside another object, for example) do not count as the CRC. A CRC in lowercase hexadecimal is accepted, as in 2.4.0 (no official source fixes the case). - An object ID may not repeat at the same level (EMV gives each object one ID per level), whatever the values are, even with a CRC that matches. Until 2.4.0 the last repeated ID won. Only crafted payloads repeat an ID.
- Mandatory objects: merchant category code (
52) of 4 digits, currency (53)986, country (58)BRin uppercase, merchant name (59) of at most 25 characters and merchant city (60) of at most 15. Only the length is checked: neither Pix manual restricts the characters of the name and the city (EMV types them asans), so a name with accents is accepted, thoughpixPayload.generatefolds both to printable ASCII. - The first Merchant Account Information template (IDs 26 to 51) that carries the
br.gov.bcb.pixGUI (case-insensitive) is the one checked, and a template without the GUI is skipped. It holds exactly one of: a Pix key written in its DICT form, aspixKey.getInforeturns it (no mask, lowercase email or UUID,+55phone), optionally with the 8-digit ISPB of a Pix Saque facilitator (fss, 26-03); or a PSP location (26-25), host and path of at most 77 characters, never next to afss. The host has dot-separated labels of letters, digits and hyphens with at least one dot, and the path takes only URL path characters (no scheme, port, query string or whitespace). - Object
01is optional. When present, it must be11or12. - The amount (
54) is digits with an optional.decimal mark (98.73,98and98.are accepted), at most 2 decimals and 13 characters. Zero is accepted only in a Pix Saque (with afss) or next to a PSP location; a payload with a key alone needs an amount greater than zero. - The Additional Data Field Template (
62) with the txid (62-05) is mandatory ("sempre presente em um BR Code", §2.6). The txid is***(no txid) or 1 to 25 letters and digits (§2.6.2). So in a static payload the-of the Manual do BR Code exampleRP12345678-2019is excluded. - Next to a PSP location, only the presence of 62-05 is checked. §2.7 says a filled txid or amount in a dynamic BR Code must be ignored, so a dynamic payload with a filled 62-05 stays valid.
- Unreserved templates (IDs 80 to 99) are ignored. A composite Pix Automático QR Code that also carries a key or a payment location is read as an ordinary payload; one that carries only the recurrence, with no key or payment location, is invalid.
- 2.4.0 checked mostly the structure. It accepted a payload without
62, a txid with-,_or spaces or over 25 characters, a masked or uppercase key, a phone key without+55, a name or city over the limits, a lowercase country code, a merchant category code that is not 4 digits and an object of length00. It rejected an amount with a.and no decimals (98.). - A value that is not a string is invalid. Whitespace around the payload is ignored.
| Parameter | Type | Required |
|---|---|---|
value | string | yes |
| returns | boolean |
Check if a Pix BR Code payload (the string behind a Pix QR Code and behind "Pix copia e cola") is valid under the Manual de Padrões para Iniciação do Pix and, where it is silent, the EMV QR Code specification it builds on.
- The payload must start with the format indicator
000201. - The TLV structure, the CRC-16 and the mandatory objects (format indicator, a 4 digit category code, currency, country, merchant name and city) are checked. An object ID may not repeat at the same level, and the CRC (
63) must be the last object of the payload, not eight characters inside another one. - One "Merchant Account Information" template (IDs 26 to 51) must carry the
br.gov.bcb.pixGUI with a key (static) or a PSP URL (dynamic), never both. - The key is written in the DICT form (§2.5.1): the one
getPixKeyInforeturns unchanged, so12345678909passes and123.456.789-09does not. Whether it is registered cannot be told from the payload. The PSP URL has at most 77 characters (§2.5.2). - The merchant name has at most 25 characters and the city at most 15; the country is
BRin uppercase. Their characters are not restricted (neither manual does, and EMV types them asans), so a name with accents is accepted, thoughgeneratePixPayloadfolds both to printable ASCII. - No BCB manual states the case of the CRC or of
BR: the only case rule they give is for the GUI, and every official example writes both in uppercase. Accepting a lowercase CRC (1d3d) and rejectingbrare choices of this library, as in 2.4.0. - Object
01(Point of Initiation Method) is optional and must be11or12when present. - Object
62(Additional Data Field) is mandatory and carries thetxid(62-05), "sempre presente em um BR Code":***or 1 to 25 letters and digits (§2.6.2); with a PSP URL any value stands, since §2.7 has the payer ignore it. The-of the Manual do BR Code exampleRP12345678-2019is outside the Pix character set of §2.6.2, so that static example is rejected. - An amount (
54) is digits with an optional.and at most two decimals (98.73,98and98.are the EMV examples), at most 13 characters, and greater than zero, except in a Pix Saque BR Code (8 digitfssin sub-object 26-03) and next to a PSP location, where the Pix API gives it0.00(the Manual do BR Code lists"0"among its examples). - Unreserved Templates (IDs 80 to 99) are ignored.
import { isValidPixPayload } from '@brazilian-utils/brazilian-utils';
isValidPixPayload(
'00020126580014br.gov.bcb.pix0136123e4567-e12b-12d1-a456-426655440000' +
'5204000053039865802BR5913Fulano de Tal6008BRASILIA62070503***63041D3D'
); // true
isValidPixPayload('00020126580014br.gov.bcb.pix...'); // false (broken CRC)Source: Manual do BR Code, Manual de Padrões para Iniciação do Pix.
Code: brazilian-utils/javascriptTry it with JavaScript isValidPixPayload
Shared test cases (69) and the result in each library pixPayload.isValid
Generate
- JavaScript library
- Python library
- Go library
- Ruby library17 cases fail
- Rust library
- .NET library
- Erlang library
Generates a Pix BR Code payload. Give exactly one of a key (static) or a PSP URL (dynamic), otherwise the function returns null.
params(GeneratePixPayloadParams):keyorurl(exactly one),merchantNameandmerchantCity(required), and the optionalamount,txidanddescription. A value that is not an object returnsnull.- With
keythe payload is static (object01is left out, so it can be paid more than once) and the key is normalized aspixKey.getInfodoes. A key thatpixKey.getInforejects returnsnull, so an email key with&returnsnull. - With
urlthe payload is dynamic (Point of Initiation12) and cannot carry anamountor atxid: either returnsnull.urlis the PSP location (field 26-25): a host optionally followed by a path, no scheme (pix.example.com/qr/v2/1234), at most 77 characters. The host has dot-separated labels of letters, digits and hyphens (a hyphen never starts or ends a label) with at least one dot, and the path takes only URL path characters (a%only as the start of a percent-encoded octet,%41). A scheme (https://...), a port, a query string, whitespace, a host without a dot, or an empty or non-stringurlreturnsnull. merchantNameandmerchantCityare required:nullwhen either is missing, blank or empty after folding. They are folded to printable ASCII (accents dropped), truncated to 25 and 15 characters, and trimmed after the truncation.amountis written with two decimal places. A value that does not survive that (0.005,123.456), or that is zero, negative, not finite or longer than 13 characters once written (9999999999.99is the largest) returnsnull. Floating-point noise beyond the second decimal, as in0.1 + 0.2(written0.30), is accepted.txidis 1 to 25 letters and digits (default***, always written in field 62-05). Anything else,***included, returnsnull.descriptionloses its accents as the name and city do. It is written in field 26-02, in whatever room is left of the 99 characters of the template after the GUI and the key or URL, and never over 72 characters, trimmed after the truncation, and dropped when nothing is left.- Every payload the function returns is one
pixPayload.isValidaccepts: the key in its DICT form, the 62-05 txid always written, the name and city within their limits and an amount greater than zero, andpixPayload.getInforeads it back. - Pix Saque (
fss), unreserved templates (IDs 80 to 99) and composite Pix Automático QR Codes are never written.
| Parameter | Type | Required |
|---|---|---|
params | GeneratePixPayloadParams | yes |
params.key | string | no |
params.url | string | no |
params.merchantName | string | yes |
params.merchantCity | string | yes |
params.amount | number | no |
params.txid | string | no |
params.description | string | no |
| returns | string | null |
Generate the payload of a Pix BR Code. Exactly one of params.key or params.url must be given; null is returned when both or neither are given.
- Params (
GeneratePixPayloadParams):keyorurl,merchantName,merchantCity, and the optionalamount,txidanddescription. - With
keythe payload is static and the key is normalized bygetPixKeyInfo. Withurlit is dynamic (object01set to12) and cannot carryamountortxid. urlis a PSP location: host and path, no scheme (pix.example.com/qr/v2/1234), at most 77 characters.amounttakes two decimal places;0.005,123.456or a value that rounds to0.00is rejected.txidis 1 to 25 characters of[A-Za-z0-9](default***).merchantName,merchantCityanddescriptionlose their accents and are truncated to 25, 15 and what is left of the template.
import { generatePixPayload } from '@brazilian-utils/brazilian-utils';
generatePixPayload({
key: '123.456.789-09',
merchantName: 'Fulano de Tal',
merchantCity: 'Brasília',
amount: 123.45
});
// "00020126330014br.gov.bcb.pix0111123456789095204000053039865406123.455802BR5913Fulano de Tal6008Brasilia62070503***630479EE"
generatePixPayload({
url: 'pix.example.com/qr/v2/1234',
merchantName: 'Fulano de Tal',
merchantCity: 'Brasília'
});
// "00020101021226480014br.gov.bcb.pix2526pix.example.com/qr/v2/12345204000053039865802BR5913Fulano de Tal6008Brasilia62070503***6304FC66"
generatePixPayload({ merchantName: 'Fulano', merchantCity: 'Brasília' }); // null (neither key nor url)Source: Manual do BR Code, Manual de Padrões para Iniciação do Pix.
Code: brazilian-utils/javascriptTry it with JavaScript generatePixPayload
Shared test cases (36) and the result in each library pixPayload.generate
Decode
- JavaScript library
- Python library
- Go library26 cases fail
- Ruby library13 cases fail
- Rust library
- .NET library17 cases fail
- Erlang library
Parses a Pix BR Code payload into its fields. Returns null exactly when pixPayload.isValid returns false, never a partial result.
- Fields: merchant name and city, point of initiation (dynamic when there is a PSP location or object
01is12, static otherwise, so a key payload with01=12is dynamic) and either the key (static) or the URL (dynamic). - Amount (a number, so
98.reads as 98), txid, description (26-02) and the withdrawal facilitator of a Pix Saque (fss, the 8-digit ISPB in 26-03) are present only when the payload carries them. The***txid marker means no txid. - With a PSP location, the function leaves out the amount and the txid, as §2.7 of the manual requires ("Se preenchidos, seu conteúdo deve ser ignorado").
- Every rule of
pixPayload.isValidapplies, so a payload without object62, with a static txid outside 1 to 25 letters and digits, or with a key not in its DICT form returnsnull. 2.4.0 parsed those payloads. - A repeated object ID, a CRC that is not the last top-level object and every other rule of
pixPayload.isValidreturnnull, so the payload is never partly read. A value that is not a string returnsnull. - A composite Pix Automático QR Code that also carries a key or a payment location is read as an ordinary payload, its recurrence location dropped. Whitespace around the payload is ignored.
| Parameter | Type | Required |
|---|---|---|
value | string | yes |
| returns | PixPayloadInfo | null |
Parse a Pix BR Code payload into its fields. Accepts what isValidPixPayload accepts and returns null for anything else, never a partial result.
- Returns a
PixPayloadInfo:merchantName,merchantCity,pointOfInitiationand eitherkey(static) orurl(dynamic). amount,txid,descriptionandwithdrawalFacilitator(thefssof a Pix Saque) are present only when the payload carries them.txidis absent for the***marker.pointOfInitiation(PixPointOfInitiation) is"dynamic"when the payload carries a PSP location (a dynamic QR Code in the Pix manual, §2.4.2) or marks itself single use with object01="12"(§2.7.2),"static"otherwise. A key payload with01="12"is therefore"dynamic";urlandkeytell the two kinds of QR Code of the manual apart.- With a PSP location,
amountandtxidare ignored and left out, as §2.7 of the manual mandates ("Se preenchidos, seu conteúdo deve ser ignorado").
import { getPixPayloadInfo } from '@brazilian-utils/brazilian-utils';
getPixPayloadInfo(
'00020126580014br.gov.bcb.pix0136123e4567-e12b-12d1-a456-426655440000' +
'5204000053039865802BR5913Fulano de Tal6008BRASILIA62070503***63041D3D'
);
// {
// merchantName: 'Fulano de Tal',
// merchantCity: 'BRASILIA',
// pointOfInitiation: 'static',
// key: '123e4567-e12b-12d1-a456-426655440000'
// }Source: Manual do BR Code, Manual de Padrões para Iniciação do Pix.
Code: brazilian-utils/javascriptTry it with JavaScript getPixPayloadInfo
Shared test cases (33) and the result in each library pixPayload.getInfo
Official sources
- bcb.gov.br/content/estabilidadefinanceira/…/ManualBRCode.pdf
- bcb.gov.br/content/estabilidadefinanceira/…/II_ManualdePadroesparaIniciacaodoPix.pdf
- github.com/bacen/pix-api
- bcb.gov.br/content/estabilidadefinanceira/…/API-DICT.html
- emvco.com/terms-of-use
See also Pix key
Last updated on
