Real Scenario

Month-end. ECR uploaded to the EPFO portal. ESI return filed. PT deducted at ₹200 for everyone. Two weeks later, a Bengaluru employee notices PT on the Maharashtra slab, a mid-month joiner has no PF number, and ESI skipped someone who dropped below the wage ceiling after LOP. Nothing “broke”. Three different rules used the HQ default instead of the employee’s actual wage and work location.

The three statutory engines Indian payroll must get right

PF, ESI and Professional Tax look like three deductions on a payslip. They are three different laws, calendars, portals and wage bases. Most growing companies fail the same way: one Excel formula, one HQ location, one assumption about “standard basic”.

1. Provident Fund (EPF)

  • Employer and employee share are typically 12% of PF wages
  • PF wages are usually basic + DA, subject to the statutory ceiling unless you contribute on actuals
  • Labour Code wage definition can pull high allowances back into the PF base — see Labour Codes 2026
  • Joiner / leaver months, arrears and unpaid LOP must recompute PF, not copy last month’s number
  • ECR, UAN seeding and monthly challans fail when KYC is sitting in a personal Drive

2. Employee State Insurance (ESI)

  • Standard rates: 0.75% employee / 3.25% employer on ESI wages (confirm latest notified rates)
  • Coverage depends on establishment registration and the employee wage ceiling (commonly ₹21,000)
  • People who cross the ceiling, go on long LOP, or join mid-month are the usual misses
  • Contribution period vs benefit period is not “the same as PF month”

3. Professional Tax (PT)

  • State tax: slabs differ in Maharashtra, Karnataka, West Bengal, Telangana, Tamil Nadu and others
  • Some states have a February bonus slab; some exempt women or differently-abled staff
  • PT follows work location, not the company’s registered office
  • Returns and payment dates are state-specific — one HR calendar is not enough

Where growing teams silently go wrong

Wrong wage base

PF on “basic only” while Labour Codes add allowances back. ESI on CTC instead of ESI wages.

Mid-month joiners & exits

Proration skipped. First ECR missing. FNF paid without last-month statutory true-up.

One PT slab, three states

HQ Maharashtra slab applied to every remote and branch employee.

Portal vs payslip mismatch

Sheet deducted PF; ECR used a different wage. Employee disputes follow the payslip, inspectors follow the portal.

Fragmented payroll vs a statutory HRMS

ControlSpreadsheet / 3 toolsIndia-ready HRMS
PF wage mappingHidden in a CTC templateEach component tagged PF / non-PF
ESI eligibilityUpdated once a yearRechecked every pay run vs ceiling
Professional TaxOne slab, HQ stateLocation-wise slabs and returns
LOP / attendancePasted after lockSame attendance that built the register
ECR / returnsRe-keyed from payslipsGenerated from the locked run
The leadership view

Statutory payroll is not “run numbers, then file”. Filing is only as true as the wage, location and eligibility flags inside the pay run. If those flags live in someone’s head, you do not have compliance — you have a lucky month.

The way forward

Tag every salary component for PF, ESI and taxable income. Store work location as the PT jurisdiction. Recompute eligibility on every locked payroll. Generate ECR and challans from that lock — never from a second sheet. Pair this with common payroll errors in India and Bynarize native payroll (payslips, Form 16, bank file). Statutory acts on India HR compliance are the same stack: ESI, PF, PT, LWF and gratuity.

Rates, ceilings and state slabs change. Confirm current EPFO, ESIC and state PT notifications before you lock a production payroll.

If you are a Founder, HR Head or Finance lead: ask your payroll owner to show one employee who changed state, one mid-month joiner and one person who crossed the ESI ceiling — on the same payslip and the same ECR. If they cannot, that is the gap.

Want PF, ESI and PT on the same payroll lock?

See India statutory deductions computed from attendance and salary structure — not a second spreadsheet.