Verificação de Eventos Webhook

Eventos de webhook podem, opcionalmente, ter sua integridade e autenticidade de conteúdo verificadas, usando uma assinatura presente nos cabeçalhos.

O processo de verificação ocorre quando o integrador é capaz de reproduzir a técnica de geração e obter a mesma assinatura recebida na mensagem.

Esse procedimento garante que o conteúdo da mensagem original não seja corrompido e que a chave de criptografia utilizada na operação seja a única conhecida por ambas as equipes.

Abaixo estão os detalhes sobre como implementar essa verificação.


Etapa 1: Chave de criptografia

O PayBrokers compartilha uma chave de criptografia com cada um de seus integradores, que é usada para assinar as mensagens enviadas.

Para maior comodidade, esta chave pode ser gerada pelo integrador no painel administrativo, através do Menu de Preferências de Webhooks.

Caso a chave não exista ou queira alterar a existente, solicite a geração de uma nova chave clicando no botão [Criar nova]. Pressione o botão [Salvar] para confirmar, ou saia da tela para manter a chave anterior.

Neste exemplo, a chave gerada é apresentada abaixo e será utilizada posteriormente neste tutorial:

  • bf8867f612a34346a57d4e1c5e98b1ecc53defe3cccc4b7b8ea72dfbcf74a349

A chave salva será fundamental para validar o conteúdo das mensagens que seu sistema recebe da PayBrokers. Se você criar e salvar uma nova chave, atualize-a em seu sistema .


Etapa 2: Validando o Conteúdo da Mensagem

Para explicar a validação de uma mensagem, vamos considerar sua estrutura, abaixo:

HeadersContent
Content-Typeapplication/json
X-Webhook-SignatureSign=5D90499D59FB0D9FAD44A15112936CFCABA73A6EE666AAA63B60A0FC03F40EA5,Nonce=b7891a74-ca9a-4770-bedd-8fd8341b122b,TS=1684633816
BodyContent
{"id":"f6431a0f-970a-4be9-9c6d-f444f729adc3","transactionState":"Completed",
"transactionDate":"2023-05-19T19:51:21.320Z","transactionAmount":"0.010000",
"transactionType":"Credit","transactionPaymentType":"PIX","payer":{"name":"Johnny Boy","taxNumber":"09977799400"}}

Uma mensagem assinada tem uma carga no formato JSON convencional. No entanto, um campo chamado X-Webhook-Signature é adicionado aos cabeçalhos das mensagens. Este campo fornece a própria assinatura (Sign) e os dados necessários para replicá-la, como Nonce e TS (Timestamp).


Para replicar a assinatura, o integrador deve seguir as etapas abaixo.

Crie uma string que combine os campos X-Webhook-Signature: Nonce, TS e as informações do conteúdo do corpo, separadas por dois pontos :.

Usando a mensagem de exemplo apresentada anteriormente, temos:

Do cabeçalho:

  • Nonce = b7891a74-ca9a-4770-bedd-8fd8341b122b
  • TS = 1684633816

Do Corpo:

  • {"id":"f6431a0f-970a-4be9-9c6d-f444f729adc3","transactionState":"Concluído","transactionDate":"2023-05-19T19:51:21.320Z","transactionAmount":"0,010000 ","transactionType":"Credit","transactionPaymentType":"PIX","payer":{"name":"Johnny Boy","taxNumber":"09977799400"}}

Assim, a string concatenada tem o seguinte formato:

  • b7891a74-ca9a-4770-bedd-8fd8341b122b:1684633816:{"id":"f6431a0f-970a-4be9-9c6d-f444f729adc3","transactionState":"Completed","transactionDate":"2023-05-19T19:51:21.320Z","transactionAmount":"0.010000","transactionType":"Credit","transactionPaymentType":"PIX","payer":{"name":"Johnny Boy","taxNumber":"09977799400"}}

Aplique um algoritmo de geração HMAC com o algoritmo de geração de hash SHA256 com dois parâmetros: a string descrita acima, como message; e a chave gerada no painel administrativo, como key.

Para isso, você pode usar por exemplo a biblioteca crypto, como no exemplo de Javascript abaixo:

const crypto = require('crypto');

const message = `b7891a74-ca9a-4770-bedd-8fd8341b122b:1684633816:{"id":"f6431a0f-970a-4be9-9c6d-f444f729adc3","transactionState":"Completed","transactionDate":"2023-05-19T19:51:21.320Z","transactionAmount":"0.010000","transactionType":"Credit","transactionPaymentType":"PIX","payer":{"name":"Johnny Boy","taxNumber":"09977799400"}}`;
const key = "bf8867f612a34346a57d4e1c5e98b1ecc53defe3cccc4b7b8ea72dfbcf74a349";
const algorithm = 'sha256';

const hmac = crypto.createHmac(algorithm, key);
hmac.update(message);

const signature = hmac.digest('hex');
console.log(signature.toUpperCase());

Se tudo estiver correto, a assinatura gerada deve ser a seguinte:

  • 5D90499D59FB0D9FAD44A15112936CFCABA73A6EE666AAA63B60A0FC03F40EA5

Essa assinatura deve corresponder ao campo Sign em X-Webhook-Signature, garantindo a integridade da mensagem recebida.


What’s Next