Skip to main content
Estimated Upgrade Time: 15-30 minutes for most applications.

Updating Dependencies

Update your composer.json file to require Shopper 2.5:
"require": {
    "shopper/framework": "^2.5"
}
Then run:
composer update -W
After updating Composer dependencies, run the migrations:
php artisan migrate
The shopper/payment package is now a dependency of shopper/framework and is installed automatically. It provides the payment driver system, transaction tracking, and the PaymentProcessingService.For Stripe support, install the driver addon separately: composer require shopper/stripe. See the Stripe addon documentation for setup instructions.

High Impact Changes

Three-Status Order System

Likelihood of Impact: High The monolithic OrderStatus enum has been split into three independent enums, each tracking a different concern:
ConcernEnumValues
Order lifecycleOrderStatusNew, Processing, Completed, Cancelled, Archived
PaymentPaymentStatusPending, Authorized, Paid, PartiallyRefunded, Refunded, Voided
ShippingShippingStatusUnfulfilled, PartiallyShipped, Shipped, PartiallyDelivered, Delivered, PartiallyReturned, Returned
The old OrderStatus values Pending, Registered, Paid, Shipped, Delivered, and Returned have been removed. You must update any code that references these values.

Before (v2.4)

use Shopper\Core\Enum\OrderStatus;

// Check payment
if ($order->status === OrderStatus::Paid) {
    // ...
}

// Check shipping
if ($order->status === OrderStatus::Shipped) {
    // ...
}

// Check delivery
if ($order->status === OrderStatus::Delivered) {
    // ...
}

After (v2.5)

use Shopper\Core\Enum\OrderStatus;
use Shopper\Core\Enum\PaymentStatus;
use Shopper\Core\Enum\ShippingStatus;

// Check payment
if ($order->payment_status === PaymentStatus::Paid) {
    // ...
}

// Check shipping
if ($order->shipping_status === ShippingStatus::Shipped) {
    // ...
}

// Check delivery
if ($order->shipping_status === ShippingStatus::Delivered) {
    // ...
}
The Order model now provides convenience methods for common status checks: isNew(), isProcessing(), isCompleted(), isArchived(), isPaid(), isPaymentAuthorized(), isRefunded(), isShipped(), isShippingPending().

Automatic Data Migration

The migration automatically maps your existing order statuses to the new three-status system. No manual data migration is needed.
Old status valueNew statusNew payment_statusNew shipping_status
pendingnewpendingunfulfilled
registeredprocessingpendingunfulfilled
paidprocessingpaidunfulfilled
shippedprocessingpaidshipped
deliveredprocessingpaiddelivered
completedcompletedpaid(unchanged)
cancelledcancelled(unchanged)(unchanged)
If you have custom order status values beyond the ones listed above, they will not be migrated automatically. You must handle them manually before or after running php artisan migrate.

PaymentMethod & Carrier Logo Handling

Likelihood of Impact: High The logo column has been removed from both the payment_methods and carriers tables. Logos are now managed through Spatie Media Library. A new driver column has been added to both tables.

Before (v2.4)

// Accessing logos
$paymentMethod->logo; // string|null — file path
$carrier->logo;       // string|null — file path

After (v2.5)

// Accessing logos via Media Library
$paymentMethod->logoUrl(); // ?string — full URL or null
$carrier->logoUrl();       // ?string — full URL or null
Both models now implement Spatie\MediaLibrary\HasMedia and use the HasMedia trait.
If you stored logos using the old logo column, you need to manually re-upload them through the admin panel or migrate the files to the media library programmatically. The old column data is removed by the migration.

Payment System

Likelihood of Impact: High Shopper 2.5 introduces a complete payment driver system through the new shopper/payment package, which is included as a dependency of shopper/framework. Key components:
  • PaymentProcessingService — orchestrates payment operations (initiate, authorize, capture, refund, cancel) through drivers
  • PaymentTransaction model — records every payment operation with driver, type, status, amount, and provider reference
  • PaymentDriver contract — interface for implementing payment providers
  • PaymentManager — resolves and manages payment drivers (a manual driver is included by default)
