PHPackages                             crmleaf/laravel-payroll - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Templating &amp; Views](/categories/templating)
4. /
5. crmleaf/laravel-payroll

ActiveLibrary[Templating &amp; Views](/categories/templating)

crmleaf/laravel-payroll
=======================

Laravel bridge for the CRMLeaf payroll engine: service provider, config, optional routes, Blade components, and payslip and GST invoice PDFs rendered inside your own application.

v1.0.0(today)00[1 PRs](https://github.com/CrmLeaf/laravel-payroll/pulls)MITPHPPHP ^8.2CI passing

Since Aug 14Pushed todayCompare

[ Source](https://github.com/CrmLeaf/laravel-payroll)[ Packagist](https://packagist.org/packages/crmleaf/laravel-payroll)[ Docs](https://github.com/crmleaf/laravel-payroll)[ RSS](/packages/crmleaf-laravel-payroll/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (7)Versions (2)Used By (0)

Laravel Payroll
===============

[](#laravel-payroll)

The Laravel bridge for [`crmleaf/payroll-core`](https://github.com/crmleaf/payroll-core): service provider, config, optional routes, Blade components, and payslip and GST invoice PDFs rendered inside your own application.

```
composer require crmleaf/laravel-payroll
php artisan vendor:publish --tag=payroll-config
```

The provider is auto-discovered. Nothing else is required, and nothing observable changes until you ask for it - no route, no migration, no middleware.

Calculate
---------

[](#calculate)

```
use Crmleaf\Payroll\Laravel\Facades\Payroll;
use Crmleaf\Payroll\Money;

$pf = Payroll::pf()->calculate(basicSalary: Money::fromRupees(30_000));

$pf->employeeContribution->format();   // "₹3,600.00"
$pf->explain();                        // the formula with the operands in it
$pf->citations();                      // the statute each step rests on
```

Every accessor on the facade - `pf()`, `esi()`, `tds()`, `incomeTax()`, `gratuity()`, `bonus()`, `ctc()`, `leaveEncashment()`, `fnf()`, `epfoPenalty()`, `professionalTax()`, `calendar()`, `roi()`, `savings()`, `payslip()`, `invoice()` - resolves a singleton from the container, so you can rebind any of them in a test or point the rate repository at tables of your own through `payroll.rates_path`.

Pass `asOf:` anywhere a statutory rate is involved to recompute a closed period at the rates that were in force then - a revised F&amp;F, an arrear paid in a later year, an audit of last year's challans.

Routes
------

[](#routes)

Off by default. A library has no business adding a public endpoint to your application uninvited.

```
// config/payroll.php
'routes' => ['enabled' => true, 'middleware' => ['web', 'auth']],
```

That registers a POST endpoint per tool under `payroll/*` (HTML) and `api/payroll/*` (JSON), named `payroll.pf` and `payroll.api.pf` respectively. Everything is POST: these are calculations, and salary figures have no business in an access log.

```
POST /api/payroll/pf        {"basic_salary": 30000}
POST /api/payroll/gratuity  {"last_drawn_salary": 45000, "years_of_service": 7, "months_of_service": 8}
POST /api/payroll/invoice   → application/pdf

```

Statutory *ineligibility* comes back as a 200 with a zero and a reason - three years' service earns no gratuity, and that is an answer, not an error. Only caller mistakes are 422s, and the validation messages say which rule you have run into.

Blade components
----------------

[](#blade-components)

```

          {{-- same component, prefixed alias --}}
```

They work with JavaScript switched off: the form posts to the tool's route, the controller redirects back, and the component renders the result out of the session. Load `@crmleaf/payroll-js` and the same markup calculates in the browser instead - an enhancement over a working baseline, not the only path.

The styles are scoped, framework-agnostic plain CSS emitted `@once` per page. Redefine the `--payroll-*` custom properties to reskin them, or set `payroll.components.styles` to false and serve `payroll-assets` yourself.

Documents
---------

[](#documents)

```
$payslip = Payroll::payslip()->fromCtc(
    ctc: Payroll::ctc()->calculate(annualCtc: Money::fromRupees(12_00_000)),
    employee: ['name' => 'R Iyer', 'code' => 'EMP-0042', 'uan' => '100123456789'],
    month: '2025-04',
);

return $payslip->download();          // or ->stream(), ->html(), ->save($path)
```

```
$invoice = Payroll::invoice()->generate(
    number: 'INV/2025/0001',
    lines: [[
        'description' => 'Payroll subscription',
        'hsn' => '997331',
        'quantity' => 1,
        'unit_price' => 10_000,
        'gst_rate' => 18,
    ]],
    recipient: ['name' => 'Acme Pvt Ltd', 'gstin' => '27AAACT2727Q1ZW'],
);
```

The invoice decides CGST+SGST versus IGST by comparing the supplier's state code with the place of supply - it is not a setting, it follows from the supply - and carries the HSN/SAC per line, the rate-wise summary rule 46 asks for, the round-off under section 170, and the total in words.

PDF rendering needs [`barryvdh/laravel-dompdf`](https://github.com/barryvdh/laravel-dompdf), which is **suggested rather than required**: most installations use the calculators and never render a document. Ask for a PDF without it and you get an exception naming the package to install. `->html()` works either way.

Your company details, GSTIN and logo live in published config and never leave your infrastructure. There is no hosted document service, and therefore no credential for a browser bundle to leak.

Publishing
----------

[](#publishing)

TagWhat it copies`payroll-config``config/payroll.php` - heavily commented; publish this one`payroll-views`the components and document templates, forked into your app`payroll-assets`the standalone stylesheet, for strict CSP setups`payroll-lang`translation stringsPublishing views forks the document templates, which then stop receiving fixes when a GST or payroll rule changes. Do it to change the branding, not to change the arithmetic - that lives in the calculators, where it is tested.

Licence
-------

[](#licence)

MIT. See [LICENSE](LICENSE).

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance100

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

0d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/315788704?v=4)[crmleaf](/maintainers/crmleaf)[@CrmLeaf](https://github.com/CrmLeaf)

---

Top Contributors

[![andolasoftuser196](https://avatars.githubusercontent.com/u/145565449?v=4)](https://github.com/andolasoftuser196 "andolasoftuser196 (1 commits)")

---

Tags

bladegstindialaravelpayrollpayslippdflaravelbladeinvoiceesiindiagsttdspayrollpayslipEPF

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/crmleaf-laravel-payroll/health.svg)

```
[![Health](https://phpackages.com/badges/crmleaf-laravel-payroll/health.svg)](https://phpackages.com/packages/crmleaf-laravel-payroll)
```

###  Alternatives

[moonshine/moonshine

Laravel administration panel

1.3k268.2k88](/packages/moonshine-moonshine)[robsontenorio/mary

Gorgeous UI components for Livewire powered by daisyUI and Tailwind

1.5k612.7k24](/packages/robsontenorio-mary)[hasinhayder/tyro-dashboard

Tyro Dashboard - Beautiful admin dashboard for managing Tyro roles, privileges, users, and settings

5495.1k](/packages/hasinhayder-tyro-dashboard)[technikermathe/blade-lucide-icons

A package to easily make use of Lucide icons in your Laravel Blade views.

18473.9k13](/packages/technikermathe-blade-lucide-icons)[hasinhayder/tyro-login

Tyro Login - Beautiful, customizable authentication views for Laravel 12 &amp; 13

2488.1k7](/packages/hasinhayder-tyro-login)[ublabs/blade-simple-icons

A package to easily make use of Simple Icons in your Laravel Blade views.

1866.3k](/packages/ublabs-blade-simple-icons)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
