Qué eventos hay
Entre otros: booking.order.*, booking.item.redeemed, payments.payment.*, payments.refund.succeeded, billing.settlement.paid y rewards.payout.paid. La lista completa está en GET /webhooks/events.
Alta
Desde Canal → Integraciones o con POST /orgs/:org/webhooks indicas una URL https pública y los eventos que quieres. La respuesta trae el secreto de firma una sola vez; puedes rotarlo cuando quieras.
Entrega y firma
Cada evento llega como POST JSON con las cabeceras roamdia-event-id, roamdia-event-type, roamdia-delivery-id y:
roamdia-signature: t=<unix>,v1=<hex HMAC-SHA256(secreto, "<t>.<cuerpo>")>Verifica la firma sobre el cuerpo tal cual llega, antes de parsear el JSON:
import { createHmac, timingSafeEqual } from 'node:crypto';
export function verify(secret, rawBody, header, toleranceSeconds = 300) {
const { t, v1 } = Object.fromEntries(header.split(',').map((p) => p.split('=')));
if (!t || !v1 || Math.abs(Date.now() / 1000 - Number(t)) > toleranceSeconds) return false;
const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest();
const given = Buffer.from(v1, 'hex');
return given.length === expected.length && timingSafeEqual(given, expected);
}Reintentos
Responde 2xx en menos de 5 segundos. Si no, se reintenta a los 30 s, 2 min, 10 min, 1 h, 6 h y 24 h. Usa roamdia-event-id para descartar repetidos. En el panel tienes el historial de entregas, el reintento manual y un evento de prueba.