tourze/order-cart-bundle
Tourze order-cart-bundle is a Symfony bundle for adding shopping cart and order workflows to PHP applications. It provides reusable cart and order structures with DI integration, helping you assemble checkout flows without rebuilding the basics.
tourze/order-cart-bundle is a domain package: it gives you cart/order entities plus the services that move a cart through checkout. It is not a turnkey storefront — expect to wire your own controllers, views, and payment handling around it.
composer require tourze/order-cart-bundle (pin to 1.0.1; see Gotchas about the changelog).src/ in this order: the entity/model directory (Cart, CartItem, Order, OrderItem), then the service/repository classes, then the bundle/DIC extension. Those three layers tell you the whole contract in about twenty minutes.config/ or a DependencyInjection/Configuration.php). Copy any defaults into your own config rather than editing vendor files.If you are on Laravel, verify the service provider is auto-discovered (extra.laravel in the package's composer.json). If it is a Symfony-style bundle without a Laravel bridge, you will add the provider manually to bootstrap/providers.php.
Cart creation and lifecycle. Treat the cart as a short-lived aggregate keyed to a session or user. A common pattern is a single CartService::getOrCreateFor($user) called from middleware, so controllers never construct carts directly. Keep the "active cart" lookup in one place — duplicating it is how you end up with two carts per user.
Line items. Add items through the service, not by appending to the collection on the entity. The service is where quantity merging (same SKU added twice) and re-validation of availability usually live. Never trust a quantity posted from the client without re-checking it server-side.
Money. Compute totals through the package's total/calculator service rather than summing in your controller. If you add discounts or tax, do it as a wrapper around the package's calculator or as an event listener, so the raw subtotal stays available for display and audit.
Checkout as a transactional unit. The cart-to-order conversion should be one DB::transaction(): re-read the cart under a lock, snapshot prices and product names into order items, decrement stock or reserve inventory, then mark the cart consumed. Order items must capture the price at time of purchase; never join back to the product's current price to render an old order.
Idempotent conversion. Guard against double submission: check whether the cart is already converted (status column or an order_id back-reference) before creating anything. This matters more than any other pattern here because payment retries are normal.
Extension points. Before subclassing, look for events and interfaces — the bundle typically emits something around cart mutation and checkout. Listeners are much cheaper to maintain across upgrades than an overridden entity.
Testing. Write a test that builds a cart in memory, applies a discount, and asserts the final total. It is the fastest regression net you can build for a domain package like this, and it survives vendor updates.
composer diff or Git compare) or read the commit log before upgrading a production app. Pin exact versions in composer.json — "tourze/order-cart-bundle": "1.0.1" — rather than allowing ^1.0 to drift silently.laravel service provider entry, you will be doing manual container bindings and may need Doctrine rather than Eloquent. That is a decision that affects everything downstream, so settle it first.Cart extends the package's entity and you forget to register the mapping or the id generator, you get an empty table and a confusing "no such column" error at runtime, not at boot.float, cast to a string/integer representation at the boundary and keep it that way.CHANGELOG.md. With no per-release notes, treat every patch as potentially behavior-affecting and run your pricing test suite after each bump.How can I help you explore Laravel packages today?