ADR-0001: Una orden por vendedor en el checkout¶
Estado¶
Aceptada
Fecha: 2026-06-02
Contexto¶
Bazaar es un marketplace multi-vendedor: un mismo carrito puede contener productos de distintos sellers. Al cerrar la compra, el sistema debe decidir cómo se modelan las entidades Order resultantes. Existen dos alternativas razonables:
- Orden única consolidada — un solo registro
Orderque agrupa todos los items del carrito, sin importar el vendedor. - Una orden por vendedor — el carrito se agrupa por
seller_emaily se crea un registroOrderpor cada vendedor distinto, compartiendoidempotency_keyy un único pago en MercadoPago.
Fuerzas en juego:
- Cada vendedor gestiona sus propias ventas: ve, procesa, despacha y cobra de forma independiente. Necesita un objeto de negocio que represente "su parte" de la transacción.
- El estado de la orden (
PAYMENT_PENDING → CONFIRMED → PROCESSING → SHIPPED → DELIVERED) avanza a distinto ritmo según el vendedor; un único estado consolidado obligaría a esperar al más lento o a inventar sub-estados. - Las autorizaciones del backend se hacen contra
orders.seller_email(endpoints/process,/ship) yorders.buyer_email(detalle); un único registro mezclaría dueños y complicaría la verificación de permisos. - MercadoPago acepta una sola preferencia de pago con múltiples ítems, así que el cobro se puede mantener unificado independientemente del modelo de datos.
- Para el comprador, "Mis compras" se muestra como una lista — agrupar visualmente varias órdenes del mismo checkout es trivial en la UI; separarlas en BD no rompe la UX.
Decisión¶
Adoptamos una orden por vendedor. El servicio de checkout agrupa los items del carrito por seller_email y crea un registro Order por cada vendedor distinto. Todas las órdenes generadas en el mismo checkout comparten la misma idempotency_key y se referencian juntas en el external_reference de la preferencia de MercadoPago, de modo que el webhook de pago confirme o rechace el conjunto en una sola operación.
Consecuencias¶
Positivas
- Cada vendedor opera su propia orden de forma independiente: avanza el estado, marca despachada y consulta detalle sin coordinarse con otros vendedores.
- La autorización es directa: cada endpoint compara
X-User-Emailcontra elseller_emailobuyer_emaildel registroOrder, sin lógica adicional para órdenes mixtas. - La máquina de estados State Pattern del checkout-service se mantiene simple — un único estado por entidad, sin sub-estados por vendedor.
- "Mis ventas" del backoffice/mobile filtra por
seller_email == X-User-Emaily devuelve sólo lo que el vendedor debe atender.
Negativas
- El webhook de MercadoPago debe iterar sobre la lista de
order_idsextraída delexternal_referencepara confirmar/rechazar todas a la vez; un único registro hubiera requerido una sola actualización. - La
idempotency_keydeja de ser PK natural deOrder(se vuelve compartida) — el unique constraint se aplica a (idempotency_key,seller_email).
Neutras
- El cobro al comprador sigue siendo único: una sola preferencia de MercadoPago, una sola transacción visible para el usuario.