Skip to main content

¿Qué vas a lograr?

Al terminar esta guía tendrás un servidor que recibe y valida webhooks de OnePay, permitiéndote reaccionar en tiempo real a eventos como pagos aprobados, cargos exitosos o dispersiones completadas.

Prerrequisitos

  • Cuenta de OnePay con llaves API
  • Un servidor web con una URL pública accesible (o Ngrok para desarrollo local)

¿Cómo funcionan los webhooks?

OnePay envía una solicitud HTTP POST a tu URL con:
  • El payload del evento en el body
  • Un header x-webhook-token con un token de autenticación
  • Una firma HMAC-SHA256 para verificar la integridad

Paso a paso

1

Configurar la URL del webhook

  1. Ve a Desarrolladores > Webhooks en el panel de OnePay
  2. Agrega la URL de tu servidor (ej: https://tuapp.com/webhooks/onepay)
  3. Copia el secreto generado y el token de autenticación - los necesitarás para verificar los webhooks
2

Crear el endpoint en tu servidor

Tu servidor debe:
  1. Recibir solicitudes POST
  2. Verificar la firma HMAC
  3. Responder 200 OK inmediatamente
  4. Procesar el evento de forma asíncrona
const express = require('express');
const crypto = require('crypto');

const app = express();
app.use(express.json());

const WEBHOOK_SECRET = 'wh_tok_TU_SECRETO';
const WEBHOOK_TOKEN = 'wh_hdr_TU_TOKEN';

app.post('/webhooks/onepay', (req, res) => {
  // 1. Verificar el token de autenticación
  const token = req.headers['x-webhook-token'];
  if (token !== WEBHOOK_TOKEN) {
    return res.status(401).send('Token inválido');
  }

  // 2. Verificar la firma HMAC
  const payload = JSON.stringify(req.body);
  const signature = crypto
    .createHmac('sha256', WEBHOOK_SECRET)
    .update(payload)
    .digest('hex');

  // 3. Responder 200 inmediatamente
  res.status(200).send('OK');

  // 4. Procesar el evento
  const event = req.body.event;
  switch (event.type) {
    case 'payment.approved':
      console.log('Pago aprobado:', req.body.payment.id);
      // Actualizar orden en tu base de datos
      break;
    case 'cashout.processed':
      console.log('Dispersión procesada:', req.body.cashout.id);
      break;
    default:
      console.log('Evento recibido:', event.type);
  }
});

app.listen(3000);
3

Probar con Ngrok (desarrollo local)

Si estás desarrollando en local, usa Ngrok para exponer tu servidor:
ngrok http 3000
Copia la URL generada (ej: https://abc123.ngrok.io/webhooks/onepay) y configúrala como URL del webhook en el panel de OnePay.

Eventos disponibles

Pagos

EventoDescripción
payment.createdSe creó una solicitud de pago
payment.approvedEl cliente completó el pago exitosamente
payment.rejectedEl pago fue rechazado
payment.expiredEl link de pago expiró
payment.deletedSe eliminó la solicitud de pago

Cargos (Débitos)

EventoDescripción
charge.succeededCargo exitoso
charge.declinedCargo rechazado

Dispersiones

EventoDescripción
cashout.createdDispersión creada
cashout.processingDispersión en proceso
cashout.processedDispersión completada exitosamente
cashout.cancelledDispersión cancelada
cashout.rejectedDispersión rechazada

Suscripciones

EventoDescripción
subscription.createdSuscripción creada
subscription.paymentSe generó un cobro de suscripción
subscription.cancelledSuscripción cancelada

Cuentas

EventoDescripción
account.enrolledCuenta bancaria vinculada exitosamente
account.failedVinculación de cuenta falló

Estructura del payload

Cada webhook tiene la siguiente estructura:
{
  "payment": {
    "id": "9e5ccd4a-d2f0-49dd-87fc-a0da752bd166",
    "amount": 150000,
    "status": "succeeded",
    ...
  },
  "event": {
    "type": "payment.approved",
    "timestamp": 1689262934,
    "environment": "test"
  }
}
El nombre del objeto principal varía según el tipo de evento (payment, charge, cashout, subscription, etc.).

Buenas prácticas

Siempre responde 200 OK antes de procesar el evento. Si tu servidor tarda mucho en responder, OnePay podría considerar que el webhook falló e intentar reenviarlo.
  1. Verifica la firma: Siempre valida el HMAC antes de procesar el evento
  2. Idempotencia: Usa el event.type + el ID del recurso para evitar procesar un evento duplicado
  3. Responde rápido: Retorna 200 inmediatamente y procesa el evento en segundo plano
  4. Registra los eventos: Guarda un log de todos los webhooks recibidos para debugging
  5. Diferencia ambientes: El campo event.environment indica si es test o live

Errores comunes

ProblemaCausaSolución
No recibo webhooksURL incorrecta o inaccesibleVerifica que tu URL sea pública y responda a POST
Firma inválidaSecreto incorrecto o payload modificadoVerifica que usas el secreto correcto y no modificas el body
Eventos duplicadosTu servidor respondió con errorImplementa idempotencia verificando el ID del evento
Webhooks en locallocalhost no es accesibleUsa Ngrok u otra herramienta de tunneling

Siguiente paso