How the Bangladesh ব্যবসার আয়কর (business income tax) calculator is verified
Inputs
| Input | Field | Type |
|---|---|---|
| Gross receipts for the year (BDT) | annualTurnover | number |
| Allowable business expenses (BDT) | annualExpenses | number |
| Your tax-free threshold group | taxpayerCategory | string |
| Children or dependants with a disability | disabledChildren | number |
| First return (new taxpayer: minimum tax ৳1,000) | newTaxpayer | boolean |
| All of it is ICT or freelancing income received by bank transfer (Sixth Schedule para 21, to 30 June 2027) | ictExempt | 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) |
|---|---|---|
| Business income (receipts − expenses) | taxableIncome | $round($max([0, $n(annualTurnover) - $n(annualExpenses)]), 2) |
| Tax-free threshold | taxFreeThreshold | ($c := taxpayerCategory; $c = 'womanOrSenior' ? $const.taxFreeWomanSenior : ($c = 'disabledOrThirdGender' ? $const.taxFreeDisabledThirdGender : ($c = 'warWounded' ? $const.taxFreeWarWounded : $const.taxFreeGeneral))) + $n(disabledChildren) * $const.disabledChildAddOn |
| Tax at the Schedule 2 rates | slabTax | ictExempt ? 0 : ($t := taxFreeThreshold; $w1 := $t + $const.bandWidth1; $w2 := $w1 + $const.bandWidth2; $w3 := $w2 + $const.bandWidth3; $w4 := $w3 + $const.bandWidth4; $round($bandedCharge(taxableIncome, [{"upTo": $t, "rate": $const.rate0}, {"upTo": $w1, "rate": $const.rate1}, {"upTo": $w2, "rate": $const.rate2}, {"upTo": $w3, "rate": $const.rate3}, {"upTo": $w4, "rate": $const.rate4}, {"upTo": null, "rate": $const.rate5}]), 2)) |
| Turnover tax: 1% of receipts | turnoverTax | ictExempt ? 0 : $round($n(annualTurnover) * $const.turnoverTaxRate, 2) |
| Regular Tax | regularTax | (ictExempt or taxableIncome <= taxFreeThreshold) ? 0 : $round($max([slabTax, newTaxpayer ? $const.minimumTaxNewTaxpayer : $const.minimumTax]), 2) |
| Income tax | incomeTax | $round($max([regularTax, turnoverTax]), 2) |
| Turnover tax above the ordinary tax, carried forward | turnoverTaxCarryForward | $round($max([0, turnoverTax - regularTax]), 2) |
| Profit after tax (৳0 at a loss) | netIncome | $round($max([0, taxableIncome - 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 |
|---|---|
taxFreeGeneral | 400000 |
taxFreeWomanSenior | 450000 |
taxFreeDisabledThirdGender | 525000 |
taxFreeWarWounded | 550000 |
bandWidth1 | 300000 |
bandWidth2 | 400000 |
bandWidth3 | 500000 |
bandWidth4 | 2000000 |
rate0 | 0 |
rate1 | 0.1 |
rate2 | 0.15 |
rate3 | 0.2 |
rate4 | 0.25 |
rate5 | 0.3 |
minimumTax | 5000 |
minimumTaxNewTaxpayer | 1000 |
disabledChildAddOn | 50000 |
turnoverTaxRate | 0.01 |
Test vectors (11)
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 — S1 ৳30 lakh receipts, ৳18 lakh expenses: ৳12 lakh profit, tax ৳30,000 + ৳60,000 + ৳20,000
given annualTurnover | 3000000 |
|---|---|
given annualExpenses | 1800000 |
given taxpayerCategory | general |
given disabledChildren | 0 |
given newTaxpayer | no |
given ictExempt | no |
expect taxableIncome | 1200000 |
expect slabTax | 110000 |
expect turnoverTax | 30000 |
expect incomeTax | 110000 |
expect netIncome | 1090000 |
Case 2 — S2 thin margin: ৳1 crore receipts, ৳5 lakh profit, turnover tax ৳1,00,000 exceeds ৳10,000
given annualTurnover | 10000000 |
|---|---|
given annualExpenses | 9500000 |
given taxpayerCategory | general |
given disabledChildren | 0 |
given newTaxpayer | no |
given ictExempt | no |
expect slabTax | 10000 |
expect turnoverTax | 100000 |
expect incomeTax | 100000 |
expect turnoverTaxCarryForward | 90000 |
expect netIncome | 400000 |
Case 3 — S3 profit below the threshold: turnover tax ৳10,000 still due
given annualTurnover | 1000000 |
|---|---|
given annualExpenses | 700000 |
given taxpayerCategory | general |
given disabledChildren | 0 |
given newTaxpayer | no |
given ictExempt | no |
expect taxableIncome | 300000 |
expect slabTax | 0 |
expect regularTax | 0 |
expect incomeTax | 10000 |
expect turnoverTaxCarryForward | 10000 |
Case 4 — S4 a loss: turnover tax applies regardless; profit after tax floored at 0
given annualTurnover | 2000000 |
|---|---|
given annualExpenses | 2500000 |
given taxpayerCategory | general |
given disabledChildren | 0 |
given newTaxpayer | no |
given ictExempt | no |
expect taxableIncome | 0 |
expect incomeTax | 20000 |
expect netIncome | 0 |
Case 5 — S5 ৳4,20,000 profit on ৳4,50,000 receipts: ৳2,000 lifted to the ৳5,000 minimum
given annualTurnover | 450000 |
|---|---|
given annualExpenses | 30000 |
given taxpayerCategory | general |
given disabledChildren | 0 |
given newTaxpayer | no |
given ictExempt | no |
expect slabTax | 2000 |
expect turnoverTax | 4500 |
expect incomeTax | 5000 |
Case 6 — S6 same as a new taxpayer: turnover tax ৳4,500 exceeds the ৳2,000 and the ৳1,000 minimum
given annualTurnover | 450000 |
|---|---|
given annualExpenses | 30000 |
given taxpayerCategory | general |
given disabledChildren | 0 |
given newTaxpayer | yes |
given ictExempt | no |
expect incomeTax | 4500 |
Case 7 — S7 woman or 65+: threshold ৳4,50,000, tax ৳1,00,000
given annualTurnover | 3000000 |
|---|---|
given annualExpenses | 1800000 |
given taxpayerCategory | womanOrSenior |
given disabledChildren | 0 |
given newTaxpayer | no |
given ictExempt | no |
expect taxFreeThreshold | 450000 |
expect incomeTax | 100000 |
Case 8 — S8 ৳1 crore profit: ৳6,90,000 + 30% of ৳64,00,000
given annualTurnover | 50000000 |
|---|---|
given annualExpenses | 40000000 |
given taxpayerCategory | general |
given disabledChildren | 0 |
given newTaxpayer | no |
given ictExempt | no |
expect slabTax | 2610000 |
expect incomeTax | 2610000 |
expect netIncome | 7390000 |
Case 9 — S9 ICT or freelancing income received by bank transfer: exempt, no turnover tax (para 21)
given annualTurnover | 3000000 |
|---|---|
given annualExpenses | 1800000 |
given taxpayerCategory | general |
given disabledChildren | 0 |
given newTaxpayer | no |
given ictExempt | yes |
expect slabTax | 0 |
expect turnoverTax | 0 |
expect incomeTax | 0 |
expect netIncome | 1200000 |
Case 10 — S10 two disabled children: threshold ৳5,00,000, tax ৳30,000 + ৳60,000
given annualTurnover | 3000000 |
|---|---|
given annualExpenses | 1800000 |
given taxpayerCategory | general |
given disabledChildren | 2 |
given newTaxpayer | no |
given ictExempt | no |
expect taxFreeThreshold | 500000 |
expect incomeTax | 90000 |
Case 11 — S11 default: the ordinary tax exceeds the turnover tax, nothing carried forward
given annualTurnover | 3000000 |
|---|---|
given annualExpenses | 1800000 |
given taxpayerCategory | general |
given disabledChildren | 0 |
given newTaxpayer | no |
given ictExempt | no |
expect regularTax | 110000 |
expect turnoverTaxCarryForward | 0 |
Sources
- Finance Act 2026 (Act 96), s.160 and Schedule 2 Part 1 para (ক): 2026-27 and 2027-28 rates · checked 2026-11-01
- ITA 2023 Sixth Schedule Pt 1 para 21: ICT and freelancing exempt (Act 96 s.157(খ)) · checked 2026-11-01
- Income Tax Act 2023 s.163(6) turnover tax (substituted by the Finance Act 2026, s.91) · checked 2026-11-01
- Finance Act 2026, Bangladesh Gazette 30 June 2026 (NBR copy) · checked 2026-11-01
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 Bangladesh ব্যবসার আয়কর (business income tax) calculator
Built with Valem — a live, verifiable calculator you can fork and embed.