Verificar assinatura
Cada webhook inclui um header X-PaysClub-Signature com uma assinatura HMAC-SHA256 do body. Use o secret do endpoint para verificar a autenticidade.
Sempre verifique a assinatura antes de processar um webhook. Não confie em webhooks sem validação.
Node.js
verify-webhook.js
const crypto = require("crypto");
function verifySignature(body, signature, secret) {
const computed = "sha256=" + crypto
.createHmac("sha256", secret)
.update(body)
.digest("hex");
// Comparação timing-safe
return crypto.timingSafeEqual(
Buffer.from(computed),
Buffer.from(signature)
);
}
// No seu endpoint:
app.post("/webhook", (req, res) => {
const signature = req.headers["x-paysclub-signature"];
const body = JSON.stringify(req.body);
if (!verifySignature(body, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send("Invalid signature");
}
const { event, data } = req.body;
console.log("Evento recebido:", event, data);
res.status(200).json({ received: true });
});Python
verify_webhook.py
import hmac
import hashlib
def verify_signature(body: bytes, signature: str, secret: str) -> bool:
computed = "sha256=" + hmac.new(
secret.encode(),
body,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(computed, signature)
# No seu endpoint Flask:
@app.route("/webhook", methods=["POST"])
def webhook():
signature = request.headers.get("X-PaysClub-Signature")
if not verify_signature(request.data, signature, WEBHOOK_SECRET):
return "Invalid signature", 401
data = request.json
print("Evento:", data["event"])
return {"received": True}Retentativas
Se seu endpoint retornar status diferente de 2xx, a PaysClub tentará reenviar até 3 vezes com backoff exponencial (5s, 30s, 2min).