EH HR Payroll Singapore CPF
A ready Singapore salary structure that computes CPF employee and employer contributions by age band, with the Ordinary Wage and Additional Wage ceilings, on the EH payroll engine.
Why this module
EH HR Payroll Singapore CPF
CPF that steps with age
Contribution percentages are not flat. The module seeds five CPF Board age bands (55 and below, above 55 to 60, above 60 to 65, above 65 to 70, above 70) and picks the band for the employee age at period end, reading birthday with elevated access so the age is used only to select a rate and never leaks into a rule.
OW and AW ceilings handled
CPF applies to the contributable wage, not raw pay. Ordinary Wage is capped at the monthly ceiling and Additional Wage at the annual ceiling remaining for the year (the annual cap less the year Ordinary Wages already subject to CPF), so bonuses are contributed correctly without manual ceiling math.
Figures you can verify
Rates and ceilings are seeded as cited CPF Board data effective 1 January 2026, with the wage ceilings exposed as company settings. The module tells you to confirm both against the current CPF Board table each year, because the senior-worker rates step up over several years.
Day in the life
Run a Singapore pay period
Assign the Singapore Standard structure to your employees and compute the period. For each payslip the engine derives gross from basic and allowances, then the CPF employee and employer lines call into the rate table: the wage is capped at the Ordinary Wage ceiling, any Additional Wage is capped at the annual remaining ceiling, and the percentage is read from the band for that employee age. A younger employee on five thousand contributes twenty percent employee and seventeen percent employer; a sixty-two year old on the same wage contributes twelve and a half percent each. Employer CPF appears as a contribution line and does not reduce take-home. Net is gross less deductions. The slips ride the platform workflow and audit log.
Edge cases
The cases most modules quietly ignore.
In the shipped code today, each one a place where a cheaper module silently does the wrong thing.
An Ordinary Wage above the monthly ceiling is capped before CPF is applied, so a ten thousand wage contributes on eight thousand, not ten thousand.
Additional Wage such as a bonus is capped at the annual ceiling remaining, computed as the annual cap less the year Ordinary Wages subject to CPF, projected as twelve months of the capped OW when an explicit annual figure is not supplied.
Age is computed at the end of the pay period from birthday, read with sudo because birthday is a group-restricted field; the value selects the band only and is never exposed to a salary rule.
When an employee has no birthday on file, the engine defaults to age thirty so the 55-and-below band applies rather than failing the run.
If the age-band table is empty, computation falls back to the company flat employee and employer rate fields against the OW-capped wage, so a payslip still computes deterministically.
Employer CPF is posted as an employer-contribution category line and is excluded from total deductions, so it never reduces the employee net by mistake.
The CPF rate table is readable by self-service staff, writable by HR officers without delete, and fully managed only by HR admin, per the shipped access rules.
What is inside
Built to do the job, end to end.
- CPF rate table by age band. eh.hr.cpf.rate stores name, inclusive age range, and employee and employer percentages at three decimals, ordered by age. A helper resolves the band covering a given age, or the youngest band as a safe default. Five bands are seeded from CPF Board figures effective 1 January 2026.
- Contribution calculation. compute_cpf takes Ordinary Wage, Additional Wage, age, and both ceilings and returns rounded employee and employer amounts. It caps OW at the monthly ceiling, caps AW at the annual remaining ceiling, sums the contributable wage, and applies the band percentages.
- Engine helpers. The Singapore payslip extends eh.hr.payslip and adds cpf_employee and cpf_employer to the rule sandbox through the engine _get_rule_helpers seam. Salary rules call cpf_employee(categories.GROSS) and cpf_employer(categories.GROSS) so no Python lives in the rule beyond the call.
- Salary structure and rules. The Singapore Standard structure seeds sequenced rules: Basic from contract wage, Gross from basic plus allowance, CPF employee as a deduction, CPF employer as an employer contribution, and Net as gross less deductions, all keyed on the engine category kinds.
- Company settings. res.company carries the monthly Ordinary Wage ceiling, the annual Additional Wage ceiling, and fallback employee and employer rate fields used only when no age band is configured, each with source notes pointing at the CPF Board figures.
- Tested against published figures. The test suite asserts real CPF Board outcomes: twenty and seventeen percent below the ceiling under 55, the OW cap at eight thousand, the twelve and a half percent senior band at age sixty-two, and the Additional Wage remaining-ceiling math on a bonus.
Honest about the edges
What this does not do, so nothing surprises you.
- This module covers CPF only. Singapore does not operate monthly PAYE withholding for resident employees, so there is no monthly income tax line; income tax is filed annually and is out of scope.
- The seeded rates and ceilings are cited as CPF Board figures effective 1 January 2026. They must be verified against the current CPF Board table each year, because the senior-worker rates step up over several years.
- The Additional Wage ceiling is applied per month using a twelve-month projection of the capped Ordinary Wage when an explicit year-to-date figure is not supplied. It is not a full year-to-date CPF reconciliation across actual prior periods.
- The seeded bands reflect Singapore Citizen and Singapore Permanent Resident third-year-onwards rates for wages above the lower CPF threshold. Graduated first and second year SPR rates and other special categories are not seeded.
- Skills Development Levy, Foreign Worker Levy, CDAC and other community fund contributions, and the Additional Wage reconciliation submission are not included.
- It is a localization on the EH payroll engine, not a standalone app. It requires eh_hr_payroll and the platform it depends on, and inherits workflow, audit, and multi-company scoping from the platform rather than defining them here.
Singapore CPF payroll Odoo, CPF contribution Odoo 18, Central Provident Fund Odoo, CPF age band rates, Ordinary Wage ceiling CPF, Additional Wage ceiling CPF, Singapore salary structure Odoo, employer CPF contribution, SPR CPF payroll, Odoo 18 Singapore HR payroll, CPF employee deduction, Singapore payroll localization
Need this fitted to the way you work?
ERP Heritage delivers end to end Odoo work: Odoo Implementation, Customization and Development, Integration, Migration, Consultation, Support and Training. We help teams put this module into production, shape it to their process, and keep it running.
We work with businesses across Australia (Melbourne, Sydney, Brisbane, Perth, Adelaide, Canberra) and the Middle East (Dubai, Abu Dhabi, Riyadh, Jeddah, Doha, Kuwait City, Muscat). Start a conversation at erpheritage.com.au or email info@erpheritage.com.au.
Languages
Available in 19 languages
The interface ships translated out of the box. Switch language in Odoo and the fields, menus, and messages follow.
Modules teams pair with this one.
Premium ERP Heritage modules that extend the same stack, each built to the same engineering bar.
Post Irish payslips to the general ledger on the Irish chart of accounts
Interactive drag and drop Gantt planner for Odoo 18 Community project tasks with a deterministic server side sche...
Employment Hero Connector is the integration core of the ERP Heritage Employment Hero suite, providing per compan...
The United Kingdom country pack for the ERP Heritage Employment Hero integration
Sync Employment Hero employees, departments and payroll bank details into standard Odoo Community HR over the pla...
Inbound webhook receiver for the Employment Hero people and payroll platform on Odoo 18 Community
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Employees (hr)
• Discuss (mail) |
| Community Apps Dependencies | Show |
| Lines of code | 2438 |
| Technical Name |
eh_hr_payroll_sg |
| License | LGPL-3 |
| Website | https://www.erpheritage.com.au/ |
Please log in to comment on this module