Ir al contenido

Webhooks

El SRI tarda de segundos a minutos en autorizar. En vez de consultar, registra una URL y Chaski te avisa.

En el panel (Webhooks) o por API:

Ventana de terminal
curl https://api.chaski.ec/v1/webhook-endpoints \
-H "Authorization: Bearer $CHASKI_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "url": "https://tu-app.com/webhooks/chaski", "events": ["invoice.authorized", "invoice.rejected"] }'

La respuesta trae el secreto whsec_… para verificar las firmas. Se muestra una sola vez. Cada endpoint pertenece al ambiente de la key con que lo creaste.

  • PATCH /v1/webhook-endpoints/{id} cambia url, description, events o enabled. Con enabled: false el endpoint deja de recibir eventos hasta que lo vuelvas a activar.
  • POST /v1/webhook-endpoints/{id}/rotate-secret genera un secreto nuevo y lo devuelve una sola vez. El anterior deja de servir de inmediato, así que actualízalo en tu servidor enseguida.

También puedes hacerlo desde el panel, en el detalle del webhook.

Evento Cuándo
invoice.authorized El SRI autorizó la factura.
invoice.rejected El SRI la rechazó (data.sri_messages dice por qué).
invoice.failed No se pudo enviar después de todos los reintentos.
invoice.voided Registraste la anulación.
credit_note.authorized / .rejected / .failed Lo mismo, para notas de crédito.
debit_note.authorized / .rejected / .failed Lo mismo, para notas de débito.
withholding.authorized / .rejected / .failed Lo mismo, para comprobantes de retención.
delivery_guide.authorized / .rejected / .failed Lo mismo, para guías de remisión.
purchase_settlement.authorized / .rejected / .failed Lo mismo, para liquidaciones de compra.
document.email_bounced El correo al comprador rebotó.
export.ready / export.failed Terminó una exportación.
certificate.expiring El certificado de un emisor vence pronto.
issuer.live_enabled Un emisor pasó a producción.
usage.threshold_reached El consumo del mes llegó al 80% o al 100% del plan.
POST /webhooks/chaski
Content-Type: application/json
Chaski-Event-Id: evt_01jbx3k9q2f8m4tn6vwz0yh5ce
Chaski-Signature: t=1793700000,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd
{
"id": "evt_01jbx3k9q2f8m4tn6vwz0yh5ce",
"type": "invoice.authorized",
"environment": "live",
"created_at": "2026-11-03T15:04:05.000Z",
"data": { "id": "inv_…", "status": "authorized", "number": "001-001-000001042", … }
}

Responde con cualquier 2xx en menos de 10 segundos. Si tu servidor falla o tarda, reintentamos a los 1, 5 y 30 minutos, 2, 12 y 24 horas. El mismo evento puede llegar más de una vez: usa Chaski-Event-Id para no procesarlo dos veces.

Chaski-Signature es t=<unix>,v1=<firma>, donde la firma es el HMAC-SHA256 en hexadecimal de "<t>.<cuerpo crudo>" con tu secreto. Rechaza firmas de más de 5 minutos.

import { verifyWebhook } from '@chaski/sdk';
app.post('/webhooks/chaski', express.raw({ type: 'application/json' }), async (req, res) => {
try {
const event = await verifyWebhook(req.body.toString('utf8'), req.header('chaski-signature'), process.env.CHASKI_WEBHOOK_SECRET!);
// procesa event.type / event.data
res.sendStatus(200);
} catch {
res.sendStatus(400);
}
});

GET /v1/events lista los eventos de tu cuenta (filtra con type), y GET /v1/webhook-endpoints/{id}/deliveries muestra cada intento de entrega con su respuesta. Si una entrega quedó failed (por ejemplo, tu servidor estuvo caído más de lo que duran los reintentos), POST /v1/webhook-endpoints/{id}/deliveries/{deliveryId}/retry la vuelve a enviar.