pushery / billing-for-laravel
Provider-neutral billing for Laravel: subscriptions, invoices, metered usage, dunning, tax and e-invoicing. Two drivers, one set of contracts.
Requires
- php: ^8.4
- ext-bcmath: *
- ext-ctype: *
- ext-dom: *
- ext-hash: *
- ext-json: *
- ext-libxml: *
- ext-mbstring: *
- guzzlehttp/psr7: ^2.0 || ^3.0
- illuminate/auth: ^13.0
- illuminate/broadcasting: ^13.0
- illuminate/bus: ^13.0
- illuminate/cache: ^13.0
- illuminate/collections: ^13.0
- illuminate/config: ^13.0
- illuminate/console: ^13.0
- illuminate/container: ^13.0
- illuminate/contracts: ^13.0
- illuminate/database: ^13.0
- illuminate/events: ^13.0
- illuminate/filesystem: ^13.0
- illuminate/hashing: ^13.0
- illuminate/http: ^13.0
- illuminate/log: ^13.0
- illuminate/notifications: ^13.0
- illuminate/queue: ^13.0
- illuminate/routing: ^13.0
- illuminate/support: ^13.0
- illuminate/translation: ^13.0
- illuminate/validation: ^13.0
- illuminate/view: ^13.0
- laravel/cashier: ^16.0
- nesbot/carbon: ^3.0
- psr/log: ^1.0 || ^2.0 || ^3.0
- stripe/stripe-php: ^17.4|^18.0|^19.0|^20.0|^21.0
- symfony/http-foundation: ^7.0 || ^8.0
- symfony/http-kernel: ^7.4|^8.0
Requires (Dev)
- adyen/php-api-library: ^25.0|^26.0|^30.1
- fakerphp/faker: ^1.24
- horstoeko/zugferd: ^1.0
- larastan/larastan: 3.12.2
- laravel/ai: ^1.0
- laravel/boost: ^2.10.0
- laravel/mcp: ^1.0.1
- laravel/pao: ^1.1
- laravel/pint: ^1.0
- livewire/livewire: ^4.3
- mollie/mollie-api-php: ^3.13 || ^4.0
- nikic/php-parser: ^5.8
- orchestra/testbench: ^11.0
- orchestra/testbench-core: ^11.4.0
- pestphp/pest: ^5.2.1
- pestphp/pest-plugin-browser: ^5.0
- pestphp/pest-plugin-evals: ^5.1
- pestphp/pest-plugin-laravel: ^5.0
- pestphp/pest-plugin-phpstan: 5.2.1
- pestphp/pest-plugin-type-coverage: ^5.0
- phpstan/phpstan: 2.2.15
- rector/rector: 2.6.7
- setasign/fpdf: ^1.8.2
- smalot/pdfparser: ^2.0
- spaze/phpstan-disallowed-calls: 4.14.0
Suggests
- ext-intl: Writes the amounts in the package's mails the way the reader's language does, through ICU. Without it an amount keeps its currency code and takes the language's decimal mark, as in 29,00 EUR.
- ext-posix: Names the system user that billing:reporting:file records as the submitter of a filing when --by is not given. Without it the name comes from the USER, LOGNAME or USERNAME environment variable.
- adyen/php-api-library: Required only for the Adyen driver -- no other driver and no local engine touches it. Deliberately not a hard dependency, the same reasoning that keeps mollie/mollie-api-php optional: an install that never selects Adyen would otherwise carry an API client it never calls. Without it the Adyen webhook verifier refuses every request rather than waving one through.
- horstoeko/zugferd: Required only to embed the EN 16931 CII XML into a ZUGFeRD/Factur-X hybrid PDF/A-3 via Invoicing\ZugferdPdfInvoice. The CII and XRechnung XML writers need none of it.
- livewire/livewire: Required only for the optional account-hub UI — the nine Livewire screens. The billing core (models, webhooks, invoicing, tax, contracts) needs none of it.
- mollie/mollie-api-php: Required only for the Mollie driver, version 3.13 or 4 — the local billing engine and every other driver need none of it. Deliberately not a hard dependency: an install that never selects billing.default=mollie would otherwise carry an HTTP client it never calls, the same reasoning that keeps horstoeko/zugferd optional.
Provides
None
Conflicts
None
Replaces
None
- dev-main
- v0.44.0.x-dev
- v0.44.0
- v0.43.0.x-dev
- v0.43.0
- v0.42.1
- v0.42.0
- v0.41.0
- v0.40.0
- v0.39.0
- v0.38.0
- v0.37.1
- v0.37.0
- v0.36.0
- v0.35.0
- v0.34.0
- v0.33.0
- v0.32.0
- v0.31.0
- v0.30.0
- v0.29.0
- v0.28.0
- v0.27.0
- v0.26.0
- v0.25.0
- v0.24.0
- v0.23.0
- v0.22.0
- v0.21.2
- v0.21.1
- v0.21.0
- v0.20.1
- v0.20.0
- v0.19.1
- v0.19.0
- v0.18.0
- v0.17.0
- v0.16.0
- v0.15.0
- v0.14.0
- v0.13.0
- v0.9.0
- v0.8.0
- v0.7.0
- v0.6.0
- v0.5.0
- v0.4.1
- v0.4.0
- v0.3.0
- v0.2.0
- v0.1.1
- v0.1.0
This package is auto-updated.
Last update: 2026-10-06 05:32:30 UTC
README
Billing for Laravel
Provider-neutral billing for Laravel: subscriptions, invoices, metered usage, dunning, tax and e-invoicing. Two drivers, one set of contracts.
Everything crosses a small set of contracts, so your app talks to billing — not to a provider. Stripe runs the subscription cycle on its own side, behind a hosted checkout. Mollie establishes a mandate through a first payment and this package runs the cycle itself, which is the path any provider without a native subscription API takes. Your application code does not change between them; billing.default does.
Highlights
- Two-layer, provider-neutral core —
PaymentRails(moves money, stores mandates) andBillingEngine(the recurring cycle). Money crosses the boundary as aMoneyvalue object, never a raw provider response. - Subscriptions — in-app upgrade/downgrade swap with a proration preview, cancel-into-grace, resume, and immediate cancel — the client submits a tier key, never a price (anti-price-injection).
- Account hub — a publishable Livewire hub (overview, subscription, change-plan, payment methods, invoices, usage, payment recovery, danger zone) with config-driven routes and a self-contained Blade view set. Drop a
<x-billing::banner />into your layout to surface a failed payment, a lapsing grace period or a trial about to end. - Webhooks — an idempotent, signature-verified backbone with effects out of the box (plan-sync, add-on credit, dunning notice, invoice persistence) and a fail-loud webhook-secret guard.
- Usage-based billing — charge a base fee plus what a customer actually used, with a retry that cannot double-bill, an outage that cannot silently lose revenue, oversell-safe reserve/work/settle metering, quota policies, and prepaid units that never expire.
- Entitlements & seats — a separate
Licensegate for what a tier unlocks (feature grants + numeric limits), independent of what it costs, plus team seats and a User-XOR-Team owner model. - Dunning, suspension & tax — a config-driven multi-level dunning ladder, a per-surface
423 Lockedsuspension gate driven by a stored delinquency clock (outage-safe), and provider tax (Stripe Tax) on the invoice with a pluggableTaxCalculatorseam for a local computation path. - E-invoicing — dependency-free EN 16931 writers in both syntaxes (XRechnung UBL and ZUGFeRD / Factur-X CII), an optional hybrid PDF/A-3 embed, and a DATEV (EXTF Buchungsstapel) export.
- Security-first — a
billing.enabledmaster switch that makes the whole surface disappear, a scoped Content-Security-Policy for the hub, a fail-closed money-eligibility gate, and card capture that happens on the provider's own hosted page, so no card data ever touches your app (PCI SAQ-A).
Requirements
- PHP 8.4+
- Laravel 13+
Tested on PostgreSQL and MySQL 8.4, the databases Laravel Cloud runs (serverless Postgres and MySQL 8.4 LTS), so it runs there out of the box. The fast suite runs on SQLite.
Installation
composer require pushery/billing-for-laravel php artisan billing:install php artisan migrate
The service provider is registered through package discovery. The Stripe driver is the default and builds on Cashier, so set your Stripe keys (STRIPE_KEY, STRIPE_SECRET, STRIPE_WEBHOOK_SECRET) as usual.
For Mollie, set BILLING_DRIVER=mollie and BILLING_MOLLIE_API_KEY, and install its SDK — composer require mollie/mollie-api-php. It is a suggestion rather than a requirement on purpose: an install that never selects that driver would otherwise carry an HTTP client it never calls.
Billable model isn't
App\Models\User? SetBILLING_CUSTOMER_MODELbefore you runbilling:install, or it adds the billing columns tousers. See the installation guide for the full detail.
Documentation
The full documentation lives at docs.pushery.com/billing-for-laravel — start there. (It is published as a site rather than carried in the repository, so these links point outward and an installed package stays unchanged.)
- New here? Choosing your setup, then the guide (installation → configuration → subscriptions → usage → invoicing → …).
- Reference: configuration · commands · events · contracts · database
- Guides: migrating from Cashier · migrating from your own billing code · testing · upgrading · troubleshooting
- Compliance: invariants · retention & erasure · security
Security
The card is captured on the provider's own hosted page, so no card data ever touches your app (PCI SAQ-A), and the webhook backbone refuses to boot in production without a signing secret. Please review the security policy and report vulnerabilities privately rather than opening a public issue.
Built by Pushery
This package is built and maintained by Pushery — a Berlin-based studio building Laravel applications, SaaS products, and open-source tools.
Building a Laravel UI? WireKit, Pushery's open-source Livewire component kit, gives you a themeable component library out of the box. Browse the rest of our work at pushery.com.
License
The MIT License (MIT). See LICENSE for details.