Skip to main content
Estimated Upgrade Time: 30 to 90 minutes depending on how much storefront code interacts with monetary values.v2.7 ships with an AI-assisted upgrade package. Install it before upgrading to get guided migration prompts.
Shopper v2.7 includes shopper/upgrade, a temporary package with Laravel Boost skills that guide your AI assistant through each breaking change.
composer require shopper/upgrade:^2.7 --dev
php artisan boost:install
This registers 4 upgrade skills in your AI assistant:
SkillWhat it does
shopper-upgrade-money-storageMigrates storefront code to smallest currency unit
shopper-upgrade-slide-oversMigrates custom slide-over components
shopper-upgrade-two-factor-authMigrates 2FA traits to SOLID interfaces
shopper-upgrade-filament-schemasMigrates InteractsWithForms to InteractsWithSchemas
Each skill checks if the migration applies to your project before suggesting changes. After completing the upgrade, remove the package:
composer remove shopper/upgrade --dev

Updating Dependencies

Update the following dependencies in your application’s composer.json file: shopper/framework to ^2.7 shopper/stripe to ^2.7 (If installed) Then run:
composer update -W
v2.7 requires Laravel 11.28+ or Laravel 12.x. If you are on an earlier Laravel 11 version, update Laravel first. Filament minimum version is now 4.9.

High Impact Changes

Money Storage: Smallest Currency Unit

Likelihood of Impact: High Affects all applications that read or write monetary values (prices, orders, cart totals, payment gateway calls). This is the most critical change in v2.7. All monetary values are now stored and returned in the smallest currency unit (cents for USD/EUR/GBP, raw value for zero-decimal currencies like XAF/JPY). This follows the Stripe/Shopify standard. What changed: All Eloquent price accessors (get/set) have been removed from Order, OrderItem, Price, CarrierOption, CartLine, CartLineTaxLine, CartLineAdjustment, and Discount.

Reading prices

Model properties now return the raw database value (smallest unit) instead of human-readable values:
$order->price_amount;
$price->amount;
These return 1200 and 16300 respectively, not 12.00 and 163.00. For display, use shopper_money_format():
shopper_money_format($order->price_amount, $order->currency_code);

Writing prices

Pass the smallest unit directly — the setter no longer multiplies by 100:
Order::create(['price_amount' => 12.00]); 
Order::create(['price_amount' => 1200]); 

Price::create(['amount' => 163]); 
Price::create(['amount' => 16300]); 

Cart pipeline

CartPipelineRunner no longer divides results by 100. All values are in cents:
$context = $cartManager->calculate($cart);
$context->subtotal; // 25.00
$context->subtotal; // 2500

Payment gateways

Values are already in cents — remove any manual multiplication:
Stripe::charge($order->price_amount * 100); 
Stripe::charge($order->price_amount); 

Zero-decimal currencies

If you use zero-decimal currencies (XAF, JPY, KRW, etc.), existing data was incorrectly multiplied by 100. Run the fix command:
# Preview what will change
php artisan shopper:upgrade:fix-zero-decimal-currencies --dry-run

# Apply the fix
php artisan shopper:upgrade:fix-zero-decimal-currencies
Put your site in maintenance mode before running this command. It modifies prices, orders, order items, carrier options, cart lines, and discounts.

New helpers

Two new helpers are available:
HelperPurpose
zero_decimal_currencies()Returns the list of zero-decimal currency codes
is_no_division_currency($code)Checks if a currency code is zero-decimal

MoneyInput component

A new Filament form component handles the conversion between human values (form display) and smallest unit (database) automatically:
use Shopper\Components\Form\MoneyInput;

MoneyInput::make('price')
    ->currency('USD')
    ->suffix('USD');
If no currency is specified, it defaults to the shop’s configured currency. For zero-decimal currencies, the mask precision adjusts to 0 automatically.

Filament table columns

Replace ->money() with the ->currency() macro:
TextColumn::make('amount')->money(fn ($record) => $record->currencyCode) 
TextColumn::make('amount')->currency(fn ($record) => $record->currencyCode) 
Existing database data for standard currencies (USD, EUR, GBP) is already correct — the old setters stored values in cents. No migration needed for these currencies.

Slide-Over Components Replaced

Likelihood of Impact: High Affects applications with custom slide-over components extending Shopper’s base class. Shopper’s internal SlideOverComponent and SlideOverPanel classes have been removed and replaced by the laravelcm/livewire-slide-overs package. If you created custom slide-over components that extend Shopper’s base class, update the import:
use Shopper\Livewire\Components\SlideOverComponent; 
use Laravelcm\LivewireSlideOvers\SlideOverComponent; 
The closePanelWithEvents() method no longer exists:
$this->closePanelWithEvents(['eventName']); 
$this->dispatch('eventName'); 
$this->closePanel(); 

