Luxavero
Engineering · 4 min read

Payroll that follows the law, calculated twice

CoalTrack turns attendance into a compliant payroll run — PPh 21 TER, BPJS, overtime — and writes the engine twice so the server and the phone agree to the rupiah.

Paper records spread across a worn wooden table

Payroll is the part that has to be right

Attendance is only half the product. The other half is turning those hours into pay — automatically, from the attendance already recorded, without a finance team rebuilding a spreadsheet at every period close.

That is where mistakes are expensive and trust is won or lost. So payroll gets the most careful code in the system.

By the regulations, not by approximation

CoalTrack calculates PPh 21 using the TER method from PP 58/2023 and PMK 168/2023 — the full rate tables, including the surcharge for employees without a tax number. BPJS covers JHT, JP, JKK, JKM and Kesehatan with their wage caps, including the highest occupational-risk class for mining.

Overtime follows Kepmenaker 102/2004 with the 1/173 hourly divisor. These aren’t settings a client has to get right themselves — they’re built in and versioned by effective date, so a rule change doesn’t silently rewrite last month.

Written twice, on purpose

The payroll engine exists in two places: a pure PHP domain service on the server, and a mirror of it in Dart inside the app. Both are framework-free — no I/O, no system clock — and cross-checked by mirror tests.

Why duplicate it? So the number an employee sees on their phone is the same number the server calculates. Two independent implementations that must agree catch the mistakes a single one would hide.

Finished paperwork, not just a number

A finalised run produces the documents people actually need: a letterheaded PDF payslip for every worker, locked with a password and emailed to them, an Excel recap for HR, and a PPh 21 export in the format Coretax accepts.

And a line we hold firmly: the app calculates and documents, but money never flows through it. Wages are paid through the company’s own bank, as before.

Keep reading

More notes.

Contact

Working on something similar?

If this touched on your problem, we’re happy to talk it through.

LanguagesEnglish · Indonesian