Webhooks
Reciba notificaciones en tiempo real cuando sus validaciones bancarias estén terminadas.
Función del Paquete Business
Los webhooks están disponibles exclusivamente con el Paquete Business. Permiten recibir notificaciones automáticas sin consultar la API continuamente (polling).
Cómo funciona
Los webhooks permiten a BankValidor enviar notificaciones HTTP POST a su servidor cuando ocurre un evento.
Registre su URL
Configure la URL de su endpoint a través de la API. Especifique los eventos a los que desea suscribirse.
Recepción automática
Para cada evento correspondiente, BankValidor envía un POST HTTP a su URL con los detalles de la validación en formato JSON.
Política de reintentos
Si su servidor no responde con un código 2xx, BankValidor reintenta automáticamente con backoff exponencial (hasta 3 intentos).
Eventos disponibles
BankValidor emite los siguientes eventos. Seleccione aquellos a los que desea suscribirse al configurar su webhook.
| Evento | Descripción |
|---|---|
| validation.completed | Emitido cuando una validación individual (US, UK, SWIFT, IBAN) se completa exitosamente. |
| validation.failed | Emitido cuando una validación individual falla (error de formato, registro no encontrado). |
| bulk.completed | Emitido cuando el procesamiento de un archivo CSV masivo finaliza. Contiene el enlace de descarga del archivo de resultados. |
| bulk.failed | Emitido cuando el procesamiento de un archivo CSV falla (error de formato, timeout, archivo corrupto). |
Formato del payload
Cada notificación webhook contiene un payload JSON estructurado con la información del evento y los datos de validación.
{
"event_id": "evt_a1b2c3d4e5f6",
"event_type": "validation.completed",
"timestamp": "2025-01-15T14:30:00Z",
"api_version": "v1",
"data": {
"validation_id": "val_x9y8z7w6",
"type": "swift",
"input": "DEUTDEFF500",
"status": "VALID",
"confidence": "HIGH",
"bank_info": {
"name": "Deutsche Bank AG",
"city": "Frankfurt am Main",
"country": "DE"
},
"validation_details": {
"syntax": true,
"checksum": true,
"registry_match": true
}
}
}Campos del payload
event_idIdentificador único del evento (para deduplicación / idempotencia)event_typeTipo de evento (validation.completed, validation.failed, bulk.completed, bulk.failed)timestampMarca de tiempo ISO 8601 del eventoapi_versionVersión de la API utilizada (actualmente v1)dataObjeto con los detalles de la validación (type, input, status, confidence, bank_info)
Seguridad
Cada notificación webhook está firmada con su secreto para garantizar la autenticidad e integridad del payload.
Encabezado de firma
BankValidor firma cada payload con HMAC-SHA256 utilizando su secreto webhook. Verifique esta firma en el servidor para asegurarse de que la notificación proviene de BankValidor.
X-Webhook-Signature: sha256=a1b2c3d4e5f6...import hmac
import hashlib
def verify_webhook_signature(payload: bytes, signature: str, secret: str) -> bool:
"""Verify the HMAC-SHA256 signature of a webhook payload."""
expected = hmac.new(
secret.encode("utf-8"),
payload,
hashlib.sha256
).hexdigest()
received = signature.replace("sha256=", "")
return hmac.compare_digest(expected, received)
# Usage in your endpoint:
# signature = request.headers["X-Webhook-Signature"]
# is_valid = verify_webhook_signature(request.body, signature, WEBHOOK_SECRET)const crypto = require("crypto");
function verifyWebhookSignature(payload, signature, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(payload, "utf-8")
.digest("hex");
const received = signature.replace("sha256=", "");
return crypto.timingSafeEqual(
Buffer.from(expected, "hex"),
Buffer.from(received, "hex")
);
}
// Usage in your Express handler:
// const signature = req.headers["x-webhook-signature"];
// const isValid = verifyWebhookSignature(req.rawBody, signature, WEBHOOK_SECRET);Configuración
Gestione sus webhooks a través de la API REST. Puede crear, listar y eliminar webhooks.
Registrar un webhook
curl -X POST https://bankvalidor.com/api/v1/webhooks \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/bank-validator",
"events": ["validation.completed", "validation.failed"],
"secret": "your_webhook_secret"
}'
# Response:
{
"id": "wh_abc123",
"url": "https://your-app.com/webhooks/bank-validator",
"events": ["validation.completed", "validation.failed"],
"active": true,
"created_at": "2025-01-15T10:00:00Z"
}Listar webhooks
curl https://bankvalidor.com/api/v1/webhooks \
-H "Authorization: Bearer YOUR_API_KEY"
# Response:
{
"webhooks": [
{
"id": "wh_abc123",
"url": "https://your-app.com/webhooks/bank-validator",
"events": ["validation.completed", "validation.failed"],
"active": true,
"created_at": "2025-01-15T10:00:00Z"
}
]
}Eliminar un webhook
curl -X DELETE https://bankvalidor.com/api/v1/webhooks/wh_abc123 \
-H "Authorization: Bearer YOUR_API_KEY"
# Response:
{
"deleted": true,
"id": "wh_abc123"
}Política de reintentos
En caso de fallo en la entrega (timeout, error HTTP 5xx), BankValidor reintenta automáticamente con un retraso creciente.
| Intento | Retraso | Timeout |
|---|---|---|
| 1er intento | Inmediato | 30s |
| 2do intento | 5 minutos | 30s |
| 3er intento | 30 minutos | 30s |
Después de 3 fallos
Si los 3 intentos fallan, el evento se marca como no entregado. Puede consultar los eventos fallidos mediante el endpoint GET /api/v1/webhooks/failures y reproducirlos manualmente.
Buenas prácticas
Responda inmediatamente con un 200
Su endpoint debe retornar un código HTTP 200 lo más rápido posible. Todo procesamiento pesado debe realizarse de forma asíncrona después de la respuesta.
Procese de forma asíncrona
Guarde el payload y procéselo en segundo plano. Esto evita timeouts y garantiza que BankValidor reciba su acuse de recibo.
Implemente idempotencia
Use el event_id para detectar e ignorar duplicados. Durante los reintentos, el mismo evento puede enviarse varias veces.
from fastapi import FastAPI, Request, BackgroundTasks
from fastapi.responses import JSONResponse
app = FastAPI()
@app.post("/webhooks/bank-validator")
async def handle_webhook(request: Request, bg: BackgroundTasks):
# 1. Respond 200 immediately
payload = await request.json()
event_id = payload["event_id"]
# 2. Check idempotency (skip if already processed)
if await is_already_processed(event_id):
return JSONResponse({"status": "already_processed"})
# 3. Process asynchronously
bg.add_task(process_validation_event, payload)
return JSONResponse({"status": "accepted"})const express = require("express");
const app = express();
app.post("/webhooks/bank-validator", express.json(), async (req, res) => {
const { event_id } = req.body;
// 1. Respond 200 immediately
res.status(200).json({ status: "accepted" });
// 2. Check idempotency (skip if already processed)
const alreadyProcessed = await checkIfProcessed(event_id);
if (alreadyProcessed) return;
// 3. Process asynchronously
processValidationEvent(req.body).catch(console.error);
});Documentación relacionada
BankValidor — Webhooks