🔐 Firmas HMAC del webhook

Valida X-Whapi-Signature (HMAC-SHA256) con el cuerpo raw de la petición.

1) Activar la firma

Configura el secret en POST /api/instance/:id/webhook. whapi enviará X-Whapi-Signature = HMAC-SHA256(body, secret).

POST /api/instance/123/webhook
Content-Type: application/json

{
  "token": "TOKEN",
  "url": "https://tu-dominio.com/webhook",
  "secret": "mi-super-secreto"
}

Tu servidor debe validar el cuerpo raw (no el JSON parseado).

Node.js (Express)

const crypto = require("crypto");
app.use(express.json({ verify: (req, _res, buf)=> { req.rawBody = buf; } }));

function verifyHmac(req, secret) {
  const sig = req.get("X-Whapi-Signature") || "";
  const comp = crypto.createHmac("sha256", secret).update(req.rawBody || "").digest("hex");
  return crypto.timingSafeEqual(Buffer.from(comp), Buffer.from(sig));
}

Python (Flask)

import hashlib, hmac
def verify_hmac(raw_body: bytes, signature: str, secret: str) -> bool:
    comp = hmac.new(secret.encode(), raw_body or b"", hashlib.sha256).hexdigest()
    return hmac.compare_digest(comp, signature or "")

PHP

<?php
$raw = file_get_contents("php://input");
$calc = hash_hmac("sha256", $raw ?: "", $secret);
$ok   = hash_equals($calc, $_SERVER["HTTP_X_WHAPI_SIGNATURE"] ?? "");