Guía para desarrolladores
Referencia de API
Explorar documentación

Recibe webhooks firmados

Verifica las firmas HMAC antes de aplicar cambios al estado de los pagos.

Registra un endpoint

curlbash
curl --request POST "${API_URL}/v1/webhooks" \
  --header "content-type: application/json" \
  --header "x-api-key: ${VEXPAY_API_KEY}" \
  --data '{
    "url": "https://merchant.example.com/webhooks/vexpay",
    "events": ["payment.pending", "payment.completed", "payment.failed", "merchant.verified", "merchant.rejected", "merchant.deactivated", "merchant.reactivated", "payout.completed", "payout.failed"]
  }'
Envoltoriojson
{
  "event": "payment.completed",
  "data": {
    "paymentId": "00000000-0000-4000-8000-000000000000",
    "status": "COMPLETED"
  },
  "timestamp": "2026-07-20T15:00:00.000Z"
}
merchant.rejectedjson
{
  "event": "merchant.rejected",
  "data": {
    "merchantId": "292d478b-a1fb-4d27-ab5c-8701ed14da88",
    "externalRef": "seller_47",
    "payoutMethodId": "0064456b-7a6a-4b7e-b0b5-d9b27b0dfa5c",
    "failureCode": "BE01",
    "reason": "Datos del cliente no corresponden a la cuenta",
    "action": "payout_method_deleted"
  },
  "timestamp": "2026-07-23T18:12:05.000Z"
}

Actualiza los eventos suscritos después con PATCH /v1/webhooks/:id — al enviar events se reemplaza la lista completa. También puedes cambiar url o isActive; el secreto de firma no se puede rotar vía PATCH.

curlbash
curl --request PATCH "${API_URL}/v1/webhooks/ENDPOINT_ID" \
  --header "content-type: application/json" \
  --header "x-api-key: ${VEXPAY_API_KEY}" \
  --data '{
    "events": ["payment.completed", "payment.failed", "payout.completed", "payout.failed"]
  }'

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.

Node.jsjavascript
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);
}