Recibe webhooks firmados
Verifica las firmas HMAC antes de aplicar cambios al estado de los pagos.
Registra un endpoint
curl --request POST "${API_URL}/v1/webhooks" \
--header "content-type: application/json" \
--header "x-api-key: ${VE_BANKING_API_KEY}" \
--data '{
"url": "https://merchant.example.com/webhooks/ve-banking",
"events": ["payment.pending", "payment.completed", "payment.failed", "payment.reversed"]
}'{
"event": "payment.completed",
"data": {
"paymentId": "00000000-0000-4000-8000-000000000000",
"status": "COMPLETED"
},
"timestamp": "2026-07-20T15:00:00.000Z"
}Usa POST /v1/notifications/test después de registrar un endpoint. Las entregas incluyen los encabezados X-Webhook-Event y X-Webhook-Signature.
Comportamiento de las entregas
- Cada evento se intenta entregar una sola vez. Las entregas fallidas no se reintentan.
- Tu endpoint tiene 10 segundos para responder.
- No se garantiza el orden de los eventos; compara el estado del pago en lugar del orden de llegada.
- Devuelve una respuesta 2xx solo después de que el evento sea aceptado para su procesamiento persistente.
- Concilia los eventos perdidos o inciertos mediante los endpoints de consulta de pagos.
Verifica la firma HMAC
Calcula un resumen HMAC-SHA256 sobre el cuerpo original exacto de la solicitud usando el secreto de tu endpoint. Compara las firmas recibida y esperada con una operación segura frente a ataques de temporización antes de analizar el evento o actuar sobre él.
import { createHmac, timingSafeEqual } from 'node:crypto';
export function verifyWebhook(rawBody, signature, secret) {
if (!/^sha256=[a-f0-9]{64}$/i.test(signature)) return false;
const expected = createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
const received = Buffer.from(signature.slice('sha256='.length), 'hex');
const calculated = Buffer.from(expected, 'hex');
return timingSafeEqual(received, calculated);
}