phdevutils/payroll

Filipino payroll calculators — SSS, PhilHealth, Pag-IBIG contributions; 13th month pay; BIR monthly withholding tax (TRAIN); net take-home. Versioned contribution tables per effective year.

Maintainers

Package info

github.com/kon2raya24/ph-payroll-php

pkg:composer/phdevutils/payroll

Statistics

Installs: 3

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.2.0 2026-05-20 03:14 UTC

This package is auto-updated.

Last update: 2026-05-20 03:16:37 UTC


README

Packagist version License: MIT Made in PH

Filipino payroll calculators for PHP — SSS, PhilHealth, Pag-IBIG monthly contributions, 13th-month pay, BIR monthly withholding tax (TRAIN), and pre-tax / post-tax net take-home. Tables versioned by effective date.

⚠️ READ FIRST

This package handles real money math. Wrong outputs cause underpayment / overpayment in actual payroll runs. Verify outputs against official agency calculators before production use. Pin your dependency version — tables change every few years. BIR WT in v0.2 is monthly-only and operates on taxable income, not raw gross. De minimis caps and the ₱90k 13th-month annual exemption are caller-handled in v0.2.

Full disclaimer: project README.

Install

composer require phdevutils/payroll

Requires PHP 8.2+.

Quick start

use PhDevUtils\Payroll\TakeHome;

// Pre-tax (v0.1 shape — unchanged):
$r = TakeHome::netTakeHome(30000);
// [
//   'gross' => 30000.0,
//   'sss' => ['msc' => 30000, 'employeeShare' => 1500.0, ...],
//   'philHealth' => ['total' => 1500.0, 'employee' => 750.0, 'employer' => 750.0],
//   'pagIbig' => ['mfs' => 10000.0, 'employee' => 200.0, 'employer' => 200.0, 'total' => 400.0],
//   'totalDeductions' => 2450.0,
//   'net' => 27550.0,
// ]

// With BIR monthly WT (v0.2 opt-in):
$r = TakeHome::netTakeHome(30000, ['includeWT' => true]);
// adds: 'taxableIncome' => 27550.0, 'withholdingTax' => 1007.55, 'netAfterTax' => 26542.45

API Reference

Sss::contribution(float $monthlyCompensation, array $opts = []): array

Source: SSS Circular 2024-006 (effective 2025-01-01, applies to 2025–2026).

Return shape:

[
  'msc' => int,                                                         // ₱500 increments, clamped 5,000–35,000
  'regular' => ['employee' => float, 'employer' => float, 'total' => float],  // MSC capped at 20,000
  'mpf'     => ['employee' => float, 'employer' => float, 'total' => float],  // MySSS Pension Booster — above 20,000
  'ec' => float,                                                        // Employees' Compensation (employer-paid)
  'employeeShare' => float,
  'employerShare' => float,
  'total' => float,
]

Math: Total rate 15% = 10% employer + 5% employee. EC ₱10 (MSC ≤ 14,500) or ₱30 (MSC ≥ 15,000), employer-paid.

use PhDevUtils\Payroll\Sss;

$r = Sss::contribution(20000);
// $r['msc'] === 20000
// $r['employeeShare'] === 1000.0, $r['employerShare'] === 2030.0

$r = Sss::contribution(30000);
// MPF kicks in: $r['regular']['total'] === 3000.0, $r['mpf']['total'] === 1500.0
// $r['employeeShare'] === 1500.0

Sss::contribution(50000)['msc'];   // 35000 (capped)
Sss::contribution(3000)['msc'];    // 5000 (floored)

PhilHealth::contribution(float $monthlySalary, array $opts = []): array

Source: RA 11223 (UHC Law) — final 5% rate (no further increases scheduled).

Return shape: ['total' => float, 'employee' => float, 'employer' => float].

Math: 5% split equally. Floor ₱500 (salary ≤ ₱10k), ceiling ₱5,000 (salary ≥ ₱100k). Each share rounded to centavo; total = sum of remitted shares.

use PhDevUtils\Payroll\PhilHealth;

PhilHealth::contribution(25000);    // ['total' => 1250.0, 'employee' => 625.0, 'employer' => 625.0]
PhilHealth::contribution(5000);     // floor: ['total' => 500.0, 'employee' => 250.0, 'employer' => 250.0]
PhilHealth::contribution(150000);   // ceiling: ['total' => 5000.0, 'employee' => 2500.0, 'employer' => 2500.0]

PagIbig::contribution(float $monthlySalary, array $opts = []): array

Source: HDMF Circular 460 (effective 2024-02-01). MFS ceiling: ₱10,000.

Return shape: ['mfs' => float, 'employee' => float, 'employer' => float, 'total' => float].

Math:

  • MFS = min(monthlySalary, 10,000)
  • If MFS ≤ ₱1,500: employee 1%, employer 2%
  • If MFS > ₱1,500: employee 2%, employer 2%
  • Max ₱200 each side at MFS = ₱10,000

Mandatory contribution only.

use PhDevUtils\Payroll\PagIbig;

PagIbig::contribution(1000);     // low bracket: ['mfs' => 1000.0, 'employee' => 10.0, 'employer' => 20.0, 'total' => 30.0]
PagIbig::contribution(5000);     // high bracket: ['mfs' => 5000.0, 'employee' => 100.0, 'employer' => 100.0, 'total' => 200.0]
PagIbig::contribution(50000);    // capped: ['mfs' => 10000.0, 'employee' => 200.0, 'employer' => 200.0, 'total' => 400.0]

