Skip to main content

O que assinar

Toda notificação clearpago → comerciante traz o header:
Digital-Signature: <base64 da assinatura>
A assinatura é ECDSA P-256 sobre o hash SHA-256 do corpo, codificada em Base64 (formato ASN.1 DER R,S — compatível com crypto/ecdsa em Go, createVerify em Node e bibliotecas Python cryptography). Importante: valide o corpo bruto (bytes), exatamente como recebido em TCP; não re-serialize o JSON parseado, para não trocar espaços, ordem de chaves ou finais de linha.

Obter a chave pública

curl -s https://api.clearpago.com.br/public-key
Use o conteúdo retornado (PEM) na verificação. Em rotação, confira a cache TTL da sua aplicação. TODO: chave pública múltipla / kid no header — a origem não descreve KeyId separado; alinhe com a implementação se existir rotação com identificador.

Node.js (esboço)

const crypto = require('crypto');

function verifyWebhookSignature(rawBodyBuffer, signatureBase64, publicKeyPem) {
  const verify = crypto.createVerify('SHA256');
  verify.update(rawBodyBuffer);
  verify.end();
  const sig = Buffer.from(signatureBase64, 'base64');
  return verify.verify(publicKeyPem, sig);
}

Python (esboço)

from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.exceptions import InvalidSignature
import base64

def verify_webhook_signature(body: bytes, signature_b64: str, public_key_pem: str) -> bool:
    public_key = serialization.load_pem_public_key(public_key_pem.encode())
    signature = base64.b64decode(signature_b64)
    try:
        public_key.verify(signature, body, ec.ECDSA(hashes.SHA256()))
        return True
    except InvalidSignature:
        return False

Depois de verificar

  1. Parse o JSON; trate o campo event_type e o bloco event.
  2. Aplique deduplicação.
  3. Responda 2xx rapidamente.

API reference

Relação com webhooks de entrada (parceiro)

Os webhooks parceiro → clearpago usam outro mecanismo (HMAC/timestamp). Não misture. Ver Parceiro → clearpago.