cboxdk / laravel-billing
Cbox Billing — the billing engine for Laravel — a gateway-agnostic library: catalog, subscriptions, real-time usage metering with hard limits, a double-entry ledger, invoicing, and pricing operations.
Requires
- php: ^8.4
- brick/money: ^0.14
- cboxdk/laravel-geo: ^0.4
- cboxdk/laravel-tax: ^0.1
- illuminate/cache: ^13.0
- illuminate/contracts: ^13.0
- illuminate/database: ^13.0
- illuminate/support: ^13.0
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.18
- orchestra/testbench: ^11.0
- pestphp/pest: ^4.0
README
cboxdk/laravel-billing — the billing engine for Laravel: a gateway-agnostic
library of billing primitives (catalog, subscriptions, real-time usage metering
with hard limits, a double-entry ledger, wallets & credits, invoicing, pricing)
you compose into a billing product. The framework peer to
cboxdk/laravel-id — UI-free and
domain-free: every capability sits behind a contract you bind, mock or replace.
This is the package, not the product. The deployable, self-hostable billing app built on it — with an admin console and customer portal — is the separate
cboxdk/cbox-billingapplication (exactly ascbox-idis the app built onlaravel-id). Reach for the app if you don't want to build the UI/hosting layer yourself; reach for this package to embed billing in your own Laravel app.
Status: v0.2.0 (pre-1.0). The architecture is settled and the full module surface — metering, wallets, ledger, reconciliation, subscriptions, entitlements, accounts, catalog, quotes/invoicing, payments, refunds — has shipped behind contracts. Start with the documentation; the architecture rationale is in
docs/getting-started/architecture.mdand the hardened decisions in the ADRs.
Documentation
Full docs live in docs/:
- Quick start — install to a hard-limited usage check.
- Core concepts — one page per module.
- Cookbook — task-first recipes.
- Extension points — contracts, adapters, testing.
- Configuration · Security.
The three-layer model (why it's correct)
Real-time enforcement, metering truth, and money are three separate concerns — the invoice is computed from the immutable event log, never read from a counter:
- Enforcement — an app-local counter (Laravel cache, atomic increment/ decrement, no custom Lua) answering "may this request proceed?" in sub-ms. Disposable; rebuildable from the event log.
- Metering truth — an immutable, append-only usage event log. Invoices are recomputed from it with the pinned price, never read from counters.
- Money — a double-entry ledger; balances derived from immutable postings.
Hard limits are enforced locally per node against a leased slice of the org's allowance (pessimistic leasing → no cross-node overspend, only a small, bounded, backfillable drift) — no shared/co-located Redis required.
Metering enforcement — shipped
use Cbox\Billing\Metering\Contracts\Enforcement; $reservation = $enforcement->reserve($org, 'api.calls', estimate: 5); // hard-blocks when exhausted // … do the work … $enforcement->commit($reservation, actual: 5); // settles + emits a durable usage event
- Lease-backed local hard limit (
LeasedEnforcement), refilling from anAllowanceLeaseSourcewhen depleted. CacheLocalStore— Laravel-cache-backed, atomic decrement-and-compensate (only ever over-rejects, never over-grants).- Durable local
UsageBufferfor crash-safe sync to billing's ingest. - Dogfooded
Testing\InteractsWithMetering+FakeAllowanceLeaseSource.
Requirements
PHP ^8.4; Laravel ^13. See docs/requirements.md and
composer.json.
Development
composer install
composer qa # pint --test, phpstan (level max), pest, license-check, audit
License
MIT.