Webhooks
Webhooks
Recibe notificaciones en tiempo real cuando ocurren eventos en tu cuenta.
Cómo funcionan los webhooks
- Registras una URL y los eventos que deseas recibir.
- Cuando ocurre un evento, enviamos un payload JSON mediante POST a tu URL.
- Tu endpoint debe devolver un código de estado 2xx en un máximo de 10 segundos.
- Si la entrega falla, reintentamos con retroceso exponencial (hasta 5 intentos en ~24 horas).
Registrar un webhook
curl https://api.facturacion.srs-ngr.com/v1/webhooks \
-u sk_test_xxx: \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/facturacion",
"eventos_suscritos": ["factura.timbrada", "factura.cancelada", "pago.creado"]
}'{
"id": "wh_1a2b3c4d",
"url": "https://your-app.com/webhooks/facturacion",
"eventos_suscritos": ["factura.timbrada", "factura.cancelada", "pago.creado"],
"secreto_firma": "whsec_a1b2c3d4e5f6..."
}El
secreto_firma solo se devuelve al momento de la creación. Guárdalo — lo necesitarás para verificar las firmas de los webhooks.Tipos de eventos
| Evento | Disparador |
|---|---|
factura.creada | Borrador de factura creado |
factura.timbrada | Factura timbrada exitosamente (tiene UUID) |
factura.timbrado_fallido | El PAC rechazó la factura |
factura.cancelada | Factura cancelada |
factura.cancelacion_fallida | Cancelación rechazada |
pago.creado | Pago registrado |
certificado.por_vencer | El CSD vence en 30 días |
certificado.vencido | El CSD ha expirado |
Payload del webhook
{
"id": "evt_1a2b3c",
"tipo": "factura.timbrada",
"creado_en": "2026-03-14T10:30:01Z",
"datos": {
"id": "fac_1a2b3c4d",
"uuid": "A1B2C3D4-E5F6-...",
"estado": "timbrada",
"total": "2320.00",
...
}
}Verificación de firmas
Cada entrega de webhook incluye un encabezado X-Facturacion-Firma que contiene una firma HMAC-SHA256 del cuerpo de la solicitud.
import hmac
import hashlib
def verify_signature(payload_body, signature_header, secret):
expected = hmac.new(
secret.encode('utf-8'),
payload_body,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature_header)func verifySignature(body []byte, signatureHeader, secret string) bool {
mac := hmac.New(sha256.New, []byte(secret))
mac.Write(body)
expected := hex.EncodeToString(mac.Sum(nil))
return hmac.Equal([]byte(expected), []byte(signatureHeader))
}Política de reintentos
| Intento | Demora |
|---|---|
| 1 | Inmediato |
| 2 | 5 minutos |
| 3 | 30 minutos |
| 4 | 2 horas |
| 5 | 24 horas |
Después de 5 intentos fallidos, la entrega se marca como fallida. Consulta el registro de eventos en el panel de control para reenviar eventos perdidos.