Skip to main content
Shopper dispatches events at key moments in the order, product, and cart lifecycle. These events allow you to hook into the system and add custom behavior like sending notifications, syncing with external services, updating analytics, or triggering workflows without modifying any Shopper code. Events are organized by domain across two namespaces:
  • Shopper\Core\Events order and product events
  • Shopper\Cart\Events cart events
use Shopper\Core\Events\Orders\OrderCompleted;
use Shopper\Core\Events\Orders\OrderPaid;
use Shopper\Core\Events\Products\ProductCreated;

Listening to Events

Register listeners in your application’s EventServiceProvider or use Laravel’s event discovery:
use Shopper\Core\Events\Orders\OrderCompleted;
use Shopper\Core\Events\Orders\OrderPaid;

protected $listen = [
    OrderPaid::class => [
        GenerateInvoice::class,
        SendPaymentConfirmation::class,
    ],
    OrderCompleted::class => [
        SendOrderCompletedEmail::class,
    ],
];
Every event carries the relevant model as a public property, accessible directly in your listener:
use Shopper\Core\Events\Orders\OrderPaid;

class GenerateInvoice
{
    public function handle(OrderPaid $event): void
    {
        $order = $event->order;

        $order->load('items', 'customer', 'billingAddress');

        Invoice::generate($order);
    }
}

Order Events

Order events cover the full lifecycle of a purchase — from creation to completion, cancellation, or archival.

Available Events

EventPayloadTrigger
OrderCreatedOrder $orderOrder is inserted in the database
OrderPaidOrder $orderAdmin marks order as paid
OrderCompletedOrder $orderAdmin marks order as completed
OrderShippedOrder $orderAll items reach shipped status
OrderCancelledOrder $orderAdmin cancels the order
OrderArchivedOrder $orderAdmin archives the order
OrderDeletedOrder $orderOrder is soft-deleted
OrderNoteAddedOrder $orderAdmin adds a note to the order
All order events carry a single public Order $order property.

Lifecycle Flow

OrderCreated

    ├── OrderPaid
    │       │
    │       ├── OrderShipped ──→ OrderCompleted
    │       │
    │       └── OrderCancelled

    ├── OrderCancelled

    ├── OrderArchived

    └── OrderDeleted

How They Are Dispatched

OrderCreated and OrderDeleted are dispatched automatically via the model observer. They fire on every insert and soft-delete, regardless of where the operation originates.
use Shopper\Core\Models\Order;

$order = Order::query()->create([...]);
Status-related events (OrderPaid, OrderCompleted, OrderCancelled, OrderArchived) are dispatched from the admin panel when an administrator changes the order status. OrderShipped is dispatched by SyncOrderShippingStatusAction when the aggregated shipping status of all items transitions to Shipped. This happens automatically after shipment events are recorded — you don’t dispatch it manually.

Queueing

All order events implement ShouldDispatchAfterCommit, meaning listeners run on the queue after the database transaction commits.
EventQueued
OrderCreatedYes
OrderPaidYes
OrderCompletedYes
OrderShippedYes
OrderCancelledYes
OrderArchivedYes
OrderDeletedYes
OrderNoteAddedYes

Shipment Events

Shipment events track the creation and delivery of individual packages within an order. A single order can have multiple shipments.

Available Events

EventPayloadTrigger
OrderShipmentCreatedOrder $order, OrderShipping $shipmentA new shipment is created with a shipping label
OrderShipmentDeliveredOrder $order, OrderShipping $shipmentA shipment is marked as delivered
Both shipment events carry two properties — the order and the specific shipment. This is useful when an order has multiple packages and you need to know which one was created or delivered.
use Shopper\Core\Events\Orders\OrderShipmentDelivered;

class NotifyCustomerOfDelivery
{
    public function handle(OrderShipmentDelivered $event): void
    {
        $order = $event->order;
        $shipment = $event->shipment;

        $trackingNumber = $shipment->tracking_number;
        $deliveredItems = $shipment->items;
    }
}

Shipment vs Order Events

