The bundled modules are the best worked examples of the plugin system. This page summarises what each one does and which core hooks it uses, so you can read the real code with a map in hand.
In the user guide: the TruPayments, Booking, TruCommerce and Payment Gateway Add-ons chapters.
| Module | Alias | Priority | Requires | Protected | Public paths |
|---|---|---|---|---|---|
| TruPayments | trupayments | 100 | — | yes | payments |
| TruCommerce | trucommerce | 99 | trupayments ^1.0 | yes | shop |
| Booking | booking | 1000 | trupayments ^1.0 | yes | booking |
| Stripe / PayPal / Braintree / Mollie | stripe … | see each module.json | trupayments ^1.0 | no | — |
Protected modules cannot be deleted from the Plugin Manager. "payments": true in module.json marks a module as a payment consumer (Module::paymentModules()).
{Name}ServiceProvider extending Nwidart\Modules\Support\ModuleServiceProvider, with child providers for routes and events.RouteServiceProvider that wraps each route file in web + the right theme middleware (admin: auth, AdminTheme, usually permission:access {module}; public: FrontTheme).AdminBooting listener that calls three helpers: {Name}Menu::register(), {Name}Settings::register() and {Name}BuilderMenu::register().boot(): translations, breadcrumbs, dashboard rows, front widgets, AppPages definitions, cache-invalidation listeners, Blade components, shortcodes and binding sources.Payment against any Vanilo Payable; TruPayments owns the payment, history, refund, address and zone tables.offline (pay in person) and bank_transfer. Others are separate modules.PaymentManager (available methods, create payment, requests and responses), GatewaySettings (gateway registry, credentials, mode, currencies), PaymentZoneManager (billing zones), RefundManager.admin/payments (methods, billing zones, transactions, refunds, settings) and shared public endpoints payments/{payment:hash}/pay|request|submit|return|cancel, payments/methods, payments/webhook/{gateway}.RefundCreated, RefundStatusChanged (after-commit), plus Vanilo's PaymentCompleted, PaymentCreated, PaymentDeclined, PaymentPartiallyReceived, PaymentTimedOut.storeBillingZone() / deleteBillingZone()).Guides: Payments and gateways.
Stripe, PayPal, Braintree and Mollie are the template for a minimal plugin: no migrations, one service provider, a settings registration, a gateway class and optionally a Blade request view. They call GatewaySettings::registerGateway('stripe', [...]) and Vanilo\Payment\PaymentGateways::register($id, GatewayClass::class) and implement TruPaymentsGateway / ConfigurableGateway. Credentials live in module-specific settings (sandbox/live sets); the webhook URL is displayed in the settings screen.
/shop): shop archive, categories, tags, search, product pages (variants, bundles, downloads, videos, tabs, reviews, comparison), cart, mini-cart, checkout with coupons and promotions, order tracking and a customer account./admin/commerce, gated by access trucommerce): products, taxonomies and categories, tags, attributes, reviews, promotions, coupons, orders, customers, stock, reports, POS registers, channels, countries, zones, tax rates and categories, shipping methods, carriers; a dashboard (trucommerce.dashboard).admin/commerce/pos): register sessions, barcode/SKU lookup, partial payments, cash reconciliation and receipts; uses the same Order/OrderItem/Payment models.CheckoutIntent (a Payable) → payment through TruPayments → the real Order is created only after payment confirmation (cash-on-delivery creates it immediately). Scheduled commands expire intents and release stock holds every 15 minutes.$concord->registerModel(Contract::class, Model::class)) in bootModels().ShippingCalculators::register()), promotion rule/action types (PromotionRuleTypes, PromotionActionTypes), attribute (property) types (PropertyTypes::register()).product, products, product-category + detail variants), and 6 AppPages (shop, cart, checkout, account, order history, order tracking)./booking): service or package → provider → time slot → details → payment → confirmation. Links can preselect a choice through the query string (?service=&provider=&date=&time=).BookingLayoutRegistry; preview any design with ?booking_design=)./admin/bookings): appointments, calendar, forms, services, categories, staff, extras, packages, customers and groups, locations, coupons, taxes, invoices, payments, refunds, waiting list, ratings, notification templates, reports, import/export./staff/bookings, permission access booking staff cabinet) and a customer cabinet.Booking itself is the payable; BookingPaymentIntent exists only for deferred/anonymous flows.booking_sms_driver, QR-code check-in.SyncBookingAfterPaymentEvent; refund events → HandleBookingRefundNotifications. The module also declares BookingCreated, BookingUpdated, BookingStatusChanged, BookingCheckedIn and BookingPaymentStatusChanged, but the current code never dispatches them; notifications go through NotificationService. Observe the Booking model instead (Events, jobs and schedules).booking:cleanup-payment-intents hourly, booking:renew-calendar-watches daily at 03:20.AppPages.access {module} on the route group; each sidebar child checks its own permission.StorefrontReferenceCache, BookingReferenceCache) invalidated by model events that also flush the response cache.boot(), not on AdminBooting, because the bake endpoint and the refresh job run outside admin requests.syncMoneyConfiguration()); format shop amounts with trucommerce_money() rather than by hand.