Códigos de error de transferencia saliente
Motivos de rechazo, razones de estado y recomendaciones de manejo para transferencias salientes de Bre-B
Los errores al crear y procesar transferencias salientes caen en dos categorías según cuándo se exponen:
- Motivos de rechazo — errores de validación devueltos de forma síncrona cuando creas un batch. La transferencia rechazada nunca se persiste.
- Razones de estado — errores que ocurren durante el procesamiento asíncrono.
Te enteras por webhooks
outgoing_transfer.failed, donde el campostate_reasonlleva el código.
Motivos de rechazo
Estos errores se devuelven en el arreglo rejected_transfers de la respuesta de
crear transferencias salientes.
Las transferencias rechazadas no se crean en el sistema — no se disparará
ningún webhook por ellas, así que tienes que manejarlas desde la respuesta síncrona.
Ejemplo de respuesta
{
"id": "batch_123e4567-e89b-12d3-a456-426614174000",
"state": "created",
"transfers": [],
"rejected_transfers": [
{
"external_id": "transfer_001",
"reason": "amount_exceeds_max_limit"
},
{
"external_id": "transfer_002",
"reason": "target_not_found"
}
]
}Referencia de códigos
| Código | Descripción | Causa | Solución sugerida |
|---|---|---|---|
amount_not_provided | Monto no provisto | El campo amount es obligatorio pero faltó o vino en null. | Incluye amount con un valor válido. |
amount_exceeds_max_limit | El monto supera el límite máximo | El monto de la transferencia supera el máximo permitido por transacción. | Reduce el monto o divídelo en varias transferencias. |
target_amount_mismatch | El monto no coincide con el target | Al usar un target_id existente con transaction_amount fijo (por ejemplo, un QR estático), el monto enviado debe coincidir exacto. | Envía el monto del target, o omite amount para usar el valor del target. |
target_already_exists | Target ya utilizado | Una transferencia activa (no fallida) ya usa este target_id. Cada target solo puede consumirse una vez. | Usa otro target o espera a que la transferencia en vuelo llegue a un estado terminal. |
target_not_found | Target no encontrado | El target_id provisto no existe o no pertenece al tenant actual. | Verifica que el target_id sea correcto y pertenezca a tu tenant. |
Razones de estado
Estos errores ocurren durante el procesamiento asíncrono y se entregan por el
webhook outgoing_transfer.failed,
con el código legible por máquina en event.data.state_reason.
Ejemplo de payload de webhook
{
"timestamp": "2025-12-17T20:14:01.947520Z",
"event": {
"type": "outgoing_transfer.failed",
"data": {
"id": "bbot_031uOJ6qb0sVclNseQfItQ",
"state": "failed",
"state_reason": "target_creditor_mismatch",
"external_id": "21752385-357e-450f-94a3-d9a0984da291",
"amount": { "currency": "COP", "amount": 100 },
"expected_creditor": {
"document_type": "CC",
"document_number": "21482961"
},
"target": {
"creditor": {
"document_type": "CC",
"document_number": "123143455",
"full_name": "Juan Carlos Perez Gomez"
}
}
}
}
}Errores de resolución de llave
Se levantan al resolver la llave Bre-B del destinatario.
| Código | Descripción | Causa | Solución sugerida |
|---|---|---|---|
key_not_found | Llave no encontrada | La llave Bre-B no existe en el sistema de pagos instantáneos. | Verifica la llave. El destinatario debe tener una llave registrada. |
key_suspended | Llave suspendida | La llave Bre-B del destinatario está temporalmente suspendida. | Pide al destinatario que regularice su llave con su entidad financiera. |
invalid_key_format | Formato inválido | El formato de la llave no cumple las reglas de Bre-B. | Verifica el formato contra la tabla de tipos de llave. |
Errores de validación del destinatario
Se levantan cuando los datos del destinatario son inválidos o no coinciden con el dueño de la llave.
| Código | Descripción | Causa | Solución sugerida |
|---|---|---|---|
target_creditor_mismatch | Creditor no coincide | El expected_creditor (tipo + número de documento) no coincide con el verdadero dueño de la llave Bre-B. | Verifica los datos del destinatario antes de enviar. Esta validación previene transferencias erradas. |
creditor_account_not_found | Cuenta del creditor no encontrada | La cuenta bancaria asociada a la llave ya no existe o fue cerrada. | El destinatario debe verificar la cuenta con su entidad financiera. |
invalid_creditor_account | Cuenta del creditor inválida | La cuenta del destinatario no puede recibir transferencias (bloqueada, inactiva, etc.). | El destinatario debe regularizar su cuenta bancaria. |
Errores de fondos
Se levantan durante el hold de fondos.
| Código | Descripción | Causa | Solución sugerida |
|---|---|---|---|
insufficient_funds | Fondos insuficientes | La cuenta origen no tiene saldo suficiente para cubrir la transferencia. | Asegúrate de tener saldo disponible antes de crear la transferencia. |
amount_exceeds_balance_limit | Monto supera límite de saldo | El monto llevaría al destinatario por encima del límite de saldo permitido. | Reduce el monto de la transferencia. |
Errores del proveedor
Se levantan por problemas del proveedor Bre-B o de sistemas aguas arriba.
| Código | Descripción | Causa | Solución sugerida |
|---|---|---|---|
risk_control | Rechazado por risk control | La transferencia fue rechazada por el sistema de risk control del proveedor. | Revisa los patrones de transacción. Puede requerir contactar soporte. |
breb_timeout | Timeout del proveedor Bre-B | El proveedor Bre-B no respondió a tiempo. | Reintenta más tarde. Si persiste, contacta soporte. |
provider_unavailable | Proveedor no disponible | El proveedor Bre-B está temporalmente fuera de servicio. | Reintenta más tarde. |
unknown | Error desconocido | Ocurrió un error no categorizado. | Contacta a soporte técnico con el id de la transferencia. |
Recomendaciones de integración
1. Valida antes de enviar
Antes de llamar al endpoint de creación de transferencias, valida:
- Que el monto esté dentro de los límites permitidos.
- Que los datos del destinatario sean correctos (si usas
expected_creditor). - Que la cuenta origen tenga saldo suficiente.
2. Maneja rejected_transfers desde la respuesta del batch
const response = await createBatch(batchData);
if (response.rejected_transfers.length > 0) {
for (const rejected of response.rejected_transfers) {
console.error(`Transfer ${rejected.external_id} rejected: ${rejected.reason}`);
// Notifica al usuario o márcalo para revisión
}
}3. Maneja los webhooks outgoing_transfer.failed
app.post('/webhook', (req, res) => {
const { event } = req.body;
if (event.type === 'outgoing_transfer.failed') {
const { id, external_id, state_reason } = event.data;
switch (state_reason) {
case 'insufficient_funds':
// Notifica al usuario que faltan fondos
break;
case 'target_creditor_mismatch':
// Pide al usuario reverificar los datos del destinatario
break;
case 'key_not_found':
// Indica que la llave es inválida
break;
default:
// Manejo por defecto
}
}
res.status(200).send();
});4. Guía de reintentos
| Error | ¿Reintentable? | Recomendación |
|---|---|---|
breb_timeout | Sí | Reintenta después de 1–5 minutos. |
provider_unavailable | Sí | Reintenta después de 5–15 minutos. |
insufficient_funds | Sí* | Reintenta cuando haya fondos disponibles. |
key_not_found | No | Confirma la llave del destinatario con el usuario. |
target_creditor_mismatch | No | Corrige los datos del destinatario. |
risk_control | No | Contacta a soporte. |
Soporte
Al contactar soporte sobre una transferencia fallida, provee el id de la transferencia (y el
id del batch si aplica), el external_id para correlación, y una descripción del escenario
y la frecuencia.