VerityPay documentation
Developer and user guide
Everything you need to set up, run, and integrate VerityPay — from first payroll to full API integration.
VerityPay documentation
Everything you need to set up, run, and integrate VerityPay — from first payroll to full API integration.
VerityPay is a South African multi-tenant payroll SaaS. Every organisation is completely isolated. All DB queries scope to organisationId — no cross-tenant data leakage is possible by design.
The system calculates PAYE using the SARS annualised method, enforces the UIF R177.12/month cap, applies SDL at 1% for organisations above the R500k annual payroll threshold, and tracks BCEA leave cycles automatically.
Create an account at /register. During onboarding you will capture:
After adding employees, navigate to Payroll and click New run. Select the pay period, confirm employees, and click Calculate. The system shows the full gross-to-net breakdown before you approve.
Two-person rule: the same user who calculated the run cannot approve it. calculatedById must differ from approvedById.
VerityPay processes a full gross-to-net pipeline per employee per run. Each run is immutable once approved. Corrections create a new correction run — the original is never modified.
The annualised method applies monthly gross to annual brackets, then divides by 12:
monthly_gross × 12 → find bracket → apply: base_tax + rate × (annual - lower_bound) → subtract rebates → ÷ 12 = monthly PAYE Rebates (2025/26): Primary: R17,235 (all taxpayers) Secondary: R9,444 (age 65+) Tertiary: R3,145 (age 75+) Thresholds: Under 65: R95,750 65–74: R148,217 75+: R165,689
Completed payroll runs are immutable. To correct an error, create a new correction run referencing the original. Both runs are retained for SARS audit purposes. Overpayments and underpayments are captured as separate line items on the correction run payslip.
Payslips are generated as branded PDFs after every approved run. Employees can download them from the self-service portal immediately. HR can bulk-download all payslips for a run from the Payroll dashboard.
VerityPay's tax engine is implemented as pure functions in lib/engines/tax/. No Prisma, no fetch calls, no side effects — only deterministic math you can unit-test in isolation.
UIF is 1% employee and 1% employer, capped at R177.12/month (salary ceiling R17,712/month).
Excluded from UIF gross: bonuses, overtime, retrenchment pay, retirement lump sums.
SDL is 1% employer-only. It applies if the annual payroll exceeds R500,000. SDL gross includes everything — no exclusions.
ETI reduces the employer's PAYE liability for qualifying employees (18–29 years, earning below the threshold). VerityPay calculates the ETI reduction and applies it before the EMP201 is generated. See SARS ETI guide for current qualifying criteria.
Leave tracking is fully BCEA-compliant. Balances update in real time after each leave transaction. The system supports annual, sick, and family responsibility leave.
Employees accrue 15 working days per year (1.25 days/month). Leave taken deducts from the accrued balance. Unused annual leave is paid out on termination (taxable, IRP5 code 3606).
30 days per rolling 3-year cycle. The system tracks the cycle start date per employee and resets automatically. Family responsibility leave: 3 days per year, no carry-over.
When an employee is terminated, all outstanding annual leave is automatically added to the final pay run as a taxable lump sum. The IRP5 code 3606 is applied. No manual calculation needed.
After each payroll run, navigate to Exports and click Generate EMP201. The file is SARS-formatted XML ready for eFiling. The system aggregates PAYE, UIF, SDL, and ETI across all employees in the run.
IRP5s are generated at year-end for all employees who received income during the tax year. Each certificate includes all taxable income, deductions, and fringe benefits correctly coded per SARS requirements.
VerityPay generates EFT files for ABSA, FNB, Nedbank, and Standard Bank. Each file contains one record per employee with their net pay amount and bank account details (AES-256 decrypted at export time, never stored in plain text).
Salary confirmation letters can be generated on demand from the Employee portal or the HR dashboard. Letters are signed with the organisation name and include current salary, employment date, and leave balance.
The VerityPay REST API allows you to integrate payroll data into your own systems. All endpoints require an API key passed as a bearer token.
Authorization: Bearer vp_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx All requests must be HTTPS. API keys are scoped to one organisation. Rotate keys from: Settings > API Keys
GET /api/v1/{orgSlug}/payroll
List all payroll runs
GET /api/v1/{orgSlug}/payroll/{runId}
Get a single run with full line items
POST /api/v1/{orgSlug}/payroll
Create a new payroll run (draft)
POST /api/v1/{orgSlug}/payroll/{runId}/approve
Approve a draft run (different user required)GET /api/v1/{orgSlug}/employees
List employees (paginated)
GET /api/v1/{orgSlug}/employees/{id}
Get employee record
POST /api/v1/{orgSlug}/employees
Create employee
PATCH /api/v1/{orgSlug}/employees/{id}
Update employee detailsVerityPay fires webhook events to your registered endpoint for key lifecycle events:
payroll.run.approved — run approved and payslips generatedemployee.created — new employee addedleave.approved — leave request approvedleave.balance.low — employee leave balance below 3 daysRate limit: 120 requests per minute per API key. All errors return JSON with code, message, and details fields.
{
"code": "PAYROLL_ALREADY_APPROVED",
"message": "This payroll run has already been approved.",
"details": { "runId": "clx..." }
}VerityPay encrypts all PII at the application layer before writing to the database. Use encryptField() and decryptField() from lib/crypto.ts for all SA ID numbers and bank account numbers.
VerityPay acts as an Operator under POPIA for the personal information it processes on behalf of your organisation (the Responsible Party). We apply purpose limitation, data minimisation, and retention policies as required by POPIA.
Payslip and payroll run data is retained for 5 years after the tax year in which it was created, in line with SARS record-keeping requirements. Employee records are retained for 3 years after employment ends. Deletion requests processed within 30 days where legally permissible.