New enums in Shopper\Payment\Enum:
EnumValues
TransactionTypeInitiate, Authorize, Capture, Refund, Cancel
TransactionStatusPending, Success, Failed
The admin panel now includes a Capture payment button on the order detail page for orders with PaymentStatus::Authorized. For Stripe payments, install the addon: composer require shopper/stripe. See the Payments documentation for the full API reference.

Medium Impact Changes

Order Contract Interface

Likelihood of Impact: Medium If you implement a custom Order model through the Shopper\Core\Models\Contracts\Order interface, you must add the following methods:
public function setDefaultOrderStatus(): void;
public function canBeCancelled(): bool;
public function isNotCancelled(): bool;
public function isNew(): bool;
public function isProcessing(): bool;
public function isCompleted(): bool;
public function isArchived(): bool;
public function isPaid(): bool;
public function isPaymentPending(): bool;
public function isPaymentAuthorized(): bool;
public function isRefunded(): bool;
public function isShipped(): bool;
public function isShippingPending(): bool;
Use Shopper\Core\Models\Order as a reference implementation. The model sets default statuses automatically via setDefaultOrderStatus() in its booted() method.

Column Renamed: canceled_at to cancelled_at

Likelihood of Impact: Medium The canceled_at column on the orders table has been renamed to cancelled_at (double-L British spelling) for consistency.

Before (v2.4)

$order->canceled_at;

After (v2.5)

$order->cancelled_at;
Update any code, queries, or Blade templates that reference the old column name.

OrderItem Fulfillment Tracking

Likelihood of Impact: Medium Two new columns have been added to the order_items table:
  • fulfillment_status — tracks per-item fulfillment using the new FulfillmentStatus enum (Pending, ForwardedToSupplier, Processing, Shipped, Delivered, Cancelled)
  • order_shipping_id — links each item to a specific shipment
This enables partial fulfillment: different items in the same order can be at different fulfillment stages and shipped in different packages. If you query or manipulate order items directly, be aware of these new columns. No action is required unless you have custom logic that conflicts.

Order Detail Page Decomposed into Components

Likelihood of Impact: Medium The order detail page has been restructured from a single monolithic page into independent, overridable Livewire components. Each section of the page is now its own component, registered in config/shopper/components/order.php. Components marked New were added in v2.5. Components marked Existing were already present but have been refactored.
ComponentAliasTypeDescription
Indexshopper-order-indexExistingOrder listing with filters and tabs
Detailshopper-order-detailExistingOrder detail page (refactored, now uses sub-components)
Shipmentsshopper-order-shipmentsNewCentralized shipment list with filters and tab navigation
Fulfillmentshopper-order-fulfillmentNewFulfillment progress stepper, shipping address, create shipment button
OrderCustomershopper-order-customerNewCustomer info, shipping and billing addresses
OrderItemsshopper-order-itemsNewPaginated order items with fulfillment status badges
OrderNotesshopper-order-notesNewNotes editor with save action
OrderSummaryshopper-order-summaryNewFinancial summary, shipping method, payment method
ShipmentTimelineshopper-order-shipment-timelineNewShipment event timeline with “Add event” action
CreateShippingLabelshopper-slide-overs.create-shipping-labelNewSlide-over form to create a shipment and assign unfulfilled items
ShipmentDetailshopper-slide-overs.shipment-detailNewSlide-over with shipment detail, event timeline, and delivery actions
If you have published order components via php artisan shopper:component:publish order, update your config/shopper/components/order.php to include the new entries:
'pages' => [
    'order-index' => \Shopper\Livewire\Pages\Order\Index::class,
    'order-detail' => \Shopper\Livewire\Pages\Order\Detail::class,
    'order-shipments' => \Shopper\Livewire\Pages\Order\Shipments::class, 
],
'components' => [
    'order-customer' => \Shopper\Livewire\Components\Orders\OrderCustomer::class, 
    'order-fulfillment' => \Shopper\Livewire\Components\Orders\Fulfillment::class, 
    'order-items' => \Shopper\Livewire\Components\Orders\OrderItems::class, 
    'order-notes' => \Shopper\Livewire\Components\Orders\OrderNotes::class, 
    'order-shipment-timeline' => \Shopper\Livewire\Components\Orders\ShipmentTimeline::class, 
    'order-summary' => \Shopper\Livewire\Components\Orders\OrderSummary::class, 
    'slide-overs.create-shipping-label' => \Shopper\Livewire\SlideOvers\CreateShippingLabel::class, 
    'slide-overs.shipment-detail' => \Shopper\Livewire\SlideOvers\ShipmentDetail::class, 
],
You can override any component by pointing the config key to your own class. For example, to customize how order items are displayed, create your own component extending Shopper\Livewire\Components\Orders\OrderItems and update the config entry.