ThirteenthMonth::fromTotal(float $totalBasicEarnings): float

Source: PD 851. Canonical DOLE formula: total / 12.

use PhDevUtils\Payroll\ThirteenthMonth;

ThirteenthMonth::fromTotal(360000);   // 30000.0
ThirteenthMonth::fromTotal(180000);   // 15000.0

ThirteenthMonth::fromMonthly(float $monthlyBasicSalary, int $monthsWorked = 12): float

Convenience for fixed-salary employees.

ThirteenthMonth::fromMonthly(30000);       // 30000.0 (full year)
ThirteenthMonth::fromMonthly(30000, 6);    // 15000.0 (6 months prorated)
ThirteenthMonth::fromMonthly(30000, 1);    // 2500.0

"Basic earnings" excludes allowances, overtime, holiday pay, NSD, and other non-base benefits.

WithholdingTax::monthly(float $taxableIncome, array $opts = []): array (v0.2+)

Source: BIR RR 11-2018 monthly table (TRAIN Law, second-phase rates effective 2023-01-01).

Return shape: ['wt' => float, 'bracket' => int (1-6), 'marginalRate' => float].

Input is taxable income, not gross. Use TaxableIncome::monthly to derive.

BIR monthly brackets (TRAIN 2023+):

Bracket Monthly taxable income Tax
1 ≤ ₱20,833 0
2 ₱20,833 – ₱33,333 15% of excess over ₱20,833
3 ₱33,333 – ₱66,667 ₱1,875 + 20% of excess over ₱33,333
4 ₱66,667 – ₱166,667 ₱8,541.80 + 25% of excess over ₱66,667
5 ₱166,667 – ₱666,667 ₱33,541.80 + 30% of excess over ₱166,667
6 > ₱666,667 ₱183,541.80 + 35% of excess over ₱666,667
use PhDevUtils\Payroll\WithholdingTax;

WithholdingTax::monthly(15000);    // ['wt' => 0.0,        'bracket' => 1, 'marginalRate' => 0.0]
WithholdingTax::monthly(25000);    // ['wt' => 625.05,     'bracket' => 2, 'marginalRate' => 0.15]
WithholdingTax::monthly(50000);    // ['wt' => 5208.4,     'bracket' => 3, 'marginalRate' => 0.20]
WithholdingTax::monthly(100000);   // ['wt' => 16875.05,   'bracket' => 4, 'marginalRate' => 0.25]
WithholdingTax::monthly(200000);   // ['wt' => 43541.7,    'bracket' => 5, 'marginalRate' => 0.30]
WithholdingTax::monthly(1000000);  // ['wt' => 300208.35,  'bracket' => 6, 'marginalRate' => 0.35]

TaxableIncome::monthly(float $gross, array $opts = []): float (v0.2+)

Derive monthly taxable income from gross. Formula:

taxableIncome = gross − mandatoryDeductions − nonTaxableAllowances

$opts keys: year, mandatoryDeductions (override; default: auto-computed from gross via SSS+PhilHealth+Pag-IBIG), nonTaxableAllowances (default: 0).

Caller-handled (not done here):

  • De minimis caps — pass only the non-taxable portion. Rice ₱2,000/mo, uniform ₱6,000/yr, medical ₱10,000/yr (employee), etc.
  • ₱90,000 annual exemption for 13th-month + bonuses — applies at year level.
use PhDevUtils\Payroll\TaxableIncome;

TaxableIncome::monthly(30000);                                     // 27550.0
TaxableIncome::monthly(30000, ['nonTaxableAllowances' => 2000]);   // 25550.0
TaxableIncome::monthly(50000, ['mandatoryDeductions' => 3200]);    // 46800.0

TakeHome::netTakeHome(float $monthlySalary, array $opts = []): array

Net take-home: gross minus mandatory SSS / PhilHealth / Pag-IBIG employee contributions, and (optionally, v0.2+) BIR withholding tax.

Return shape (always):

[
  'gross' => float,
  'sss' => array,         // full Sss::contribution result
  'philHealth' => array,  // full PhilHealth::contribution result
  'pagIbig' => array,     // full PagIbig::contribution result
  'totalDeductions' => float,
  'net' => float,
  // when ['includeWT' => true]:
  'taxableIncome'  => float,
  'withholdingTax' => float,
  'netAfterTax'    => float,
]

$opts keys: year, includeWT (default false — preserves v0.1 shape), nonTaxableAllowances (only used with includeWT).

use PhDevUtils\Payroll\TakeHome;

// v0.1 shape (default) — pre-tax:
TakeHome::netTakeHome(30000)['net'];     // 27550.0
TakeHome::netTakeHome(8000)['net'];      // 7190.0
TakeHome::netTakeHome(150000)['net'];    // 145550.0

// v0.2+ with WT:
TakeHome::netTakeHome(30000, ['includeWT' => true])['withholdingTax'];   // 1007.55
TakeHome::netTakeHome(30000, ['includeWT' => true])['netAfterTax'];      // 26542.45

// v0.2+ with non-taxable allowances:
TakeHome::netTakeHome(30000, ['includeWT' => true, 'nonTaxableAllowances' => 2000])['withholdingTax'];
// 707.55

Versioning & rate changes

Tables change. The package contract:

  • Within a major+minor version (e.g. 0.1.*), tables don't change.
  • New tables ship in new minor versions (0.2.0).
  • Pin your dependency to a specific minor to avoid silent changes mid-payroll-cycle.

File issues when circulars drop — patches ship quickly.

License

MIT