TechStore’s shopping cart system provides a persistent, user-specific cart that stores items before purchase. The cart seamlessly converts to orders during checkout, automatically managing stock validation and order creation.
Carts are persistent and user-specific. Each user has one active cart that survives across sessions.
POST /api/carrito/{usuarioId}/agregar?productoId={id}&cantidad={qty}Authorization: Bearer {token}
Example: POST /api/carrito/5/agregar?productoId=10&cantidad=2Adds a product to the cart. If the product already exists in the cart, the quantity is increased:
@PostMapping("/{usuarioId}/agregar")public ResponseEntity<Carrito> agregar( @PathVariable Long usuarioId, @RequestParam Long productoId, @RequestParam Integer cantidad) { return ResponseEntity.ok( carritoService.agregarProducto(usuarioId, productoId, cantidad) );}
Implementation:
@Transactionalpublic Carrito agregarProducto(Long usuarioId, Long productoId, Integer cantidad) { Carrito carrito = obtenerOCrearCarrito(usuarioId); Producto producto = productRepository.findById(productoId) .orElseThrow(() -> new RuntimeException("Producto no encontrado")); // Check if product already in cart carrito.getItems().stream() .filter(item -> item.getProducto().getId().equals(productoId)) .findFirst() .ifPresentOrElse( // If exists, increment quantity item -> item.setCantidad(item.getCantidad() + cantidad), // If new, add to cart () -> { CarritoItem nuevoItem = new CarritoItem(); nuevoItem.setProducto(producto); nuevoItem.setCantidad(cantidad); nuevoItem.setCarrito(carrito); carrito.getItems().add(nuevoItem); } ); return carritoRepository.save(carrito);}
The system automatically handles both new items and quantity updates for existing items in a single operation.
Example: DELETE /api/carrito/5/eliminar/10Removes a specific product from the cart:
@DeleteMapping("/{usuarioId}/eliminar/{productoId}")public ResponseEntity<Carrito> eliminarProducto( @PathVariable Long usuarioId, @PathVariable Long productoId) { return ResponseEntity.ok( carritoService.eliminarProducto(usuarioId, productoId) );}
Implementation:
@Transactionalpublic Carrito eliminarProducto(Long usuarioId, Long productoId) { Carrito carrito = carritoRepository.findByUsuarioId(usuarioId) .orElseThrow(() -> new RuntimeException( "Carrito no encontrado para el usuario: " + usuarioId )); // Remove item from collection boolean removido = carrito.getItems().removeIf(item -> item.getProducto().getId().equals(productoId) ); if (removido) { // orphanRemoval = true automatically deletes the item return carritoRepository.save(carrito); } else { throw new RuntimeException("El producto no estaba en el carrito"); }}
To update quantity without removing, use the add endpoint with the desired final quantity difference.