Documentación
Explorar documentación
Idioma
EN ES

Recibir eventos con webhooks

Recibe actualizaciones firmadas de facturas y cumplimiento sin consultar repetidamente la API.
Ver como Markdown

Los webhooks avisan a tu integración cuando ocurre algo importante en una cuenta Live o Test. Son especialmente útiles para los resultados asíncronos de verificación de NIF y VERI*FACTU y para los movimientos de saldo, pero también informan sobre clientes, facturas, rectificaciones y PDF.

Crea un destino de Test

Crea el destino con una clave de API de Test para que las pruebas no se mezclen con eventos Live. Suscríbete solo a los eventos que entienda tu integración; usa "*" únicamente cuando quieras recibir deliberadamente todos los tipos actuales y futuros.

curl https://api.fiscalrail.com/v1/event-destinations \
  --request POST \
  --header "Authorization: Bearer ak_test_..." \
  --header "Content-Type: application/json" \
  --data '{
    "name": "Invoice updates",
    "url": "https://example.com/webhooks/fiscalrail",
    "enabled_events": [
      "invoice.amended",
      "invoice.verifactu_registration.accepted",
      "invoice.verifactu_registration.accepted_with_errors",
      "invoice.verifactu_registration.rejected"
    ]
  }'

La respuesta contiene un secreto de firma whsec_.... Guárdalo de forma segura. FiscalRail puede devolverlo al consultar ese destino, pero lo omite en los listados.

El endpoint debe usar HTTPS público. Durante el desarrollo local, expón el controlador mediante un túnel HTTPS de confianza y sustituye la URL del destino cuando cambie.

Verifica antes de interpretar

FiscalRail firma el cuerpo exacto de la petición y envía el resultado en FiscalRail-Signature. Verifica la firma antes de interpretar el JSON o empezar el trabajo.

import hashlib
import hmac
import time


def verify_fiscalrail_signature(raw_body, header, secret):
    parts = dict(item.split("=", 1) for item in header.split(","))
    timestamp = int(parts["t"])
    if abs(time.time() - timestamp) > 300:
        return False

    signed = str(timestamp).encode() + b"." + raw_body
    expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts["v1"])

La firma cubre timestamp + "." + raw_body mediante HMAC-SHA256. Rechaza marcas de tiempo con más de cinco minutos y compara las firmas en tiempo constante. Cada reintento recibe una marca de tiempo y una firma nuevas.

Confirma la recepción rápidamente

Devuelve cualquier respuesta 2xx en cuanto hayas autenticado el evento y lo hayas guardado de forma duradera en una cola. Realiza el trabajo lento después de confirmarlo.

La entrega es al menos una vez y no está ordenada. Guarda el identificador del evento antes de procesarlo e ignora los que ya hayas tratado. No supongas que invoice.issued llegará antes que invoice.amended ni que un resultado de VERI*FACTU llegará inmediatamente después de la emisión.

Los payloads de webhook son deliberadamente breves. Identifican el evento y el recurso relacionado, pero omiten la instantánea inmutable data. Consulta el evento por su identificador cuando necesites la instantánea histórica o el recurso relacionado cuando necesites su estado actual.

Suscribe un destino Live a billing.balance_transaction.created para conciliar los cargos de uso y los abonos de saldo. Consulta el evento completo para leer la instantánea inmutable de la transacción. En un cargo de uso, source_event identifica el evento de dominio que originó el cargo.

Prueba el flujo completo

Emite o corrige una factura en la misma cuenta de Test. Tu endpoint debería recibir el evento correspondiente. Comprueba que el controlador:

  1. verifica el cuerpo original y la marca de tiempo;
  2. registra cada identificador de evento una sola vez;
  3. devuelve 2xx rápidamente;
  4. consulta el evento o la factura relacionada de forma asíncrona;
  5. ignora de forma segura los tipos de evento que no conoce.

FiscalRail intenta cada entrega fallida hasta cinco veces. Si todos los intentos siguen fallando durante 24 horas, desactiva el destino. Corrige el endpoint y vuelve a activar el destino mediante la API o el panel.

Consulta la referencia de eventos para conocer el envelope y la referencia de webhooks para ver los campos del destino y las reglas de entrega.