bacen / pix-api

API Pix: a API do Arranjo de Pagamentos Instantâneos Brasileiro, Pix, criado pelo Banco Central do Brasil.
https://bacen.github.io/pix-api
2.3k stars 262 forks source link

Validação do CRC 16 e EMV #189

Open felipecamargo opened 3 years ago

felipecamargo commented 3 years ago

Percebi que muitos QR CODE estão sendo enviados com CRC 16 calculado invalido. E pouquíssimos PSP's pagadores estão validando tanto o CRC16 quanto o padrão do EMV Merchant Presented Mode como um todo.

Quanto a Estrutura EMV, pelo que eu observei não estão sendo validados:

A maioria dos PSPs estão aceitando QR CODEs conforme listado abaixo, provavelmente os único bancos que estão tentando realizar as consistências do Padrão EMV e também dos certificados dos sites QR CODE dinâmico são Itaú e Banco do Brasil.

Exemplo:

  1. Iniciado de forma incorreta >>> 0020101021226990014br.gov.bcb.pix2577qrcode.pix.bancobmg.com.br/qrs1/01mWFiCMHqRMdrkzWFWazsiurgfoqpsJFbuXx3IcpRqfj52040000530398654040.015802BR5917JEFFERSON F SOUZA6009SAO PAULO62290525QRS1-F5CMMUTDLOVWF8UBT7Q4630413DF -> calculado errado deveria ser 2E7D

  2. Mal formatado 000201 2640 0014BR.GOV.BCB.PIX 0114+55149916479660200 52040000 5303986 54030.05 802BR5921JULIO DE SOUZA RUGOLO6009SAO.PAULO6238050050300017BR.GOV.BCB.BRCODE01051.0.06304BD79

  3. CRC 16 invalido 00020126360014BR.GOV.BCB.PIX0114+55339999117485204000053039865802BR5924LEANDRO ALVES PEREIRA 6009SAO.PAULO623450300017BR.GOV.BCB.BRCODE01051.0.063044867 -> deveria ser C3F4.

  4. Mal formatado 000201 010212 2641 0005Cielo< deveria ser indicação de BR CODE -> 14br.gov.bcb.pix 0116001019064975000102087748103252040000530398654120000000031005802BR5921AUTO POSTO BASE AEREA6011CURITIBA PR801010033"https://www.cielo.com.br/qrcode"0116111117082C14677A0212171120183512030420000404000105020106020163043256

  5. Mal formatado 000201 2653 0014BR.GOV.BCB.PIX 0127takeshinho2001@yahoo.com.br 0200 tamanho 00 não é permitido pelo padrão EMV. 52040000530398654030.05802BR5922ANTONIO TAKESHI FUKUDA6009SAO.PAULO6238050050300017BR.GOV.BCB.BRCODE01051.0.063045B1A

  6. Merchant Name 000201 2636 0014br.gov.bcb.pix 0114+5531998925047 52040000 5303986 54071000.00 5802BR 5938SUELI DO CARMO PEREIRA DA SILVA KUSTER -- Limite de 25 caracteres 6008CONTAGEM 6241 0503*** 5030 0017br.gov.bcb.brcode 01051.0.0 63049602

  7. Mal Formatado (nubank) 000201 2662 0014BR.GOV.BCB.PIX 013639b6c11f-8383-4378-87c1-ce62df204ab8 0200 <<< NÃO PODE SER TAMANHO 00 5204000053039865406127.505802BR5925LARISSA JUSTUS RAYMUNDO 36009SAO PAULO61080540900062160512NUomZK5qzGvA630440BB

  8. Mal Formatado (nubank) 000201 2672 0014BR.GOV.BCB.PIX 18 01366ae8a1ab-8a46-49ef-9a14-6b03df474f6a 40 0210Toma lim㯵2 040000 530398654046.005802BR5924F D C HUMMEL EIRELI - ME6009SAO PAULO61080540900062160512NUNFFQwm3oLJ63040974

ninrod commented 3 years ago

Percebi que muitos QR CODE estão sendo enviados com CRC 16 calculado invalido. E pouquíssimos PSP's pagadores estão validando tanto o CRC16 quanto o padrão do EMV Merchant Presented Mode como um todo.

Quanto a Estrutura EMV, pelo que eu observei não estão sendo validados:

Reference label até 25 caracteres. Merchant Name até 25 caracteres. City Name até 15 caracteres.

@felipecamargo , obrigado pelo reporte.

dmkamers commented 3 years ago

@felipecamargo Aproveito a issue, muito bem colocada, para agregar algumas informações pertinentes:

  1. Mal formatado 2641 00-05 Cielo **< deveria ser indicação de BR CODE -> 14br.gov.bcb.pix 01-16 0010190649750001 02-08 77481032

