Payroll
Multi-country payroll processing with plugin-based tax calculations, employee compensation, and automated payment batches
Overview#
The payroll system supports multi-country payroll processing with a plugin-based calculation architecture. The ERP backend is country-agnostic -- it stores employee data, receives pre-calculated results, and handles GL posting and payments. Country-specific tax calculation logic lives in separate plugins that can be added without changing the core system.
Key Features#
- Effective-dated compensation records
- Plugin-based country-specific tax calculations
- Pre-tax and post-tax deductions with limits
- Multi-step processing (draft, calculated, approved, paid)
- Risk-based approval workflows
- Employee-direct payments via bank accounts
- Dual payee payment batches (vendor lines for taxes + employee lines for net pay)
Supported Countries#
- Estonia -- Income tax (22%), social tax (33%), unemployment, funded pension
- Additional countries can be added by creating new plugins -- no backend code changes required
Plugin-Based Architecture#
The backend provides data and receives results. Plugins handle all country-specific logic:
ERP Backend (Data) Plugin (Calculations) ERP Backend (Results)
1. Read employee data --> 2. Calculate payroll --> 3. Submit results
- compensation using country-specific via submit_calculation
- tax settings plugin formulas
- deductions 4. Store detail records
- tax jurisdictions 5. Generate GL lines
6. Create payment batch
This design means:
- Rate changes require no code changes -- update tax jurisdiction rates in the database
- New countries require no backend changes -- create a new plugin with the country's formulas
- All intelligence stays in plugins -- the backend is a dumb data store and validator
Three-Table Data Architecture#
Plugins read three tables at calculation time:
| Table | What It Stores | Changes When |
|---|---|---|
| Tax Jurisdictions | Statutory base rates (income tax percentages, social tax rates, brackets) | Rates change yearly -- database update only |
| Employee Tax Settings | Per-employee modifiers (pension tier, basic exemption, filing status) | Employee changes elections |
| Employee Deductions | Voluntary and court-ordered deductions (pension III, health insurance, garnishments) | Employee enrolls in benefits, court order arrives |
Employee Data#
Compensation Records#
Compensation records track salary and wage information with effective dates:
| Field | Description | Examples |
|---|---|---|
| Compensation type | How the employee is paid | Salary, hourly, commission, contract, stipend |
| Pay frequency | How often they are paid | Monthly, bi-weekly, weekly, semi-monthly, annual |
| Base amount | Salary or hourly rate | $75,000/year or $25.00/hour |
| Standard hours | For hourly employees | 40.00 hours/week |
| Overtime multiplier | Overtime rate | 1.50 (time and a half) |
| Effective period | When this compensation applies | Start date, optional end date |
Tax Settings#
Tax settings are country-agnostic with per-country specifics:
Common fields:
- Country and state/locality codes
- Tax identification (SSN, personal ID, etc.)
- Filing status and allowances
- Additional withholding amounts
US-specific:
- W-4 version and steps
- State code and state allowances
Estonia-specific:
- Pension tier (2%, 4%, or 6% for II pillar)
- Basic exemption application (700 EUR/month)
- Employment register ID
Employee Deductions#
Deductions support multiple calculation methods and tax treatments:
| Deduction Type | Examples |
|---|---|
| Benefits | Health insurance, dental, vision, life insurance |
| Retirement | 401(k), Roth 401(k), 403(b), HSA, FSA |
| Legal | Garnishments, child support |
| Other | Union dues |
Each deduction specifies:
- Calculation method -- Fixed amount, percentage of gross, or per-hour rate
- Annual limits -- Maximum deduction per year (e.g., 401(k) contribution limit)
- Employer match -- Match percentage and limit
- Tax treatment -- Pre-tax or post-tax, which taxes it reduces
Payroll Processing#
Payroll Periods#
Pay periods define the time range and pay date for each payroll cycle:
| Field | Description |
|---|---|
| Period name | "January 2025" or "2025-W02" |
| Period type | Monthly, bi-weekly, weekly, semi-monthly |
| Date range | Period start and end dates |
| Pay date | When employees receive payment |
| Status | Open, processing, or closed |
Payroll Run Lifecycle#
Draft --> Calculated --> Approved --> Paid
--> Voided (if errors found)
| Status | Description |
|---|---|
| Draft | Run created, employees selected |
| Calculated | Plugin has submitted calculation results |
| Approved | Approved for payment (requires approval) |
| Paid | Payments executed |
| Voided | Run reversed (creates correcting entries) |
Processing Steps#
- Create payroll run -- Select entity, period, and run type (regular, correction, bonus, final)
- Plugin calculates -- Plugin reads employee data, applies country-specific formulas, submits results
- Review results -- Review per-employee breakdown: gross pay, taxes, deductions, net pay
- Approve -- Approval required (red lane workflow due to financial impact)
- Execute payment -- Creates payment batch with dual payee lines
Per-Employee Calculation Results#
For each employee, the calculation produces:
Earnings:
- Gross pay, regular pay, overtime pay
- Bonus pay, commission pay, other earnings
Employee Taxes Withheld:
- Federal/state/local income tax
- Social security and Medicare (US)
- Unemployment insurance (employee portion)
- Pension contributions
Employer Taxes:
- Social tax (e.g., Estonia 33%)
- Employer social security and Medicare (US)
- Federal and state unemployment (US)
Deductions:
- Pre-tax deductions (401(k), HSA)
- Post-tax deductions (Roth 401(k), garnishments)
Net Pay:
- Gross pay minus employee taxes minus deductions
Vendor-Linked Detail Lines#
Each tax and deduction amount is linked to a specific vendor (e.g., tax authority, insurance provider) and GL account. This enables:
- Accurate AP tracking for tax remittances
- Automated payment batch creation with vendor lines
- Clear audit trail from payroll calculation to payment
Payment Integration#
Payroll runs create dual payee payment batches:
| Payee Type | What Gets Paid | Example |
|---|---|---|
| Employees | Net pay amounts | Direct deposit to employee bank accounts |
| Vendors | Tax remittances and deduction payments | Income tax to tax authority, 401(k) to plan administrator |
Employee payments use the employee's configured bank account with split deposit support. Tax and deduction payments go to the mapped vendor for each line type.
Vendor Configuration#
Each tax and deduction type is mapped to a vendor and GL accounts per legal entity:
| Line Type | Vendor | Expense Account | Payable Account |
|---|---|---|---|
| Income tax | Tax authority | -- | Tax payable |
| Social tax | Tax authority | Social tax expense | Social tax payable |
| Unemployment (employee) | Unemployment fund | -- | Unemployment payable |
| Unemployment (employer) | Unemployment fund | Unemployment expense | Unemployment payable |
| Pension | Pension fund | -- | Pension payable |
This mapping is configured per entity, allowing different vendors and accounts for different countries and jurisdictions.
Workflow Summary#
| Operation | Approval Level | Description |
|---|---|---|
| Create compensation | Requires approval | Add salary or wage record |
| Update compensation | Requires approval | Change pay rate |
| Create tax settings | Requires approval | Configure tax withholding |
| Update tax settings | Requires approval | Change W-4 or tax elections |
| Create deduction | Requires approval | Add benefit or garnishment |
| Update deduction | Requires approval | Change deduction amount |
| Create payroll period | Auto-approved | Set up pay period |
| Close payroll period | Requires approval | Close after all runs complete |
| Create payroll run | Requires approval | Start payroll processing |
| Submit calculation | Auto-approved | Plugin submits results |
| Approve payroll | High-risk approval | Authorize for payment |
| Process payment | High-risk approval | Execute payments |
| Void payroll run | High-risk approval | Reverse a completed run |
Estonian Payroll Example#
For an Estonian employee earning 3,000 EUR/month with 2% II pillar pension and basic exemption applied:
| Component | Calculation | Amount |
|---|---|---|
| Gross salary | 3,000.00 EUR | |
| Unemployment insurance (employee) | 3,000 x 1.6% | -48.00 EUR |
| Funded pension (II pillar) | 3,000 x 2% | -60.00 EUR |
| Taxable income | 3,000 - 48 - 60 - 700 (exemption) | 2,192.00 EUR |
| Income tax | 2,192 x 22% | -482.24 EUR |
| Net pay | 3,000 - 48 - 60 - 482.24 | 2,409.76 EUR |
| Employer costs | ||
| Social tax | 3,000 x 33% | 990.00 EUR |
| Unemployment insurance (employer) | 3,000 x 0.8% | 24.00 EUR |
| Total employer cost | 3,000 + 990 + 24 | 4,014.00 EUR |
Best Practices#
- Set up tax settings before running payroll -- Every employee must have tax settings with the correct country code
- Keep tax jurisdiction rates current -- Update when rates change (yearly for most countries)
- Map vendors before first run -- Ensure all tax and deduction types have vendor mappings
- Review before approving -- Check per-employee breakdowns, especially for new employees
- Use correction runs for errors -- Never manually adjust; create a correction run instead
- Close periods after completion -- Prevents accidental re-runs for the same period
Subscribe to new posts
Get notified when we publish new insights on AI-native finance.