Events
Internal Event Reference
Last updated: August 18, 2026
STOAR emits a domain event at every significant business action — an order is placed, stock runs low, a review is approved. These events are the extension surface of the platform: the same signals that drive outbound webhooks are available in-process to custom modules, so a self-hosted or SaaS deployment can bolt on behaviour without touching core code.
Every event follows the stoar.shop.<domain>.<action> naming convention and
carries a small payload (the relevant record, plus any context).
Listening from a custom module #
A custom module registers a listener in its service provider. When the event fires, your listener runs — queue an email, sync to an external system, write an audit row, anything:
use Illuminate\Support\Facades\Event;
// In your module's ServiceProvider::boot()
Event::listen('stoar.shop.order.created', function ($order) {
// React to the new order.
});
Because listeners run in-process, they see live model records and can act before or alongside the built-in handlers. This is how the bundled low-stock logger, payment gateways, and notification emails all attach — nothing is hard-wired.
Entity lifecycle events #
Core records (products, categories, customers, coupons, addresses) emit
created, updated, and deleted events from a single seam, so a listener
catches the change no matter where it originated — the admin panel, the REST
API, the storefront, or a background job. Bulk operations such as a backup
restore intentionally stay quiet so listeners aren't flooded during an import.
Event reference #
Orders
| Event | Fires when |
|---|---|
order.created |
An order is placed (any payment method) |
order.completed |
An order is paid |
order.statusChanged |
Order status changes |
order.cancelled |
An order is cancelled |
order.refunded |
An order is refunded (full or partial) |
order.paymentFailed |
A payment fails or the session expires |
order.disputeCreated |
A chargeback is opened |
order.offline_pending |
An offline/manual order awaits payment |
order.bank_transfer_pending |
A bank-transfer order awaits payment |
Customers
| Event | Fires when |
|---|---|
customer.created |
Any customer record is created |
customer.updated |
A customer record is updated |
customer.deleted |
A customer is deleted |
customer.registered |
A shopper self-registers (carries the verification link) |
customer.passwordReset |
A password reset is requested |
customer.emailChangeRequested |
An email-address change is requested |
customer.wishlist.added |
A product is added to a wishlist |
customer.address.created / .updated / .deleted |
A customer address changes |
Products & Catalog
| Event | Fires when |
|---|---|
product.created / .updated / .deleted |
A product changes |
category.created / .updated / .deleted |
A category changes |
Reviews
| Event | Fires when |
|---|---|
review.submitted |
A shopper submits a review |
review.approved |
A review is made visible |
review.rejected |
A review is hidden |
review.deleted |
A review is deleted |
Inventory
| Event | Fires when |
|---|---|
inventory.reserved |
Stock is reserved at checkout |
inventory.released |
A reservation is released |
inventory.adjusted |
Stock changes via the audited adjustment log |
inventory.low |
Stock falls to/below the low-stock threshold |
inventory.backInStock |
Stock recovers above the threshold |
Coupons & Gift Cards
| Event | Fires when |
|---|---|
coupon.created / .updated / .deleted |
A coupon changes |
coupon.applied |
A coupon is applied to a cart |
coupon.redeemed |
Coupon usage is recorded against an order |
giftcard.issued |
A gift card is issued |
giftcard.redeemed |
An amount is redeemed from a gift card |
Subscriptions
| Event | Fires when |
|---|---|
subscription.created |
A subscription is created |
subscription.cancelled |
A subscription is cancelled |
subscription.paymentFailed |
A renewal payment fails |
Other
| Event | Fires when |
|---|---|
newsletter.subscribed |
Someone subscribes to the newsletter |
contact.submitted |
The contact form is submitted |
Every name above is prefixed with
stoar.shop.when you subscribe — e.g.stoar.shop.inventory.low.
Events vs. webhooks #
Both are driven by the same signals. Reach for webhooks when an external system needs to be notified over HTTP. Reach for event listeners when a custom module needs to run logic inside the store.