# Estados y webhooks

Beta
Smart Collections está actualmente en Beta. Algunos contratos en esta página aún están siendo confirmados con nuestro equipo de ingeniería, por lo que deben considerarse provisionales y se esperan refinamientos antes de la disponibilidad general, incluyendo:

- Cargas útiles de webhook y códigos de eventos
- Actualizaciones de referencia de la API para los endpoints de Collection Instructions, Payment Authorization y Charge
- Nombres de campos y mejoras en la documentación (terminología, diagramas)


Contacta a tu gerente de cuenta de Belvo para unirte al programa Beta.

Esta página es la referencia para los estados de los objetos y los webhooks utilizados en ambas fases de Smart Collections. Para el flujo paso a paso, consulta Fase 1 y Fase 2.

## Estados

### Instrucción de Colección

| Estado  | Significado |
|  --- | --- |
| `PROCESSING` | Creado. Belvo está monitoreando (o ha terminado de monitorear) sus ítems. Una instrucción permanece `PROCESSING` hasta que la canceles; verifica el estado de cada ítem para ver cómo terminó el monitoreo. |
| `CANCELLED` | Cancelaste la instrucción. Cualquier ítem que aún estaba siendo monitoreado también fue cancelado. |


### Elemento de Instrucción de Cobro

Solo `CHARGE_SETTLED` envía un webhook. Para leer el estado de cualquier elemento, obtén los detalles de la instrucción.


```mermaid
stateDiagram-v2
    [*] --> PENDING
    PENDING --> PROCESSING: a balance check starts
    PROCESSING --> PENDING: not enough funds yet
    PROCESSING --> CHARGE_SETTLED: enough funds, webhook sent
    PROCESSING --> POLICY_EXPIRED: no collection window left
    PROCESSING --> CHARGE_REJECTED: the account can't be read
    PENDING --> COMPLETED: you mark it complete
    PENDING --> CANCELLED: you cancel it
    PROCESSING --> CANCELLED: you cancel it
```

| Estado  | Significado |
|  --- | --- |
| `PENDING` | Esperando la próxima verificación de saldo programada. |
| `PROCESSING` | Una verificación de saldo está en progreso. |
| `CHARGE_SETTLED` | El saldo cubrió el `amount` del elemento y Belvo te envió `item_ready_to_charge`. El monitoreo se detiene. A pesar de su nombre, este estado **no** significa que se realizó un Cargo: tú creas el Cargo en la Fase 2. |
| `POLICY_EXPIRED` | Todas las ventanas de cobro del elemento terminaron sin saldo suficiente. **No se envía webhook.** |
| `CHARGE_REJECTED` | Belvo no pudo leer el saldo de ninguna de las cuentas del usuario (por ejemplo, el consentimiento de datos ya no es válido). **No se envía webhook.** |
| `FAILED` | Un error interno detuvo el monitoreo. **No se envía webhook.** |
| `COMPLETED` | Tú marcaste el elemento como completo (lo cobraste fuera de Belvo), por lo que Belvo dejó de monitorearlo. |
| `CANCELLED` | Cancelaste el elemento (o toda su instrucción). |


### Autorización de Pago y Cargo

La Fase 2 utiliza Autorizaciones de Pago y Cargos de Smart Transfers. Para conocer sus estados, consulta la referencia de estados de Smart Transfers.

## Webhooks

Smart Collections utiliza **dos canales de webhook**. Debes configurar un endpoint en cada uno.

| Canal  | Fase  | Eventos  | Versionado |
|  --- | --- | --- | --- |
| Aggregation (`COLLECTIONS`) | Fase 1 | `item_ready_to_charge` | Ninguno (los webhooks de agregación no tienen versión) |
| Payments | Fase 2 | `PAYMENT_AUTHORIZATION`, `CHARGE` | `Payments-BR.V2` |


### Fase 1: `item_ready_to_charge` (Agregación)

Se envía una vez, cuando el saldo de una de las cuentas del usuario cubre el `amount` de un ítem. El ítem se mueve a `CHARGE_SETTLED` y Belvo deja de monitorearlo.


