Skip to content
  1. Extras
  2. MiniShop3
  3. Development
  4. Events

Events and plugins ​

MiniShop3 runs on the MODX event system. A plugin steps into cart, order, product and customer processing without changing the source code.

Getting started ​

  • Working with plugins — how to get parameters, abort an operation, modify data, pass data between plugins

Events by category ​

Cart ​

EventDescription
msOnBeforeGetCartBefore getting cart
msOnGetCartAfter getting cart
msOnBeforeAddToCartBefore adding product
msOnAddToCartAfter adding product
msOnBeforeChangeInCartBefore changing quantity
msOnChangeInCartAfter changing quantity
msOnBeforeChangeOptionsInCartBefore changing options
msOnChangeOptionInCartAfter changing options
msOnBeforeRemoveFromCartBefore removing product
msOnRemoveFromCartAfter removing product
msOnBeforeEmptyCartBefore clearing cart
msOnEmptyCartAfter clearing cart
msOnGetStatusCartGetting cart status

Order ​

EventDescription
msOnBeforeAddToOrderBefore adding field to order
msOnAddToOrderAfter adding field
msOnBeforeValidateOrderValueBefore field validation
msOnValidateOrderValueAfter field validation
msOnErrorValidateOrderValueValidation error
msOnBeforeRemoveFromOrderBefore removing field
msOnRemoveFromOrderAfter removing field
msOnBeforeEmptyOrderBefore clearing order draft
msOnEmptyOrderAfter clearing order draft
msOnSubmitOrderFrontend order submit
msOnBeforeMgrCreateOrderBefore manager finalization
msOnMgrCreateOrderAfter manager finalization
msOnBeforeCreateOrderBefore creating order
msOnCreateOrderAfter creating order

Cost ​

EventDescription
msOnBeforeGetCartCostBefore cart cost calculation
msOnGetCartCostAfter cart cost calculation
msOnBeforeGetDeliveryCostBefore delivery cost calculation
msOnGetDeliveryCostAfter delivery cost calculation
msOnBeforeGetPaymentCostBefore payment fee calculation
msOnGetPaymentCostAfter payment fee calculation
msOnBeforeGetOrderCostBefore order total (cart + delivery + payment)
msOnGetOrderCostAfter total: override cost / cart_cost / delivery_cost / payment_cost

Order status ​

EventDescription
msOnBeforeChangeOrderStatusBefore status change
msOnChangeOrderStatusAfter status change

Customer ​

EventDescription
msOnBeforeGetOrderCustomerBefore getting customer
msOnGetOrderCustomerAfter getting customer
msOnBeforeGetOrderUserBefore resolving modUser on submit
msOnGetOrderUserAfter resolving modUser
msOnBeforeAddToCustomerBefore adding field
msOnAddToCustomerAfter adding field
msOnBeforeValidateCustomerValueBefore field validation
msOnValidateCustomerValueAfter field validation
msOnErrorValidateCustomerValueValidation error
msOnBeforeCreateCustomerBefore creating customer
msOnCreateCustomerAfter creating customer
msOnBeforeUpdateCustomerBefore updating customer (processor; neither the manager nor the Web API calls it yet)
msOnUpdateCustomerAfter updating customer (processor; neither the manager nor the Web API calls it yet)
msOnBeforeAddCustomerAddressBefore adding address
msOnAddCustomerAddressAfter adding address

Products (catalog) ​

EventDescription
msOnGetProductPriceProduct price modification
msOnGetProductWeightProduct weight modification
msOnGetProductFieldsProduct fields modification
msOnGetPublicSeoAfter the public SEO set is assembled (PublicSeoService, ms3_public_seo_tv_map)

msProducts snippet ​

Events for integrating third-party packages (ms3Variants, msBrands and others) without changing core code.

EventDescription
msOnProductsLoadAfter product list is loaded (bulk loading)
msOnProductPreparePreparing each product's data

usePackages parameter

To enable data loading, pass the package name in the snippet parameter: &usePackages='ms3Variants,msBrands'

Order products ​

EventDescription
msOnBeforeCreateOrderProductBefore adding product to order
msOnCreateOrderProductAfter adding product
msOnBeforeUpdateOrderProductBefore updating product
msOnUpdateOrderProductAfter updating product
msOnBeforeRemoveOrderProductBefore removing product
msOnRemoveOrderProductAfter removing product

Order model (xPDO) ​