Isso parece ser um BRCode contendo um 'rail' do tipo "Cielo" (os campos '01e '02 que seguem nao parecem ter relação com o Pix mesmo). Neste caso, esse formato de GUI EMV Cielo estaria errado de fato (pela especificação EMV). EDIT3: nao esta errado, se Cielo for um ApplicationId registrado (mas está fora do contexto Pix, nao se validam outros rails; cada um faz a sua parte).

EDIT: não se espera que os campos 01, 02, desse arranjo Cielo sejam Pix-like... um pagador Pix, ao ler este QR, deveria ignorar tudo o que está abaixo desse objeto 26 no exemplo (caso esteja esperando pagar um Pix). Apenas um pagador Cielo vai ler e entender o que vem ali.

EDIT2: um Pix poderia conviver perfeitamente no mesmo BRCode, mas estaria sob um objeto 27..., e etc.

  1. Merchant Name ... 6241 0503*** 50-30 00-17 br.gov.bcb.brcode 01-05 1.0.0

Neste (e em varios outros casos) aparece esse objeto 50 (sob o template 62). Isto não existe (gui br.gov.bcb.brcode, versão 1.0.0), não deve ser utilizado (versão obsoleta do manual BRCode).

jeansentose commented 3 years ago

Pessoal, boa tarde!

Alguém poderia dar uma idéia de como calcular o CRC16?

Agradeço!

cryptographix commented 3 years ago

Pessoal, boa tarde!

Alguém poderia dar uma idéia de como calcular o CRC16?

Agradeço!

@jeansentose tem várias bibliotecas em linguagens diversas no github.

Tem uma rotina neste link, em typescript (javascript++), fácil de converter para a tua linguagem de estimação.

https://github.com/NascentSecureTech/pix-qrcode-utils/blob/master/packages/emv-merchant-qrcode/src/crc.ts

cryptographix commented 3 years ago

@jeansentose depois se quiser, pode copie e cola a string que gerou aqui neste site para validação.

jeansentose commented 3 years ago

@jeansentose depois se quiser, pode copie e cola a string que gerou aqui neste site para validação.

Valeu, meu amigo !! Agradeço o apoio !!

jeansentose commented 3 years ago

Pessoal, boa tarde! Alguém poderia dar uma idéia de como calcular o CRC16? Agradeço!

@jeansentose tem várias bibliotecas em linguagens diversas no github.

Tem uma rotina neste link, em typescript (javascript++), fácil de converter para a tua linguagem de estimação.

https://github.com/NascentSecureTech/pix-qrcode-utils/blob/master/packages/emv-merchant-qrcode/src/crc.ts

@SeanWykes Só uma dúvida... qual o campo que ele usa para validar? Digo, a posição que ele usa como base...

cryptographix commented 3 years ago

Então, acabei de gerar um QR estático pelo site gerarpix.com.br, assim: 00020126330014BR.GOV.BCB.PIX01112178262481352040000530398654041.005802BR5902me6009somewhere62130509pagamento6304C3A7

Quebrando em tags (incluí espaços, indentação e quebras de linha para melhorar a leitura), tem: 0002 01 2633 .... 0014 BR.GOV.BCB.PIX .... 0111 21782624813 5204 0000 5303 986 5404 1.00 5802 BR 5902 me 6009 somewhere 6213 .... 0509 pagamento 6304 C3A7

Observe a última tag 63, de tamanho 04. O CRC deve ser calculado do início da string do QR até, e incluindo, o 6304.

Neste exemplo, calcula-se o CRC sobre 00020126330014BR.GOV.BCB.PIX01112178262481352040000530398654041.005802BR5902me6009somewhere62130509pagamento6304

No final, concatena o CRC, que tem 16 bits / 2 bytes, como 4 caracteres HEXA (com padding de "0" em cada byte).

A página que passei tem um botão para recalcular o CRC (mas é preciso que a estrutura de tags seja válida)

jeansentose commented 3 years ago

Valeu meu querido !! Agradeço muito a ajuda !!

alexandresanlim commented 3 years ago

Valeu meu querido !! Agradeço muito a ajuda !!

Você conseguiu gerar? se sim para qual linguagem? não estou conseguindo gerar em c# :/

cryptographix commented 3 years ago

@alexandresanlim pode usar este site para validar a sua geração. A tela também gera QR estático e dinâmico, e pode regerar o CRC correto para um QR.

Em C# tem várias libs no github, como por exemplo https://github.com/juanroman-zz/emvqr

alexandresanlim commented 3 years ago

@alexandresanlim pode usar este site para validar a sua geração. A tela também gera QR estático e dinâmico, e pode regerar o CRC correto para um QR.

Em C# tem várias libs no github, como por exemplo https://github.com/juanroman-zz/emvqr

