Probar webhooks en local
Con el CLI fiscalapi recibes en tu computadora los eventos de tu cuenta, disparas eventos de prueba y reenvías los que te faltaron, sin exponer tu servidor a internet.
Cómo funciona
fiscalapi listenabre tu escucha de CLI: un webhook sin URL, uno por persona, con su propio secreto de firma.- Cuando ocurre un evento en tu cuenta, o cuando lo disparas, el servidor de Fiscalapi lo genera, lo firma con el secreto de tu escucha y crea una entrega para ella.
- El CLI toma la entrega y la reenvía a tu servidor local como un POST con el cuerpo exacto y los headers firmados.
- Tu servidor verifica la firma y responde, igual que con un webhook de URL.
Tu computadora no genera los eventos ni necesita una URL pública: el CLI pide las entregas a Fiscalapi y las reenvía a localhost.
Instalar el CLI
fiscalapi es un solo binario para Windows, Linux y macOS; no necesitas instalar .NET. Descarga el empaque de tu sistema y el archivo SHA256SUMS desde GitHub Releases, y verifica el SHA-256 antes de ejecutarlo.
| Sistema | Empaque |
|---|---|
| Windows x64 | fiscalapi-win-x64.zip |
| Linux x64, glibc 2.28 o más nueva | fiscalapi-linux-x64.tar.gz |
| macOS Apple Silicon | fiscalapi-osx-arm64.tar.gz |
| macOS Intel | fiscalapi-osx-x64.tar.gz |
Linux
base=https://github.com/FiscalAPI/fiscalapi-cli/releases/latest/download
curl -fsSLO "$base/fiscalapi-linux-x64.tar.gz"
curl -fsSLO "$base/SHA256SUMS"
grep ' fiscalapi-linux-x64.tar.gz$' SHA256SUMS | sha256sum -c - # debe decir: OK
tar -xzf fiscalapi-linux-x64.tar.gz
sudo install -m 0755 fiscalapi /usr/local/bin/fiscalapi
fiscalapi --version
macOS
package=fiscalapi-osx-arm64.tar.gz # en una Mac Intel: fiscalapi-osx-x64.tar.gz
base=https://github.com/FiscalAPI/fiscalapi-cli/releases/latest/download
curl -fsSLO "$base/$package"
curl -fsSLO "$base/SHA256SUMS"
grep " $package\$" SHA256SUMS | shasum -a 256 -c - # debe decir: OK
tar -xzf "$package"
sudo mkdir -p /usr/local/bin
sudo install -m 0755 fiscalapi /usr/local/bin/fiscalapi
fiscalapi --version
Windows (PowerShell)
$base = 'https://github.com/FiscalAPI/fiscalapi-cli/releases/latest/download'
Invoke-WebRequest "$base/fiscalapi-win-x64.zip" -OutFile fiscalapi-win-x64.zip
Invoke-WebRequest "$base/SHA256SUMS" -OutFile SHA256SUMS
$expected = (Select-String -Path SHA256SUMS -Pattern ' fiscalapi-win-x64\.zip$').Line.Split(' ')[0]
$actual = (Get-FileHash fiscalapi-win-x64.zip -Algorithm SHA256).Hash.ToLowerInvariant()
if ($actual -ne $expected) { throw "El SHA-256 no coincide: $actual" } else { 'SHA-256 OK' }
$dir = Join-Path $env:LOCALAPPDATA 'Programs\fiscalapi'
Expand-Archive fiscalapi-win-x64.zip -DestinationPath $dir -Force
La verificación debe decir OK. Si dice FAILED o no coincide, borra lo que descargaste y vuelve a bajarlo.
Estos comandos instalan la última versión publicada. Para una versión fija, cambia releases/latest/download por releases/download/v0.1.0.
Cómo agregar el CLI al PATH en Windows, qué hacer si Gatekeeper o SmartScreen lo bloquean, cómo actualizarlo y cómo desinstalarlo está en el repositorio del CLI.
Iniciar sesión
Terminal
$ fiscalapi login
API key:
Tenant key:
Listo. Credenciales guardadas para test.fiscalapi.com.
El comando pide tu API key y tu tenant key sin mostrarlas, las valida con la API y las guarda en el almacén de credenciales de tu sistema. Trabaja en el ambiente de pruebas por omisión; para producción usa fiscalapi login --live. Obtén tus llaves en Obtener credenciales.
La API key necesita el permiso Webhooks.Manage. Sin él, listen, trigger y los comandos de webhooks responden 403, y login te lo advierte al guardar las llaves.
En Linux sin almacén de credenciales (WSL, un servidor sin escritorio o un contenedor), login termina con "No hay un almacén de credenciales disponible en este sistema." En ese caso define las variables de entorno FISCALAPI_API_KEY y FISCALAPI_TENANT_KEY, las dos juntas, y no uses login.
Recibir eventos en tu servidor local
Terminal 1
$ fiscalapi listen --forward-to http://localhost:3000/webhooks
Listo. Tu secreto de firma es whsec_… (escucha 9b2e7c4a-1d3f-4e6b-8a5c-0f1e2d3c4b5a)
2026-10-12 09:47:46 --> invoice.canceled [3f9c1d2e-7b4a-4e8f-9a1b-2c3d4e5f6a7b] [200]
Cambia la URL por la ruta de tu servidor que recibe los webhooks. Cada línea trae la hora local, el tipo, el id del evento (el header webhook-id) y lo que respondió tu servidor:
| Final de la línea | Qué significa |
|---|---|
[200] | Tu servidor respondió ese código. |
[error: Timeout] | Tu servidor no respondió en 15 segundos. |
[error: ConnectionFailed] | No se pudo conectar: nada escucha en esa URL o se rechazó la conexión. |
[error: TlsFailed] | Falló el TLS hacia tu servidor, por ejemplo con un certificado autofirmado. |
listen corre hasta que lo detienes con Ctrl+C.
| Opción | Para qué |
|---|---|
--forward-to <url> | URL http o https de tu servidor. Sin ella, listen solo muestra los eventos en la terminal. |
--events <tipos> | Solo estos tipos, separados por coma, por ejemplo invoice.canceled,invoice.cancellation_rejected. Por omisión, todos. |
--skip-verify | No verifica el certificado TLS de tu servidor. Nunca afecta a la conexión con Fiscalapi. |
Verificar las entregas
Configura tu servidor con el secreto whsec_… que imprime listen y verifica cada entrega como cualquier otra, sobre el cuerpo crudo: Verificar la firma. Es el secreto de tu escucha de CLI, distinto del de tus webhooks de URL y estable entre reinicios, así que lo configuras una vez.
Para llevarlo a una variable de entorno sin copiarlo de la terminal:
export FISCALAPI_WEBHOOK_SECRET=$(fiscalapi listen --print-secret)
Con --print-secret, el CLI abre una sesión igual que listen. Córrelo antes de arrancar listen, no mientras corre.
Disparar un evento de prueba
Con listen abierto, dispara un evento desde otra terminal:
Terminal 2
$ fiscalapi trigger invoice.canceled
Evento disparado: 3f9c1d2e-7b4a-4e8f-9a1b-2c3d4e5f6a7b al webhook 9b2e7c4a-1d3f-4e6b-8a5c-0f1e2d3c4b5a.
El evento tiene la forma y la firma de uno real de su tipo, y llega solo a tu escucha aunque su tipo no esté en tus --events. Puedes disparar cualquier tipo de evento salvo webhook.test.
| Opción | Para qué |
|---|---|
--related-object-id <id> | Id de un recurso real de tu cuenta, para que tu servidor pueda consultarlo. Sin ella, el evento lleva un id sintético y el GET de relatedObject.url responde 404. |
--person-id <id> | Persona de tu cuenta dueña del recurso. Por omisión, el evento va sin persona. |
--webhook <id> | Entrega el evento a ese webhook de URL en lugar de a tu escucha. |
Solo funciona en el ambiente de pruebas: con --live responde 403 con el detalle "fiscalapi trigger no está disponible en producción; usa el ambiente de pruebas." Sin --webhook ni un listen abierto, responde 409.
Reenviar un evento
Busca el evento con fiscalapi events list y reenvíalo a tu escucha:
Terminal 2
$ fiscalapi events resend 3f9c1d2e-7b4a-4e8f-9a1b-2c3d4e5f6a7b
Reenvío creado: entrega d1e2f3a4-b5c6-4d7e-8f9a-0b1c2d3e4f5a al webhook 9b2e7c4a-1d3f-4e6b-8a5c-0f1e2d3c4b5a.
Sin --webhook, el reenvío va a tu escucha y necesita un listen abierto; si no, responde 409. Llega con el mismo webhook-id y el mismo cuerpo, así que tu deduplicación lo reconoce.
Lo que conviene saber
| Situación | Qué ocurre |
|---|---|
| Disparas un evento | Lo genera el servidor de pruebas de Fiscalapi, no tu computadora. Queda en la lista de eventos y se reenvía como cualquier otro. |
listen está cerrado o sin conexión | Los eventos de ese lapso no le llegan después. Recupéralos con fiscalapi events resend. |
| Tu servidor falla una entrega de la escucha | No hay reintentos: la entrega queda con ese resultado. Repítela con fiscalapi events resend. |
Abres otro listen con tu misma persona | Solo hay una sesión por persona: la nueva reemplaza a la anterior, que termina con un 409. |
| Disparas o reenvías un evento de prueba a un webhook de URL que está fallando | Su 2xx no lo saca de la racha de fallas: el webhook sigue acumulando sus 5 días sin respuestas exitosas. |
Referencia del CLI
fiscalapi --help y fiscalapi <comando> --help describen cada opción. La referencia completa, con la salida en JSON, los códigos de salida y la solución de problemas, está en el repositorio del CLI.