Skip to main content
Shopper dispatches events at key moments in the order and product lifecycle. These events allow you to hook into the system and add custom behavior — sending notifications, syncing with external services, updating analytics, or triggering workflows — without modifying any Shopper code. All events are located in the Shopper\Core\Events namespace and are organized by domain.
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
OrderCancelOrder $orderAdmin cancels the order
OrderArchivedOrder $orderAdmin archives the order
OrderDeletedOrder $orderOrder is soft-deleted
AddNoteToOrderOrder $orderAdmin adds a note to the order
All order events carry a single public Order $order property.

Lifecycle Flow

OrderCreated

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

    ├── OrderCancel

    ├── 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, OrderCancel, 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

Most order events implement ShouldQueueAfterCommit, meaning listeners run on the queue after the database transaction commits. AddNoteToOrder is synchronous.
EventQueued
OrderCreatedYes
OrderPaidYes
OrderCompletedYes
OrderShippedYes
OrderCancelYes
OrderArchivedYes
OrderDeletedYes
AddNoteToOrderNo

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 $orderA new shipment is created with a shipping label
OrderShipmentDeliveredOrder $order, OrderShipping $shipmentA shipment is marked as delivered
OrderShipmentDelivered is the only event that carries two properties — the order and the specific shipment that was delivered. This is useful when an order has multiple packages and you need to know which one arrived.
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);
    }
}
Product events are synchronous (ProductCreated, ProductUpdated) except for ProductDeleted which implements ShouldQueueAfterCommit.

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));
    }
}

All Events Reference

NamespaceEventPayloadQueued
Events\OrdersOrderCreatedOrder $orderYes
Events\OrdersOrderPaidOrder $orderYes
Events\OrdersOrderCompletedOrder $orderYes
Events\OrdersOrderShippedOrder $orderYes
Events\OrdersOrderCancelOrder $orderYes
Events\OrdersOrderArchivedOrder $orderYes
Events\OrdersOrderDeletedOrder $orderYes
Events\OrdersAddNoteToOrderOrder $orderNo
Events\OrdersOrderShipmentCreatedOrder $orderYes
Events\OrdersOrderShipmentDeliveredOrder $order, OrderShipping $shipmentYes
Events\ProductsProductCreatedProduct $productNo
Events\ProductsProductUpdatedProduct $productNo
Events\ProductsProductDeletedProduct $productYes