HRM — Payroll
Turning hours, leave, and salary structures into payslips
The built-in country presets (tax/PF/ESI etc.) are scaffolding. Always verify rates against your jurisdiction before paying real people. The product surfaces this disclaimer too.
What This Module Does (Plain Language)
Payroll calculates what each person earns and produces a payslip. It pulls together their salary structure (basic + allowances + deductions), days worked and overtime (from attendance), paid/unpaid leave (from the leave module), and any salary advances being repaid — then computes gross pay, deductions, and net pay. Once a payslip is finalized and approved it becomes a locked legal document: you never edit it; corrections are issued as adjustment lines on a future payslip.
The Pieces
| Entity | What it is |
|---|---|
| Salary Structure | A reusable compensation template (e.g. "Standard IT"), optionally tied to a country. |
| Salary Component | A line in a structure — Basic, House Rent, PF, Tax — with a type and a calculation method. |
| Employee Salary | An effective-dated assignment of a structure + basic pay to a specific employee. |
| Payroll Run | A batch covering a pay period for some or all employees. |
| Payslip | One employee's result for one run. Immutable once finalized. |
| Salary Advance | A loan to an employee, recovered over future paychecks. |
Key enums
| Enum | Values |
|---|---|
SalaryComponentType | EARNING · DEDUCTION · STATUTORY_DEDUCTION · EMPLOYER_CONTRIBUTION · REIMBURSEMENT · ADJUSTMENT |
ComponentCalcMethod | FIXED · PERCENT_OF_BASIC · PERCENT_OF_GROSS · FORMULA · ATTENDANCE_DERIVED |
PayCycle | MONTHLY · BIWEEKLY · WEEKLY |
PayrollRunStatus | DRAFT · PROCESSING · REVIEW · APPROVED · PAID · CANCELLED · FAILED |
PayslipStatus | DRAFT · FINALIZED · VOIDED |
SalaryAdvanceStatus | PENDING · APPROVED · DISBURSED · RECOVERING · SETTLED · REJECTED · CANCELLED |
Step 1 — Build a Salary Structure
You can build a structure component-by-component, or apply a country preset to get a sensible starting set you can then edit.
Then apply a preset (this copies components into your structure — no live link, so you stay free to edit afterward):
Manage component lines under
/api/v2/hr/payroll/salary-structures/:id/components[/:cid].
Step 2 — Assign Salaries to Employees
Dev OnlyPOST /api/v2/hr/payroll/employee-salaries
A raise doesn't overwrite history. Assigning a new salary creates a new row
with an effectiveFrom date and closes the previous one. A payroll
run for May uses the salary that was effective during May — so a June
1 raise never retroactively changes the May payslip.
Step 3 — Run Payroll
A payroll run moves through a strict state machine. Each transition is a separate endpoint and a separate permission — this is how POSVelo enforces separation of duties (the person who approves must not be the one who processed).
Create the run
POST /api/v2/hr/payroll/runs · hr.payroll.run.create.
A storeId of null covers all stores.
Process it
POST .../runs/:id/process queues a background job that computes
every employee's draft payslip, then moves the run to REVIEW.
Review the drafts
HR checks the batch. If anything upstream was missing (no salary, no attendance), that employee is flagged for a human to verify rather than silently zeroed.
Approve
POST .../runs/:id/approve finalizes the payslips —
DRAFT → FINALIZED. From here they are immutable. Must be a
different person than the processor; step-up 2FA may be required.
Disburse
POST .../runs/:id/disburse records who paid and when, and can
notify employees that payslips are ready. (Actual bank transfer integration
is a later release.)
How a payslip is computed
For each employee the engine resolves the salary effective during the period, walks the structure's components in order, and applies each one:
| Calc method | What it does |
|---|---|
FIXED | A flat amount. |
PERCENT_OF_BASIC | A percentage of basic pay. |
PERCENT_OF_GROSS | A percentage of gross-so-far (order matters). |
FORMULA | A preset, pure function (used by country presets). |
ATTENDANCE_DERIVED | Overtime earnings and loss-of-pay deductions from attendance. |
Then it recovers any due salary-advance installment as a deduction, totals up gross / deductions / net, and writes a draft payslip whose line labels and codes are snapshotted as text — so renaming a component later never changes an old payslip.
Re-processing a run on the same inputs produces byte-identical drafts. No randomness, no "now" timestamps inside the math.
Payslips Are Immutable
Once a payslip is FINALIZED it cannot be edited or deleted — it's
a legal record for pay disputes and tax. To fix a mistake you create a new run
with an ADJUSTMENT line that points back at the original (and the
original may be marked VOIDED). Both stay in history.
Employees download their own payslips as PDF/print via ESS
(GET /api/v2/me/payslips/:id/pdf); HR can fetch any payslip
(GET /api/v2/hr/payroll/payslips/:id and .../pdf).
Salary Advances
A short loan recovered over future paychecks.
Each subsequent payroll run automatically recovers one installment as a
deduction until the advance is fully repaid (SETTLED).
Money Discipline
All money is stored as fixed-precision decimals (e.g. 50000.00)
and all arithmetic uses a decimal library — never JavaScript floating-point —
so totals always add up to the cent.
In the App
| Page | Route |
|---|---|
| Payroll overview | /hr/payroll |
| Runs | /hr/payroll/runs |
| Run detail | /hr/payroll/runs/[id] |
| Salary structures | /hr/payroll/structures |
| Structure detail | /hr/payroll/structures/[id] |
| Employee salaries | /hr/payroll/salaries |
| Advances | /hr/payroll/advances |
Who Can Do What
| Capability | ADMIN | HR_MANAGER | ACCOUNTANT | EMPLOYEE |
|---|---|---|---|---|
| Manage structures / components | Yes | Yes | Limited view | No |
| Create / process runs | Yes | Yes | Yes | No |
| Approve a run | Yes | Yes | If not the processor | No |
| Disburse a run | Yes | Yes | Yes | No |
| Manage advances | Yes | Yes | Yes | No |
| Read own payslips | Yes | Yes | Yes | Yes (via ESS) |
Employees see their payslips, leave balance, roster, and attendance in the Employee Self-Service portal.