category = 'smallScale' and $n(monthlySales) < $const.monthlyThreshold
VAT withheld and remitted by the buyer
withheldVat
reverseCharge ? $round(netAmount * rate, 2) : 0
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
standardRate
0.13
reducedRate1
0.09
reducedRate2
0.06
zeroRate
0
simplifiedRate
0.03
smallScaleReducedRate
0.01
registrationThreshold
5000000
monthlyThreshold
100000
Test vectors (12)
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 — V1 1,000 yuan of goods at 13%
given amount
1000
given direction
add
given category
standard
given reverseCharge
no
given annualTurnover
0
given monthlySales
100000
expect vatAmount
130
expect grossAmount
1130
expect netAmount
1000
Case 2 — V2 1,130 yuan gross back to net at 13%
given amount
1130
given direction
remove
given category
standard
given reverseCharge
no
given annualTurnover
0
given monthlySales
100000
expect netAmount
1000
expect vatAmount
130
Case 3 — V3 construction at 9%
given amount
1000
given direction
add
given category
reduced1
given reverseCharge
no
given annualTurnover
0
given monthlySales
100000
expect vatAmount
90
expect grossAmount
1090
Case 4 — V4 consulting at 6%
given amount
1000
given direction
add
given category
reduced2
given reverseCharge
no
given annualTurnover
0
given monthlySales
100000
expect vatAmount
60
expect grossAmount
1060
Case 5 — V5 small-scale taxpayer at the 2026 1% rate
given amount
1000
given direction
add
given category
smallScale
given reverseCharge
no
given annualTurnover
0
given monthlySales
100000
expect vatAmount
10
expect grossAmount
1010
Case 6 — V6 exported goods are zero-rated
given amount
1000
given direction
add
given category
zero
given reverseCharge
no
given annualTurnover
0
given monthlySales
100000
expect vatAmount
0
expect grossAmount
1000
Case 7 — V7 3% simplified levy rate
given amount
1000
given direction
add
given category
simplified
given reverseCharge
no
given annualTurnover
0
given monthlySales
100000
expect vatAmount
30
Case 8 — V8 overseas seller: the buyer withholds 130 at the rate; the seller charges none
given amount
1000
given direction
add
given category
standard
given reverseCharge
yes
given annualTurnover
0
given monthlySales
100000
expect vatAmount
0
expect grossAmount
1000
expect withheldVat
130
Case 9 — V9 exactly 5 million yuan is still small-scale (“未超过五百万元”)
given amount
100
given direction
add
given category
standard
given reverseCharge
no
given annualTurnover
5000000
given monthlySales
100000
expect mustRegister
false
Case 10 — V10 above 5 million yuan: general taxpayer
given amount
100
given direction
add
given category
standard
given reverseCharge
no
given annualTurnover
6000000
given monthlySales
100000
expect mustRegister
true
Case 11 — V11 small-scale, monthly sales of 99,999 do not reach the threshold (“未达到起征点”): no VAT
given amount
1000
given direction
add
given category
smallScale
given reverseCharge
no
given annualTurnover
0
given monthlySales
99999
expect belowThreshold
true
expect vatAmount
0
expect grossAmount
1000
Case 12 — V12 small-scale, monthly sales of exactly 100,000 reach it: 1% on the whole amount
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.