Hoje pela manhã eu finalmente consegui tendo o seu código em TypeScript como base, o resultado esta aqui. Muito obrigado pela resposta!

vitorgsoares commented 3 years ago

Pessoal, boa tarde! Alguém poderia dar uma idéia de como calcular o CRC16? Agradeço!

@jeansentose tem várias bibliotecas em linguagens diversas no github.

Tem uma rotina neste link, em typescript (javascript++), fácil de converter para a tua linguagem de estimação.

https://github.com/NascentSecureTech/pix-qrcode-utils/blob/master/packages/emv-merchant-qrcode/src/crc.ts

@jeansentose Eu utilizo PHP para gerar o QRCODE.

A funcao que utilizo é: function crc16($string) { $CRC16POLINOMIO = 0x1021; $result = 0xFFFF; if (($length = strlen($string)) > 0) { for ($offset = 0; $offset < $length; $offset++) { $result ^= (ord($string[$offset]) << 8); for ($bitwise = 0; $bitwise < 8; $bitwise++) { if (($result <<= 1) & 0x10000) $result ^= $CRC16POLINOMIO; $result &= 0xFFFF; } } } return $result; } $CRC16 = crc16($stringPix); //Nessa string deve conter o final "6304" $CRC16 = dechex($CRC16); //transformo de decimal para hexadecimal $CRC16 = strtoupper($CRC16); //Transformo para maiusculas

Estou trabalhando em um conversor online. O exemplo está no link https://showcommerce.com.br/pix

ghost commented 3 years ago

Pessoal estou enroscado aqui com o CRC16 minha string esta tudo OK mas o calculo do CRC16 não bate de jeito nenhum, uso Delphi, baixei algumas função de calculo de CRC16 mas nada esta dando certo, alguém ai que trabalhe com Delphi e já tenha passado por esse problema, pra me fazer um Freelance aqui. obrigado meu contato WhatsApp (42) 9 8403-0313 - Sergio.

uso essas funções se sucesso: function Crc16(texto: string; Polynom: WORD = $1021; Seed: WORD = $FFFF): WORD; var i, j: Integer; begin Result := Seed; for i := 1 to length(texto) do begin Result := Result xor (ord(texto[i]) shl 8); for j := 0 to 7 do begin if (Result and $8000) <> 0 then Result := (Result shl 1) xor Polynom else Result := Result shl 1; end; end; Result := Result and $FFFF; end;

function Crc16(texto: string): WORD; const polynomial = $1021; var crc: WORD; i, j: Integer; b: Byte; bit, c15: Boolean; begin crc := $FFFF; for i := 1 to length(texto) do begin b := Byte(texto[i]); for j := 0 to 7 do begin bit := (((b shr (7 - j)) and 1) = 1); c15 := (((crc shr 15) and 1) = 1); crc := crc shl 1; if (c15 xor bit) then crc := crc xor polynomial; end; end; Result := crc and $FFFF; end;

aslsoftware commented 3 years ago

Fala ai blz, em delphi estou gerando desta forma.

function CRC16CCITT(texto: string): WORD; const polynomial = $1021; var crc: WORD; i, j: Integer; b: Byte; bit, c15: Boolean; begin crc := $FFFF; for i := 1 to length(texto) do begin b := Byte(texto[i]); for j := 0 to 7 do begin bit := (((b shr (7 - j)) and 1) = 1); c15 := (((crc shr 15) and 1) = 1); crc := crc shl 1; if (c15 xor bit) then crc := crc xor polynomial; end; end; Result := crc and $FFFF; end;

e chamo a função desta forma.

inttohex(CRC16CCITT(minhachave),4);

Testei em diversos bancos só o Itau que estou dependendo do gerente descobrir lá onde libera kkkk.

renatofrota commented 3 years ago

Testei em diversos bancos só o Itau que estou dependendo do gerente descobrir lá onde libera kkkk.

https://github.com/renatofrota/pix-pendencias/issues/26

GabrielPaixaoJustino commented 3 years ago

Boa tarde Pessoal, estou tentando gerar meu calculo CRC16 através de uma função criada no SQL. Mas o calculo não está retornando da maneira esperada, conseguem dar uma força? Ou identificar algo que não estou conseguindo na minha função. Segue a fórmula abaixo: `` ALTER FUNCTION [dbo].[CRC16] ( @input varchar(max) ) RETURNS int WITH SCHEMABINDING AS BEGIN DECLARE @crc bigint = 0xffff , @result int ; SELECT @crc = dbo.CRC16calc(@crc, Ascii(Substring(@input, v.id, 1))) FROM dbo.IndexTable(1, LEN(@input)) AS v ORDER BY v.Id ; SET @result = UPPER(CONVERT(int, CONVERT(VARBINARY(4), ~@crc))) ; RETURN @result ; END

