💰 How Payroll Works

A complete guide to payroll processing in HRSanad — from first setup to final bank transfer.

🌍 The Big Picture

Think of payroll as a factory. Every month, raw materials go in (employee details, attendance, leaves, loans) and a finished product comes out (a salary slip for every employee, and a file that tells the bank who gets paid how much).

What payroll does, in plain words:

  1. Figures out how much each person earned this month (basic salary + allowances + overtime)
  2. Figures out what gets taken away (loan repayments, deductions)
  3. Subtracts deductions from earnings to get the net salary
  4. Sends the results to the bank via a special UAE government file called WPS
  5. Sets aside money every month for the employee's end-of-service gratuity
Employees + Attendance + Leaves & Loans Payroll Engine Calculates earnings Calculates deductions Computes net salary Salary Slips One per employee Full breakdown WPS File + JV Sent to bank Posted to accounts

The payroll pipeline: people & data go in → money goes out correctly.

🧱 Pay Components — The Building Blocks

A salary is not just one number. It is built from many smaller pieces called pay components. Each component is either something the employee earns or something that gets deducted.

The three types of components

Earning

Money added to what the employee receives.

  • Basic Salary
  • Housing Allowance
  • Transport Allowance
  • Phone Allowance
  • Overtime Pay
  • Performance Bonus

Deduction

Money subtracted before the employee receives their pay.

  • Loan Instalment
  • Salary Advance Repayment
  • Absence Deduction
  • Social Security (if applicable)

Employer Contribution

