Skip to main content

¿Qué es un Webhook?

Un webhook es una notificación HTTP POST que OnePay envía a tu servidor cuando ocurre un evento relevante (pago aprobado, cargo exitoso, dispersión procesada, etc.). En lugar de consultar la API constantemente, tu sistema recibe la información automáticamente.

Ejemplo Rápido

Cuando ocurre un evento, OnePay envía una solicitud POST a tu endpoint con este formato:
{
  "payment": {
    "id": "9e02ac3f-8d1b-4f5e-9c2a-7b3d4e5f6a7b",
    "amount": 150000,
    "amount_label": "$150.000",
    "status": "approved",
    "customer": {
      "id": "9dd4158b-0e45-42bc-b56f-a4c1f856814d",
      "first_name": "Juan",
      "last_name": "Pérez",
      "email": "juan@example.com"
    }
  },
  "event": {
    "id": "evt_9e02ac3f-8d1b",
    "type": "payment.approved",
    "timestamp": 1707398765,
    "environment": "production"
  }
}
Headers recibidos:
x-webhook-token: wh_hdr_abc123...
x-signature: 8f3a2b1c9d4e5f6a7b8c9d0e1f2a3b4c...
Content-Type: application/json

¿Por qué usar Webhooks?

Sin webhooksCon webhooks
Tu sistema consulta la API cada X segundosOnePay notifica a tu sistema al instante
Mayor consumo de recursos y requestsSolo procesas cuando hay un evento real
Posible retraso en detectar cambiosActualización en tiempo real

Configuración

1. Crear un endpoint público

Tu servidor debe exponer un endpoint HTTPS que reciba solicitudes POST. Ejemplo:
https://tuapp.com/webhooks/onepay

2. Registrar el webhook en OnePay

Puedes configurar tus webhooks de dos maneras: Opción A: Mediante el administrador web

Administrar webhooks

Opción B: Mediante la API

3. Verificar la firma HMAC-SHA256

Cada webhook incluye una firma HMAC-SHA256 en el header x-signature para verificar que proviene de OnePay. Debes validar esta firma antes de procesar el evento.
const crypto = require('crypto');

function verifyWebhookSignature(req) {
  const signature = req.headers['x-signature'];
  const secret = process.env.ONEPAY_WEBHOOK_SECRET; // wh_tok_...

  // El body debe ser el raw string, NO el objeto parseado
  const rawBody = JSON.stringify(req.body);

  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');

  return signature === expectedSignature;
}

// Uso en Express
app.post('/webhooks/onepay', express.json(), (req, res) => {
  if (!verifyWebhookSignature(req)) {
    return res.status(401).send('Invalid signature');
  }

  const { event } = req.body;
  console.log(`Received event: ${event.type}`);

  // Procesar el evento...

  res.status(200).send('OK');
});
Importante: Siempre usa el raw body (string) para calcular la firma, no el objeto JSON parseado. Cualquier diferencia en espacios o formato invalidará la firma.
HMAC es un hash con clave, no un cifrado. No se puede “descifrar”, solo se puede comparar calculando el mismo hash con los mismos datos y la misma clave.

4. Verificar el header de autenticación

Cada solicitud incluye un header x-webhook-token con un token de autorización. Este token es diferente al webhook secret y también sirve para verificar el origen:
x-webhook-token: 'wh_hdr_...'

Eventos disponibles

Los tipos de webhook que puedes recibir se documentan en cada sección:
RecursoEventosCuándo se disparaDocumentación
Paymentspayment.approvedEl cliente completó el pago exitosamenteVer detalles
payment.declinedEl pago fue rechazadoVer detalles
payment.cancelledEl cliente canceló el pagoVer detalles
Chargescharge.succeededEl cargo automático se procesó exitosamenteVer detalles
charge.declinedEl cargo automático fue rechazadoVer detalles
Cashoutscashout.processedLa dispersión se completó exitosamenteVer detalles
cashout.failedLa dispersión fallóVer detalles
Subscriptionssubscription.activatedLa suscripción se activóVer detalles
subscription.cancelledLa suscripción fue canceladaVer detalles
subscription.payment_failedFalló el cobro de una cuotaVer detalles
Accountsaccount.activeLa cuenta bancaria fue validadaVer detalles
account.rejectedLa cuenta fue rechazadaVer detalles

Testing local

Para desarrollo local, usa Ngrok para exponer tu servidor:
ngrok http 3000
Esto genera una URL pública temporal (ej: https://abc123.ngrok.io) que puedes registrar como webhook.

Buenas prácticas

  • Responde con HTTP 200 lo antes posible para evitar reintentos
  • Procesa los eventos de forma asíncrona (usa una cola de trabajo)
  • Verifica siempre la firma HMAC antes de procesar el evento
  • Implementa idempotencia para manejar eventos duplicados
  • Registra los eventos recibidos para depuración