Pix copia e cola (BR Code)

O payload BR Code por trás do QR Code Pix e do Pix copia e cola.

  • Matriz de paridade

Validar

Valida o payload de um BR Code Pix contra o Manual de Padrões para Iniciação do Pix v2.10.0 e, onde o manual é omisso, o EMV QRCPS-MPM em que ele se baseia. A função verifica a forma da chave, não se ela está registrada no DICT.

  • Estrutura: TLV bem formado com todo tamanho de 01 a 99, o indicador de formato 000201 como primeiro objeto e o CRC-16 (63) como último objeto de nível superior, inteiro e conferindo com o payload. Oito caracteres finais que só parecem 6304 e um checksum (dentro de outro objeto, por exemplo) não contam como o CRC. Um CRC em hexadecimal minúsculo é aceito, como na 2.4.0 (nenhuma fonte oficial define maiúsculas ou minúsculas).
  • Um ID de objeto não pode se repetir no mesmo nível (o EMV dá a cada objeto um ID por nível), quaisquer que sejam os valores, mesmo com um CRC que confere. Até a 2.4.0 o último ID repetido prevalecia. Só payloads forjados repetem um ID.
  • Objetos obrigatórios: código de categoria (52) com 4 dígitos, moeda (53) 986, país (58) BR em maiúsculas, nome do recebedor (59) com no máximo 25 caracteres e cidade (60) com no máximo 15. Só o tamanho é verificado: nenhum dos manuais do Pix restringe os caracteres do nome e da cidade (o EMV os classifica como ans), então um nome com acentos é aceito, embora pixPayload.generate reduza ambos a ASCII imprimível.
  • O primeiro template Merchant Account Information (IDs 26 a 51) que traz o GUI br.gov.bcb.pix (sem diferenciar maiúsculas de minúsculas) é o verificado, e um template sem o GUI é ignorado. Ele contém exatamente um entre: uma chave Pix na forma do DICT, como pixKey.getInfo a retorna (sem máscara, e-mail ou UUID em minúsculas, telefone com +55), opcionalmente com o ISPB de 8 dígitos de um facilitador de Pix Saque (fss, 26-03); ou uma location do PSP (26-25), host e caminho com no máximo 77 caracteres, nunca junto de um fss. O host tem rótulos separados por ponto, com letras, dígitos e hífens, e ao menos um ponto, e o caminho aceita só caracteres de caminho de URL (sem esquema, porta, query string ou espaço em branco).
  • O objeto 01 é opcional. Quando presente, deve ser 11 ou 12.
  • O valor (54) tem dígitos com um . decimal opcional (98.73, 98 e 98. são aceitos), no máximo 2 casas e 13 caracteres. Zero só é aceito em um Pix Saque (com fss) ou junto de uma location do PSP; um payload só com chave precisa de valor maior que zero.
  • O Additional Data Field Template (62) com o txid (62-05) é obrigatório ("sempre presente em um BR Code", §2.6). O txid é *** (sem txid) ou de 1 a 25 letras e dígitos (§2.6.2). Assim, num payload estático o - do exemplo do Manual do BR Code RP12345678-2019 fica excluído.
  • Junto de uma location do PSP, só a presença do 62-05 é verificada. O §2.7 diz que txid ou valor preenchidos num BR Code dinâmico devem ser ignorados, então um payload dinâmico com 62-05 preenchido continua válido.
  • Templates não reservados (IDs 80 a 99) são ignorados. Um QR Code composto do Pix Automático que também traz uma chave ou uma location de pagamento é lido como um payload comum; um que traz só a recorrência, sem chave nem location de pagamento, é inválido.
  • A 2.4.0 verificava sobretudo a estrutura. Aceitava payload sem 62, txid com -, _ ou espaços ou com mais de 25 caracteres, chave com máscara ou em maiúsculas, chave de telefone sem +55, nome ou cidade acima dos limites, código de país em minúsculas, código de categoria que não tem 4 dígitos e objeto com tamanho 00. Rejeitava um valor com . e sem decimais (98.).
  • Um valor que não é string é inválido. Espaços nas pontas do payload são ignorados.
ParâmetroTipoObrigatório
valuestringsim
retornaboolean

