Skip to main content

ZIMRA Fiscal Device Integration Library - Simple and Pythonic API for ZIMRA fiscal device operations

Project description

Fiscguy

A Python library for integrating with ZIMRA (Zimbabwe Revenue Authority) fiscal devices. Provides a simple, Pythonic API for managing fiscal operations including device registration, receipt generation, and fiscal day management.

Features

  • Secure Device Integration - Certificate-based authentication with ZIMRA FDMS
  • Receipt Management - Create and submit receipts with multiple tax types
  • Fiscal Day Operations - Open and close fiscal days with automatic counter management
  • Device Status - Query device status and configuration
  • Configuration Management - Fetch and manage device configuration
  • Tax Support - Supports standard, zero-rated, exempt, and withholding taxes
  • Fully Tested - Comprehensive unit tests with 90%+ code coverage

Installation

pip install fiscguy

Or from source:

git clone https://github.com/cassymyo-spec/zimra.git
cd zimra
pip install -e .

Quick Start

Important: Register a Device First

Before using Fiscguy, you must register and initialize a fiscal device:

python manage.py init_device

This interactive command will guide you through:

  • Device information entry
  • Certificate generation
  • Device registration with ZIMRA
  • Configuration and tax synchronization

Important: Environment Switching

When running python manage.py init_device:

If switching FROM TEST TO PRODUCTION:

  • Safe to proceed - All test data will be automatically deleted
  • The command will warn you and require confirmation (YES)
  • All the following test data will be permanently deleted:
    • Fiscal Days
    • Fiscal Counters
    • Receipts & Receipt Lines
    • Device Configuration
    • Certificates
    • Device record itself
    • Taxes

If switching FROM PRODUCTION TO TEST:

  • NOT ADVISABLE - This will delete your production records
  • Only do this if you're absolutely sure you want to lose all production data
  • The command will warn you and require confirmation (YES)

How to switch safely:

  1. Run python manage.py init_device
  2. Answer the environment question (yes=production, no=test)
  3. If different from current environment, you'll see a warning
  4. Review the warning carefully
  5. Type YES to confirm deletion and switch

Using the Library

Once your device is registered, you can use the library:

from fiscguy import (
    open_day,
    close_day,
    submit_receipt,
    get_status,
    get_configuration,
    get_taxes,
)

# Check device status
status = get_status()
print(f"Device: {status['device_id']}, Counter: {status['counter']}")

# Open a fiscal day
result = open_day()
print(f"Day opened: {result['fiscal_day_number']}")

# Submit a receipt
receipt_data = {
    "receipt_type": "fiscalinvoice",
    "currency": "USD",
    "total_amount": "100.00",
    "payment_terms": "cash",
    "lines": [
        {
            "product": "Test Item",
            "quantity": "1",
            "unit_price": "100.00",
            "line_total": "100.00",
            "tax_amount": "15.50",
            "tax_name": "standard rated 15.5%",
        }
    ],
    "buyer": 1,
}

result = submit_receipt(receipt_data)
print(f"Receipt submitted: {result['receiptID']}")

# Close the fiscal day
result = close_day()
print(f"Day closed, signature: {result['signature'][:20]}...")

API Reference

open_day() -> Dict[str, Any]

Open a new fiscal day.

Returns:

  • fiscal_day_number: The fiscal day number
  • fiscal_day_date: The date the day was opened (ISO format)
  • message: Status message (if day already open)

Raises:

  • RuntimeError: If no device is registered

close_day() -> Dict[str, Any]

Close the currently open fiscal day.

Returns:

  • signature: Device signature for the fiscal day
  • closing_string: Raw closing day string

Raises:

  • RuntimeError: If no device or no open fiscal day exists

submit_receipt(receipt_data: Dict[str, Any]) -> Dict[str, Any]

Create and submit a receipt to ZIMRA.

Parameters:

  • receipt_data: Receipt dictionary with required fields:
    • receipt_type: "fiscalinvoice" or "creditnote"
    • currency: "USD", "ZWL", etc.
    • total_amount: Total amount (string or Decimal)
    • payment_terms: "cash", "cheque", "card", etc.
    • lines: List of line items
    • buyer: Buyer ID (integer)

Line Item Structure:

{
    "product": "Product name",
    "quantity": "1",
    "unit_price": "100.00",
    "line_total": "100.00",
    "tax_amount": "15.50",
    "tax_name": "standard rated 15.5%",
}

Returns:

  • receiptID: ZIMRA receipt ID
  • receipt_data: Full receipt data

Raises:

  • ValidationError: If tax_name doesn't match any database tax
  • RuntimeError: If submission to ZIMRA fails

get_status() -> Dict[str, Any]

Get current device and fiscal status.

Returns:

  • device_id: Device identifier
  • counter: Global receipt counter
  • fiscal_day: Current fiscal day number (or null if none open)
  • fiscal_day_status: Status of fiscal day

