Idempotencia
Cada solicitud mutante (initiate, process, cancel) requiere un header
X-Idempotency. Si envía la misma clave dos veces, el plugin devuelve la respuesta original sin crear una operación duplicada.
Reglas:
- Use un UUID v4 o un identificador de negocio único (por ejemplo, su ID de orden interno)
- Longitud máxima: 255 caracteres
- Las claves tienen alcance por organización — la misma clave de dos organizaciones diferentes se trata como dos solicitudes distintas
- Las respuestas en caché se devuelven durante 24 horas
X-Idempotency-Replayed: true cuando la respuesta se sirve desde la caché.
Detección de duplicados
Más allá de las claves de idempotencia, el plugin detecta duplicados basados en el contenido. Genera un hash a partir de la organización (del headerX-Tenant-Id), senderAccountId, datos del destinatario y monto, y lo almacena en Redis durante 60 segundos (configurable). Si ya se envió una transferencia coincidente dentro de la ventana, la solicitud es rechazada con 409 BTF-0012.
Esto captura los casos en que el cliente envía la misma transferencia con una clave de idempotencia diferente — por ejemplo, después de un timeout donde no se recibió la respuesta original.
Estrategia de reintentos
Use backoff exponencial para errores transitorios. No todos los errores deben reintentarse.
| Estado HTTP | Tipo de error | ¿Reintentar? | Notas |
|---|---|---|---|
400 | Error de validación | No | Corrija la solicitud antes de reintentar |
404 | No encontrado | No | El recurso no existe |
409 | Duplicado | No | Idempotente — use la respuesta original |
410 | Expirado | No | Cree una nueva iniciación |
422 | Regla de negocio | No | Horario, límites — la condición debe cambiar primero |
429 | Límite de tasa | Sí | Espere el valor del header Retry-After (segundos) |
500 | Error interno | Sí | Reintentar con backoff |
503 | No disponible | Sí | Reintentar con backoff; verifique /health/ready si persiste |
Para
503 BTF-1000 (JD SPB no disponible): después de agotar los reintentos, la transferencia debe marcarse para reconciliación manual. No siga reintentando indefinidamente — la red JD SPB tiene horarios operativos definidos.Manejo de estados
Máquina de estados de TED OUT
Las transferencias siguen una progresión estricta. Una vez que una transferencia sale deCREATED o PENDING, no puede cancelarse.

| Estado | Significado | Acción recomendada |
|---|---|---|
CREATED | Confirmado por el usuario, en cola para envío | Mostrar “Procesando” en la interfaz; hacer polling o esperar webhook |
PENDING | Enviado a JD, esperando reconocimiento | Mostrar “Procesando”; no permitir cancelación |
PROCESSING | JD aceptó y está enrutando la transferencia | Mostrar “Procesando”; SLA típico menor a 10 minutos |
COMPLETED | Liquidado | Mostrar confirmación con confirmationNumber |
REJECTED | JD rechazó (datos inválidos, violación de regla) | Mostrar error al usuario; fondos ya liberados |
FAILED | JD inaccesible o timeout | Mostrar error; fondos ya liberados; permitir reintento si se desea |
CANCELLED | Cancelado antes del envío | Mostrar confirmación de cancelación |
Máquina de estados de iniciación
La entidadPaymentInitiation (creada por el endpoint initiate) tiene su propio ciclo de vida antes de que se cree un Transfer.

Máquina de estados de TED IN

Máquina de estados de P2P
P2P no tiene estadoPENDING. La liquidación es atómica e instantánea.

Polling vs. webhooks
Prefiera los webhooks para el estado en tiempo real. Si los webhooks aún no están configurados, haga polling enGET /v1/transfers/{transferId} con un máximo de 10 intentos usando el mismo programación de backoff que los reintentos. Después de 10 minutos sin un estado terminal (COMPLETED, REJECTED, FAILED, CANCELLED), marque la transferencia para revisión manual.
Consulte Obtener Transferencia y Webhooks.
Integración de webhooks
Para los esquemas de payload de eventos y la lista completa de eventos, consulte Webhooks.
Validación de firma
Cada solicitud de webhook incluye un headerX-Signature con una firma HMAC-SHA256. Siempre valide antes de procesar.
JSON.stringify — la representación en bytes debe coincidir exactamente) usando su webhookSecret, luego compare usando una función de tiempo constante.
JavaScript
JavaScript
Python
Python
Go
Go
Procesamiento idempotente de webhooks
Su endpoint puede recibir el mismo evento más de una vez (entrega al menos una vez). UsetransferId + event como clave compuesta para deduplicar.
Patrones de manejo de errores
Mapee los códigos de error de la API a acciones orientadas al usuario. Consulte la lista completa de errores para todos los códigos.
| Escenario | Código | Mensaje para el usuario | Acción |
|---|---|---|---|
| Fuera del horario operativo | BTF-0010 | ”Transferencias disponibles lun–vie, 06:30–17:00 (Brasilia). Próxima ventana: “ | Mostrar próxima hora disponible |
| Límite diario excedido | BTF-0011 | ”Límite diario de transferencias alcanzado. Intente mañana.” | Mostrar límite restante |
| Transferencia duplicada | BTF-0012 | ”Esta transferencia ya fue enviada.” | Devolver transferId original |
| Datos de destinatario inválidos | BTF-0001 | ”Verifique los datos del destinatario e intente nuevamente.” | Resaltar campos inválidos |
| Iniciación expirada | BTF-0202 | ”Sesión expirada. Por favor, inicie una nueva transferencia.” | Reiniciar el flujo de iniciación |
| JD SPB no disponible | BTF-1000 | ”Servicio de transferencias temporalmente no disponible. Intente nuevamente en unos minutos.” | Reintentar con backoff |
| Midaz no disponible | BTF-2000 | ”Servicio temporalmente no disponible. Intente nuevamente en unos minutos.” | Reintentar con backoff |
Lista de verificación para salida en producción
Antes de habilitar la integración en producción:
-
X-Idempotencyse envía en cada solicitud de initiate, process y cancel - Lógica de reintentos implementada con backoff exponencial para errores 5xx/503
- Endpoint de webhook desplegado y devolviendo
200en menos de 5 segundos - Validación de firma activa en el endpoint de webhook
- Deduplicación de eventos de webhook implementada usando
transferId + event - Horario de funcionamiento validado en el lado del cliente antes de llamar a initiate (reduce los 422 innecesarios)
- Tanto
transferIdcomoconfirmationNumberalmacenados para reconciliación - Estados terminales (
COMPLETED,REJECTED,FAILED,CANCELLED) gestionados en la interfaz - Expiración de iniciación (24h) manejada — se solicita al usuario que reinicie si la ventana expira
-
GET /health/readymonitoreado en su sistema de alertas para despliegues BYOC - Redis está disponible y monitoreado — el servicio no aceptará solicitudes si Redis es inalcanzable
-
PLUGIN_AUTH_ENABLED=trueconfigurado en producción, conPLUGIN_AUTH_ADDRESS,PLUGIN_AUTH_CLIENT_IDyPLUGIN_AUTH_CLIENT_SECRETválidos

