Introduction
Tashil (تسهيل — Arabic for "facilitation") is a Laravel package for subscription and feature management. It gives your application a complete, well-tested foundation for selling plans, gating features, metering usage, running trials, and driving the billing lifecycle — so you don't have to reinvent any of it.
It is built around a simple, deliberate boundary: Tashil owns subscription state; your application owns money movement. Tashil issues invoices and runs the state machine that decides what a subscription can access and when; your app's payment integration charges the card and tells Tashil when an invoice was paid.
What Tashil gives you
- A plan catalog with five feature types — boolean, limit, consumable, enum, and metered.
- Feature gating with atomic, race-safe usage counters.
- A first-class trial lifecycle — start, warn, convert, expire.
- A full billing lifecycle: activate-on-payment, renewal, dunning (failed payments), reactivation, and proration on plan changes.
- Metered billing — per-unit charges against a balance your app controls.
- An immutable event log with a strictly monotonic sequence number per subscription, for audit and point-in-time replay.
- Route middleware, Blade directives, scheduled jobs, and analytics out of the box.
New to subscription billing?
You don't need to understand every concept up front. Start with Installation, follow the Quick Start, then read each Core Concept page as you reach for it. Every page includes complete, copy-paste examples.
What Tashil owns — and what it doesn't
This split is the most important idea in the whole package. Keep it in mind and everything else falls into place.
Tashil owns (in scope):
- Plans (packages) with pricing, billing cadence, trial config, and feature definitions.
- Polymorphic subscribers — any Eloquent model (
User,Team,Organization, a tenant model) that implements theSubscribablecontract. - The subscription lifecycle: create → pending → active / on-trial → past-due → suspended → cancel (grace or immediate) → resume → reactivate → switch → pause → expire.
- The activate-on-payment model: a priced plan subscribes as
Pendingand gains access only when its first invoice is paid. - Dunning: failed renewals escalate
PastDue → Suspended → Expiredon a configurable schedule. - Proration on in-place plan changes.
- Feature gating with atomic usage tracking, scheduled quota resets, and an immutable event log.
- Renewal invoice issuance and the
InvoiceIssued/InvoicePaidevents. - Live analytics: MRR, churn, trial conversion, and per-package breakdowns.
Your application owns (out of scope):
- Card capture, payouts, refund execution, and payment-gateway synchronization.
- The actual retry charge during dunning — Tashil owns the dunning state machine and schedule and fires the events; your app performs the charge.
- The wallet / balance that funds metered features.
- Coupons and discount engines, cross-currency (FX) conversion, and revenue-waterfall reporting.
Why this boundary?
Payment gateways differ wildly, and money movement is where the legal and operational risk lives. By owning only state, Tashil stays gateway-agnostic and easy to reason about — it works the same whether you charge with Stripe, Paddle, bKash, or manual bank transfers.
How it fits into your app
The integration contract is a short, predictable loop:
- Tashil issues an invoice (status
pending) and firesInvoiceIssued. - Your listener charges the card through your gateway of choice.
- On success, your code calls
$invoice->markAsPaid(). - Tashil's
InvoiceObserverreflects that decision — activating, renewing, or reactivating the subscription as appropriate — and fires the matching domain event.
That's the whole handshake. You can read the full version in Billing Lifecycle.
Core concepts at a glance
| Concept | What it covers |
|---|---|
| Subscriptions | Subscribe, cancel, pause, switch, resume — the lifecycle and its states. |
| Feature System | The five feature types, snapshots, counters, and reset cadence. |
| Trials | Trial start, conversion, expiry, and strict on-trial semantics. |
| Billing Lifecycle | Activation, renewal, dunning, reactivation, and proration. |
| Metered Billing | Per-unit charges against a host-owned balance. |
| Scheduler & Jobs | The seven idempotent commands that drive unattended transitions. |
| Events | Every domain event and the immutable event store. |
| Middleware & Blade | Gating routes and views. |
| Analytics & Reporting | Live KPIs and point-in-time reporting. |
| Database Schema | Every table, column, and index. |
Requirements
- PHP 8.2 – 8.5
- Laravel 10.x, 11.x, 12.x, or 13.x
- Redis (optional — only when the caching layer is enabled)
Tashil's CI matrix tests every supported combination of Laravel, PHP, and database (SQLite, MySQL 8, and PostgreSQL 16).
Next steps
Head to Installation to add Tashil to your project, then work through the Quick Start to build your first plan, subscribe a user, and gate a feature.