Ir al contenido
Log in

Webhooks

Para verificar que el webhook es auténtico y fue enviado por B2Brouter, comprueba la firma incluida en la cabecera X-B2Brouter-Signature. A continuación se explica cómo verificar la firma en tu servidor:

  1. Extraer la información de la cabecera: La cabecera X-B2Brouter-Signature contiene dos componentes:

    • t: El timestamp UNIX en el momento en que se firmó el payload.
    • s: La firma HMAC-SHA256. Ejemplo de cabecera:
    t=1732530076,s=9f117925ea533a2ea74b19699e03ab5de5664b4ff021d3d01eaff8868ed29e4d
  2. Recrear el payload: Combina el timestamp recibido (t) y el payload JSON en bruto (data) usando un punto (.):

    payload = "#{timestamp}.#{data}"
  3. Calcular la firma HMAC-SHA256: Usa la signature_key compartida y el payload para calcular la firma:

    computed_signature = HMAC-SHA256(signature_key, payload)
  4. Comparar las firmas: Compara computed_signature con el valor s de la cabecera. Si coinciden, el webhook es válido.

  1. PHP:
$headers = getallheaders();
$header = $headers['X-B2Brouter-Signature'];
preg_match('/t=([^,]+),s=(.+)/', $header, $matches);
$timestamp = $matches[1];
$signatureHash = $matches[2];
$recalculatedHash = hash_hmac(
'sha256',
$timestamp . '.' . file_get_contents('php://input'),
'your_webhook_secret'
);
$isValid = hash_equals($signatureHash, $recalculatedHash);
  • ledger.state_change — se dispara cuando un ledger (Flux 10 de la DGFiP, Verifactu) cambia de estado. Consulta Envío de un archivo de Flux 10 para ver la forma del payload y la lista de estados.

Cada evento genera una entrega: B2Brouter hace un POST con el payload firmado a la URL del webhook.

  • Una respuesta 2xx da la entrega por hecha.
  • Si tu servidor responde 5xx o 429, no responde a tiempo o no se puede conectar con él (DNS, conexión, TLS), B2Brouter vuelve a intentar la entrega más tarde. El intervalo entre intentos crece en cada intento, y los reintentos duran aproximadamente una semana. Este plazo puede cambiar.
  • Cualquier otra respuesta 4xx es definitiva: la entrega no se vuelve a intentar.

Responde 2xx en cuanto recibas el webhook y procesa el evento después. Una respuesta lenta cuenta como un error temporal, y la entrega se repite.

Además de X-B2Brouter-Signature, cada intento lleva estas cabeceras:

  • X-B2Brouter-Delivery-Id: el identificador de la entrega. Es el mismo en todos los intentos de una misma entrega.
  • X-B2Brouter-Delivery-Attempt: el número del intento, empezando por 1.

Una misma entrega puede llegar más de una vez. Usa X-B2Brouter-Delivery-Id para descartar los duplicados.

Las entregas no siempre llegan en orden: mientras una entrega espera su reintento, los eventos posteriores se entregan igualmente. Un webhook avisa de que un objeto ha cambiado. Antes de actuar, consulta su estado actual con la API.

En el Registro de webhooks, cada entrega muestra su estado y el número de intentos:

  • Reintentando: la entrega ha fallado y hay más intentos programados.
  • Abandonado: se han agotado los intentos.
  • Fallido: tu servidor ha respondido con un error definitivo (4xx).
  • Entregado: la entrega se ha hecho.
  • Cancelado: el webhook se ha desactivado o eliminado antes de que la entrega terminara.

Para repetir una entrega, ábrela en el registro y usa Reenviar. Un reenvío lleva en X-B2Brouter-Delivery-Attempt el número del último intento. El registro conserva las entregas 15 días.