Cómo implementar entrega eventual entre ERP y tienda virtual usando colas e idempotencia (sin pedidos duplicados)
Por Kevin Marcondes · Publicado el · Actualizado el · 8 min de lectura
¿Necesitas saber cómo implementar entrega eventual entre ERP y tienda virtual usando colas e idempotencia para evitar pedidos duplicados? El enfoque combina mensajería, un diseño consistente de eventos y deduplicación en la aplicación. A continuación entenderás las causas de los duplicados, la arquitectura recomendada y un paso a paso práctico para activar esto de forma segura.
El problema real: pedidos duplicados y stock incorrecto
Los pedidos duplicados aparecen cuando las integraciones hacen reintentos sin control. Timeouts, inestabilidades y concurrencia provocan reprocesos. Sin idempotencia, el mismo mensaje puede generar dos pedidos, agotar stock y desordenar la contabilidad. A continuación, síntomas comunes y sus causas típicas.
| Síntoma | Causa posible | Impacto |
|---|---|---|
| Dos pedidos con el mismo pago | Reintento del gateway/API sin idempotencia | Contracargos y conciliación demorada |
| Stock negativo tras el cambio de hora | Procesamiento concurrente de eventos de baja | Pedidos cancelados por indisponibilidad |
| Facturas duplicadas | Ejecución repetida del flujo de trabajo | Retrabajo fiscal y contable |
| Pedidos atascados en “Procesando” | Cola sin DLQ y mensaje envenenado | Backlog creciente y pérdida de ventas |
| Webhook reenviado múltiples veces | At-least-once sin deduplicación | Efecto en cascada de duplicidad |
Conceptos esenciales: entrega eventual, colas e idempotencia
La entrega eventual acepta un pequeño retraso para ganar resiliencia. Una cola de mensajes desacopla sistemas y permite reintentos. La mayoría de las colas operan con “al menos una vez” (at-least-once): el mismo mensaje puede llegar repetido. Por eso la aplicación debe ser idempotente: procesar N veces con el mismo resultado final.
Las colas FIFO con deduplicación ayudan a reducir reentregas, pero no eliminan la necesidad de idempotencia en el borde de la aplicación. La idempotencia debe residir cerca de la base de datos y de las reglas de negocio.
Arquitectura recomendada para ERP ↔ e‑commerce
Una topología robusta combina patrones de integración orientada a eventos con deduplicación en el consumidor.
Componentes prácticos:
- Patrón outbox en el ERP o en la tienda: el sistema registra el evento y el estado de negocio en la misma transacción de la base de datos. Un publicador asíncrono lee y coloca en la cola.
- Cola (FIFO o estándar) con DLQ: reintentos con backoff e aislamiento de mensajes problemáticos.
- Consumidor idempotente: antes de crear/actualizar un pedido, verifica una clave única y registra el procesamiento.
Si tu ERP no expone cambios con facilidad, considera CDC (Change Data Capture) y un outbox. Hay una guía de migración con CDC: Estrategia de migración de bases de datos con cero tiempo de inactividad usando CDC.
Paso a paso de implementación
Un camino incremental reduce riesgos y aporta visibilidad.
- Mapea los flujos críticos: creación de pedido, decremento de stock, facturación y cancelación.
- Define el contrato de eventos: identificadores inmutables, versión del evento y origen.
- Implementa outbox o CDC para publicar eventos de forma fiable.
- Provisiona la cola y la DLQ; ajusta la política de reintentos y visibilidad.
- En el consumidor, crea un repositorio de idempotencia (tabla) con índice único.
- Usa upsert transaccional para crear/actualizar pedidos de forma idempotente.
- Aplica backoff exponencial, idempotencia con TTL cuando tenga sentido.
- Prueba bajo fallos: simula timeouts y caídas de red. Consejos de rendimiento: Cómo reducir la latencia de APIs REST: caché y optimización SQL.
Idempotencia en la práctica: claves, upsert y deduplicación
La clave idempotente debe identificar de forma única la intención de negocio. Ejemplos: orderId de la tienda, paymentIntentId del proveedor, o un hash estable de campos del pedido.
Buenas prácticas para el consumidor:
- Persistir la clave idempotente antes de la acción: INSERT con clave única; si ya existe, tratar como repetición.
- Usar upsert (INSERT ... ON CONFLICT/ON DUPLICATE KEY) para cambios idempotentes.
- Registrar el estado del procesamiento (en curso, completado, falló) y timestamps.
- Evitar efectos secundarios fuera de la transacción (emails, webhooks) sin una comprobación de idempotencia propia.
Reintentos, DLQ y garantía de al menos una vez
Fallas ocurren. Los reintentos con backoff exponencial reducen picos. Usa DLQ para aislar mensajes que fallan siempre y evitar bloquear el flujo.
No confundas idempotencia con limitación de tasa o autenticación. Se complementan. Para reforzar la frontera de la API, consulta la Guía de APIs seguras con OAuth2 y limitación de tasa (rate limiting).
- Define límites de reintentos por tipo de error (transitorio vs permanente).
- Aplica backoff exponencial con jitter para evitar thundering herd.
- Monitorea la tasa de DLQ, la latencia end-to-end y el backlog de la cola.
- Implementa reprocesamiento asistido de la DLQ con observabilidad detallada.
Pruebas y observabilidad antes de activar
Sin telemetría, la idempotencia se vuelve una caja negra. Instrumenta contadores de duplicados evitados, latencia por etapa y tamaño del backlog.
La prueba de carga debe incluir mensajes duplicados y entregas fuera de orden. Demuestra que el mismo evento N veces no cambia el estado final.
Registra correlaciones: traceId, idempotencyKey y orderId. Dashboards y alertas reducen el MTTR en incidentes.
Señales de que es hora de cambiar y próximos pasos
Algunas señales indican la necesidad de entrega eventual con idempotencia. Si varias se aplican, vale la pena priorizar esta implementación.
Para planear el protocolo de integración, elige REST o GraphQL según el caso de uso. Comparativa útil: Comparativa: GraphQL vs REST para integración entre e‑commerce y ERP (sincronización de catálogo y stock).
- Pedidos, facturas o webhooks duplicados en picos.
- Timeouts y reintentos frecuentes en el ERP o en la tienda.
- Stock divergente tras cancelaciones o reembolsos.
- Backlog creciente de integraciones y ventanas manuales de corrección.
| Decisión | Cuándo usar | Riesgo si se ignora |
|---|---|---|
| Entrega eventual + cola | Flujos asíncronos toleran pequeño retraso | Acoplamiento rígido y caídas que derriban ventas |
| Clave idempotente única | Eventos pueden reentregarse | Pedidos duplicados y conciliación costosa |
| DLQ + reprocesamiento | Existen mensajes envenenados | La cola se bloquea y causa backlog |
| Observabilidad | Entorno heterogéneo y distribuido | Diagnóstico lento y correcciones a ciegas |
Preguntas frecuentes
¿Cuál es la mejor clave idempotente para pedidos de e‑commerce?
La clave idempotente debe representar la intención de negocio y ser inmutable: por ejemplo orderId de la tienda, paymentIntentId del proveedor o un hash estable del payload. Persiste esa clave en una tabla con índice único y registra el estado del procesamiento (en curso, completado, falló). Así, al recibir el mismo evento de nuevo se detecta la repetición y se evita duplicar acciones.
¿Las colas FIFO eliminan la duplicación de mensajes?
Las colas FIFO reducen la reordenación y algunas ofrecen deduplicación por ventana temporal, pero muchas colas siguen operando en modo “al menos una vez”. Eso significa que pueden ocurrir reentregas; por tanto la deduplicación en la cola ayuda pero no sustituye a que el consumidor sea idempotente y valide claves antes de aplicar cambios al negocio.
¿Cómo evitar emails o webhooks duplicados al reprocesar?
Trata los efectos secundarios como operaciones idempotentes: guarda una clave por evento enviado y verifica antes de enviar. Evita ejecutar envíos fuera de la transacción sin una comprobación previa. Usa registros de envío con TTL cuando proceda y mantén trazabilidad (traceId, idempotencyKey) para saber qué ya fue remitido y así impedir duplicados al reprocesar mensajes.
¿Qué enviar a la DLQ y cómo reprocesar con seguridad?
A la DLQ deben ir mensajes que exceden el límite de reintentos o fallan por errores de datos no resolubles automáticamente. Reprocésalos solo tras corregir la causa raíz, manteniendo la trazabilidad del evento y del fallo. Implementa un flujo asistido de reprocesamiento que valide idempotencia antes de reintroducir mensajes y evita reintentar a ciegas sin inspección previa.
¿Necesito consistencia fuerte en el stock?
No siempre; en operaciones de alto volumen suele ser aceptable un pequeño retraso usando entrega eventual con idempotencia. Si la consistencia es crítica, combina reservas temporales o comprobaciones síncronas puntuales para confirmar la disponibilidad final, mientras el resto del flujo permanece asíncrono y diseñado para tolerar reintentos y reentregas sin causar inconsistencias.
¿Listo para eliminar pedidos duplicados?
Mapeemos tus flujos, definamos claves idempotentes y activemos colas con seguridad. Una conversación breve ayuda a estimar esfuerzo y riesgos en tu escenario.
Hablar sobre mi integraciónVer también
- Cómo recuperar estadísticas e índices corruptos en PostgreSQL que dejaron consultas lentas
- API REST con picos de latencia por queries N+1 y GC en PHP — cómo diagnosticar y corregir
- Error 'Too many connections' en PostgreSQL durante pico de facturación — guía práctica de diagnóstico y corrección
- Reducir costos migrando Magento a OpenMage con plan de rollback y pruebas de aceptación