Valida um payload de BR Code Pix (a string por trás de um QR Code Pix e do "Pix copia e cola") pelo Manual de Padrões para Iniciação do Pix e, onde ele é omisso, pela especificação EMV de QR Code em que ele se apoia.

  • O payload precisa começar pelo format indicator 000201.
  • A estrutura TLV, o CRC-16 e os objetos obrigatórios (format indicator, category code de 4 dígitos, moeda, país, nome e cidade do recebedor) são verificados. Um ID de objeto não pode se repetir no mesmo nível, e o CRC (63) precisa ser o último objeto do payload, não oito caracteres dentro de outro.
  • Um template "Merchant Account Information" (IDs 26 a 51) precisa trazer o GUI br.gov.bcb.pix com uma chave (estático) ou a URL do PSP (dinâmico), nunca os dois.
  • A chave vem na forma do DICT (§2.5.1): a que getPixKeyInfo devolve sem mudar, então 12345678909 passa e 123.456.789-09 não. Se ela está registrada não dá para saber pelo payload. A URL do PSP tem no máximo 77 caracteres (§2.5.2).
  • O nome do recebedor tem no máximo 25 caracteres e a cidade no máximo 15; o país é BR em maiúsculas. Os caracteres deles não são restritos (nenhum dos manuais restringe, e o EMV os tipa como ans), então um nome com acento é aceito, embora generatePixPayload reduza os dois a ASCII imprimível.
  • Nenhum manual do BCB diz se o CRC ou o BR podem estar em minúsculas: a única regra de caixa que eles dão é a do GUI, e todos os exemplos oficiais escrevem os dois em maiúsculas. Aceitar CRC em minúsculas (1d3d) e rejeitar br são escolhas desta biblioteca, como na 2.4.0.
  • O objeto 01 (Point of Initiation Method) é opcional e precisa ser 11 ou 12 quando presente.
  • O objeto 62 (Additional Data Field) é obrigatório e traz o txid (62-05), "sempre presente em um BR Code": *** ou de 1 a 25 letras e dígitos (§2.6.2); com URL do PSP qualquer valor vale, já que o §2.7 manda o pagador ignorá-lo. O - do exemplo RP12345678-2019 do Manual do BR Code está fora do conjunto de caracteres do Pix do §2.6.2, então esse exemplo estático é rejeitado.
  • Um valor (54) é feito de dígitos com um . opcional e no máximo duas casas decimais (98.73, 98 e 98. são os exemplos do EMV), com no máximo 13 caracteres, e maior que zero, exceto num BR Code de Pix Saque (fss de 8 dígitos no subobjeto 26-03) e junto de uma URL do PSP, em que a API Pix lhe dá 0.00 (o Manual do BR Code traz "0" entre os exemplos).
  • Os Unreserved Templates (IDs 80 a 99) são ignorados.
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 (CRC quebrado)

Fonte: Manual do BR Code, Manual de Padrões para Iniciação do Pix.

Código: brazilian-utils/javascript
Teste com JavaScript isValidPixPayload
As entradas começam com o primeiro caso compartilhado. Mude uma para ver o novo resultado.

Roda @brazilian-utils/brazilian-utils 2.5.0 no seu navegador.

Casos de teste compartilhados (69) e o resultado em cada biblioteca pixPayload.isValid

Gerar

