graystackit/laravel-mollie-billing
Batteries-included Mollie billing for Laravel with VAT/OSS compliance, wallet-based metered billing, coupons, scheduled plan changes, trials, an admin panel and a Livewire 4 customer portal, all keyed off a Billable contract.
Architecture fit. The package is opinionated and horizontal: it assumes a Billable contract on a tenant-like model (typically Organization), not User, and keys all polymorphic foreign keys off a configurable key type. That is the right shape for B2B SaaS with org-level subscriptions, but it forces an architectural decision (billable = org vs. user) before you write a line of integration code. It also assumes multi-tenant URL structures, Livewire 4 for all customer/admin surface area, and a commercial Flux Pro license — three assumptions that are not typical of a stock Laravel app. Fit is strong only if your existing stack already resembles these assumptions; otherwise the package dictates your stack rather than adapting to it.
Integration feasibility. Mechanically straightforward: composer install, publish config/migrations/views/lang, set billable_model and both key types, implement HasBilling, wire resolveBillableUsing() and authUsing(), mount three route groups (portal, checkout, admin) plus a webhook group that must live outside the web middleware. The docs are unusually candid about the sharp edges — the checkout-route fallback, the authUsing() cross-tenant gate, the PropagateRouteDefaults vs. urlParametersUsing() split, and the billable_key_type migration-time constraint. That candor is a positive signal; it also means every one of those is a real bug you can introduce.
Technical risk. High, concentrated in three areas:
mollie/laravel-mollie ^4, bavix/laravel-wallet, mpociot/vat-calculator, Livewire 4, Flux Pro, Tailwind v4 @source scanning. That is five independent external contracts plus a commercial license. Any of them bumping major versions can strand this package on Laravel 12/13.Key questions.
bavix/laravel-wallet's double-entry model match our finance team's expectations for metered billing reconciliation?Stack fit. This is a Laravel 12/13 + Livewire 4 + Tailwind v4 package. If we are on Laravel 11, Livewire 3, or a non-Vite asset pipeline, we cannot adopt it without a platform upgrade first. The dependency chain is narrow and current, which is good for correctness and bad for optionality — it pins us to the bleeding edge of the Laravel ecosystem for the lifetime of the package.
Migration path. There is no incremental adoption story. The package owns the subscription, wallet, invoice, coupon, and audit tables. Adopting it means:
billable_key_type and user_key_type before first migrate — this rewrites wallets.holder_id, transactions.payable_id, transfers.{from,to}_id and other polymorphic keys, and changing them later requires manual ALTERs across third-party tables. This is the single biggest irreversible decision.billing:check-config, then migrate.If we already have Stripe or a homegrown billing stack, expect a dual-write period and a reconciliation step; the package is not designed for coexistence.
Compatibility. The route group split (portal / checkout / admin / webhook) has to map cleanly onto our tenant middleware. checkoutRoutes() must live outside tenant scoping; the webhook must live outside web entirely. In a multi-tenant app with a {organization:slug} prefix, the package supplies PropagateRouteDefaults, but queued jobs and webhook callbacks need the global urlParametersUsing() resolver — both must be wired, and the docs are explicit that this is not optional.
Sequencing (recommended):
billing:check-config, exercise a test Mollie checkout end-to-end in the Mollie test dashboard. This is 1–2 days and answers 80% of the "does it fit" question.@source scanning renders the portal correctly in our build.resolveBillableUsing() and authUsing() with a tenant-comparing closure — not auth()->check(). The docs explicitly warn that a lazy auth callback turns the checkout query-parameter fallback into a cross-tenant billing-data read.urlParametersUsing() for webhook/queued-mail contexts and test a queued notification end-to-end.Maintenance. This is a single-vendor, single-maintainer-shaped package with one star and zero dependents. Assume you may have to fork it. Budget for: periodic Laravel/Livewire major upgrades the maintainer may not ship, Flux Pro license renewal, Mollie SDK v4→v5 migration whenever that lands, and ongoing VAT rule changes (EU OSS rates, VIES availability, UK/Swiss edge cases). Treat it as a vendored dependency, not a fire-and-forget composer line.
Support. Docs are strong (README, docs/vat-handling.md, docs/audit.md, changelog, releases) — better than most packages this size. But there is no visible community, no issue triage history to review, and no evidence of an SLA. Your escape hatch is the MIT license: keep a fork ready. Assign an internal owner who can read the Mollie SDK and the VAT calculator, and who has the authority to patch the vendor tree.
Scaling. The hot paths are webhook handling (every payment), wallet transaction writes (bavix/laravel-wallet is a double-entry ledger — fine at moderate volume, but plan for indexing and archival), and the three-way country reconciliation that runs at every recurring payment. That last one is the sleeper: it means every renewal does VIES lookups, IP lookups, and a reconciliation write. Under load, this is a queue candidate, not a synchronous path — verify with the maintainer or in code that it is dispatchable.
Failure modes to plan for.
RouteNotFoundException [billing.webhook] before it ever reaches Mollie. Verify in CI with a smoke test, not in staging.adminRoutes(), set BILLING_AUTO_LOAD_ADMIN_ROUTES=false.billable_key_type/user_key_type set wrong at first migrate → manual column rewrites across wallet tables; treat as a data-loss-class incident.@source missing → silent unstyled rendering of all package views.authUsing() too permissive → ?organization=acme-corp on the checkout route discloses another tenant's address and VAT number.Ramp-up. Roughly 3–5 engineer-days to a working checkout in a greenfield Laravel 12 app; 2–3 engineer-weeks if we need to upgrade Laravel, adopt Livewire 4, license Flux Pro, and migrate existing subscription data. Team knowledge required: Laravel service providers and middleware, Livewire 4 SFCs, Mollie's subscription/mandate/webhook model, bavix/laravel-wallet's ledger semantics, and EU VAT/OSS fundamentals. The last one is not optional — the package implements a compliance workflow, and someone on the team has to be able to argue with it and with a tax advisor. Plan for a named billing owner, an internal fork-ready repo, and a written runbook covering the mismatch workflow, refunds/credit notes, and admin override justifications before go-live.
How can I help you explore Laravel packages today?