The Problem
A salary correction from three months ago sounds simple — adjust the number, recalculate, pay the difference. But payroll isn't a spreadsheet. It's a time-ordered sequence of legal events, and rewriting the past creates cascading effects that most payroll systems handle poorly.
The core difficulty: retroactive corrections don't exist in isolation. A salary correction in January may change the social security base for February and March. A correction that crosses a year boundary hits a different tax table and a different contribution ceiling. And the delta that flows into the current payslip must be precisely calculated — not re-running the whole period, but computing only what changed.
Key insight: In Germany, the same correction is subject to two competing legal principles. For income tax (Lohnsteuer), the Zuflussprinzip applies — the payment is taxed when received. For social security (Sozialversicherung), the Entstehungsprinzip applies — contributions are calculated based on when the entitlement arose. Same money, different rules.
How It Works
Retro correction mechanics vary significantly by country. The common thread is a delta-only flow: only the difference between the original and corrected calculation appears in the current payslip. The original period records remain unchanged for audit purposes.
The delta calculation
For a salary correction from EUR 3,000 to EUR 3,500 in January (corrected in April):
- Re-run January with salary = 3,500
- Subtract original January results from re-run results
- The delta (difference per wage type) flows into April as an additional line item
- April's own calculation runs independently on April salary
This sounds straightforward, but the devil is in the details. The re-run must use January's parameters — January's tax tables, January's SV rates, January's ceilings. Not April's. And if January crossed a contribution ceiling that April hasn't reached yet, the delta calculation must respect that ceiling correctly.
Country-specific mechanics
| Country | Tax principle | SV principle | Key complexity |
|---|---|---|---|
| DE | Zuflussprinzip (cash) | Entstehungsprinzip (accrual) | Märzklausel, year-boundary BBG |
| UK | Cumulative PAYE self-corrects | NI recalculated per period | Tax code updates retroactively adjust cumulative tax |
| NL | Loonheffing per period | Premies per period | Retro-safe YTD via separate fiscal wage tracking |
| LU | RIS via annual barème | CCSS per period | Delta + current period stacked in one payslip |
| BE | BV full grid recalculation | RSZ per period | BV recalc requires full-year projection to apply correctly |
| ES | IRPF regularization formula | SS per period (base cotización) | Explicit created timestamps on caseFieldValues for late entry |
| US | FIT per period (or cumulative annualized) | FICA SS annual wage base | YTD cache management, zero-delta persistence for SS refund |
Where It Gets Tricky
The Märzklausel (Germany)
Germany's Märzklausel (§ 23a SGB IV) is the canonical example of retro complexity. When a one-time payment is made in January, February, or March and it pushes the employee over the annual SV ceiling (BBG), the payment is attributed to the previous December for contribution purposes. This means the retro correction doesn't just affect the original period — it changes which year's BBG applies.
A correction in April that retroactively increases a January one-time payment may trigger or un-trigger the Märzklausel. The BBG for the prior year may be different from the current year. The social security recalculation must happen against December of the prior year, not January.
Year-boundary crossings
A correction that crosses December 31st is the hardest case. The prior year has different tax tables, different SV ceilings, and different contribution rates. The re-run must apply prior-year parameters precisely. YTD accumulators (for tax and for annual wage bases) must be recalculated correctly for both years.
The storeEmptyResults problem
When a delta is zero — because the re-run and original calculation produce identical results for some wage types — those zero deltas must still be stored. This is non-obvious: a system that only stores non-zero results will silently omit zero deltas, causing YTD aggregations to give wrong results in subsequent periods.
How PE Solves It
Payroll Engine's retro architecture is built around three design principles:
1. Period-parametrized re-runs
Every payrun re-run uses the parameters (tax tables, SV rates, ceilings) that were active during the original period. Data regulations in PE use validFrom versioning — a lookup for 2024 SV rates returns 2024 values even when run in 2026. The re-run is deterministic and parameter-isolated.
2. Delta wage types
Each correctable wage type has a corresponding delta variant. The delta is computed as new - original and stored separately. Zero deltas are stored explicitly (using storeEmptyResults: true) to preserve YTD integrity. This means the current payslip always shows the exact correction amount — not a re-run of the full period.
3. Forecast isolation
Retro runs use the Forecast job type, which has its own result store separate from the Legal payrun. This means a retro correction can be calculated, reviewed, and approved before it flows into the production payslip. Legal runs are never used for retro preview — they would interfere with the approval workflow.
Test Case References
The following integration tests validate the retro correction scenarios described in this article:
| Test | Country | Scenario |
|---|---|---|
WT-TC1135-DE-Retro-GehaltsKorrektur |
DE | Salary correction: Zuflussprinzip (LSt) vs. Entstehungsprinzip (SV) |
WT-TC5010-DE-SvBrutto-DezemberVerfahren |
DE | Märzklausel: one-time payment in Jan–Mar attributed to prior December |
WT-TC5130-NL-LoonheffingNetto-Retro |
NL | Retro-safe YTD via fiscal wage period tracking |
WT-TC5100-LU-RetenueSalaires-Retro |
LU | RIS retro delta + current period (salary 3,000 → 3,500) |
WT-TC5130-BE-BVNetto-Retro |
BE | Full BV grid recalculation across periods |
WT-TC5150-ES-RetencionIRPF-Regularizacion-Retro |
ES | IRPF regularization with explicit created timestamps |
WT-TC5200-YTD-Refund |
US | FICA SS refund via YTD cache with zero-delta persistence |
All test cases listed above are integration tests that run against a live Payroll Engine backend. They verify both the calculation logic and the period-parametrization — ensuring that re-runs use historically correct parameters rather than current-period values.
See how PE handles this
Explore the full technical implementation — retro architecture, delta wage types, and period-parametrized re-runs across all 11 countries.
Request a Demo →
Germany
United Kingdom
Netherlands
Luxembourg
Belgium
Spain
United States