Abaixo estão as informações que estão sendo calculadas: 01 12 0014br.gov.bcb.pix2572qrpix.bradesco.com.br/qr/v2/62d42bf-848854-ba0e-f877d54475663e2b52f5-4b5 0000 986 1.00 BR SIRICOMERCIOESERVICOSLTDA SAOPAULO 0515DF06B1AAD182021 A2DA

renatofrota commented 3 years ago

Abaixo estão as informações que estão sendo calculadas: 01 12 0014br.gov.bcb.pix2572qrpix.bradesco.com.br/qr/v2/62d42bf-848854-ba0e-f877d54475663e2b52f5-4b5 0000 986 1.00 BR SIRICOMERCIOESERVICOSLTDA SAOPAULO 0515DF06B1AAD182021 A2DA

Não sei se entendi exatamente o que você está tentando fazer. Você está tentando validar o CRC de um QR Code diretamente no SQL? Esses valores que você mencionou não são um BR Code completo. As informações estão sem os IDs dos "templates" EMV e seus tamanhos.

Por ex: o primeiro valor, 01, provavelmente deveria ser 000201 (template 00, tamanho 02, valor 01). Depois o valor 12, deveria ser 010212 (template 01, tamanho 02, valor 12). E assim por diante.

GabrielPaixaoJustino commented 3 years ago

Abaixo estão as informações que estão sendo calculadas: 01 12 0014br.gov.bcb.pix2572qrpix.bradesco.com.br/qr/v2/62d42bf-848854-ba0e-f877d54475663e2b52f5-4b5 0000 986 1.00 BR SIRICOMERCIOESERVICOSLTDA SAOPAULO 0515DF06B1AAD182021 A2DA

Não sei se entendi exatamente o que você está tentando fazer. Você está tentando validar o CRC de um QR Code diretamente no SQL? Esses valores que você mencionou não são um BR Code completo. As informações estão sem os IDs dos "templates" EMV e seus tamanhos.

Por ex: o primeiro valor, 01, provavelmente deveria ser 000201 (template 00, tamanho 02, valor 01). Depois o valor 12, deveria ser 010212 (template 01, tamanho 02, valor 12). E assim por diante.

Na verdade ele possui os tamanhos de forma correta, esse foi só um exemplo que passei das infos, segue abaixo minha string que está sendo gerada.

00020101021226940014br.gov.bcb.pix2572qrpix.bradesco.com.br/qr/v2/62d42bf-848854-ba0e-f877d54475663e2b52f5-4b552040000530398654041.005802BR5925SIRICOMERCIOESERVICOSLTDA6008SAOPAULO62190515F8F0E7A863120216304461A

Seu jogar essa string no validador ele retorna a seguinte mensagem: ERROR - Invalid CRC, clicando em FIX CRC, ele passa...

renatofrota commented 3 years ago

O CRC deve ser calculado em cima de:

00020101021226940014br.gov.bcb.pix2572qrpix.bradesco.com.br/qr/v2/62d42bf-848854-ba0e-f877d54475663e2b52f5-4b552040000530398654041.005802BR5925SIRICOMERCIOESERVICOSLTDA6008SAOPAULO62190515F8F0E7A863120216304

que é "tudo menos o próprio CRC" (inclusive o 6304, que é o template ID 63, tamanho 04) e resulta em 8119 (diferente do seu resultado, 461A).

dmkamers commented 3 years ago

qrCode.ods Se dá pra fazer em planilha, deve dar pra fazer em sql... :)

GabrielPaixaoJustino commented 3 years ago

O CRC deve ser calculado em cima de:

00020101021226940014br.gov.bcb.pix2572qrpix.bradesco.com.br/qr/v2/62d42bf-848854-ba0e-f877d54475663e2b52f5-4b552040000530398654041.005802BR5925SIRICOMERCIOESERVICOSLTDA6008SAOPAULO62190515F8F0E7A863120216304

que é "tudo menos o próprio CRC" (inclusive o 6304, que é o template ID 63, tamanho 04) e resulta em 8119 (diferente do seu resultado, 461A).

Sim, já estou fazendo isso. Por isso que estou achando que existe algum problema na minha função, pois já estou contemplando a string exatamente dessa maneira, segue o trecho da minha função em SQL.

ALTER FUNCTION [dbo].[CRC16] ( @input varchar(max) ) RETURNS int WITH SCHEMABINDING AS BEGIN DECLARE @Crc bigint = 0xffff , @Result int ; SELECT @Crc = dbo.CRC16calc(@Crc, Ascii(Substring(@input, v.id, 1))) FROM dbo.IndexTable(1, LEN(@input)) AS v ORDER BY v.Id ; SET @Result = UPPER(CONVERT(int, CONVERT(VARBINARY(4), ~@Crc))) ; RETURN @Result ; END

renatofrota commented 3 years ago