get_configuration() -> Dict[str, Any]

Fetch device configuration from the database.

Returns:

  • Dictionary with configuration fields
  • Empty dict if no configuration exists

get_taxes() -> List[Dict[str, Any]]

Fetch all configured tax types.

Returns:

  • List of tax dictionaries with fields: code, name, percent, tax_id

Django Integration

Fiscguy is built on Django ORM. To use in a Django project:

  1. Add to INSTALLED_APPS in settings:
INSTALLED_APPS = [
    ...
    "fiscguy",
    "rest_framework",
]
  1. Run migrations:
python manage.py migrate fiscguy
  1. Initialize a device:
python manage.py init_device
  1. Use the library:
from fiscguy import open_day, submit_receipt

Models

Fiscguy provides Django ORM models for:

  • Device - Fiscal device information
  • FiscalDay - Fiscal day records
  • FiscalCounter - Receipt counters for fiscal days
  • Receipt - Receipt records
  • ReceiptLine - Individual receipt line items
  • Taxes - Tax type definitions
  • Configuration - Device configuration
  • Certs - Device certificates and keys
  • Buyer - Buyer/customer information

Error Handling

from fiscguy import submit_receipt
from rest_framework.exceptions import ValidationError

try:
    result = submit_receipt(receipt_data)
except ValidationError as e:
    print(f"Validation error: {e.detail}")
except RuntimeError as e:
    print(f"Runtime error: {e}")

Testing

# All tests
pytest

# With coverage
pytest --cov=fiscguy

# Specific test
pytest fiscguy/tests/test_api.py::SubmitReceiptTest::test_submit_receipt_success

Development

# Clone and setup
git clone https://github.com/cassymyo-spec/zimra.git
cd zimra
python -m venv venv
source venv/bin/activate
pip install -e ".[dev]"

# Run tests
pytest

# Code formatting
black fiscguy
isort fiscguy

# Linting
flake8 fiscguy
pylint fiscguy

# Type checking
mypy fiscguy

Architecture

Public API (api.py)
- open_day, close_day, submit_receipt, etc.
         |
Services Layer
- ReceiptService
- ClosingDayService
         |
Handler Layer
- ZIMRAReceiptHandler
         |
Client Layer
- ZIMRAClient (FDMS API)
- ZIMRACrypto (Signing)

Key Components

  • fiscguy/api.py - Public library interface (6 functions)
  • fiscguy/services/ - Business logic (ReceiptService, ClosingDayService)
  • fiscguy/zimra_base.py - ZIMRA FDMS HTTP client
  • fiscguy/zimra_receipt_handler.py - Receipt formatting and signing
  • fiscguy/zimra_crypto.py - Cryptographic operations
  • fiscguy/models.py - Django ORM models
  • fiscguy/serializers.py - DRF serializers
  • fiscguy/tests/ - Unit tests (22+ tests)

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Add/adjust tests
  4. Submit a PR

See CONTRIBUTING.md for detailed guidelines.

License

MIT License

Support

Changelog

0.1.0 (2026-02-08)

Initial Release

  • Public library API with 6 core functions
  • Receipt creation and submission
  • Fiscal day management
  • Device status and configuration
  • Tax type management
  • 22+ comprehensive unit tests
  • Full error handling and logging
  • Lazy-loaded module caching

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

fiscguy-0.1.2.tar.gz (35.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fiscguy-0.1.2-py3-none-any.whl (37.7 kB view details)

Uploaded Python 3

File details

Details for the file fiscguy-0.1.2.tar.gz.

File metadata

  • Download URL: fiscguy-0.1.2.tar.gz
  • Upload date:
  • Size: 35.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fiscguy-0.1.2.tar.gz
Algorithm Hash digest
SHA256 60ddcf553b88b94deed24aa404dcf1d79526318828f6269daf9135a907b5eef2
MD5 a992d8b17e6eddbeb07728929956e101
BLAKE2b-256 5ec4000a8a4ba175f1c9238e02fcbc7d390ede5d9e68102469d5c8af37ade6cd

See more details on using hashes here.

Provenance

The following attestation bundles were made for fiscguy-0.1.2.tar.gz:

Publisher: release.yml on DigitalTouchCode/fisc

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fiscguy-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: fiscguy-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 37.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fiscguy-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 23ee3b0dabfc4acfed557bcb078daa724e7089ba3ffc07fe00c1d9ecfac8b0c1
MD5 2846768a576387ccdce67b092ea4b8a4
BLAKE2b-256 3753ff1c3747c6f39e0d355f2691f6acdd56f2fa79aca420586f3d18dbbef4e7

See more details on using hashes here.

Provenance

The following attestation bundles were made for fiscguy-0.1.2-py3-none-any.whl:

Publisher: release.yml on DigitalTouchCode/fisc

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page