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.
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.








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.