Acho que é porque você está fazendo UPPER() depois do cálculo CRC ser realizado (a alteração de caixa invalida o CRC).

GabrielPaixaoJustino commented 3 years ago

Acho que é porque você está fazendo UPPER() depois do cálculo CRC ser realizado (a alteração de caixa invalida o CRC).

Esse teste eu realizei depois Renato, mesmo sem o Upper não funciona...

renatofrota commented 3 years ago

Eu não manjo tanto assim de SQL.

O input que tá sendo passado pra função que calcula o CRC é a string 00020101021226940014br.gov.bcb.pix2572qrpix.bradesco.com.br/qr/v2/62d42bf-848854-ba0e-f877d54475663e2b52f5-4b552040000530398654041.005802BR5925SIRICOMERCIOESERVICOSLTDA6008SAOPAULO62190515F8F0E7A863120216304 ?

GabrielPaixaoJustino commented 3 years ago

Eu não manjo tanto assim de SQL.

O input que tá sendo passado pra função que calcula o CRC é a string 00020101021226940014br.gov.bcb.pix2572qrpix.bradesco.com.br/qr/v2/62d42bf-848854-ba0e-f877d54475663e2b52f5-4b552040000530398654041.005802BR5925SIRICOMERCIOESERVICOSLTDA6008SAOPAULO62190515F8F0E7A863120216304 ?

Isso mesmo. De qualquer forma, obrigado pela força.

renatofrota commented 3 years ago

É MySQL? Ou outro banco?

Achei essa resposta no SO que pode ser útil: https://stackoverflow.com/a/63901938/2847575

renatofrota commented 3 years ago

E essa pra SQL Server: https://pt.stackoverflow.com/questions/485228/como-converter-uma-fun%C3%A7%C3%A3o-crc16-em-mysql-para-sql-server (a resposta é direcionada ao Pix, inclusive).

admsilva commented 3 years ago

Boa tarde a todos,

Segue solução que estou utilizando em PL/SQL:

CREATE OR REPLACE FUNCTION CRC16(V_STRING VARCHAR2) RETURN VARCHAR2 IS CURSOR C_BYTES (PIX_STRING VARCHAR2) IS SELECT TO_NUMBER(COLUMN_VALUE) AS BYTES FROM XMLTABLE( SUBSTR( DUMP(PIX_STRING), INSTR( DUMP(PIX_STRING), ':' )+1 ) );

C NUMBER; J NUMBER;

V_ANSWER VARCHAR2(4000) := 'FFFF'; V_POLINOMIO VARCHAR2(4) := '1021';

V_VERIFY NUMBER;

V_ID_CRC16 CHAR(2) := '63'; V_QTD_CRC16 CHAR(2) := '04'; BEGIN FOR R_BYTES IN C_BYTES(V_STRING||V_ID_CRC16||V_QTD_CRC16) LOOP C := R_BYTES.BYTES;

  IF (C_BYTES%ROWCOUNT = 1) THEN
    V_ANSWER := TO_NUMBER(V_ANSWER, 'XXXX');
  END IF;

  J := (C * POWER(2,8));
  V_ANSWER := (J + V_ANSWER) - BITAND(J, V_ANSWER) * 2;

  FOR BITWISE IN 0..7 LOOP
    V_ANSWER := V_ANSWER * POWER(2,1);
    V_VERIFY := BITAND(V_ANSWER, TO_NUMBER('10000', 'XXXXX'));

    IF (V_VERIFY <> 0) THEN
      V_ANSWER := (V_ANSWER + TO_NUMBER(V_POLINOMIO, 'XXXX')) - BITAND(V_ANSWER, TO_NUMBER(V_POLINOMIO, 'XXXX')) * 2;
    END IF;

    V_ANSWER := BITAND(V_ANSWER,  TO_NUMBER('FFFF', 'XXXX'));
  END LOOP;
END LOOP;

RETURN V_ID_CRC16||V_QTD_CRC16||TRIM(TO_CHAR(V_ANSWER, 'XXXX'));

END CRC16;

Estou utilizando Oracle Database 11g Release 11.2.0.4.0 - 64bit Production.

Att,

GabrielPaixaoJustino commented 3 years ago

Boa tarde a todos,

Segue solução que estou utilizando em PL/SQL:

CREATE OR REPLACE FUNCTION CRC16(V_STRING VARCHAR2) RETURN VARCHAR2 IS CURSOR C_BYTES (PIX_STRING VARCHAR2) IS SELECT TO_NUMBER(COLUMN_VALUE) AS BYTES FROM XMLTABLE( SUBSTR( DUMP(PIX_STRING), INSTR( DUMP(PIX_STRING), ':' )+1 ) );

C NUMBER; J NUMBER;

V_ANSWER VARCHAR2(4000) := 'FFFF'; V_POLINOMIO VARCHAR2(4) := '1021';

