Saltar al contenido principal

Visión General de Estados

Un pago avanza por varios estados desde su creación hasta la liquidación final. Rastrear estos estados te permite confirmar la entrega, detectar fallos temprano y proporcionar información precisa a tus usuarios.

Flujo de Estados

Descripción de Estados

EstadoDescripciónMensaje Sugerido
CREATEDEl pago ha sido recibido y persistido. Está en espera de entrar a la cola de procesamiento.”Pago enviado”
PENDINGEl pago está en cola y esperando ser despachado al proveedor de pagos.”Próximamente en proceso”
PROCESSINGLa dispersión ha sido enviada al proveedor de pagos y está esperando confirmación.”Transferencia en progreso”
COMPLETEDEl proveedor de pagos confirmó la entrega exitosa de fondos al beneficiario.”¡Pago entregado!”
ERROROcurrió un error interno del sistema. No se dispersaron fondos. Contacta soporte si persiste.”Error interno — contacta soporte”
FAILEDLa dispersión fue rechazada por datos de cuenta del beneficiario inválidos o incorrectos.”Transferencia fallida — verifica datos del beneficiario”
REJECTEDEl pago fue bloqueado por una revisión de cumplimiento y no será procesado.”Transferencia rechazada — problema de cumplimiento”
REFUNDEDLos fondos dispersados han sido devueltos al saldo pre-financiado.”Fondos reembolsados al saldo”

Obtener Estado del Pago

GET /api/v2/payouts/{id}
const obtenerEstadoPago = async (payoutId) => {
  const response = await fetch(
    `https://sandbox.killb.app/api/v2/payouts/${payoutId}`,
    {
      headers: { 'Authorization': `Bearer ${token}` }
    }
  );

  const pago = await response.json();
  return pago.status;
};

Polling de Estado

Usa polling como respaldo cuando los webhooks no estén disponibles:
const esperarPago = async (payoutId, timeoutMs = 300000) => {
  const estadosTerminales = ['COMPLETED', 'ERROR', 'FAILED', 'REJECTED', 'REFUNDED'];
  const inicio = Date.now();

  while (Date.now() - inicio < timeoutMs) {
    const response = await fetch(
      `https://sandbox.killb.app/api/v2/payouts/${payoutId}`,
      { headers: { 'Authorization': `Bearer ${token}` } }
    );

    const pago = await response.json();
    console.log('Estado:', pago.status);

    if (estadosTerminales.includes(pago.status)) {
      return pago;
    }

    // Esperar 15 segundos antes del siguiente check
    await new Promise(resolve => setTimeout(resolve, 15000));
  }

  throw new Error(`El pago ${payoutId} no se liquidó dentro del tiempo límite`);
};

const resultado = await esperarPago('payout-abc123');

if (resultado.status === 'COMPLETED') {
  console.log('Fondos entregados exitosamente');
} else {
  console.error('El pago terminó con estado:', resultado.status);
}
Usa webhooks como método de notificación principal. El polling cada 15–30 segundos es apropiado como respaldo.

Webhooks para Actualizaciones de Estado

Suscríbete al tipo de evento PAYOUT para recibir notificaciones en tiempo real en cada cambio de estado:
// Suscribirse a eventos de pago
await fetch('/api/v2/webhooks', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    url: 'https://tu-app.com/webhooks/killb',
    secret: 'tu-secreto-webhook',
    events: ['PAYOUT'],
    active: true
  })
});
Maneja los eventos webhook de pago entrantes:
app.post('/webhooks/killb', (req, res) => {
  const { event, data } = req.body;

  switch (event) {
    case 'payout.pending':
      actualizarEstadoPago(data.id, 'PENDING');
      break;

    case 'payout.processing':
      actualizarEstadoPago(data.id, 'PROCESSING');
      break;

    case 'payout.completed':
      actualizarEstadoPago(data.id, 'COMPLETED');
      notificarDestinatario(data);
      break;

    case 'payout.error':
      // Error interno del sistema — no se dispersaron fondos
      actualizarEstadoPago(data.id, 'ERROR');
      alertarEquipoOps(data);
      break;

    case 'payout.failed':
      // Datos de cuenta del beneficiario inválidos o incorrectos
      actualizarEstadoPago(data.id, 'FAILED');
      notificarBeneficiarioInvalido(data);
      break;

    case 'payout.rejected':
      // Bloqueado por revisión de cumplimiento
      actualizarEstadoPago(data.id, 'REJECTED');
      escalarACumplimiento(data);
      break;

    case 'payout.refunded':
      // Fondos devueltos al saldo pre-financiado
      actualizarEstadoPago(data.id, 'REFUNDED');
      reconciliarSaldo(data);
      break;
  }

  res.status(200).json({ received: true });
});

Mejores Prácticas

Siempre configura un endpoint webhook para eventos PAYOUT. Esto te da actualizaciones instantáneas de estado sin sobrecarga de polling y reduce llamadas innecesarias a la API.
Si falla la entrega de tu webhook, consulta GET /api/v2/payouts/{id} cada 15–30 segundos. Establece un timeout razonable (ej. 5 minutos) y alerta a tu equipo si un pago permanece en PROCESSING más tiempo del esperado.
Cada estado de fallo no exitoso tiene una causa distinta y la remediación apropiada difiere:
  • ERROR — Un problema interno del sistema en KillB. No se requiere acción en los datos del beneficiario; contacta soporte si el problema recurre.
  • FAILED — El banco del beneficiario rechazó la transferencia por datos de cuenta inválidos o incorrectos. Revisa y corrige los datos del beneficiario antes de reintentar.
  • REJECTED — El pago fue bloqueado por una revisión de cumplimiento. No reintentar automáticamente; escalar internamente para revisión.
Obtén todos los pagos del día anterior vía GET /api/v2/payouts y reconcilia con tu libro mayor interno. Compara los estados terminales esperados vs. reales para detectar discrepancias temprano.
const { payouts } = await listarPagos({ limit: 100 });
const necesitanAtencion = payouts.filter(p =>
  ['ERROR', 'FAILED', 'REJECTED'].includes(p.status)
);

if (necesitanAtencion.length > 0) {
  console.warn(`${necesitanAtencion.length} pagos necesitan atención`, necesitanAtencion);
}

Próximos Pasos

Configurar Webhooks

Configura y asegura las notificaciones webhook

Manejo de Errores

Gestiona fallos de API con elegancia