Medium Impact Changes

Two-Factor Authentication: SOLID Interfaces

Likelihood of Impact: Medium Affects applications that override the User model and use two-factor authentication. The monolithic TwoFactorAuthenticatable trait has been split into focused interfaces and traits:
use Shopper\Traits\TwoFactorAuthenticatable; 
use Shopper\Contracts\HasStoreAuthentication; 
use Shopper\Contracts\HasStoreAuthenticationRecovery; 
use Shopper\Traits\InteractsWithStoreAuthentication; 
use Shopper\Traits\InteractsWithStoreAuthenticationRecovery; 

class User extends Authenticatable
class User extends Authenticatable implements HasStoreAuthentication, HasStoreAuthenticationRecovery
{
    use TwoFactorAuthenticatable; 
    use InteractsWithStoreAuthentication; 
    use InteractsWithStoreAuthenticationRecovery; 
}
The two-factor columns on the users table have been renamed to avoid conflicts with Laravel Fortify’s own 2FA columns. Update the $hidden array on your User model:
protected $hidden = [
    'password',
    'remember_token',
    'two_factor_secret', 
    'two_factor_recovery_codes', 
    'store_two_factor_secret', 
    'store_two_factor_recovery_codes', 
];

Filament HasForms to HasSchemas

Likelihood of Impact: Medium Affects applications with custom Filament components that use InteractsWithForms. Shopper now uses InteractsWithSchemas instead of InteractsWithForms. If you have custom components in app/Shopper/ or app/Livewire/:
use Filament\Forms\Concerns\InteractsWithForms; 
use Filament\Forms\Contracts\HasForms; 
use Filament\Schemas\Concerns\InteractsWithSchemas; 
use Filament\Schemas\Contracts\HasSchemas; 
InteractsWithForms still works in Filament 4.x — this migration is recommended but not urgent.

Dependency Version Bumps

Likelihood of Impact: Medium Affects all applications.
DependencyBeforeAfter
laravel/framework^11.0|^12.0^11.28|^12.0|^13.0
filament/filament^4.7^4.9
spatie/laravel-permission^6.24^6.24|^7.0

Low Impact Changes

InteractsWithSlideOverForm Trait

10 slide-over form components now use the shared InteractsWithSlideOverForm trait and a generic Blade view. Their dedicated Blade views have been removed: add-collection-form.blade.php, attribute-form.blade.php, brand-form.blade.php, category-form.blade.php, create-team-member.blade.php, discount-form.blade.php, supplier-form.blade.php, update-variant.blade.php If you published and customized any of these views, you’ll need to adapt to the new generic view or override the component’s render() method.

Shipment Event Date Validation

Shipment events now enforce chronological ordering — you cannot create an event with a date earlier than the previous event. The RecordShipmentEventAction validates this server-side.

Nested Sortable Categories

Categories can now be reordered with drag & drop in the admin panel. No code changes required.

Collection Price Rules

Automatic collection price rules now filter by the shop’s default currency when evaluating products.

New Features

Upgrade Package

shopper/upgrade is a new temporary package with Laravel Boost skills for AI-assisted upgrades and an artisan command for zero-decimal currency data fixes. Install it before upgrading, remove it after.

MoneyInput Component

A new MoneyInput Filament form component that handles currency-aware conversion between human values and smallest unit storage.

Migration Checklist

1

Install the upgrade package

Run composer require shopper/upgrade:^2.7 --dev and php artisan boost:install to get AI-assisted migration prompts.
2

Update storefront price reads

Replace direct price property access with shopper_money_format() for display. Use raw values for calculations.
3

Update storefront price writes

Pass values in smallest currency unit to all create() / update() calls on monetary fields.
4

Update payment gateway code

Remove any * 100 multiplication before sending to Stripe or other providers.
5

Fix zero-decimal currency data

Run php artisan shopper:upgrade:fix-zero-decimal-currencies if you use XAF, JPY, or other zero-decimal currencies.
6

Update slide-over imports

Replace Shopper\Livewire\Components\SlideOverComponent with Laravelcm\LivewireSlideOvers\SlideOverComponent in any custom slide-overs.
7

Update 2FA traits and hidden fields

Replace TwoFactorAuthenticatable with the new interfaces and traits if you override the User model. Update your $hidden array to use store_two_factor_secret and store_two_factor_recovery_codes instead of the old column names.
8

Update dependencies

Run composer update -W after setting shopper/framework to ^2.7.
9

Run tests

Run php artisan test and fix assertions that expect human-readable price values instead of cents.
10

Remove upgrade package

Run composer remove shopper/upgrade --dev when done.