V_VERIFY NUMBER;

V_ID_CRC16 CHAR(2) := '63'; V_QTD_CRC16 CHAR(2) := '04'; BEGIN FOR R_BYTES IN C_BYTES(V_STRING||V_ID_CRC16||V_QTD_CRC16) LOOP C := R_BYTES.BYTES;

  IF (C_BYTES%ROWCOUNT = 1) THEN
    V_ANSWER := TO_NUMBER(V_ANSWER, 'XXXX');
  END IF;

  J := (C * POWER(2,8));
  V_ANSWER := (J + V_ANSWER) - BITAND(J, V_ANSWER) * 2;

  FOR BITWISE IN 0..7 LOOP
    V_ANSWER := V_ANSWER * POWER(2,1);
    V_VERIFY := BITAND(V_ANSWER, TO_NUMBER('10000', 'XXXXX'));

    IF (V_VERIFY <> 0) THEN
      V_ANSWER := (V_ANSWER + TO_NUMBER(V_POLINOMIO, 'XXXX')) - BITAND(V_ANSWER, TO_NUMBER(V_POLINOMIO, 'XXXX')) * 2;
    END IF;

    V_ANSWER := BITAND(V_ANSWER,  TO_NUMBER('FFFF', 'XXXX'));
  END LOOP;
END LOOP;

RETURN V_ID_CRC16||V_QTD_CRC16||TRIM(TO_CHAR(V_ANSWER, 'XXXX'));

END CRC16;

Estou utilizando Oracle Database 11g Release 11.2.0.4.0 - 64bit Production.

Att,

Boa tarde. Obrigado, vou verificar para converter em SQL.

reichert-lucas commented 2 years ago

Pessoal, boa tarde! Alguém poderia dar uma idéia de como calcular o CRC16? Agradeço!

@jeansentose tem várias bibliotecas em linguagens diversas no github. Tem uma rotina neste link, em typescript (javascript++), fácil de converter para a tua linguagem de estimação. https://github.com/NascentSecureTech/pix-qrcode-utils/blob/master/packages/emv-merchant-qrcode/src/crc.ts

@jeansentose Eu utilizo PHP para gerar o QRCODE.

A funcao que utilizo é: function crc16($string) { $CRC16POLINOMIO = 0x1021; $result = 0xFFFF; if (($length = strlen($string)) > 0) { for ($offset = 0; $offset < $length; $offset++) { $result ^= (ord($string[$offset]) << 8); for ($bitwise = 0; $bitwise < 8; $bitwise++) { if (($result <<= 1) & 0x10000) $result ^= $CRC16POLINOMIO; $result &= 0xFFFF; } } } return $result; } $CRC16 = crc16($stringPix); //Nessa string deve conter o final "6304" $CRC16 = dechex($CRC16); //transformo de decimal para hexadecimal $CRC16 = strtoupper($CRC16); //Transformo para maiusculas

Estou trabalhando em um conversor online. O exemplo está no link https://showcommerce.com.br/pix

Bom dia, pessoal.

Eu estou usando uma solução semelhante a esta em PHP, porém notei que para resultados menores que 4095 (Hexadecimal: FFF), o tamanho não seria o 4, que é o padrão do PIX, seria 3. Para solucionar esse problema, eu adicionei um padding com zeros no início do hexadecimal, que não altera o valor final.

$resultadoCrc16 = strtoupper(dechex($resultadoCrc16));
$resultadoCrc16 = str_pad($resultadoCrc16, 4, '0', STR_PAD_LEFT);
sibelius commented 2 years ago

temos um validador online para QRCode EMV ?

cryptographix commented 2 years ago

tente https://pix.nascent.com.br/tools/pix-qr-decoder/. Tem opção de verificar e corrigir o CRC.

thiagosabino-prog commented 2 years ago

Fala ai blz, em delphi estou gerando desta forma.

function CRC16CCITT(texto: string): WORD; const polynomial = $1021; var crc: WORD; i, j: Integer; b: Byte; bit, c15: Boolean; begin crc := $FFFF; for i := 1 to length(texto) do begin b := Byte(texto[i]); for j := 0 to 7 do begin bit := (((b shr (7 - j)) and 1) = 1); c15 := (((crc shr 15) and 1) = 1); crc := crc shl 1; if (c15 xor bit) then crc := crc xor polynomial; end; end; Result := crc and $FFFF; end;

e chamo a função desta forma.

inttohex(CRC16CCITT(minhachave),4);

Testei em diversos bancos só o Itau que estou dependendo do gerente descobrir lá onde libera kkkk.

Estou gerando dessa forma também e em alguns bancos lê de boa e no Itaú, banco do brasil e bradesco não funciona. Teve algum retorno do Itau?

