How the China 增值税 (VAT) calculator is verified

Inputs

InputFieldType
Amount (CNY)amountnumber
This amount isdirectionstring
What is being soldcategorystring
Annual taxable sales (CNY)annualTurnovernumber
Monthly sales (CNY) — small-scale taxpayersmonthlySalesnumber
Overseas seller — the Chinese buyer withholds the VATreverseChargeboolean

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)
Rateratecategory = 'reduced1' ? $const.reducedRate1 : (category = 'reduced2' ? $const.reducedRate2 : (category = 'zero' ? $const.zeroRate : (category = 'simplified' ? $const.simplifiedRate : (category = 'smallScale' ? $const.smallScaleReducedRate : $const.standardRate))))
Effective RateeffectiveRatereverseCharge or belowThreshold ? 0 : rate
NetnetAmountdirection = 'remove' ? $round(amount / (1 + effectiveRate), 2) : $round(amount, 2)
VAT charged by the sellervatAmount$round(netAmount * effectiveRate, 2)
GrossgrossAmount$round(netAmount + vatAmount, 2)
Must RegistermustRegisterannualTurnover > $const.registrationThreshold
Below ThresholdbelowThresholdcategory = 'smallScale' and $n(monthlySales) < $const.monthlyThreshold
VAT withheld and remitted by the buyerwithheldVatreverseCharge ? $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.

ConstantValue
standardRate0.13
reducedRate10.09
reducedRate20.06
zeroRate0
simplifiedRate0.03
smallScaleReducedRate0.01
registrationThreshold5000000
monthlyThreshold100000

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 amount1000
given directionadd
given categorystandard
given reverseChargeno
given annualTurnover0
given monthlySales100000
expect vatAmount130
expect grossAmount1130
expect netAmount1000

Case 2 — V2 1,130 yuan gross back to net at 13%

given amount1130
given directionremove
given categorystandard
given reverseChargeno
given annualTurnover0
given monthlySales100000
expect netAmount1000
expect vatAmount130

Case 3 — V3 construction at 9%

given amount1000
given directionadd
given categoryreduced1
given reverseChargeno
given annualTurnover0
given monthlySales100000
expect vatAmount90
expect grossAmount1090

Case 4 — V4 consulting at 6%

given amount1000
given directionadd
given categoryreduced2
given reverseChargeno
given annualTurnover0
given monthlySales100000
expect vatAmount60
expect grossAmount1060

Case 5 — V5 small-scale taxpayer at the 2026 1% rate

given amount1000
given directionadd
given categorysmallScale
given reverseChargeno
given annualTurnover0
given monthlySales100000
expect vatAmount10
expect grossAmount1010

Case 6 — V6 exported goods are zero-rated

given amount1000
given directionadd
given categoryzero
given reverseChargeno
given annualTurnover0
given monthlySales100000
expect vatAmount0
expect grossAmount1000

Case 7 — V7 3% simplified levy rate

given amount1000
given directionadd
given categorysimplified
given reverseChargeno
given annualTurnover0
given monthlySales100000
expect vatAmount30

Case 8 — V8 overseas seller: the buyer withholds 130 at the rate; the seller charges none

given amount1000
given directionadd
given categorystandard
given reverseChargeyes
given annualTurnover0
given monthlySales100000
expect vatAmount0
expect grossAmount1000
expect withheldVat130

Case 9 — V9 exactly 5 million yuan is still small-scale (“未超过五百万元”)

given amount100
given directionadd
given categorystandard
given reverseChargeno
given annualTurnover5000000
given monthlySales100000
expect mustRegisterfalse

Case 10 — V10 above 5 million yuan: general taxpayer

given amount100
given directionadd
given categorystandard
given reverseChargeno
given annualTurnover6000000
given monthlySales100000
expect mustRegistertrue

Case 11 — V11 small-scale, monthly sales of 99,999 do not reach the threshold (“未达到起征点”): no VAT

given amount1000
given directionadd
given categorysmallScale
given reverseChargeno
given annualTurnover0
given monthlySales99999
expect belowThresholdtrue
expect vatAmount0
expect grossAmount1000

Case 12 — V12 small-scale, monthly sales of exactly 100,000 reach it: 1% on the whole amount

given amount1000
given directionadd
given categorysmallScale
given reverseChargeno
given annualTurnover0
given monthlySales100000
expect belowThresholdfalse
expect vatAmount10
expect grossAmount1010

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 增值税 (VAT) calculator

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