Confirmando autenticidade da notificação

O campo da assinatura no header contém uma assinatura gerada por meio do algoritmo SHA-256 para confirmar a autenticidade da requisição e prevenir fraudes.

Para que seja possível a comparação da assinatura recebida utilize as informações abaixo para implementar uma solução customizada.

1 - Etapa: Guardar payload e token

Nossa assinatura é composta pelo token de sua conta + o payload recebido.

Então é importante guardar o token de sua conta fornecido via iBanking e também armazenar o payload no recebimento da notificação.

Exemplo de payload recebido:

{"id":"CHAR_354828dd-786b-4cca-8ce4-6f7a1f3f2a1a","status":"WAITING","created_at":"2019-09-24T18:31:19.027-03:00","description":"This is the payment transaction description","amount":{"value":100,"currency":"BRL","summary":{"total":100,"paid":0,"refunded":0}},"payment_response":{"code":"20000","message":"SUCESSO"},"payment_method":{"type":"BOLETO","boleto":{"id":"eafadc9b-6e15-41ff-ab07-86218770d93b","barcode":"03399853012970000035869420601010782490000000100","formatted_barcode":"03399.85301 29700.000358 69420.601010 7 82490000000100","due_date":"2020-05-08","instruction_lines":{"line_1":"Pagamento processado para DESC Fatura","line_2":"Via PagSeguro"},"holder":{"name":"Jose da Silva","tax_id":"90792099028","email":"[email protected]","address":{"region":"Sao Paulo","city":"Sao Paulo","postal_code":"01452002","street":"Avenida Brigadeiro Faria Lima","number":"1384","locality":"Pinheiros","country":"Brasil","region_code":"SP"}}}},"links":[{"rel":"SELF","href":"https://charge-rest.digital-payments.aws.intranet.pagseguro.uol/charges/354828dd-786b-4cca-8ce4-6f7a1f3f2a1a","media":"application/json","type":"GET"},{"rel":"SELF","href":"https://boleto.pagseguro.com.br/eafadc9b-6e15-41ff-ab07-86218770d93b.pdf","media":"application/pdf","type":"GET"},{"rel":"SELF","href":"https://boleto.pagseguro.com.br/eafadc9b-6e15-41ff-ab07-86218770d93b.png","media":"image/png","type":"GET"}],"notification_urls":["https://yourserver.com/nas_ecommerce/277be731-3b7c-4dac-8c4e-4c3f4a1fdc46/"],"metadata":{"Exemplo":"Aceita qualquer informação","NotaFiscal":"123","idComprador":"123456"}}

❗️

ATENÇÃO

O payload recebido não deve estar formatado pois qualquer espaço adicional fará com que o hash dê divergência e não possa ser validado.

2 - Etapa: Preparar campos

Agora use o algoritmo SHA256 considerando o payload e o token guardados com um hífen entre eles ({token}-{payload}).

Exemplo:

signature := sha256.Sum256([]byte(jsonToken.Token + - + request.Body))
override fun generateSign(requestBody: String, token: String): String {
  return toHashSHA256("$token-$requestBody")
  }

private fun toHashSHA256(content: String): String {
  val bytes = content.toByteArray()
    val md = MessageDigest.getInstance("SHA-256")
    val digest = md.digest(bytes)
    return digest.fold("", { str, it -> str + "%02x".format(it) })
  }
String assinatura = token+"-"+payload
 
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] encodedhash = digest.digest(
  assinatura.getBytes(StandardCharsets.UTF_8));
 
private static String bytesToHex(byte[] hash) {
    StringBuffer hexString = new StringBuffer();
    for (int i = 0; i < hash.length; i++) {
    String hex = Integer.toHexString(0xff & hash[i]);
    if(hex.length() == 1) hexString.append('0');
        hexString.append(hex);
    }
    return hexString.toString();
}
//import maven
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.11</version>
</dependency>
   
// Usando a lib apache commons 
String sha256hex = DigestUtils.sha256Hex(token+"-"+requestBody);

3 - Etapa: Comparar as assinaturas

Você irá receber o header conforme abaixo:

x-authenticity-token : 8d09afba2eed749f2173cfd6faf16dc7f0228846ecf5ba1d7a11f33270d1513f
content-type : application/json

Compare a assinatura gerada para validação com o campo x-authenticity-token recebido no header.

❗️

ATENÇÃO

Se os tokens NÃO coincidirem o evento recebido deve ser descartado pois não será confiável.