EventDescription
msOnBeforeSaveOrderBefore save (xPDO)
msOnSaveOrderAfter save (xPDO)
msOnBeforeRemoveOrderBefore remove (xPDO)
msOnRemoveOrderAfter remove (xPDO)
msOnBeforeUpdateOrderReserved — never fired (#844)
msOnUpdateOrderReserved — never fired (#844)

Notifications ​

EventDescription
msOnBeforeSendNotificationBefore sending notification
msOnAfterSendNotificationAfter sending notification
msOnRegisterNotificationChannelsChannel registration

Vendors ​

EventDescription
msOnBeforeVendorCreateBefore creating vendor
msOnVendorCreateAfter creating
msOnBeforeVendorUpdateBefore updating
msOnVendorUpdateAfter updating
msOnBeforeVendorDeleteBefore deleting
msOnVendorDeleteAfter deleting

All six vendor events are fired only by the older Settings/Vendor/* processors. CRUD in the manager goes through the Manager API, and that does not call them — see vendor events and issue #847.

Import ​

EventDescription
msOnBeforeImportBefore import start
msOnAfterImportAfter import complete
msOnImportRowWhen processing a row

Manager ​

EventDescription
msOnManagerCustomCssJsLoading scripts and styles

Shipments ​

The logic lives in ShipmentLifecycleService (ms3_shipment_lifecycle), the tables are ms3_shipments and ms3_shipment_events. Creating a shipment and setTracking work even with ms3_shipment_enabled=0, while the delivery webhook answers 404 in that case. Before-events are aborted with success=false in the invokeEvent response. The response of after-events is not read at all: an error raised by a plugin on msOnCreateShipment, msOnChangeShipmentStatus or msOnUpdateShipmentTracking neither aborts the operation nor reaches the log.

EventParametersWhen
msOnBeforeCreateShipment / msOnCreateShipmentbefore: order_id, delivery_id; after: shipment (the record)create()
msOnBeforeChangeShipmentStatus / msOnChangeShipmentStatusbefore: shipment, status; after: shipmenttransition() / delivery provider webhook
msOnBeforeUpdateShipmentTracking / msOnUpdateShipmentTrackingbefore: shipment, tracking_number; after: shipmentsetTracking() / webhook on a tracking change

Shipment statuses: preparing, shipped, in_transit, delivered, cancelled, returned, failed (ShipmentStatus).

Inventory ​

With ms3_inventory_enabled=1 the work is done by ProductStockInventory (ms3_inventory), the contract is InventoryServiceInterface. Event parameters: key (InventoryKey), qty, ctx (InventoryContext: orderId, origin — defaults to 'order', holdState — defaults to null). A before-event returning success=false raises an InventoryException (ms3_err_inventory_cancelled). Passing $notify=false to reserve and release skips the event pair — compensation happens inside the SQL transaction.

Inventory after-events abort the operation too

Reserve, commit and release share one dispatch method, so success=false in an after-event raises the same InventoryException — after the database write. An output() in msOnInventoryCommit breaks the status change when the stock decrement is already committed.

The Adjust pair behaves differently: the after-event response only goes to the error log. For an analytics plugin that subscribes to after-events just to observe, the difference matters.

Reserve: before per line, after in a batch

reserveBatch() fires msOnBeforeInventoryReserve for every order line, while msOnInventoryReserve fires once per held line — but only after the whole batch has been held. If the third line runs out of stock, the first two are rolled back through an internal release with notify = false.

A plugin that pairs before with after will see a before without an after on a partial failure — and no release event either.

EventWhen, in terms of order status
msOnBeforeInventoryReserve / msOnInventoryReserveReserve on ms3_status_new (and right before commit, when an order goes straight to paid)
msOnBeforeInventoryCommit / msOnInventoryCommitCommit on ms3_status_paid (does not decrease the stock twice)
msOnBeforeInventoryRelease / msOnInventoryReleaseRelease on ms3_status_canceled before commit. Also when payment send() fails
msOnBeforeInventoryAdjust / msOnInventoryAdjustEditing order lines in the manager: the reserve is brought to the new line quantity (since 1.14.3-beta1)

The Adjust pair has its own parameters, not the ones used by reserve, commit and release:

ParameterTypeValue
product_idintThe product whose reserve changes
order_idintThe order
old_qtyfloatHow much the order held before the edit
new_qtyfloatHow much it will hold after
forcedboolThe edit went through despite a shortage, using the msorder_inventory_override permission

The event fires for every product whose quantity changed, including when a line is removed. Then new_qty is zero. msOnBeforeInventoryAdjust with success=false cancels the edit: the order line is not saved, and the stock and the reserve stay as they were.

Changes from miniShop2 ​

miniShop2MiniShop3Changes
productmsProductParameter renamed
msOnGetOrderCostKept + 3 partialsAlso msOnGetCartCost, msOnGetDeliveryCost, msOnGetPaymentCost. Override the total in msOnGetOrderCost
controllercontrollerIn miniShop2 the parameter arrived in msOnManagerCustomCssJs and in the order and settings controllers. In MiniShop3 it is present in every cart event and in the msOnBeforeGetOrderCustomer / msOnGetOrderCustomer pair; see The controller parameter
msOnBeforeEmptyOrder / msOnEmptyOrderSame namesCarried over from miniShop2 unchanged. Draft cleanup
msOnBeforeMgrCreateOrder / msOnMgrCreateOrderSame namesCarried over from miniShop2 unchanged. Manager finalization
—msOnBeforeGetOrderUser / msOnGetOrderUsermodUser on submit
—msOnBeforeValidateCustomerValueNew event
—msOnCreateCustomerNew event
—msOnAddCustomerAddressNew event
—msOnBeforeSendNotificationNew event
—msOnImportRowNew event
—msOnProductsLoadThird-party package integration
—msOnProductPrepareThird-party package integration
—msOnGetPublicSeoPublic SEO for the Web API
—msOn*Shipment*Shipment lifecycle
—msOn*Inventory*Stock reserve / commit / release

Call chains (where to look in code) ​

ActionEvents in order
Clear draft (order/clean)msOnBeforeEmptyOrder → field reset → msOnEmptyOrder
Frontend totalcart/delivery/payment cost → msOnBeforeGetOrderCost → compose → msOnGetOrderCost (return any of the 4 amounts)
Frontend submitmsOnSubmitOrder → … → msOnBeforeCreateOrder → msOnCreateOrder
Manager finalizemsOnBeforeMgrCreateOrder → msOnBeforeCreateOrder → msOnCreateOrder → msOnMgrCreateOrder

All names above are registered in MODX; the registration list is _build/elements/events.php.