```json item_ready_to_charge webhook
{
  "webhook_id": "e29b41d4a7164a4fae1112b8c9d3f5a2",
  "webhook_type": "COLLECTIONS",
  "webhook_code": "item_ready_to_charge",
  "process_type": null,
  "link_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", // [!code warning]
  "external_id": null,
  "data": {
    "item_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
    "external_id": "inv-2026-001",
    "amount": "150.50"
  }
}
```

| Campo  | Descripción |
|  --- | --- |
| `webhook_id` | Un ID único para esta entrega de webhook. Úsalo para detectar y descartar entregas duplicadas. |
| `webhook_type` | Siempre `COLLECTIONS` para este evento. |
| `webhook_code` | Siempre `item_ready_to_charge` para este evento. |
| `process_type` | Siempre `null` para este evento. |
| `link_id` | El `id` del Link OFDA que esta Instrucción de Cobro monitorea. |
| `external_id` | Siempre `null` para este evento. Usa `data.external_id` en su lugar. |
| `data.item_id` | El `id` del ítem de la Instrucción de Cobro cuya condición de saldo se cumplió. |
| `data.external_id` | El `external_id` que configuraste en ese ítem, o `null` si no configuraste uno. |
| `data.amount` | El `amount` del ítem: lo que debes cobrar en la Fase 2, como una cadena de texto. |


Identifica el ítem, no la cuenta o la política
La carga útil te indica qué **ítem** coincidió, pero no cuál de las cuentas del usuario tenía el saldo, ni qué ventana de `collection_policy` estaba abierta. Para cobrar de una cuenta específica, consulta Fase 2.

Consulta Webhooks de Agregación para el sobre general del webhook de Agregación.

No hay webhook cuando el monitoreo termina sin fondos
Los ítems que terminan en `POLICY_EXPIRED`, `CHARGE_REJECTED` o `FAILED` no activan un webhook. Haz seguimiento de la última `end_date` de tus ítems y concilia aquellos que nunca produjeron un `item_ready_to_charge`.

### Fase 2: `PAYMENT_AUTHORIZATION` y `CHARGE` (Pagos)

Estos son webhooks estándar de `Payments-BR.V2`. Solo te informan que un recurso cambió, por lo que debes hacer un `GET` al recurso para leer su estado:


```json Payments V2 webhook
{
  "schema_version": "2.0.0",
  "resource": "CHARGE",
  "resource_id": "0d3ffb69-f83b-456e-ad8e-208d0998d71d",
  "resource_version": "V2",
  "timestamp": "2026-10-16T15:00:07Z"
}
```

Para el formato del payload y cómo obtener los detalles completos, consulta Webhooks de Pagos (Brasil).

### Confiabilidad de los webhooks

- **Configuraciones separadas por canal:** Los webhooks de `COLLECTIONS` se configuran por separado de los webhooks de Payments en el panel de Belvo, cada uno con su propia URL y un token Bearer opcional.
- **Autenticación:** Belvo no firma los webhooks (sin HMAC). Restringe tu endpoint con una lista de IPs permitidas de las IPs de Belvo, y opcionalmente configura un token Bearer.
- **Reintentos:** `item_ready_to_charge` se reintenta hasta tres veces solo cuando Belvo no puede conectarse a tu endpoint, así que asegúrate de que tu endpoint sea accesible y responda rápidamente. Para los reintentos de webhooks de Payments, consulta Webhooks de Payments (Brasil).
- **Orden:** los webhooks pueden llegar fuera de orden o muy cerca uno del otro. Debido a que los webhooks de Payments no llevan el estado, hacer un `GET` por cada webhook mantiene tu vista del estado correcta.
- **Recuperación de eventos perdidos:** no hay repetición de eventos. Ejecuta una tarea recurrente que verifique autorizaciones y Cargos que aún no estén en un estado final, y elementos de Instrucción de Cobro que aún estés esperando.