OrderShipping: Status Column & Events

Likelihood of Impact: Medium The order_shipping table has a new status column (using the ShipmentStatus enum with 8 values) and the shipped_at column is now nullable. A new order_shipping_events table tracks the complete delivery timeline for each shipment. The OrderShipping model now uses the HasFulfillmentTransitions trait, which provides a state machine for valid status transitions:
use Shopper\Core\Enum\ShipmentStatus;

// Check allowed transitions
$shipment->canTransitionTo(ShipmentStatus::InTransit); // bool

// Execute a transition (logs an event automatically)
$shipment->transitionTo(ShipmentStatus::InTransit, [
    'location' => 'Distribution Center',
    'description' => 'Package picked up by carrier',
]);
See the Fulfillment documentation for the full transition map.

Low Impact Changes

New Events

Likelihood of Impact: Low Three new events have been added in Shopper\Core\Events\Orders:
EventWhen it fires
OrderArchivedAn order is archived
OrderShipmentCreatedA new shipment is created for an order
OrderShipmentDeliveredA shipment is marked as delivered
The SyncOrderShippingStatusListener automatically listens to OrderShipmentCreated and syncs the order’s shipping_status based on all items’ fulfillment states.

New Enums

Likelihood of Impact: Low Four new enums have been added to Shopper\Core\Enum:
EnumValues
PaymentStatusPending, Authorized, Paid, PartiallyRefunded, Refunded, Voided
ShippingStatusUnfulfilled, PartiallyShipped, Shipped, PartiallyDelivered, Delivered, PartiallyReturned, Returned
ShipmentStatusPending, PickedUp, InTransit, AtSortingCenter, OutForDelivery, Delivered, DeliveryFailed, Returned
FulfillmentStatusPending, ForwardedToSupplier, Processing, Shipped, Delivered, Cancelled
All follow the same pattern as existing enums: backed string enums implementing HasColor, HasIcon, and HasLabel.

Translation Keys

Likelihood of Impact: Low New translation keys have been added under shopper-core::status.* for the new enums. If you have published and customized the Shopper core translations, add the new keys from the packages/core/resources/lang/en/status.php file. The old OrderStatus translation keys for removed values (pending, registered, paid, shipped, delivered, returned) are no longer used.

New Features

Payment Driver System

The new shopper/payment package provides a driver-based payment architecture. Drivers handle payment operations while Shopper manages the order’s payment_status automatically. A manual driver is included for offline payments, and Stripe is available as an addon.

Capture Payment in Admin

Orders with PaymentStatus::Authorized now display a Capture payment button on the order detail page. Clicking it calls the payment driver’s capturePayment() method, records a transaction, and updates the payment status to Paid.

Shipment Tracking

Each shipment now tracks its delivery progress through a ShipmentStatus state machine with automatic event logging. The OrderShippingEvent model records status changes with timestamps, location data, and optional GPS coordinates.

Shipments Management

A new Shipments page in the admin panel provides a centralized view of all shipments with filtering by status, order, and carrier.

Migration Checklist

  • Update composer.json: require shopper/framework: ^2.5
  • Run composer update -W
  • Run php artisan migrate
  • Replace removed OrderStatus values with PaymentStatus / ShippingStatus equivalents
  • Rename $order->canceled_at to $order->cancelled_at
  • Replace $paymentMethod->logo with $paymentMethod->logoUrl()
  • Replace $carrier->logo with $carrier->logoUrl()
  • If using a custom Order model: implement the new contract methods
  • If published order components: update config/shopper/components/order.php with new entries
  • Optional: composer require shopper/stripe for Stripe payments
  • Clear caches: php artisan optimize:clear
  • Test your application