Singapore CPF Payroll for Odoo 16
CPF employee and employer contributions, computed by age band with the Ordinary and Additional Wage ceilings, on the EH payroll engine.
Why this module
Singapore CPF Payroll for Odoo 16
CPF that steps with age, not a flat rate
Employee and employer percentages come from the age band covering the employee at the period end, across the five published bands from 55-and-below through above 70. The senior bands are seeded so older workers contribute at the right rate, not the headline 20/17.
Ordinary and Additional Wage caps done right
Ordinary Wage is capped at the monthly ceiling; the bonus that lands as Additional Wage is capped at what the annual AW ceiling leaves after the year's OW already subject to CPF. The contribution lands on the contributable wage, not the gross.
Cited figures you confirm each year
Rates and ceilings ship as data with their CPF Board source noted, and the tests assert the published figures rather than numbers the test invents. The CPF Board revises these, so the copy and field help tell you to verify against the current table each year.
Day in the life
A monthly run with a bonus and a senior employee
Assign the Singapore - Standard structure to your employees and compute the month. For each payslip the engine reads the employee's age at the period end, picks the matching CPF band, caps the Ordinary Wage at the monthly ceiling, and posts CPF_EE as a deduction and CPF_ER as an employer cost. A staff member over 60 contributes at the lower senior rate automatically. When a bonus pushes someone into Additional Wage, only the portion under the remaining annual AW ceiling attracts CPF. Net pay reflects the employee share; the employer share sits as an employer-side line and does not reduce take-home.
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.
When an employee has no birthday on file, age resolves to the 55-and-below band rather than failing, so the slip still computes with a defensible default.
An Ordinary Wage above the monthly ceiling is capped before the percentage applies, so a high earner contributes on the ceiling, not the full salary.
A bonus is treated as Additional Wage and capped at the annual AW ceiling less the year's OW already subject to CPF, with the annual OW projected as twelve months of the capped OW when no actual figure is supplied.
If the age-band table is empty, the calculation falls back to the company flat employee and employer rates rather than returning zero, so a misconfigured install still produces a number.
Date of birth is a group-restricted field, so it is read with elevated rights only to choose the age band and is never exposed to a salary rule.
The engine rebuilds payslip lines from scratch on every compute, so recomputing a slip after a wage or age correction never doubles or strands CPF lines.
What is inside
Built to do the job, end to end.
- CPF rate table by age band. An eh.hr.cpf.rate model holds the employee and employer percentages per age band, ordered by age, with a helper that resolves the band for a given age. Five bands ship seeded from CPF Board figures effective January 2026.
- Contribution calculation with ceilings. A single compute_cpf routine applies the OW monthly cap and the AW annual cap, sums the contributable wage, and returns rounded employee and employer amounts. The rule seam exposes cpf_employee() and cpf_employer() to salary rules.
- Singapore standard structure. A seeded Singapore - Standard structure wires BASIC, GROSS, CPF employee, CPF employer, and NET rules in sequence, so the structure is ready to assign without writing Python.
- Company ceiling settings. The monthly Ordinary Wage ceiling and annual Additional Wage ceiling are company fields defaulting to the published 8,000 and 102,000, with flat-rate employee and employer fallbacks used only when no band table is configured.
- Tests against published figures. Four tests assert real CPF Board outcomes: contributions below the ceiling, capping at the OW ceiling, the senior age band, and the Additional Wage ceiling 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 income tax deduction; income tax is filed annually and is out of scope.
- It does not produce IR8A, IR21, or any IRAS electronic submission or auto-inclusion file.
- Skill Development Levy, Foreign Worker Levy, and CDAC, MBMF, SINDA, or ECF community fund contributions are not included.
- CPF rates and wage ceilings ship as cited data effective the dates noted and must be verified against the current CPF Board table each year, since the Board revises them.
- It calculates Citizen and Permanent Resident contributions at the wages-above-750 rates and does not model the graduated SPR first and second year rates or the partial bands below 750 per month.
- There is no payslip PDF, bank file, or CPF e-submission export in this module; it requires the eh_hr_payroll engine, which provides compute, payslip lines, and the workflow.
Singapore payroll Odoo, CPF contributions Odoo 16, Central Provident Fund payroll, Singapore salary structure, Ordinary Wage ceiling CPF, Additional Wage ceiling, CPF age band rates, employer CPF Odoo, Odoo 16 HR payroll Singapore, senior worker CPF rates, Singapore monthly payroll, ERP Heritage payroll
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 16 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 16 Community
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Employees (hr)
• Discuss (mail) |
| Community Apps Dependencies | Show |
| Lines of code | 2427 |
| Technical Name |
eh_hr_payroll_sg |
| License | LGPL-3 |
| Website | https://www.erpheritage.com.au/ |
Please log in to comment on this module