Costs the company pays on top of the salary that do not go to the employee directly — but are still a cost to the business (e.g., employer's pension contribution in some countries).

How a component's value is calculated

MethodHow it worksExample
fixed A flat amount every month, always the same. Transport Allowance = AED 800
pct_basic A percentage of the employee's basic salary. Housing = 25% of Basic → 25% × 10,000 = AED 2,500
pct_gross A percentage of total gross earnings (all earnings combined). Bonus = 5% of Gross
pct_component A percentage of one specific other component. Extra Allowance = 10% of Housing Allowance
formula A custom mathematical expression evaluated by the system. (basic * 0.3) + 500

🏗️ The Three-Layer Salary Setup

HRSanad uses a smart three-layer system to decide each employee's pay components. You don't have to set up every allowance for every employee individually — defaults flow down automatically.

1

Grade Defaults

Every employee grade (e.g., "Manager", "Engineer") has a standard set of pay components with default values. All employees in that grade start with these.

Example: All Managers get Housing = 30% of Basic by default.

2

Grade-Level Overrides

A specific value or percentage override can be set at the grade level — affecting all employees in that grade without touching each one individually.

Example: Temporarily fix Housing to AED 3,000 flat for all Managers this year.

3

Employee Overrides

The highest priority. If an individual employee has a specific override, it completely replaces the grade default for that component, for that person only.

Example: Ahmed's Housing is fixed at AED 4,500 regardless of his grade's default.

Layer 1 — Grade Defaults Housing=25%, Transport=800, Phone=200 override? Layer 2 — Grade-Level Override Housing overridden to fixed AED 3,000 for this grade override? Layer 3 — Employee Override (Highest Priority) Ahmed's Housing: AED 4,500 (ignores all above)

Layer 3 always wins. If no override exists, the value falls through from Layer 2, then Layer 1.

💡 Why this matters You configure a grade once, and every employee in that grade automatically gets the right allowances. You only need individual overrides for exceptions — keeping setup fast and maintenance easy.

🔄 The Payroll Run — Step by Step

Every month you create a Payroll Run. Think of it as a container that holds every employee's salary slip for that month. A run always follows a strict sequence of statuses — you cannot skip steps or go backwards.

📄 DRAFT
Run created, nothing calculated yet
🔢 CALCULATED
All salary slips computed
✅ APPROVED
HR Manager has reviewed & signed off
🏦 FINALIZED
Ready for bank payment
🔒 LOCKED
WPS file generated, no more changes allowed
⚠️ This is a one-way road A run can only move forward: Draft → Calculated → Approved → Finalized → Locked. You can never move it backwards. This is intentional — it prevents accidental changes to a payroll that employees have already been paid.

Detailed walkthrough of each step

  1. Create the Run (DRAFT)

    Go to Payroll → Runs → New Run. Choose the year, month, and which company's employees to include. The run is created in draft status — it's just an empty shell at this point. No numbers yet.

    API call: POST /v1/payroll/runs with { year, month, company_id }

  2. Calculate (DRAFT → CALCULATED)

    Click Calculate. The system now works through every active employee one by one and produces a salary slip for each. This is the most important step — see the next section for exactly how the math works.

    API call: POST /v1/payroll/runs/:id/calculate

    After this, you can view all the salary slips and check for any errors.

  3. Review the Slips

    Open the run and browse each department's slips. Look for anything unusual — an employee with zero salary, an unexpectedly high overtime figure, a missing loan deduction. Fix the root data (attendance, pay components) if needed, then recalculate.

    API call: GET /v1/payroll/runs/:id/slips (supports department filter & pagination)

  4. Approve (CALCULATED → APPROVED)

    Once you're satisfied, click Approve. This represents the HR Manager's or Finance Manager's sign-off that the numbers are correct. After this, the slips are locked for editing.

    API call: POST /v1/payroll/runs/:id/approve

  5. Finalize (APPROVED → FINALIZED)

    Finalization confirms that the payroll is ready for payment. It's a second confirmation layer (e.g., CFO sign-off) before the bank files are generated.

    API call: POST /v1/payroll/runs/:id/finalize

  6. Generate WPS File (FINALIZED → LOCKED)

    Click Generate WPS. The system creates a SIF file (Standard Input Format) which is the official UAE Wage Protection System format accepted by all UAE banks. Once generated, the run is locked — no more changes of any kind.

    API call: POST /v1/payroll/runs/:id/generate-wps

    You upload this SIF file to your bank's portal and the bank processes the transfers.

  7. Generate Journal Voucher (Optional)

    If your company uses accounting software (Oracle GL, SAP, Temenos T24, or any system accepting CSV), click Generate JV. This creates a journal entry CSV with payroll costs broken down by cost centre, department, and pay component — ready to import into your accounts.

    API call: POST /v1/payroll/runs/:id/generate-jv

🧮 How the Calculation Works

When you hit Calculate, the engine processes every eligible employee in this order:

  1. Fetch the employee's pay components

    Using the three-layer system described above, the engine builds a final list of all applicable pay components and their values for this employee.

  2. Get attendance data from TNA

    From the Time & Attendance module, the engine reads how many working days were in the month, how many the employee was present, any absent days, and total overtime hours.

    • Working days: total scheduled working days in the month (weekends and holidays excluded)
    • Paid days: working days minus absent days
    • Absent days: days with no attendance and no approved leave
  3. Calculate each earning component

    For each earning component, compute its value using the method (fixed, pct_basic, formula, etc.). Then pro-rate it if the employee was absent:

    pro_rated_amount = (component_value / working_days) × paid_days

    If the employee worked all days, paid_days = working_days, so they get the full amount.

  4. Add Overtime Pay

    Overtime is calculated from TNA data. UAE Labour Law rates:

    • Weekday overtime: 1.5× the hourly basic rate
    • Public holiday overtime: 2× the hourly basic rate
    hourly_rate = basic_salary / (working_days_in_month × 8)
    ot_pay = ot_hours × hourly_rate × 1.5
  5. Compute total earnings
    total_earnings = sum of all earning components + ot_pay
  6. Apply deductions

    Each deduction component is calculated (same methods as earnings). Loan instalments are automatically fetched from the Loans module for active loans and added as deductions.

    total_deductions = sum of all deduction components + loan_instalments
  7. Calculate net salary
    net_salary = total_earnings − total_deductions
  8. Compute employer costs (not paid to employee)
    • Gratuity accrual: how much gratuity liability built up this month (see Gratuity section)
    • Leave accrual: simplified as basic_salary / 12 per month
    • Employer contributions: any employer-side components (e.g., pension)

📄 The Salary Slip — Anatomy

Each employee gets a salary slip (also called a payslip) that shows the complete breakdown. Here is what a typical slip looks like:

TechCorp LLC — Salary Slip

April 2026  |  Processed: 30 Apr 2026

Ahmed Al-Mansouri

EMP-0042  |  Engineering Manager

Earnings

Basic Salary 10,000.00
Housing Allowance 2,500.00
Transport Allowance800.00
Phone Allowance 200.00
Overtime Pay (4h) 156.25
Total Earnings13,656.25

Deductions

Car Loan Instalment1,200.00
Salary Advance 500.00
Total Deductions1,700.00

Attendance

Working Days 22
Paid Days 22
Absent Days 0
Overtime Hours 4h
📌 Note on Gratuity and Leave Accrual The gratuity and leave accrual figures on the slip are not deducted from the employee's salary. They are cost estimates that help Finance track the company's growing liability towards each employee. The actual gratuity is paid when the employee leaves.

🏅 End-of-Service Gratuity (UAE Law)

Under UAE Labour Law (Federal Decree 33/2021), every employee who completes at least one year of service is entitled to an end-of-service gratuity payment when they leave.

⚠️ The most common mistake The daily salary rate for gratuity is calculated by dividing the basic salary by 30, not 26. HRSanad enforces this correctly. Never change this divisor.

The gratuity formula

daily_rate   = basic_salary / 30
gratuity     = days_per_year × daily_rate × years_in_this_band

The number of days_per_year depends on total service length, split into bands:

Less than 1 year
None
No gratuity entitlement
1 – 5 years
21 days
per year of service
Beyond 5 years
30 days
per additional year

Example — 7 years of service, Basic Salary = AED 10,000

BandYearsDays/YearDaily RateAmount
1–5 years521 daysAED 333.33 (10,000÷30)AED 35,000
Beyond 5 years230 daysAED 333.33AED 20,000
Total GratuityAED 55,000
💡 Gratuity slabs are stored in the database The slab values (21 days, 30 days, divisor of 30) are never hardcoded in HRSanad. They are stored in finance.gratuity_slabs table. If the law changes, the slabs are updated in the database and all future calculations automatically reflect the new rules — no code changes needed.

Monthly Gratuity Accrual on the Payslip

Every month, payroll computes how much gratuity liability grew that month. This appears on the payslip as an informational figure (not deducted from the employee):

monthly_accrual = annual_gratuity_for_full_service / years_of_service / 12

🏦 WPS — Wage Protection System

In the UAE, all private-sector companies are legally required to pay salaries through the Wage Protection System (WPS), regulated by the Central Bank of UAE (CBUAE) and the Ministry of Human Resources.

WPS works like this:

  1. HRSanad generates a SIF file (Standard Input Format) — a structured text file listing every employee's IBAN, the amount to pay, and the payment date.
  2. You upload the SIF file to your bank's corporate online portal.
  3. The bank processes the file and transfers money to each employee's bank account on the specified date.
  4. The bank reports back to CBUAE confirming that salaries were paid. If a company fails to pay on time, CBUAE can issue fines or freeze the company's work permit applications.
✅ Which components go into WPS? Only components marked is_wps_included = true are included in the WPS payment amount. Typically this is basic salary + fixed allowances. Some employer contributions or one-time bonuses may be excluded depending on company policy.
🚨 WPS is mandatory in UAE WPS is not optional. Failure to pay salaries through WPS can result in: fines, inability to renew work permits, and in serious cases, company blacklisting. HRSanad enforces this by only allowing WPS file generation after the run is in finalized status.

📒 Journal Voucher (JV Export)

After payroll is finalized, Finance needs to post the payroll costs to the company's accounting system. HRSanad generates a Journal Voucher (JV) CSV that can be imported directly into:

The JV breaks down payroll costs by:

✅ How to Run Payroll — Month-End Checklist

Before you start

Running the payroll

  1. Go to Payroll → Runs → New Run
  2. Select Year, Month, Company → Click Create
  3. Click Calculate — wait for all slips to generate
  4. Review slips — spot-check 5–10 employees for accuracy
  5. If anything is wrong, fix the source data (TNA, pay components, loans) and click Recalculate
  6. When satisfied, click Approve
  7. Get sign-off from Finance Manager, then click Finalize
  8. Click Generate WPS — download the SIF file
  9. Upload the SIF file to your bank portal
  10. Click Generate JV — import the CSV into your accounting system

After payroll is processed

🔌 API Quick Reference

ActionMethodEndpointRequired Status
List runsGET/v1/payroll/runsAny
Create runPOST/v1/payroll/runs
Get run detailsGET/v1/payroll/runs/:idAny
Calculate slipsPOST/v1/payroll/runs/:id/calculatedraft
View slipsGET/v1/payroll/runs/:id/slipscalculated+
View single slipGET/v1/payroll/runs/:id/slips/:slipIdcalculated+
Approve runPOST/v1/payroll/runs/:id/approvecalculated
Finalize runPOST/v1/payroll/runs/:id/finalizeapproved
Generate WPS (SIF)POST/v1/payroll/runs/:id/generate-wpsfinalized
Generate JV CSVPOST/v1/payroll/runs/:id/generate-jvfinalized
List employee pay compsGET/v1/payroll/employees/:id/pay-components
Add pay component overridePOST/v1/payroll/employees/:id/pay-components
Remove pay component overrideDELETE/v1/payroll/employees/:id/pay-components/:pcId
🔑 Access control All payroll endpoints require the user role to be one of: hr_admin, payroll_admin, or sysadmin. Employees can only view their own pay components and payslips via the ESS portal. Salary data is never returned to users without role verification.

📋 Key Business Rules

RuleDescription
BR-PAY-001 Monthly payroll supports mid-month processing via a separate run_type (for new joiners or separations mid-month).
BR-PAY-004 Payroll finalization requires workflow approval — the status machine enforces the sequence and cannot be bypassed.
BR-PAY-005 WPS file can only be generated when the run is in approved or finalized status.
Gratuity daily rate Always basic_salary / 30. Never use 26. This is UAE Labour Law.
Gratuity slabs Always read from finance.gratuity_slabs table. Never hardcoded.
Overtime rates 1.5× on weekdays, 2× on public holidays (UAE Labour Law Article 67).
Minimum service for gratuity Employee must have completed at least 1 full year of service. Less than 1 year = AED 0 gratuity.
HRSanad HRMS — How Payroll Works Last updated: April 2026  |  Owner: Waheed Rahuman Kamaludeen