User model to Lunar’s Customer model, resolving the current customer through the storefront session, and understanding what happens to the cart on login and logout.
Overview
Lunar separates authentication (handled by Laravel) from commerce data (stored inLunar\Core\Models\Customer). The two are linked through the Lunar\Core\Models\Concerns\IsLunarUser trait and the Lunar\Core\Contracts\LunarUser contract, which together add customer, cart, and order relationships to the application’s User model. This guide walks through setting up the connection, creating a customer on registration, resolving the current customer from the storefront session, and how the cart behaves across login and logout.
The examples below use standard Laravel controllers and Blade templates. The same concepts apply whether the storefront is built with Livewire, Inertia, or a headless API.
Setting Up the User Model
Implement theLunarUser contract and add the IsLunarUser trait to the application’s User model.
This is one of the required setup steps documented on the installation page. Several parts of Lunar core — cart association on login, the storefront session’s customer resolution — check for this contract, so it needs to be in place for the rest of this guide to work.
IsLunarUser trait provides the following relationships:
It also provides a helper method:
A user can be associated with multiple customers. This supports scenarios like a sales representative managing multiple accounts. For most storefronts, each user has a single customer record.
Creating a Customer on Registration
When a new user registers, create a correspondingLunar\Core\Models\Customer record and link the two together.
Registration Controller
Adding to an Existing Registration Flow
If the application already has registration (for example, via Laravel Breeze or Fortify), add customer creation using a listener on theRegistered event instead:
Event facade, typically in a service provider’s boot() method:
The Storefront Session
Lunar\Core\Facades\StorefrontSession tracks the selections that frame a storefront visit — region, channel, currency, customer, and customer groups. It is resolved once per request (bound scoped in the container, not singleton, so nothing leaks between requests under Octane or a queue worker) and restores its state from the session automatically on construction.
How Customer Resolution Works
WhenStorefrontSession is constructed, it resolves the current customer using this cascade:
- Check the session for a previously stored customer ID.
- If none is found and a user is authenticated whose model implements
LunarUser, call$user->latestCustomer()to find the most recently created customer. - Store the resolved customer ID in the session for subsequent requests.
latestCustomer().
Setting the Customer Manually
In some cases the customer needs to be set explicitly, for example immediately after registration (to avoid the redirect round-trip), or when a user has multiple customer accounts:Changing Channel or Currency
Lunar\Core\Facades\CartSession, so an existing cart is re-priced in the new currency.
See the Storefront Session reference for the full API, including regions, customer groups, and resolving an immutable
StorefrontContext snapshot for code that should not depend on there being an HTTP session (queued jobs, an API resolving selections from headers).Cart Behavior on Login and Logout
Lunar automatically handles cart association when users log in and out, throughLunar\Core\Listeners\CartSessionAuthListener. This listener is registered by Lunar’s service provider and responds to Laravel’s Login and Logout authentication events. It only acts when the authenticating user’s model uses IsLunarUser.
What Happens on Login
- If a cart already exists in the session and has no
user_id(a guest cart), it is associated with the newly authenticated user. Depending on the configured policy, the guest cart’s lines are either merged into the user’s existing cart, or the guest cart overrides it. - If no cart exists in the session at all, the listener looks for the user’s most recent active cart and loads it into the session.
What Happens on Logout
On logout, the listener callsCartSession::forget(), which by default soft-deletes the session’s cart in addition to clearing it from the session — controlled by delete_on_forget in config/lunar/cart_session.php (defaults to true). Because the cart is soft-deleted, it is excluded from the normal queries used to find “the user’s active cart”, so it is not picked up again on the next login. Set delete_on_forget to false to keep the cart around (and restorable on the next login) instead.
Cart Association Policy
The association policy used on login is configured inconfig/lunar/cart.php:
Customer Account Page
Build an account dashboard that displays the customer’s profile, linked addresses, and recent orders.Account Controller
Displaying Customer Details
$order->format('total') returns the total formatted as a currency string. Order totals are stored as integers in the currency’s minor unit and cast through Lunar\Core\Models\Concerns\FormatsPrices, which every model implementing HasCurrency uses. See the Order History guide for the full breakdown.Updating Customer Profile
Checking Authentication in Views
UseStorefrontSession to conditionally display content based on whether a customer is resolved:
Routes
Putting It All Together
Here is a complete registration controller and account controller:Next Steps
- Review the Customers reference for the full list of customer model fields, relationships, and customer groups.
- Review the Storefront Session reference for the full session API and the
StorefrontContextsnapshot. - Review the Customer Addresses guide for managing saved addresses.
- Review the Order History guide for displaying past orders.
- Review the Cart guide for details on cart calculation and session management.