# Dominio Purchase ## Propósito Implementa el ciclo de compra y checkout: crea la cabecera de compra desde un carrito, mantiene sus líneas vivas contra catálogo durante el checkout, inicia el pago y materializa el snapshot definitivo al confirmar, o cancela y vence la operación. ## Modelo - `Purchase`: raíz de la compra; estados `created`, `pending_payment`, `in_review`, `paid`, `cancelled`, `rejected` y `expired`. - `PurchaseItem`: snapshot definitivo del producto o variante, creado recién al confirmar la compra. - `TelepagosQr` y `TelepagosPayment`: datos del QR e intentos/resultados del proveedor. - `PurchasePaid`: evento emitido una sola vez al pasar a pagada bajo bloqueo transaccional. ## Servicios de checkout `CheckoutService` es la fachada estable. Delega en: - `StartCheckoutService`: inicia la compra desde el carrito o crea un carrito técnico para compra directa, sin crear todavía `PurchaseItem`. - `EditCheckoutService`: modifica los datos del comprador antes del cierre. - `CompleteCheckoutService`: completa, envía a revisión o materializa los `PurchaseItem` al confirmar el pago. - `ReleaseCheckoutService`: cancela, vence y procesa vencimientos pendientes. - `SourceCartService`: sincroniza o finaliza el carrito de checkout asociado a la compra. - `CatalogSelectionResolver` y `PurchaseItemSnapshotFactory`: resuelven selecciones y generan snapshots. Al informar una transferencia, la compra pasa de `pending_payment` a `in_review` y deja de vencer. Si el comprador abandona el checkout durante la revisión, la compra y sus reservas permanecen intactas y se crea un carrito activo nuevo para que pueda seguir comprando. Adminapp puede confirmar o anular explícitamente la compra en revisión. Las cantidades y variantes se editan mediante el dominio Cart. El endpoint autenticado `PATCH /checkout-carts/{cart}/items/{cartItem}` valida que el carrito pertenezca al usuario y a una compra editable. Cuando existe un cambio real, invalida atómicamente el intento de pago anterior, recalcula el total y renueva la reserva; Purchase no expone operaciones sobre líneas antes de la confirmación. `UserPurchaseLimitService` controla límites de compra y `CheckoutService` conserva el punto de entrada para controladores e integraciones. ## Endpoints Bajo `/tenants/{tenant:codigo}/compras`, con `auth:sanctum`: listado, inicio, detalle, edición de ítems, datos del cliente, intención de pago, finalización, revisión y cancelación. ## Dependencias y reglas Depende de `Cart`, `Catalog`, `Tenant`, `Auth` e `Integration`; emite eventos consumidos por `Ticket` y `Notification`. Los cambios de estado e inventario deben ser transaccionales y usar los servicios del checkout, no actualizaciones directas del modelo.