Shipment events fire at the package level, order events fire at the order level:
ScenarioEvents fired
First package shipped (2 of 3 items)OrderShipmentCreated
Second package shipped (last item)OrderShipmentCreated, OrderShipped
First package deliveredOrderShipmentDelivered
Last package deliveredOrderShipmentDelivered, then OrderCompleted (if order is processing)

Product Events

Product events are dispatched when products are created, updated, or deleted through the admin panel.

Available Events

EventPayloadTrigger
ProductCreatedProduct $productProduct is created via admin
ProductUpdatedProduct $productProduct is updated via admin
ProductDeletedProduct $productProduct is deleted via admin
use Shopper\Core\Events\Products\ProductCreated;

class SyncProductToCatalog
{
    public function handle(ProductCreated $event): void
    {
        $product = $event->product;

        ExternalCatalog::push($product);
    }
}
All product events implement ShouldDispatchAfterCommit — listeners run on the queue after the database transaction commits.

Example: Order Notification System

Here’s how you might use Shopper events to build a notification flow for your store. Each listener handles a single responsibility. Register your listeners:
use Shopper\Core\Events\Orders\OrderCreated;
use Shopper\Core\Events\Orders\OrderPaid;
use Shopper\Core\Events\Orders\OrderShipped;
use Shopper\Core\Events\Orders\OrderShipmentDelivered;

protected $listen = [
    OrderCreated::class => [
        SendOrderConfirmationToCustomer::class,
        NotifyWarehouseTeam::class,
    ],
    OrderPaid::class => [
        GenerateInvoice::class,
        SyncPaymentToAccounting::class,
    ],
    OrderShipped::class => [
        SendShippingConfirmation::class,
    ],
    OrderShipmentDelivered::class => [
        SendDeliveryConfirmation::class,
        RequestProductReview::class,
    ],
];
A listener that sends a shipping confirmation:
use Shopper\Core\Events\Orders\OrderShipped;

class SendShippingConfirmation implements ShouldQueue
{
    public function handle(OrderShipped $event): void
    {
        $order = $event->order;

        $order->load('customer', 'shippings.carrier');

        Mail::to($order->customer->email)
            ->send(new OrderShippedMail($order));
    }
}

Cart Events

Cart events are dispatched when a cart reaches a key state during the checkout process.

Available Events

EventPayloadTrigger
CartCompletedCart $cartCart is converted to an order
CouponAppliedCart $cart, string $codeA coupon code is successfully applied to the cart
CouponRemovedCart $cart, string $codeA coupon code is removed from the cart
Cart events are in the Shopper\Cart\Events namespace:
use Shopper\Cart\Events\CartCompleted;
use Shopper\Cart\Events\CouponApplied;
use Shopper\Cart\Events\CouponRemoved;

Example: Sending a Cart Recovery Email on Coupon Removal

use Shopper\Cart\Events\CouponRemoved;

class OfferAlternativeCoupon
{
    public function handle(CouponRemoved $event): void
    {
        $cart = $event->cart;
        $removedCode = $event->code;

        $customer = $cart->customer;

        if ($customer) {
            Mail::to($customer->email)->send(new AlternativeDiscountMail($cart));
        }
    }
}

All Events Reference

NamespaceEventPayloadQueued
Events\OrdersOrderCreatedOrder $orderYes
Events\OrdersOrderPaidOrder $orderYes
Events\OrdersOrderCompletedOrder $orderYes
Events\OrdersOrderShippedOrder $orderYes
Events\OrdersOrderCancelledOrder $orderYes
Events\OrdersOrderArchivedOrder $orderYes
Events\OrdersOrderDeletedOrder $orderYes
Events\OrdersOrderNoteAddedOrder $orderYes
Events\OrdersOrderShipmentCreatedOrder $order, OrderShipping $shipmentYes
Events\OrdersOrderShipmentDeliveredOrder $order, OrderShipping $shipmentYes
Events\ProductsProductCreatedProduct $productYes
Events\ProductsProductUpdatedProduct $productYes
Events\ProductsProductDeletedProduct $productYes
Cart\EventsCartCompletedCart $cartNo
Cart\EventsCouponAppliedCart $cart, string $codeNo
Cart\EventsCouponRemovedCart $cart, string $codeNo