renatofrota commented 2 years ago

Estou gerando dessa forma também e em alguns bancos lê de boa e no Itaú, banco do brasil e bradesco não funciona. Teve algum retorno do Itau?

Compartilhe um exemplo de QR Code que você gerou. Somente assim poderemos apontar os erros.

thiagosabino-prog commented 2 years ago

Pessoal consegui agora que funcione em todos os banco que testei. As correções que tive que fazer foram: 1 - Valores terminados e 0, tipo 1,20 estava passando para string 1.2 e no caso do itaú especificamente não aceita tem que ser formatado assim: 1.20 2 - Cidades com mais de 15 caracteres e acento também não aceita te que ser no máximo 15 e sem acento.

Feito essas correções até agora está tudo funcionando.

inklys commented 2 years ago

Olá, tenho esse payload do pix dinamico e não faço a minima ideia de por que não está sendo aceito pelo aplicativo do banco do brasil:

000201 2683 0014br.gov.bcb.pix 2561api.pagseguro.com/pix/v2/916CED9B-C6EE-4C8B-A6B2-C0D652B63BBB 52048999 5303986 5802BR 5921Pagseguro Internet SA 6009SAO PAULO 6230 0526riz8aOMtu5m6YURewDFpsEBpjy 6304A5C6

Quem puder me ajudar fico grato.

reichert-lucas commented 2 years ago

Olá, tenho esse payload do pix dinamico e não faço a minima ideia de por que não está sendo aceito pelo aplicativo do banco do brasil:

000201 2683 0014br.gov.bcb.pix 2561api.pagseguro.com/pix/v2/916CED9B-C6EE-4C8B-A6B2-C0D652B63BBB 52048999 5303986 5802BR 5921Pagseguro Internet SA 6009SAO PAULO 6230 0526riz8aOMtu5m6YURewDFpsEBpjy 6304A5C6

Quem puder me ajudar fico grato.

Bom dia. Aparentemente o seu elemento 62 (Additional Data Field Template) > 05 (Reference Label) ultrapassou o tamanho máximo de 25 caracteres, ele tem 26. Você pode fazer esse tipo de verificação da string do Qrcode nesse endereço: https://pix.nascent.com.br/tools/pix-qr-decoder/. Além disso, esse campo deve conter o valor ***, sem passar o txid.

rubenskuhl commented 2 years ago

Olá, tenho esse payload do pix dinamico e não faço a minima ideia de por que não está sendo aceito pelo aplicativo do banco do brasil:

000201 2683 0014br.gov.bcb.pix 2561api.pagseguro.com/pix/v2/916CED9B-C6EE-4C8B-A6B2-C0D652B63BBB 52048999 5303986 5802BR 5921Pagseguro Internet SA 6009SAO PAULO 6230 0526riz8aOMtu5m6YURewDFpsEBpjy 6304A5C6

Quem puder me ajudar fico grato.

No QR-Code dinâmico, o campo 62:05 deve conter apenas *** (três asteriscos), e não o txid.

inklys commented 2 years ago

Obrigado ao reichert-lucas e rubenskuhl, final mente funcionou. Não sei se faz parte do assunto desse tópico, mas se tiver alguém para me dar uma orientação sobre notificações (PagSeguro) fico grato.

rubenskuhl commented 2 years ago

Obrigado ao reichert-lucas e rubenskuhl, final mente funcionou. Não sei se faz parte do assunto desse tópico, mas se tiver alguém para me dar uma orientação sobre notificações (PagSeguro) fico grato.

Na última vez que olhei a API do PagSeguro, eles me parecem seguir (finalmente) a API padrão do Banco Central... então se isso for verdade para a parte de notificações, podemos tentar nessa linha. Até onde você chegou e o que não funcionou ?

inklys commented 2 years ago

Na verdade eu nem comecei, não ficou muito claro pra mim o conceito de webhook, e como preparar o sistema para receber a notificação

reichert-lucas commented 2 years ago

Na verdade eu nem comecei, não ficou muito claro pra mim o conceito de webhook, e como preparar o sistema para receber a notificação

A webhook é uma forma de tu ter um retorno sobre as atualizações de um pagamento (por exemplo), basicamente, tu vai ter uma rota no teu sistema que vai estar preparada para atualizar o pagamento quando o gateway de pagamento te informar que houve um pagamento. Um exemplo pode ser do próprio pix, se tu gerar uma cobrança do pix é muito menos trabalhoso o gateway de pagamento te avisar quando o pagamento for realizado, caso contrário tu teria que ficar consultando se o pagamento foi realizado (de tempos em tempos, por exemplo de 30 em 30 segundos), e isso acaba gastando mais recursos da sua aplicação e do gateway de pagamento.

rubenskuhl commented 2 years ago

