> ## Documentation Index
> Fetch the complete documentation index at: https://docs.killb.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Seguimiento de Estado de Pagos

> Monitorea y gestiona el estado de las dispersiones

## Visión General de Estados

Un pago avanza por varias fases desde su creación hasta la liquidación final. Cada fase tiene tres estados — Pendiente, En Procesamiento y Completado — ofreciéndote visibilidad granular en cada etapa del pipeline.

## Flujo de Estados

```mermaid theme={null}
graph TD
    CREATED --> CASH_IN_PENDING
    CASH_IN_PENDING --> CASH_IN_PROCESSING
    CASH_IN_PROCESSING --> CASH_IN_COMPLETED
    CASH_IN_COMPLETED --> KYT_OUT_PENDING
    KYT_OUT_PENDING --> KYT_OUT_PROCESSING
    KYT_OUT_PROCESSING --> KYT_OUT_COMPLETED
    KYT_OUT_COMPLETED --> CASH_OUT_PENDING
    CASH_OUT_PENDING --> CASH_OUT_PROCESSING
    CASH_OUT_PROCESSING --> CASH_OUT_COMPLETED
    CASH_OUT_COMPLETED --> COMPLETED

    KYT_OUT_PROCESSING -.-> REVIEW_NEEDED
    REVIEW_NEEDED -.->|resuelto| KYT_OUT_COMPLETED
    REVIEW_NEEDED -.->|bloqueado| REJECTED

    FAILED --> REFUND_PENDING
    ERROR --> REFUND_PENDING
    REJECTED --> REFUND_PENDING
    REFUND_PENDING --> REFUND_PROCESSING
    REFUND_PROCESSING --> REFUNDED

    CASH_IN_PROCESSING -.-> FAILED
    CASH_IN_PROCESSING -.-> ERROR

    KYT_OUT_PROCESSING -.-> FAILED
    KYT_OUT_PROCESSING -.-> ERROR
    CASH_OUT_PROCESSING -.-> FAILED
    CASH_OUT_PROCESSING -.-> REJECTED
    CASH_OUT_PROCESSING -.-> ERROR

    style COMPLETED fill:#22c55e,color:#fff
    style REJECTED fill:#f97316,color:#fff
    style FAILED fill:#ef4444,color:#fff
    style ERROR fill:#ef4444,color:#fff
    style REFUNDED fill:#6366f1,color:#fff
    style REVIEW_NEEDED fill:#eab308,color:#000
```

<Warning>
  Durante la fase de **Cash In**, `FAILED` y `ERROR` son estados terminales — no se recolectaron fondos, por lo que no se emite ningún reembolso. Para todas las fases siguientes (KYT Out, Cash Out), `FAILED` y `ERROR` son transitorios: el pago transiciona al flujo de reembolso (`REFUND_PENDING` → `REFUND_PROCESSING` → `REFUNDED`). `REJECTED` también activa el flujo de reembolso, ya que solo ocurre después del Cash In.
</Warning>

## Descripción de Estados

| Estado                | Fase            | Descripción                                                                                                                             | Mensaje Sugerido                                          |
| --------------------- | --------------- | --------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
| `CREATED`             | Inicial         | Pago recibido y persistido, en espera de entrar a la cola                                                                               | "Pago enviado"                                            |
| `CASH_IN_PENDING`     | Cash In         | Colección de fondos entrantes en cola                                                                                                   | "Procesando pago"                                         |
| `CASH_IN_PROCESSING`  | Cash In         | Recolectando fondos del saldo pre-financiado                                                                                            | "Recolectando fondos"                                     |
| `CASH_IN_COMPLETED`   | Cash In         | Fondos recolectados exitosamente                                                                                                        | "Fondos recolectados"                                     |
| `KYT_OUT_PENDING`     | KYT Out         | Transacción saliente en cola para verificación de cumplimiento                                                                          | "Verificación de salida pendiente"                        |
| `KYT_OUT_PROCESSING`  | KYT Out         | Revisión de cumplimiento en progreso (saliente)                                                                                         | "Verificación de salida en progreso"                      |
| `KYT_OUT_COMPLETED`   | KYT Out         | Verificación de cumplimiento saliente aprobada                                                                                          | "Listo para transferir"                                   |
| `CASH_OUT_PENDING`    | Cash Out        | Dispersión al beneficiario en cola                                                                                                      | "Transferencia en cola"                                   |
| `CASH_OUT_PROCESSING` | Cash Out        | Fondos enviados al proveedor de pagos                                                                                                   | "Transferencia en progreso"                               |
| `CASH_OUT_COMPLETED`  | Cash Out        | Proveedor de pagos confirmó la entrega                                                                                                  | "Transferencia entregada"                                 |
| `COMPLETED`           | Terminal        | Pago totalmente liquidado                                                                                                               | "¡Pago entregado!"                                        |
| `REVIEW_NEEDED`       | Revisión        | Transacción marcada para revisión manual de cumplimiento                                                                                | "En revisión — te notificaremos"                          |
| `FAILED`              | Estado de Error | Operación fallida. Terminal durante Cash In (no se recolectaron fondos). Inicia flujo de reembolso si ocurre en fase posterior.         | "Transferencia fallida — verifica datos del beneficiario" |
| `REJECTED`            | Estado de Error | Pago bloqueado por revisión de cumplimiento. Siempre activa el flujo de reembolso, ya que solo ocurre después del Cash In.              | "Transferencia rechazada — problema de cumplimiento"      |
| `ERROR`               | Estado de Error | Error interno del sistema. Terminal durante Cash In (no se recolectaron fondos). Inicia flujo de reembolso si ocurre en fase posterior. | "Error interno — contacta soporte"                        |
| `REFUND_PENDING`      | Reembolso       | Reembolso al saldo pre-financiado en cola                                                                                               | "Reembolso iniciado"                                      |
| `REFUND_PROCESSING`   | Reembolso       | Reembolso en progreso                                                                                                                   | "Reembolso en progreso"                                   |
| `REFUNDED`            | Terminal        | Fondos devueltos al saldo pre-financiado                                                                                                | "Fondos reembolsados al saldo"                            |

