Nigerian tax compliance SDK — VAT, PAYE, WHT, Pension, Payroll, Invoicing. NTA 2025 compliant.
Project description
ngtaxkit
Nigerian tax compliance SDK for Python. Implements the Nigeria Tax Act (NTA) 2025 — VAT, PAYE, WHT, Pension, Statutory deductions, Marketplace transactions, and Payroll batch processing.
Zero dependencies. Pure functions. Deterministic output. Python 3.10+.
Install
pip install ngtaxkit
Optional extras:
pip install ngtaxkit[pdf] # PDF generation (fpdf2)
pip install ngtaxkit[cloud] # Cloud API client (httpx)
Quick Start
from ngtaxkit import vat, paye, wht, pension, payroll
# ─── VAT ────────────────────────────────────────────────────────────────────
# Calculate VAT on an amount
result = vat.calculate(amount=100_000)
# → {'net': 100000, 'vat': 7500, 'gross': 107500, 'rate': 0.075, 'rate_type': 'standard', ...}
# Extract VAT from an inclusive amount
result = vat.extract(amount=107_500)
# → {'net': 100000, 'vat': 7500, 'gross': 107500, ...}
# Zero-rated categories
result = vat.calculate(amount=50_000, category='basic-food')
# → {'vat': 0, 'rate': 0, 'rate_type': 'zero-rated', 'input_vat_recoverable': True, ...}
# Exempt categories
result = vat.calculate(amount=200_000, category='residential-rent')
# → {'vat': 0, 'rate_type': 'exempt', 'input_vat_recoverable': False, ...}
# ─── PAYE ───────────────────────────────────────────────────────────────────
result = paye.calculate(
gross_annual=5_000_000,
pension_contributing=True,
nhf_contributing=True,
rent_paid_annual=600_000,
)
# → {
# 'annual_paye': ...,
# 'monthly_paye': ...,
# 'effective_rate': ...,
# 'tax_bands': [...],
# 'reliefs': {'consolidated_relief', 'pension_relief', 'nhf_relief', 'rent_relief', 'total'},
# 'net_monthly': ...,
# 'monthly_deductions': {'paye', 'pension', 'nhf', 'total'},
# 'employer_costs': {'pension', 'nsitf', 'itf', 'total'},
# 'legal_basis': '...',
# }
# ─── WHT ────────────────────────────────────────────────────────────────────
result = wht.calculate(
amount=500_000,
payee_type='company',
service_type='professional',
)
# → {
# 'wht_amount': 50000,
# 'rate': 0.1,
# 'net_payment': 450000,
# 'credit_note_required': True,
# 'remittance_deadline': '2026-05-21',
# }
# ─── Pension ────────────────────────────────────────────────────────────────
result = pension.calculate(
basic_salary=300_000,
housing_allowance=100_000,
transport_allowance=50_000,
)
# → {
# 'pensionable_earnings': 450000,
# 'employee_contribution': 36000,
# 'employer_contribution': 45000,
# 'total_contribution': 81000,
# }
# ─── Payroll (batch) ────────────────────────────────────────────────────────
result = payroll.calculate_batch([
{'name': 'Amina', 'gross_annual': 4_000_000, 'state_of_residence': 'LA', 'pension_contributing': True},
{'name': 'Chidi', 'gross_annual': 8_000_000, 'state_of_residence': 'FC', 'pension_contributing': True},
{'name': 'Bola', 'gross_annual': 2_400_000, 'state_of_residence': 'LA', 'nhf_contributing': True},
])
# → {
# 'employees': [...],
# 'by_state': {
# 'LA': {'state_name': 'Lagos', 'irs_name': 'LIRS', 'employee_count': 2, ...},
# 'FC': {'state_name': 'FCT', 'irs_name': 'FCT-IRS', 'employee_count': 1, ...},
# },
# 'totals': {'total_gross', 'total_paye', 'total_pension', 'total_nhf', 'employee_count'},
# }
Modules
| Module | Description |
|---|---|
vat |
VAT calculation, extraction, category classification |
paye |
PAYE income tax with NTA 2025 graduated brackets and reliefs |
wht |
Withholding tax by service type and payee type |
pension |
Contributory Pension Scheme — employee/employer splits |
statutory |
NHF, NSITF, ITF statutory deductions |
marketplace |
End-to-end marketplace transaction: VAT + commission + WHT + payout |
payroll |
Batch payroll with per-state aggregation and filing info |
rates |
Versioned rate registry — all rates, brackets, and thresholds |
Statutory Deductions
from ngtaxkit import statutory
# Individual deductions
nhf = statutory.nhf(basic_salary=300_000)
nsitf = statutory.nsitf(monthly_payroll=5_000_000)
itf = statutory.itf(annual_payroll=60_000_000, employee_count=25)
# All at once
all_deductions = statutory.calculate_all(
basic_salary=300_000,
monthly_payroll=5_000_000,
annual_payroll=60_000_000,
employee_count=25,
)
Marketplace Transactions
from ngtaxkit import marketplace
result = marketplace.calculate_transaction(
sale_amount=100_000,
platform_commission=0.10, # 10% commission
seller_vat_registered=True,
buyer_type='individual',
service_category='standard',
)
# → {
# 'sale_amount': 100000,
# 'vat': {'net': 100000, 'vat': 7500, ...},
# 'total_from_buyer': 107500,
# 'platform_commission': {'rate': 0.1, 'amount': 10000, ...},
# 'seller_payout': ...,
# 'wht': {...} or None,
# 'vat_liability': {'collected_by': 'seller', 'amount': 7500, ...},
# }
VAT Categories
| Category | Rate | Type | Input VAT Recoverable |
|---|---|---|---|
standard |
7.5% | Standard | Yes |
basic-food |
0% | Zero-rated | Yes |
medicine |
0% | Zero-rated | Yes |
medical-equipment |
0% | Zero-rated | Yes |
medical-services |
0% | Zero-rated | Yes |
educational-books |
0% | Zero-rated | Yes |
tuition |
0% | Zero-rated | Yes |
electricity |
0% | Zero-rated | Yes |
export-services |
0% | Zero-rated | Yes |
humanitarian-goods |
0% | Zero-rated | Yes |
residential-rent |
0% | Exempt | No |
public-transport |
0% | Exempt | No |
financial-services |
0% | Exempt | No |
insurance |
0% | Exempt | No |
Key Design Decisions
- Banker's rounding — all monetary values use round-half-even to 2 decimal places (Python's
ROUND_HALF_EVEN) - Legal citations — every result includes a
legal_basisstring citing the NTA 2025 section - Versioned rates — bundled as JSON; override at runtime via
rates.set_custom() - Cross-language parity — produces identical results to the TypeScript version, enforced by shared test fixtures
- Type hints — full
py.typedsupport with strict mypy compliance
Framework Integrations
Django
# settings.py
INSTALLED_APPS = [..., 'ngtaxkit.contrib.django']
# models.py
from ngtaxkit.contrib.django import TINField, NairaField, VATCategoryField
class Invoice(models.Model):
seller_tin = TINField()
amount = NairaField()
category = VATCategoryField()
# templates
{% load ngtaxkit_tags %}
{{ amount|naira }} {# NGN 1,234,567.89 #}
{{ amount|vat_amount }} {# NGN 92,592.59 #}
{% vat_rate "standard" %} {# 7.5% #}
Flask
from ngtaxkit.contrib.flask import init_app
app = Flask(__name__)
init_app(app) # Registers /tax/vat/calculate, /tax/paye/calculate, /tax/wht/calculate + Jinja filters
# In templates
{{ amount|naira }}
{{ amount|vat }}
FastAPI
from ngtaxkit.contrib.fastapi import create_router
app = FastAPI()
app.include_router(create_router(), prefix="/api")
# Adds /api/tax/vat/calculate, /api/tax/paye/calculate, etc. with Pydantic validation
Install extras:
pip install ngtaxkit[django] # Django fields + template tags
pip install ngtaxkit[flask] # Flask blueprint + Jinja filters
pip install ngtaxkit[fastapi] # FastAPI router + Pydantic models
License
MIT — see LICENSE
Author
Abraham Tanta
Links
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ngtaxkit-0.0.5.tar.gz.
File metadata
- Download URL: ngtaxkit-0.0.5.tar.gz
- Upload date:
- Size: 39.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2b07248da175000ac72785d71e5536142374420d0c6c103baee95a9e95b522f4
|
|
| MD5 |
c726302627bc877edf25e323d1a205af
|
|
| BLAKE2b-256 |
35a266a2b0d2a76977e082760b895d1ee2a07f79daea89541435b221c7045c5a
|
Provenance
The following attestation bundles were made for ngtaxkit-0.0.5.tar.gz:
Publisher:
pypi-publish.yml on mr-tanta/ngtaxkit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ngtaxkit-0.0.5.tar.gz -
Subject digest:
2b07248da175000ac72785d71e5536142374420d0c6c103baee95a9e95b522f4 - Sigstore transparency entry: 1245355823
- Sigstore integration time:
-
Permalink:
mr-tanta/ngtaxkit@50e51b15efeffb9419f2a9212b58aa3a43f49988 -
Branch / Tag:
refs/tags/v0.0.5 - Owner: https://github.com/mr-tanta
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@50e51b15efeffb9419f2a9212b58aa3a43f49988 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ngtaxkit-0.0.5-py3-none-any.whl.
File metadata
- Download URL: ngtaxkit-0.0.5-py3-none-any.whl
- Upload date:
- Size: 42.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b14eb261194b0bdcf76de22fa851b35caeb659f7aa5f0ed9c093d05d285b88c3
|
|
| MD5 |
e77173569691aa8da67725a82caf0c39
|
|
| BLAKE2b-256 |
63962bd1675cbe3be35ae613b5ecaf06cf5ced74258cd530fcf13a0031fa7de6
|
Provenance
The following attestation bundles were made for ngtaxkit-0.0.5-py3-none-any.whl:
Publisher:
pypi-publish.yml on mr-tanta/ngtaxkit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ngtaxkit-0.0.5-py3-none-any.whl -
Subject digest:
b14eb261194b0bdcf76de22fa851b35caeb659f7aa5f0ed9c093d05d285b88c3 - Sigstore transparency entry: 1245355844
- Sigstore integration time:
-
Permalink:
mr-tanta/ngtaxkit@50e51b15efeffb9419f2a9212b58aa3a43f49988 -
Branch / Tag:
refs/tags/v0.0.5 - Owner: https://github.com/mr-tanta
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@50e51b15efeffb9419f2a9212b58aa3a43f49988 -
Trigger Event:
push
-
Statement type: