Mono Colombia
Bre-B ParticipantArquitectura

Ciclo de vida del recaudo

Máquina de estados para recaudos Bre-B — transiciones, webhooks y estados terminales

Un recaudo es un endpoint receptor de Bre-B — típicamente un código QR o una llave de pago compartible — que permite a uno o más pagadores enviar fondos a tu cuenta tenant. Desde el momento en que lo creas, el recaudo se mueve por una secuencia determinística de estados. Cada transición mapea a un evento de webhook, así que tu integración puede rastrear el progreso sin polling. Esta guía explica qué significa cada estado, qué hace que un recaudo se mueva entre ellos y cómo distinguir el éxito terminal de la falla terminal.

Diagrama de estados

Estados de un vistazo

Estado¿Terminal?Evento de webhook
createdNocollection.created
readyNocollection.ready
minimum_paidNocollection.minimum_paid
paidcollection.paid
discardedcollection.discarded
failedcollection.failed

Los intentos de pago se rastrean por separado

Los intentos de pago individuales contra un recaudo ready o minimum_paid tienen su propia máquina de estados (successful, rejected, failed) y emiten sus propios eventos — collection.attempt_successful y collection.attempt_unsuccessful. Un intento fallido no saca al recaudo de su estado actual — solo incrementa el contador failed_attempts del recaudo.

Recorrido detallado

1. created

Estado inicial. Un recaudo entra a este estado tan pronto como create collection acepta tu request. La fila del recaudo existe en nuestro sistema y tiene un id que puedes usar para búsquedas, pero la llave Bre-B subyacente todavía no fue registrada con el directorio central (DICE), así que aún no puede aceptar pagos.

Los errores de validación nunca llegan a este estado

Si el request falla la validación síncrona — por ejemplo, los límites de monto son inválidos o el formato de la llave está mal formado — la API devuelve una respuesta 4xx y el recaudo no se persiste. Nunca pasará por esta máquina de estados y no se disparará ningún webhook.

Qué pasa después: el sistema registra la llave Bre-B con DICE. Esto típicamente se completa en segundos.

2. ready

La llave Bre-B fue registrada exitosamente con DICE y el arreglo keys del recaudo está poblado con la llave activa. El recaudo ya está vivo y puede aceptar pagos entrantes — los pagadores pueden escanear el QR o enviar a la llave.

Siguientes estados:

  • minimum_paid (solo recaudos multi-uso) una vez que el paid_amount acumulado alcanza o supera el total_minimum_amount.
  • paid una vez que el paid_amount acumulado alcanza el total_maximum_amount. Para recaudos de un solo uso esto pasa en el primer pago exitoso.
  • discarded si el recaudo se borra, expira o se auto-descarta por inactividad antes de ser pagado.

3. minimum_paid

Aplica solo a recaudos multi-uso que definen tanto un mínimo como un máximo. El paid_amount acumulado cruzó total_minimum_amount, lo que significa que el recaudo cumplió su objetivo soft pero sigue abierto a pagos adicionales hasta total_maximum_amount.

Este estado es útil para escenarios de pago parcial — por ejemplo, una recolección por objetivo que cumplió su meta pero sigue aceptando contribuciones hasta un tope duro.

Siguientes estados:

  • paid una vez que paid_amount alcanza total_maximum_amount.
  • discarded por expiración o inactividad.

4. paid (terminal)

El recaudo fue pagado por completo. paid_amount es igual a total_maximum_amount. El recaudo ya no acepta pagos y no ocurren más transiciones de estado.

5. discarded (terminal)

El recaudo fue removido del conjunto activo. El campo state_reason te dice por qué:

  • deleted — removido explícitamente vía delete collection.
  • expired — el recaudo pasó su expires_at sin alcanzar un estado terminal de pagado.
  • inactivity — el recaudo estuvo inactivo lo suficiente como para ser auto-descartado por el sistema.

No ocurren más transiciones de estado.

6. failed (terminal)

El recaudo no pudo ser usable. Esto pasa cuando el registro de la llave Bre-B falla entre created y ready. El campo state_reason lleva la causa — valores comunes incluyen key_already_registered, key_registration_failed y key_canceled.

Los recaudos fallidos no aceptan pagos y nunca vuelven a transicionar. Para recuperar, crea un nuevo recaudo (típicamente con otra llave).

Trabajando con estados en tu integración

  1. Trata cada estado no terminal como transitorio. Un recaudo en created aún no es usable — espera ready antes de mostrar el QR o la llave a los pagadores.
  2. Trabaja con webhooks, no con polling. Cada transición de estado emite un webhook con el nuevo estado y, donde aplique, un state_reason. Verifica cada webhook (ver Verificación de firma de webhook) y actualiza tu registro local de forma idempotente — el mismo estado puede ser reintentado por nuestros workers.
  3. Maneja entrega fuera de orden. Las entregas de webhook son at-least-once. Si ves paid antes que minimum_paid, conserva el estado más reciente e ignora el anterior. Una regla simple: si el recaudo ya está en un estado terminal localmente, ignora los webhooks no terminales.
  4. Distingue el estado del recaudo del estado del intento. Un recaudo ready puede tener muchos eventos collection.attempt_unsuccessful sin dejar el estado ready. Surface los fallos de intento por separado del estado del recaudo en tu UI y lógica de conciliación.
  5. Tres estados son finales. paid, discarded y failed son los únicos estados terminales. Una vez que un recaudo alcanza cualquiera de ellos, nunca volverá a moverse.

En esta página