niiko/developers

El contrato

Webhooks

Registra un destino y niiko te avisa cuando algo se resuelve — sobre todo lo que quedó en pending_approval, que por definición termina después de que colgaste.

Última actualización

Configuración → Desarrolladores → Webhooks. Dos eventos: action.completed y action.failed. El secreto se muestra una sola vez, al crear el destino.

La firma

Cada entrega lleva una cabecera Niiko-Signature con una marca de tiempo y un HMAC-SHA256 de la marca y el cuerpo, unidos por un punto:

Niiko-Signature: t=<unix seconds>,v1=<hex>
v1 = HMAC-SHA256(secret, t + "." + body)

La marca de tiempo va dentro de lo firmado: firmar solo el cuerpo deja una firma válida para siempre. Verifica que t sea reciente (±5 minutos) y que la firma coincida, con una comparación en tiempo constante.

// Node.js — verify a delivery
import { createHmac, timingSafeEqual } from "node:crypto";

const [t, v1] = /t=(\d+),v1=([0-9a-f]+)/.exec(req.headers["niiko-signature"]).slice(1);
const expected = createHmac("sha256", SECRET).update(t + "." + rawBody).digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 300;      // the timestamp is part of the proof
const ok = fresh && timingSafeEqual(Buffer.from(expected), Buffer.from(v1));

Reintentos

Si tu servidor no contesta 2xx, la entrega se reintenta con espera creciente (seis intentos). Un 4xx que no sea 408 ni 429 no se reintenta: significa que el destino está mal, no ocupado. Tras muchos fallos seguidos el destino se apaga solo — y el panel dice por qué. Cada entrega lleva el mismo id en todos los intentos: úsalo para deduplicar.