Ir al contenido

Errores y reintentos

La API Transaccional usa dos familias de respuesta para señalizar problemas: códigos HTTP (problemas de transporte, autenticación o rate limit) y validación de negocio (problemas semánticos del payload, devueltos como HTTP 200 con valid: false). Entender la diferencia es clave para reintentar sin generar transacciones duplicadas.

Códigos HTTP

CampoTipoDescripción
400
Bad Request
Payload con formato o tipos inválidos. Revisa los campos antes de reintentar.
401
Unauthorized
Token ausente, expirado o inválido. Refresca el access token y reintenta una vez.
403
Forbidden
IP fuera de la lista permitida, credencial en estado BLOCKED/REVOKED o política denegada. No reintentar hasta corregir la causa.
409
Conflict
DUPLICATE_EXTERNAL_REFERENCE: el externalReferenceId ya existe para tu empresa, sin importar su estado (también si quedó FAILED). El mismo ID nunca crea una transacción duplicada; consulta su estado o, si fue rechazada, corrige la causa y envía un ID nuevo.
429
Too Many Requests
Rate limit excedido. Aplica backoff exponencial y respeta el header Retry-After cuando esté presente.
5xx
Server Error
Error transitorio del procesador. Consulta el estado de la transacción antes de reintentar. En la versión 2, un 502 con ACCOUNT_ENRICHMENT_FAILED o BALANCE_VALIDATION_FAILED es un rechazo: corrige la causa y envía un externalReferenceId nuevo.

Validación de negocio — 200 + valid: false

Cuando la petición está bien formada pero viola una regla de negocio (monto fuera de rango, cuenta inválida, propósito bloqueado, etc.) la API responde con HTTP 200 y un cuerpo con la lista de violaciones.

Copiar código
CampoDescripción
validtrue cuando el payload pasa todas las validaciones; false en caso contrario.
statusPROCESSING cuando se acepta; FAILED cuando se rechaza por validación.
violationsLista de violaciones. Vacía cuando valid: true.

Errores de la versión 2

Los errores de v2 usan el mismo cuerpo que las violaciones de la versión 1: externalReferenceId, status: "FAILED", valid: false y la lista violations. Ninguno de estos rechazos cotiza ni debita saldo.

HTTPrulefieldsourceCuándo ocurre
400NOT_NULLwalletIdREQUESTEnviaste X-Api-Version: 2 sin walletId.
400ORIGIN_WALLET_NOT_FOUNDwalletIdACCOUNTEl walletId no existe o no pertenece a la empresa autenticada.
502ACCOUNT_ENRICHMENT_FAILED—ACCOUNTNo se pudo consultar la cuenta por un error interno.

400 NOT_NULL en walletId

Copiar código

Incluye el walletId en el cuerpo, o quita el header X-Api-Version: 2 si quieres seguir usando la versión 1.

400 ORIGIN_WALLET_NOT_FOUND

Copiar código

Vuelve a consultar GET /b2b/accounts y usa un walletId de una cuenta de tu empresa.

502 ACCOUNT_ENRICHMENT_FAILED

Copiar código

La violación no trae field. Se devuelve cuando la cuenta no se pudo consultar por un error interno, y también cuando el servicio interno de cuentas responde un 400 o 403 al validarla: un 400/403 interno se traduce en un 502 para ti. No es un error de tu payload; espera unos segundos y envía el pago de nuevo con un externalReferenceId nuevo. Si persiste, escribe a soporte con el externalReferenceId del intento.

Saldo y validación asíncrona

Los pagos REMITTANCE y P2P donde la moneda de origen es igual a la de destino se procesan de forma asíncrona: se aceptan y se ponen en cola, y la API responde 200 con status: PROCESSING, que significa “aceptado”, no “validado”. El saldo, la cotización, el beneficiario y el propósito se validan después; si algo falla, la transacción queda en FAILED. Por eso un saldo insuficiente en estos pagos no llega como error en la respuesta: consúltalo en GET /b2b/transactions/detail.

El 502 BALANCE_VALIDATION_FAILED solo se devuelve de forma sincrónica en pagos EXCHANGE y en pagos entre monedas distintas.

Reintentos idempotentes

El externalReferenceId es el identificador único de cada transacción del lado del cliente. La API lo busca por empresa, sin importar el estado de la transacción, y rechaza un duplicado con 409 DUPLICATE_EXTERNAL_REFERENCE. Por eso reenviar el mismo ID nunca genera un cargo doble, pero tampoco reintenta un pago que ya fue rechazado.

Reglas prácticas

  • Rechazo explícito (valid: false o 502 de validación): corrige la causa y reintenta con un externalReferenceId nuevo, porque el mismo devuelve 409.
  • Timeouts / errores de red: consulta el estado con GET /b2b/transactions/detail antes de reintentar. Si la transacción no existe, puedes reenviar con el mismo externalReferenceId usando backoff exponencial: si ya existía, recibirás 409 y no se duplica. Si el segundo intento también falla, espera un poco más antes del tercero.
  • 5xx sin detalle de validación: trátalo como un timeout. Consulta el estado antes de reintentar.
  • 409 Conflict: el externalReferenceId ya existe, incluso si esa transacción quedó FAILED. Consulta su estado: si está en PROCESSING o completada, no reenvíes; si fue rechazada, corrige la causa y envía un ID nuevo.
  • 429 Too Many Requests: respeta el header Retry-After si está presente. Si no, espera al menos 1 segundo y duplica el tiempo en cada reintento (1s → 2s → 4s → 8s, tope 30s).
  • 401 Unauthorized: intenta una sola vez refrescar el token. Si persiste, el problema es de credenciales, no de transporte.
  • 403 Forbidden: no reintentes. Resuelve la causa raíz primero.

Backoff sugerido

IntentoEspera mínimaEspera sugerida
1—primer intento fallido
2500 ms1 segundo
31 s2 segundos
42 s4 segundos
54 s8 segundos
6+8 s16–30 segundos

Soporte

Si necesitas ayuda para investigar un estado inesperado o una petición fallida, escríbenos a soporte.tech@global66.com indicando el clientId y un ejemplo de la petición fallida (timestamp, request id, status HTTP).