How the China 个体工商户 (individual business) calculator is verified
Inputs
| Input | Field | Type |
|---|---|---|
| Annual business profit (CNY) | profitAnnual | number |
| Social insurance | socialInsurance | string |
| Chosen monthly contribution base (7,270 to 36,348) | contributionBase | number |
| I also have salary or other comprehensive income | hasSalary | boolean |
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 value | Field | Formula (JSONata) |
|---|---|---|
| Si Base | siBase | $clampFloorCap($n(contributionBase), $const.siBaseFloor, $const.siBaseCap) |
| Your social insurance for the year | socialInsuranceAnnual | socialInsurance = 'none' ? 0 : $round((siBase * $const.flexPensionRate + siBase * $const.flexUnemploymentRate + $const.flexMedicalMonthly) * 12, 2) |
| Taxable business income | taxableIncome | ($v := $n(profitAnnual) - (hasSalary ? 0 : socialInsuranceAnnual + $const.basicDeductionAnnual); $round($v > 0 ? $v : 0, 2)) |
| Tax at 5–35% | taxBeforeRelief | $round($bandedCharge(taxableIncome, [{"upTo": $const.bizBand1, "rate": $const.bizRate1}, {"upTo": $const.bizBand2, "rate": $const.bizRate2}, {"upTo": $const.bizBand3, "rate": $const.bizRate3}, {"upTo": $const.bizBand4, "rate": $const.bizRate4}, {"upTo": null, "rate": $const.bizRate5}]), 2) |
| Halving relief (first 2 million) | halvingRelief | ($t := taxableIncome < $const.halvingCap ? taxableIncome : $const.halvingCap; $round($bandedCharge($t, [{"upTo": $const.bizBand1, "rate": $const.bizRate1}, {"upTo": $const.bizBand2, "rate": $const.bizRate2}, {"upTo": $const.bizBand3, "rate": $const.bizRate3}, {"upTo": $const.bizBand4, "rate": $const.bizRate4}, {"upTo": null, "rate": $const.bizRate5}]) * $const.halvingShare, 2)) |
| Income tax after the halving | incomeTax | $round(taxBeforeRelief - halvingRelief, 2) |
| Net income / year | netIncome | $round($max([0, $n(profitAnnual) - socialInsuranceAnnual - incomeTax]), 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.
| Constant | Value |
|---|---|
basicDeductionAnnual | 60000 |
bizBand1 | 30000 |
bizBand2 | 90000 |
bizBand3 | 300000 |
bizBand4 | 500000 |
bizRate1 | 0.05 |
bizRate2 | 0.1 |
bizRate3 | 0.2 |
bizRate4 | 0.3 |
bizRate5 | 0.35 |
halvingShare | 0.5 |
halvingCap | 2000000 |
siBaseFloor | 7270 |
siBaseCap | 36348 |
flexPensionRate | 0.2 |
flexUnemploymentRate | 0.01 |
flexMedicalMonthly | 593.68 |
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 — E1 200,000 profit, Beijing insurance at the 7,270 floor: 25,444.56 of insurance, 12,411.09 before the halving, 6,205.54 relief
given profitAnnual | 200000 |
|---|---|
given socialInsurance | beijing |
given contributionBase | 7270 |
given hasSalary | no |
expect socialInsuranceAnnual | 25444.56 |
expect taxableIncome | 114555.44 |
expect taxBeforeRelief | 12411.09 |
expect halvingRelief | 6205.54 |
expect incomeTax | 6205.55 |
Case 2 — E1b 200,000 profit insured elsewhere: 140,000 taxable, 17,500 halved to 8,750
given profitAnnual | 200000 |
|---|---|
given socialInsurance | none |
given contributionBase | 7270 |
given hasSalary | no |
expect taxableIncome | 140000 |
expect taxBeforeRelief | 17500 |
expect halvingRelief | 8750 |
expect incomeTax | 8750 |
expect netIncome | 191250 |
Case 3 — E2 taxable income of exactly 80,000 — STA 解读 example 2 with no other relief: 6,500 tax, relief 3,250
given profitAnnual | 165444.56 |
|---|---|
given socialInsurance | beijing |
given contributionBase | 7270 |
given hasSalary | no |
expect taxableIncome | 80000 |
expect taxBeforeRelief | 6500 |
expect halvingRelief | 3250 |
expect incomeTax | 3250 |
Case 4 — E3 taxable income of 2,400,000 — STA 解读 example 3 with no other relief: half the tax on the first 2 million (317,250)
given profitAnnual | 2460000 |
|---|---|
given socialInsurance | none |
given contributionBase | 7270 |
given hasSalary | no |
expect taxableIncome | 2400000 |
expect taxBeforeRelief | 774500 |
expect halvingRelief | 317250 |
expect incomeTax | 457250 |
Case 5 — E4 at or below 60,000 with no insurance: nothing taxable
given profitAnnual | 60000 |
|---|---|
given socialInsurance | none |
given contributionBase | 7270 |
given hasSalary | no |
expect taxableIncome | 0 |
expect incomeTax | 0 |
expect netIncome | 60000 |
Case 6 — E5 base above the cap is clamped to 36,348
given profitAnnual | 500000 |
|---|---|
given socialInsurance | beijing |
given contributionBase | 50000 |
given hasSalary | no |
expect siBase | 36348 |
expect socialInsuranceAnnual | 98721.12 |
Case 7 — E6 200,000 profit with salary income elsewhere: no 60,000 deduction or insurance here, 29,500 halved to 14,750
given profitAnnual | 200000 |
|---|---|
given socialInsurance | beijing |
given contributionBase | 7270 |
given hasSalary | yes |
expect taxableIncome | 200000 |
expect taxBeforeRelief | 29500 |
expect halvingRelief | 14750 |
expect incomeTax | 14750 |
expect netIncome | 159805.44 |
Sources
- Individual Income Tax Law of the PRC (个人所得税法, seventh amendment 2018, 全文有效): art. 6(3) and Schedule 2, the 5–35% business-income table · checked 2026-10-31
- Regulations for the Implementation of the IIT Law (个人所得税法实施条例, State Council 2018, 有效 on the national law database), art. 15: a business-income earner with no comprehensive income deducts 60,000 yuan, special deductions and special additional deductions · checked 2026-10-31
- State Taxation Administration Announcement 2023 No. 12 (全文有效): individual businesses’ taxable income up to 2 million yuan is taxed at half, 2023-01-01 to 2027-12-31, with the relief formula · checked 2026-10-31
- STA 解读 of Announcement 2023 No. 12, part 7: the relief formula and worked examples 2–3 · checked 2026-10-31
- Beijing HRSS Bureau et al., 京人社发〔2026〕7号 (20 Aug 2026): people insured in their own name choose a base between 7,270 and 36,348 yuan and pay 7,269.6 / 363.48 yuan of pension / unemployment at the upper limit and 1,454 / 72.7 at the lower (20% and 1%), and 593.68 yuan a month of medical insurance · checked 2026-10-31
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 个体工商户 (individual business) calculator
Built with Valem — a live, verifiable calculator you can fork and embed.