Caso de estudio 02 · Sistemas distribuidos

El pago se completa, pero el pedido no.

Una investigación funcional y técnica de un fallo distribuido en el procesamiento de pedidos a través de APIs REST, microservicios y mensajería asíncrona.

Pruebas de APIRESTPostmanMicroserviciosLogsPruebas de integraciónAWS SNS/SQSAnálisis de causa raízAnálisis técnico
01

Sistema

Seguir la transacción de negocio, no solo el endpoint.

01Frontend
02Orders API
03Payment Service
04AWS SNS
05AWS SQS
06Order Processor
07Order DB
08Notification Service
02

Incidencia

Un pago aprobado con un resultado de negocio incompleto

Pago
AprobadoPAY-99821
Pedido
Pendiente de pagoORD-78451
Notificación
No enviada

El cargo ya se ha realizado al cliente.

Tu pago se ha realizado correctamente. Estamos procesando tu pedido.
03

Hipótesis

Antes de repetir la prueba, mapear dónde puede diverger el estado.

  1. H01Payment Service no publicó el evento
  2. H02SNS no encaminó el evento
  3. H03El mensaje de SQS no fue consumido
  4. H04El consumidor rechazó el evento por datos de contrato no válidos
  5. H05La actualización del pedido falló en la capa de persistencia
  6. H06El pedido se actualizó, pero una lectura posterior devolvió datos desactualizados
04

Validación de API

Ambas APIs síncronas responden correctamente, pero la transacción sigue fallando.

POST /api/v1/orders
{
  "customerId": "CUS-1842",
  "items": [
    {
      "productId": "PROD-901",
      "quantity": 2,
      "unitPrice": 24.9
    }
  ],
  "currency": "EUR"
}
201 CreatedOrder = PENDING_PAYMENT
POST /api/v1/payments
{
  "orderId": "ORD-78451",
  "amount": 49.8,
  "currency": "EUR",
  "paymentMethod": "CARD"
}
200 OKPayment = APPROVED
Una respuesta correcta de la API no garantiza una transacción de negocio correcta.
05

Contrato de eventos

Inspeccionar el evento que conecta los servicios.

payment.completed · evt-78310
{
  "eventType": "payment.completed",
  "eventVersion": "2.0",
  "eventId": "evt-78310",
  "timestamp": "2026-09-10T09:42:18Z",
  "data": {
    "orderId": "ORD-78451",
    "paymentId": "PAY-99821",
    "amount": 49.8,
    "currency": "EUR",
    "status": "APPROVED"
  }
}
Contrato del consumidor
Versión soportada
1.0
Versión recibida
2.0
Rechazado

Unsupported eventVersion: 2.0

06

Análisis de logs

Seguir la evidencia servicio a servicio.

order-processing · traza de un entorno similar a producción
PAYMENTPayment approved PAY-99821
PAYMENTPublishing payment.completed event
SNSPublish successful messageId=MSG-7719
SQSMessage delivered to order-processing-queue
ORDER_PROCESSORReceived message MSG-7719
ORDER_PROCESSORParsing event payment.completed
ORDER_PROCESSORERROR Unsupported eventVersion: 2.0; expected 1.0
ORDER_PROCESSORMessage moved to DLQ
07

Causa raíz

El defecto está en el contrato entre servicios.

01Pago ✓
02Publicación del evento ✓
03SNS ✓
04SQS ✓
05Consumidor ✕
06Actualización del pedido — no ejecutada
07Notificación — no ejecutada
El productor publica eventVersion 2.0, mientras que el Order Processor solo admite la 1.0. El mensaje rechazado termina en la DLQ, por lo que el cliente tiene el cargo realizado mientras el pedido continúa pendiente.
08

Defecto

Traducir la evidencia técnica a impacto en negocio.

IDORD-2173
TítuloEl pedido permanece en PENDING_PAYMENT tras un pago aprobado debido a una versión del contrato de evento no soportada
SeveridadCrítica
AfectadosPayment Service · Order Processor
EsperadoPago APPROVED → pedido CONFIRMED → notificación de confirmación
ActualPago APPROVED; evento rechazado; el pedido permanece en PENDING_PAYMENT
Impacto en negocioCliente con el cargo realizado y sin pedido confirmado; aumento de contactos con soporte, necesidad de conciliación, riesgo de duplicados y pérdida de confianza.
09

Regresión y pruebas de contrato

Convertir la incidencia en una cobertura de calidad más sólida.

Pruebas de contrato

Validar la compatibilidad productor/consumidor antes del despliegue.

Pruebas de integración

Verificar la publicación, entrega y consumo de eventos.

Pruebas end-to-end

Checkout → pago → confirmación del pedido → notificación.

Monitorización

Generar alertas cuando lleguen mensajes a la Dead Letter Queue.

Colección de Postman
PassPOST /orders · 201 Created
PassPOST /payments · 200 OK
FailGET /orders/ORD-78451 · expected CONFIRMED
Escenarios adicionalesVersión no soportadaorderId ausenteEvento duplicadoEvento retrasadoConsumidor no disponible
10

Idempotencia

El mismo evento nunca debe producir el mismo efecto dos veces.

Comportamiento automatizado
evt-78310 × 2

Si el evento evt-78310 se entrega dos veces, el pedido solo debe pasar a CONFIRMED una vez.

processedEvents.length = 1
11

Resultado de la investigación

Del síntoma a la causa raíz

Punto de fallo acotado

La investigación permitió acotar el problema desde el flujo completo del pedido hasta la interacción entre el evento de pago y su consumidor.

Causa raíz identificada

El productor publicó payment.completed con el contrato de evento v2.0, mientras que el Order Processor solo admitía v1.0.

Evidencias técnicas conectadas

Las respuestas de las APIs, los payloads de los eventos, los logs de los servicios y el comportamiento de la DLQ se analizaron conjuntamente para validar la hipótesis.

Impacto en negocio explicado

Un pago técnicamente correcto podía dejar al cliente con el cargo realizado y el pedido todavía en PENDING_PAYMENT.

Riesgo de regresión identificado

La compatibilidad de contratos entre productor y consumidor se identificó como un riesgo crítico de integración.

Cobertura preventiva definida

Las pruebas de contrato, las pruebas de integración, la validación end-to-end, la idempotencia y la monitorización de la DLQ se identificaron como controles complementarios.

12

Conclusión

La calidad es una propiedad del sistema completo.

Validar servicios de forma aislada no es suficiente. El sistema completo debe ser capaz de entregar el resultado de negocio esperado.