DWG 001

IustumHR

Cambodian payroll compliance, from the prakas up.

Illustration — the employees and payroll figures are fabricated. The statutory parameters are the values this product ships, shown as configured.

Client
Internal product
Role
Design, build, operate
Stack
React · Vite · TypeScript · Supabase · Vercel
Status
In production

The problem

Most payroll software sold in Cambodia was built elsewhere and localised afterwards. The rules arrive as a settings page somebody has to remember to update, and when a rate changes mid-year nobody is sure which payslips were computed under which regime.

What it looks like

Every capture below comes from a fabricated demo company. The people, salaries and dates are invented; the statutory parameters are the ones this product ships, shown as configured rather than asserted as law.

hr.iustumos.com/payroll
The statutory parameters as configured — Tax on Salary brackets, NSSF rates, the contributory-wage floor and cap
hr.iustumos.com/payroll
One payslip, with every deduction traceable to the rule that produced it
hr.iustumos.com/payroll
The filing exports, prepared for manual submission — the app writes the files and says out loud that it does not file them for you
A punch refused outside the geofence — the check runs on the server, against the company’s own coordinates
A month of attendance, with lateness graded rather than reduced to present or absent
hr.iustumos.com/teams
One employee across a year: punctuality, hours, leave and salary in a single view
hr.iustumos.com/calendar
Holidays, anniversaries and approved absences, each drawn from its own source rather than a shared table
hr.iustumos.com/report
The company-wide report, with payroll cost across every finalised run

What it does

NSSF contributions, Tax on Salary withholding, GDT filing outputs, seniority accrual, shift scheduling, leave balances, geofenced attendance, daily NBC exchange rates, multi-tenant isolation at the database level.

The hard part

An employee can hold two contracts in one month for two entirely different reasons: one replaced the other mid-month, or they genuinely hold both at once. In the data those are the same shape — two contract rows overlapping one payroll period — and they have to produce different arithmetic. Gross pay was never the problem; it summed and itemised correctly throughout, and so did the tax and contributions drawn from it. Every rate derived from it was wrong. On a back-to-back renewal the overtime hourly rate, the price of an unpaid day and the seniority base were all computed from the two salaries added together, even though only one contract was ever in force on any given day. Nothing on the payslip looked wrong, because the headline figure was right.

The first correction took the highest salary in the period instead of the sum. That is right for a renewal and wrong for genuine concurrency, where it prices overtime against one contract rather than the combined wage — and under-pricing overtime is a compliance question, not a rounding preference. We had also proposed simply preventing contracts from overlapping. That was the wrong instinct: holding two at once is a real employment shape, not a data-entry error, and the engine had to serve it rather than forbid it. So it stopped asking which contract applies and started asking which day. Every rate now derives from the salaries actually in force day by day — one contract on a renewal day, both on a concurrent one. Single-contract months come out byte-identical, which the test suite proves, and that suite is the point: its expected figures are worked out by hand from the statutory rules and written beside the assertions, never copied from whatever the engine happened to produce.

Every rule, cited

NSSF occupational-risk contributions, calculated at the current rate against the statutory wage ceiling.

Authority
Prakas 449/2017 LV/PrK
In force from
[Awaiting primary-source check]
Also governed by
Sub-Decree 144 (wage floor and ceiling)
Last reviewed
[Awaiting primary-source check]
Enforced in
Payroll engine — contribution calculation

Tax on Salary withheld at the resident progressive brackets.

Authority
Law on Taxation
Issuing authority
[To verify]
Last reviewed
[Awaiting primary-source check]
Enforced in
Payroll engine — withholding

Seniority payment accrued against length of service.

Authority
Labour Law
Issuing authority
[To verify]
Last reviewed
[Awaiting primary-source check]
Enforced in
Payroll engine — accrual

Where it stands

In production, running real payroll every month.