## Obtener Estado del Pago

```bash theme={null}
GET /api/v2/payouts/{id}
```

```javascript theme={null}
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:

```javascript theme={null}
const esperarPago = async (payoutId, timeoutMs = 300000) => {
  const estadosTerminales = ['COMPLETED', 'FAILED', 'REJECTED', 'ERROR', '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);
}
```

<Tip>
  Usa webhooks como método de notificación principal. El polling cada 15–30 segundos es apropiado como respaldo.
</Tip>

## Webhooks para Actualizaciones de Estado

Suscríbete al tipo de evento `PAYOUT` para recibir notificaciones en tiempo real en cada cambio de estado:

```javascript theme={null}
// 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:

```javascript theme={null}
app.post('/webhooks/killb', (req, res) => {
  const { event, data } = req.body;

  switch (event) {
    // Eventos de progreso de fase — actualiza el indicador de estado en tu interfaz
    case 'payout.cash_in_pending':
    case 'payout.cash_in_processing':
    case 'payout.cash_in_completed':
    case 'payout.kyt_out_pending':
    case 'payout.kyt_out_processing':
    case 'payout.kyt_out_completed':
    case 'payout.cash_out_pending':
    case 'payout.cash_out_processing':
    case 'payout.cash_out_completed':
    case 'payout.refund_pending':
    case 'payout.refund_processing': {
      const status = event.replace('payout.', '').toUpperCase();
      actualizarEstadoPago(data.id, status);
      break;
    }

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

    case 'payout.review_needed':
      // Transacción marcada para revisión manual — no se requiere acción
      actualizarEstadoPago(data.id, 'REVIEW_NEEDED');
      alertarEquipoCumplimiento(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

<AccordionGroup>
  <Accordion title="Webhooks como Canal Principal" icon="bell">
    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.
  </Accordion>

  <Accordion title="Polling como Respaldo" icon="rotate">
    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 cualquier estado de procesamiento más tiempo del esperado.
  </Accordion>

  <Accordion title="Distinguir Estados de Fallo" icon="circle-xmark">
    Cada estado de fallo tiene una causa distinta. La fase en que ocurre `FAILED` o `ERROR` determina si se emite un reembolso:

    * **`FAILED` / `ERROR` durante Cash In** — Terminal. No se recolectaron fondos, por lo que no se emite reembolso. Para `ERROR`, contacta soporte si recurre.
    * **`FAILED` / `ERROR` después de Cash In** (KYT Out, Cash Out) — Transitorio. Como los fondos ya fueron recolectados, el pago transiciona automáticamente a `REFUND_PENDING` → `REFUND_PROCESSING` → `REFUNDED`.
    * **`REJECTED`** — Bloqueado por revisión de cumplimiento. No reintentar automáticamente; escalar internamente. Siempre activa el flujo de reembolso ya que los fondos fueron recolectados.
    * **`REVIEW_NEEDED`** — Una verificación KYT marcó la transacción para revisión manual. El pago se reanuda automáticamente o transiciona a `REJECTED`; no se requiere acción de tu parte.
  </Accordion>

  <Accordion title="Reconciliar Diariamente" icon="calculator">
    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.

    ```javascript theme={null}
    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);
    }
    ```
  </Accordion>
</AccordionGroup>

## Próximos Pasos

<CardGroup cols={2}>
  <Card title="Configurar Webhooks" icon="bell" href="/es/guides/webhooks/setup">
    Configura y asegura las notificaciones webhook
  </Card>

  <Card title="Manejo de Errores" icon="shield" href="/es/resources/error-handling">
    Gestiona fallos de API con elegancia
  </Card>
</CardGroup>