Gera o payload de um BR Code Pix. Informe exatamente uma chave (estático) ou uma URL do PSP (dinâmico). Caso contrário, a função retorna null.

  • params (GeneratePixPayloadParams): key ou url (exatamente um), merchantName e merchantCity (obrigatórios) e, opcionalmente, amount, txid e description. Um valor que não é objeto retorna null.
  • Com key o payload é estático (o objeto 01 fica de fora, então ele pode ser pago mais de uma vez) e a chave é normalizada como pixKey.getInfo faz. Uma chave que pixKey.getInfo rejeita retorna null, então uma chave de e-mail com & retorna null.
  • Com url o payload é dinâmico (Point of Initiation 12) e não pode trazer amount nem txid: qualquer um dos dois retorna null. url é a location do PSP (campo 26-25): um host seguido opcionalmente de um caminho, sem esquema (pix.example.com/qr/v2/1234), com no máximo 77 caracteres. O host tem rótulos separados por ponto, com letras, dígitos e hífens (um hífen nunca abre nem fecha um rótulo), e ao menos um ponto, e o caminho aceita só caracteres de caminho de URL (um % só como início de um octeto codificado, %41). Um esquema (https://...), uma porta, uma query string, espaço em branco, um host sem ponto, ou uma url vazia ou que não é string, retorna null.
  • merchantName e merchantCity são obrigatórios: null quando um deles falta, está em branco ou fica vazio após a redução. Eles são reduzidos a ASCII imprimível (sem acentos), truncados em 25 e 15 caracteres e, depois do truncamento, ficam sem espaços nas pontas.
  • amount é escrito com duas casas decimais. Um valor que não sobrevive a isso (0.005, 123.456), ou que é zero, negativo, não finito ou maior que 13 caracteres depois de escrito (9999999999.99 é o maior) retorna null. O ruído de ponto flutuante depois da segunda casa, como em 0.1 + 0.2 (escrito 0.30), é aceito.
  • txid tem de 1 a 25 letras e dígitos (padrão ***, sempre escrito no campo 62-05). Qualquer outra coisa, *** inclusive, retorna null.
  • description perde os acentos como o nome e a cidade. Ela é escrita no campo 26-02, no espaço que sobra dos 99 caracteres do template depois do GUI e da chave ou URL, e nunca com mais de 72 caracteres, sem espaços nas pontas depois do truncamento, e é descartada quando não sobra nada.
  • Todo payload que a função retorna é aceito por pixPayload.isValid: a chave na forma do DICT, o txid 62-05 sempre escrito, nome e cidade dentro dos limites e um valor maior que zero, e pixPayload.getInfo o lê de volta.
  • Pix Saque (fss), templates não reservados (IDs 80 a 99) e QR Codes compostos do Pix Automático nunca são escritos.
ParâmetroTipoObrigatório
paramsGeneratePixPayloadParamssim
params.keystringnão
params.urlstringnão
params.merchantNamestringsim
params.merchantCitystringsim
params.amountnumbernão
params.txidstringnão
params.descriptionstringnão
retornastring | null

Gera o payload de um BR Code Pix. Exatamente um entre params.key e params.url deve ser informado; null é retornado quando ambos ou nenhum são informados.

  • Parâmetros (GeneratePixPayloadParams): key ou url, merchantName, merchantCity e os opcionais amount, txid e description.
  • Com key o payload é estático e a chave é normalizada por getPixKeyInfo. Com url é dinâmico (objeto 01 definido como 12) e não pode carregar amount nem txid.
  • url é uma localização de PSP: host e caminho, sem esquema (pix.example.com/qr/v2/1234), com no máximo 77 caracteres.
  • amount recebe duas casas decimais; 0.005, 123.456 ou um valor que arredonda para 0.00 é rejeitado.
  • txid tem de 1 a 25 caracteres de [A-Za-z0-9] (padrão ***).
  • merchantName, merchantCity e description perdem os acentos e são truncados a 25, 15 e o que sobra do 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 (nem key nem url)

Fonte: Manual do BR Code, Manual de Padrões para Iniciação do Pix.

Código: brazilian-utils/javascript
Teste com JavaScript generatePixPayload
As entradas começam com o primeiro caso compartilhado. Mude uma para ver o novo resultado.

Roda @brazilian-utils/brazilian-utils 2.5.0 no seu navegador.

Casos de teste compartilhados (36) e o resultado em cada biblioteca pixPayload.generate

Decodificar

Decompõe o payload de um BR Code Pix em seus campos. Retorna null exatamente quando pixPayload.isValid retorna false, nunca um resultado parcial.

  • Campos: nome e cidade do recebedor, point of initiation (dinâmico quando há uma location do PSP ou o objeto 01 é 12, estático nos outros casos, então um payload com chave e 01 = 12 é dinâmico) e a chave (estático) ou a URL (dinâmico).
  • Valor (um número, então 98. é lido como 98), txid, descrição (26-02) e o facilitador de saque de um Pix Saque (fss, o ISPB de 8 dígitos em 26-03) só aparecem quando o payload os traz. O marcador de txid *** significa sem txid.
  • Com uma location do PSP, a função deixa de fora o valor e o txid, como o §2.7 do manual exige ("Se preenchidos, seu conteúdo deve ser ignorado").
  • Todas as regras de pixPayload.isValid valem, então um payload sem o objeto 62, com txid estático fora de 1 a 25 letras e dígitos ou com chave fora da forma do DICT retorna null. A 2.4.0 decompunha esses payloads.
  • Um ID de objeto repetido, um CRC que não é o último objeto de nível superior e toda outra regra de pixPayload.isValid retornam null, então o payload nunca é lido em parte. Um valor que não é string retorna null.
  • Um QR Code composto do Pix Automático que também traz uma chave ou uma location de pagamento é lido como um payload comum, sem a location da recorrência. Espaços nas pontas do payload são ignorados.
ParâmetroTipoObrigatório
valuestringsim
retornaPixPayloadInfo | null

Interpreta um payload de BR Code Pix e retorna seus campos. Aceita o que isValidPixPayload aceita; para o resto retorna null, nunca um resultado parcial.

  • Retorna um PixPayloadInfo: merchantName, merchantCity, pointOfInitiation e key (estático) ou url (dinâmico).
  • amount, txid, description e withdrawalFacilitator (o fss do Pix Saque) só aparecem quando o payload os traz; txid fica ausente para o marcador ***.
  • pointOfInitiation (PixPointOfInitiation) é "dynamic" quando o payload traz uma localização de PSP (o QR Code dinâmico do manual do Pix, §2.4.2) ou se marca como de uso único com o objeto 01 = "12" (§2.7.2); senão, "static". Um payload com chave e 01 = "12" é, portanto, "dynamic"; url e key distinguem os dois tipos de QR Code do manual.
  • Com localização de PSP, amount e txid são ignorados e ficam de fora, como manda o §2.7 do manual ("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'
// }

Fonte: Manual do BR Code, Manual de Padrões para Iniciação do Pix.

Código: brazilian-utils/javascript
Teste com JavaScript getPixPayloadInfo
As entradas começam com o primeiro caso compartilhado. Mude uma para ver o novo resultado.

Roda @brazilian-utils/brazilian-utils 2.5.0 no seu navegador.

Casos de teste compartilhados (33) e o resultado em cada biblioteca pixPayload.getInfo

Fontes oficiais

Veja também Chave Pix

Atualizado em

Nesta página