Na verdade eu nem comecei, não ficou muito claro pra mim o conceito de webhook, e como preparar o sistema para receber a notificação

Na API Pix tem 3 jeitos de saber que uma cobrança foi paga:

Como mesmo com o webhook é bom ter um "recuperador", comece implementando um dos outros dois. Aí parta para implementar o webhook, que normalmente requer mais traquejo de configuração de webserver do que os devs usuais tem.

inklys commented 2 years ago

Obrigado pelas dicas rubenskuhl, eu gostaria mesmo é da Webhook, tem que implementar algum certificado, curl, ou é só pegar os dados da request mesmo? Sabe se vem em Json?

rubenskuhl commented 2 years ago

Obrigado pelas dicas rubenskuhl, eu gostaria mesmo é da Webhook, tem que implementar algum certificado, curl, ou é só pegar os dados da request mesmo? Sabe se vem em Json?

Tem que implementar certificado, o Banco Central exige que haja mTLS na transação. Os dados vem sim em JSON, um exemplo:


  "pix": [
    {
      "endToEndId": "E1803615022211340s08793XPJ",
      "txid": "fc9a43k6ff384ryP5f41719",
      "chave": "2c3c7441-b91e-4982-3c25-6105581e18ae",     
      "valor": "0.01",
      "horario": "2020-12-21T13:40:34.000Z",
      "infoPagador": "pagando o pix"
    }
  ]
}```
matias-prog commented 2 years ago

Segue solução que estou utilizando em PL/SQL:

CREATE OR REPLACE FUNCTION CRC16(V_STRING VARCHAR2) RETURN VARCHAR2 IS CURSOR C_BYTES (PIX_STRING VARCHAR2) IS SELECT TO_NUMBER(COLUMN_VALUE) AS BYTES FROM XMLTABLE( SUBSTR( DUMP(PIX_STRING), INSTR( DUMP(PIX_STRING), ':' )+1 ) );

C NUMBER; J NUMBER;

V_ANSWER VARCHAR2(4000) := 'FFFF'; V_POLINOMIO VARCHAR2(4) := '1021';

V_VERIFY NUMBER;

V_ID_CRC16 CHAR(2) := '63'; V_QTD_CRC16 CHAR(2) := '04'; BEGIN FOR R_BYTES IN C_BYTES(V_STRING||V_ID_CRC16||V_QTD_CRC16) LOOP C := R_BYTES.BYTES;

IF (C_BYTES%ROWCOUNT = 1) THEN V_ANSWER := TO_NUMBER(V_ANSWER, 'XXXX'); END IF;

J := (C POWER(2,8)); V_ANSWER := (J + V_ANSWER) - BITAND(J, V_ANSWER) 2;

FOR BITWISE IN 0..7 LOOP V_ANSWER := V_ANSWER * POWER(2,1); V_VERIFY := BITAND(V_ANSWER, TO_NUMBER('10000', 'XXXXX'));

IF (V_VERIFY <> 0) THEN
  V_ANSWER := (V_ANSWER + TO_NUMBER(V_POLINOMIO, 'XXXX')) - BITAND(V_ANSWER, TO_NUMBER(V_POLINOMIO, 'XXXX')) * 2;
END IF;

V_ANSWER := BITAND(V_ANSWER,  TO_NUMBER('FFFF', 'XXXX'));

END LOOP; END LOOP;

RETURN V_ID_CRC16||V_QTD_CRC16||TRIM(TO_CHAR(V_ANSWER, 'XXXX'));

END CRC16;

Estou utilizando Oracle Database 11g Release 11.2.0.4.0 - 64bit Production.

Att,

No entiendo, ¿qué hay en la tabla XMLTABLE?, ¿de dónde sale?.

inklys commented 2 years ago

Olá, Estou tentando implementar o webhook, do pagseguro, mas não faço a menor ideia de como implementar a autenticação mTSL, quem puder me passar alguma dica ou material em PHP fico muito grato.

rubenskuhl commented 2 years ago

Olá, Estou tentando implementar o webhook, do pagseguro, mas não faço a menor ideia de como implementar a autenticação mTSL, quem puder me passar alguma dica ou material em PHP fico muito grato.

Apesar de ser de outro PSP, esta documentação provavelmente resolva suas questões dada a padronização da API Pix: https://dev.gerencianet.com.br/docs/api-pix-endpoints#section-entendendo-o-padr-o-mtls

A questão é muito mais o web server que você utiliza (na seção seguinte a acima há exemplos de configuração para Apache, nginx e outros servidores), do que a linguagem que você utiliza.

Robertodevinomazzarolo commented 2 years ago

Senhores, tem alguém que desenvolveu o calculo do CRC16 em VBA?? peguei um que o Professor Rebson Mendes liberou mas não esta funcionando sera que alguem tem outro pra eu comparar onde estou errando??