Projects
Case Study Production

Payfactor — Payroll & HR SaaS

A multi-tenant SaaS payroll and HR platform for Philippine enterprises — automating biometric timekeeping, DTR computation, statutory deductions, payslips, 13th-month, and final pay across isolated per-company databases.

Full-stack Software Engineer ·2022 – 2023 ·Subscription-based SaaS product

Angular TypeScript PHP MySQL Docker Nginx

Executive Summary

Payfactor is a multi-tenant, subscription-based SaaS payroll and HR platform built for Philippine enterprises. It automates the full payroll cycle — from biometric timekeeping and Daily Time Record (DTR) computation, through payroll batch runs and statutory deductions (SSS, PhilHealth, Pag-IBIG, and BIR withholding tax), to payslips, 13th-month pay, and final pay on separation.

The product is an Angular single-page application backed by a PHP and MySQL API, with the heavy payroll math implemented as MySQL stored procedures for set-based performance. Each client company runs in its own isolated database, so a single deployment serves many organizations without their data ever mixing.

Business Problem

Philippine payroll is unusually rules-heavy and unforgiving of mistakes. A single pay run has to reconcile multiple payment frequencies (weekly, semi-monthly, monthly), shifting and rotating work schedules, overtime and night differentials, government contributions whose rates change yearly, and graduated withholding tax — then produce 13th-month and final-pay computations that must hold up to audit.

Done in spreadsheets, this is slow, error-prone, and impossible to scale:

  • Manual DTR reconciliation. Turning raw biometric punches into payable hours by hand is tedious and inconsistent across timekeepers.
  • Rules that change every year. Statutory contribution tables and tax brackets are revised regularly; hard-coded logic rots immediately.
  • No safe multi-company story. Payroll providers needed to serve many client companies at once without any risk of cross-company data leakage.

Payfactor’s goal was to encode these rules once, configurably, and process biometric attendance into compliant payroll at scale — for many companies from one platform.

My Responsibilities

I worked across the full stack on both the frontend and backend:

  • Angular application. Built the feature modules — timekeeping, payroll, HRIS, reports, and system setup — as standalone components, with an RxJS-based service layer and route guards for authenticated, tenant-scoped access.
  • PHP API. Implemented the REST endpoints that the SPA consumes, against a custom MySQL data-access layer.
  • Payroll computation. Designed and maintained the MySQL stored procedures that do the DTR and payroll batch processing, branching by schedule type, payment computation, and frequency.
  • Multi-tenancy. Implemented the per-request database selection that isolates each company’s data.
  • Configuration surfaces. Built the setup screens for statutory tables, payroll periods, holidays, schedules, and cost centers so rules live in data, not code.
  • Delivery. Containerized the development and production environments with Docker (Nginx + PHP-FPM + MySQL) and maintained the E2E and unit test setup.

Technical Highlights

  • Angular SPA with standalone components and an RxJS service layer over the REST API, with Cypress end-to-end tests and Karma/Jasmine unit tests.
  • PHP + MySQL backend behind Nginx and PHP-FPM, fully containerized for both development and production with Docker Compose.
  • Stored-procedure-driven payroll. The expensive computations (sp_dtrBatchProcess, sp_payrollBatchProcess, final pay, and 13th-month routines) run as set-based MySQL procedures, keeping large pay runs fast instead of looping per employee in PHP.
  • Database-per-tenant multi-tenancy. Each company is a separate database selected dynamically per request, giving hard data isolation between clients.
  • Configurable statutory tables. SSS, PhilHealth, Pag-IBIG, and withholding-tax rates — including ceilings and exemptions — are maintained as data, so annual changes don’t require a code release.
  • Approval workflow with period locking. Payroll periods carry multi-level locks (kiosk → approver → final) so a run can’t be processed or altered out of sequence.
  • Built for long batch jobs. The serving layer is tuned for large uploads and long-running requests so company-wide pay runs complete reliably.

Key Engineering Challenges

  • Biometric logs into clean DTR. Translating raw punch-in/out data into payable records meant handling split shifts, overlapping or overrun breaks, late conversions, and overtime/leave cancellations — all before payroll could even start.
  • Flexible, shifting schedules. Employees are tagged with schedules per assignment or cost center, and rotating versus perfect-attendance schedules each follow different computation paths, so the engine had to branch correctly for every case.
  • Multiple frequencies and computation methods. Weekly, semi-monthly, and monthly runs — and hourly versus daily computation — each route to the right stored procedure, which had to be selected deterministically from the employee and period setup.
  • Statutory accuracy. Government contributions and graduated withholding tax had to respect ceilings, exemptions, and year-to-date cumulative computation so each payslip reconciled exactly.
  • 13th-month and final pay. Both require proportional computation by tenure, plus accrued-leave monetization and separation clearance — edge-case-heavy math that has to be exactly right.
  • Multi-tenant isolation at scale. Serving many client companies from one platform meant guaranteeing that every query ran against the correct company database, with no path for one tenant’s data to surface in another’s.