The Modern Python Library for ZIMRA Fiscal Device Integration
FiscGuy gives Django applications a simple, Pythonic interface for every fiscal operation required by the Zimbabwe Revenue Authority — receipt submission, fiscal day management, certificate handling, and more. Built on Django REST Framework, it drops into any Django project in minutes.
Installation · Quick Start · API Reference · REST Endpoints · Full Documentation · Contributing
- Seven core API functions —
open_day,close_day,submit_receipt,get_status,get_configuration,get_taxes,get_buyer - Full fiscal day lifecycle — open, manage counters, close with ZIMRA-compliant hash and signature
- Receipt types — Fiscal Invoice, Credit Note, Debit Note with correct counter tracking
- Offline resilience — receipts queued locally when FDMS is unreachable, synced automatically on reconnect
- Certificate management — CSR generation, device registration, certificate renewal via
init_device - Multi-currency — USD and ZWG support with per-currency counter tracking
- Multiple payment methods — Cash, Card, Mobile Wallet, Bank Transfer, Coupon, Credit, Other
- Buyer management — optional buyer TIN and registration data on receipts
- Cursor pagination — efficient receipt listing for large datasets
- Typed exceptions — every error condition has its own exception class
- 90%+ test coverage — mocked ZIMRA and crypto, fast CI
- Python 3.11, 3.12, or 3.13
- Django 4.2+
- Django REST Framework 3.14+
pip install fiscguygit clone https://github.com/digitaltouchcode/fisc.git
cd fisc
pip install -e ".[dev]"# settings.py
INSTALLED_APPS = [
# ...
"fiscguy",
"rest_framework",
]python manage.py migratepython manage.py init_deviceThis interactive command collects your device credentials, generates a CSR, registers the device with ZIMRA, and fetches taxes and configuration automatically.
# urls.py
from django.urls import path, include
urlpatterns = [
path("fiscguy/", include("fiscguy.urls")),
]from fiscguy import open_day, submit_receipt, close_day
open_day()
receipt = submit_receipt({
"receipt_type": "fiscalinvoice",
"currency": "USD",
"total_amount": "115.00",
"payment_terms": "Cash",
"lines": [
{
"product": "Consulting Service",
"quantity": "1",
"unit_price": "115.00",
"line_total": "115.00",
"tax_amount": "15.00",
"tax_name": "standard rated 15%",
}
],
})
close_day()--
When URLs are included, FiscGuy exposes the following endpoints:
| Method | Endpoint | Description |
|---|---|---|
POST |
/fiscguy/open-day/ |
Open a new fiscal day |
POST |
/fiscguy/close-day/ |
Close the current fiscal day |
GET |
/fiscguy/get-status/ |
Get device and fiscal day status |
POST |
/fiscguy/get-ping/ |
Ping FDMS to report device is online |
GET |
/fiscguy/receipts/ |
List receipts (cursor paginated) |
POST |
/fiscguy/receipts/ |
Submit a new receipt |
GET |
/fiscguy/receipts/{id}/ |
Retrieve a receipt by ID |
GET |
/fiscguy/configuration/ |
Get taxpayer configuration |
POST |
/fiscguy/sync-config/ |
Manually sync configuration from FDMS |
GET |
/fiscguy/taxes/ |
List all tax types |
POST |
/fiscguy/issue-certificate/ |
Renew device certificate |
* |
/fiscguy/buyer/ |
Buyer CRUD (ModelViewSet) |
Receipt listing supports cursor-based pagination:
GET /fiscguy/receipts/?page_size=20
Default page size: 10. Maximum: 100.
All operations raise typed exceptions. Import them from fiscguy.exceptions:
from fiscguy.exceptions import (
ReceiptSubmissionError,
CloseDayError,
FiscalDayError,
ConfigurationError,
CertificateError,
DevicePingError,
StatusError,
)
try:
close_day()
except CloseDayError as e:
print(f"Close day failed: {e}")| Exception | Raised when |
|---|---|
ReceiptSubmissionError |
Receipt processing or FDMS submission fails |
CloseDayError |
FDMS rejects the close day request |
FiscalDayError |
Fiscal day cannot be opened or is already open |
ConfigurationError |
Configuration is missing or sync fails |
CertificateError |
Certificate issuance or renewal fails |
DevicePingError |
Ping to FDMS fails |
StatusError |
Status fetch from FDMS fails |
DeviceRegistrationError |
Device registration with ZIMRA fails |
CryptoError |
RSA signing or hashing fails |
FiscGuy adds the following tables to your database:
| Model | Description |
|---|---|
Device |
Fiscal device registration details |
Configuration |
Taxpayer configuration synced from FDMS |
Certs |
Device certificate and private key |
Taxes |
Tax types synced from FDMS on day open |
FiscalDay |
Daily fiscal period with receipt counter |
FiscalCounter |
Running totals per tax / payment method |
Receipt |
Submitted receipts with hash, signature, QR code |
ReceiptLine |
Individual line items on a receipt |
Buyer |
Optional buyer registration data |
Access them directly:
from fiscguy.models import Device, Receipt, FiscalDay, Taxes
device = Device.objects.first()
open_days = FiscalDay.objects.filter(is_open=True)
receipts = Receipt.objects.select_related("buyer").prefetch_related("lines")Interactive device setup — run once per device:
python manage.py init_deviceThe command will:
- Prompt for
org_name,activation_key,device_id,device_model_name,device_model_version,device_serial_number - Ask whether to use production or testing FDMS
- Generate an RSA key pair and CSR
- Register the device with ZIMRA to obtain a signed certificate
- Fetch and persist configuration and taxes
# Run all tests
pytest
# With coverage report
pytest --cov=fiscguy --cov-report=html
# Run a specific test file
pytest fiscguy/tests/test_views.py
# Run a specific test
pytest fiscguy/tests/test_closing_day_service.py::TestBuildSaleByTaxAll tests mock ZIMRA API calls and crypto operations — no network access required.
Our comprehensive documentation covers everything you need to know:
- Installation Guide - Detailed setup instructions
- Receipt Types - Fiscal Invoice, Credit Note, Debit Note rules
- Fiscal Counters - Counter tracking and calculations
- Closing Day - Hash string and signature specifications
- Certificate Management - Certificate lifecycle and renewal
- Error Reference - All exceptions and troubleshooting
This documentation is automatically deployed to GitHub Pages when you push to the main branch.
No local scripts needed - GitHub Actions handles everything automatically!
| Document | Description |
|---|---|
| Installation | Detailed installation and setup guide |
| Receipt Types | Fiscal Invoice, Credit Note, Debit Note rules |
| Fiscal Counters | How counters work and how they are calculated |
| Closing Day | Closing day hash string and signature spec |
| Certificate Management | Certificate lifecycle and renewal |
| Error Reference | All exceptions and what causes them |
| Changelog | Version history |
| Contributing | Contributing guidelines |
Contributions are welcome. Please read CONTRIBUTING.md first.
# Set up dev environment
git clone https://github.com/digitaltouchcode/fisc.git
cd fisc
pip install -e ".[dev]"
pre-commit install
# Before submitting a PR
black fiscguy
isort fiscguy
flake8 fiscguy
pytestMIT — see LICENSE.