How the China 税后工资 (take-home pay) calculator is verified

Inputs

InputFieldType
Gross monthly salary (CNY)grossMonthlynumber
Housing fund rate, % (5 to 12)housingFundRatenumber
Children you claim for (education or under-3 care)childrennumber
Supporting a parent aged 60 or overelderlySupportstring
Housing deductionhousingstring
Degree continuing education (400 a month)continuingEducationboolean

The formula

Each derived value below is computed by the Valem engine from the expression shown, in this order. Nothing else runs — there is no hidden code path.

Derived valueFieldFormula (JSONata)
Contribution base (social insurance)siBase($g := $n(grossMonthly); $g <= 0 ? 0 : $clampFloorCap($g, $const.siBaseFloor, $const.siBaseCap))
Pension 8% / monthpensionMonthly$round(siBase * $const.pensionRate, 2)
Medical 2% + 3 / monthmedicalMonthly$round(siBase > 0 ? siBase * $const.medicalRate + $const.medicalMutualAidMonthly : 0, 2)
Unemployment 0.5% / monthunemploymentMonthly$round(siBase * $const.unemploymentRate, 2)
Housing fund / monthhousingFundMonthly($g := $n(grossMonthly); $b := $g <= 0 ? 0 : $clampFloorCap($g, $const.hfBaseFloor, $const.hfBaseCap); $floor($b * $clampFloorCap($n(housingFundRate) / 100, $const.hfRateMin, $const.hfRateMax) + 0.5))
Your contributions / monthcontributionsMonthly$round(pensionMonthly + medicalMonthly + unemploymentMonthly + housingFundMonthly, 2)
Special additional deductions / monthspecialAdditionalMonthly$floor($n(children)) * $const.childDeductionMonthly + (elderlySupport = 'onlyChild' ? $const.elderlyOnlyChildMonthly : (elderlySupport = 'shared' ? $const.elderlySharedMaxMonthly : 0)) + (housing = 'rent' ? $const.housingRentMonthly : (housing = 'loan' ? $const.housingLoanMonthly : 0)) + (continuingEducation ? $const.continuingEducationMonthly : 0)
Taxable income for the yeartaxableAnnual($v := $n(grossMonthly) * 12 - contributionsMonthly * 12 - $const.basicDeductionAnnual - specialAdditionalMonthly * 12; $round($v > 0 ? $v : 0, 2))
Individual income tax for the yeariitAnnual$round($bandedCharge(taxableAnnual, [{"upTo": $const.iitBand1, "rate": $const.iitRate1}, {"upTo": $const.iitBand2, "rate": $const.iitRate2}, {"upTo": $const.iitBand3, "rate": $const.iitRate3}, {"upTo": $const.iitBand4, "rate": $const.iitRate4}, {"upTo": $const.iitBand5, "rate": $const.iitRate5}, {"upTo": $const.iitBand6, "rate": $const.iitRate6}, {"upTo": null, "rate": $const.iitRate7}]), 2)
Net / yearnetAnnual$round($max([0, $n(grossMonthly) * 12 - contributionsMonthly * 12 - iitAnnual]), 2)
Net / monthnetMonthly$round(netAnnual / 12, 2)

Rates and thresholds

The expressions above read these as $const. They are the figures the annual refresh replaces, so they live as data rather than being written into the formulas — which is what makes a year-on-year change a one-line diff instead of an edit to arithmetic.

ConstantValue
basicDeductionAnnual60000
iitBand136000
iitBand2144000
iitBand3300000
iitBand4420000
iitBand5660000
iitBand6960000
iitRate10.03
iitRate20.1
iitRate30.2
iitRate40.25
iitRate50.3
iitRate60.35
iitRate70.45
childDeductionMonthly2000
elderlyOnlyChildMonthly3000
elderlySharedMaxMonthly1500
housingRentMonthly1500
housingLoanMonthly1000
continuingEducationMonthly400
siBaseFloor7270
siBaseCap36348
pensionRate0.08
medicalRate0.02
medicalMutualAidMonthly3
unemploymentRate0.005
hfBaseFloor2540
hfBaseCap36348
hfRateMin0.05
hfRateMax0.12

Test vectors (7)

Every case is executed against this model on each build, by the Java engine and independently by a JavaScript one. A mismatch of a single cent fails the build, so the page cannot ship advertising a figure the model no longer produces.

Case 1 — C1 20,000 a month, 12% housing fund, no deductions — 10,076.40 tax for the year

given grossMonthly20000
given housingFundRate12
given children0
given elderlySupportnone
expect pensionMonthly1600
expect medicalMonthly403
expect unemploymentMonthly100
expect housingFundMonthly2400
expect contributionsMonthly4503
expect taxableAnnual125964
expect iitAnnual10076.4
expect netAnnual175887.6
expect netMonthly14657.3

Case 2 — C2 one child and an only child supporting a parent: 5,000 a month off

given grossMonthly20000
given housingFundRate12
given children1
given elderlySupportonlyChild
expect specialAdditionalMonthly5000
expect taxableAnnual65964
expect iitAnnual4076.4
expect netAnnual181887.6

Case 3 — C3 50,000 a month: both bases cap at 36,348, housing fund 4,362 as the notice’s table

given grossMonthly50000
given housingFundRate12
given children0
given elderlySupportnone
expect siBase36348
expect pensionMonthly2907.84
expect medicalMonthly729.96
expect unemploymentMonthly181.74
expect housingFundMonthly4362

Case 4 — C4 5,000 a month: the social-insurance base floors at 7,270 and no tax is due

given grossMonthly5000
given housingFundRate12
given children0
given elderlySupportnone
expect siBase7270
expect pensionMonthly581.6
expect medicalMonthly148.4
expect unemploymentMonthly36.35
expect housingFundMonthly600
expect taxableAnnual0
expect iitAnnual0

Case 5 — C5 housing fund at the 5% minimum

given grossMonthly20000
given housingFundRate5
given children0
given elderlySupportnone
expect housingFundMonthly1000
expect contributionsMonthly3103

Case 6 — C6 sibling share of elderly support counts 1,500

given grossMonthly20000
given housingFundRate12
given children0
given elderlySupportshared
expect specialAdditionalMonthly1500

Case 7 — C7 rent in Beijing plus degree study: 1,900 a month off, 7,796.40 tax

given grossMonthly20000
given housingFundRate12
given children0
given elderlySupportnone
given housingrent
given continuingEducationyes
expect specialAdditionalMonthly1900
expect taxableAnnual103164
expect iitAnnual7796.4
expect netAnnual178167.6

Sources

Check it yourself — and reuse it

The whole model as JSON — inputs, outputs, formulas, vectors and sources in one re-runnable document.

This model is published under CC BY 4.0: use it, adapt it, build on it, with attribution. The licence covers the model — the expression of each rule and the arrangement of the catalog. The rates and thresholds are law, and nobody licenses those; the sources above are where they come from.

← Back to the China 税后工资 (take-home pay) calculator

Built with Valem — a live, verifiable calculator you can fork and embed.