QZ Tray printing integration for Koha
What's new in v1.2.2
1.2.2 - 2026-09-18
Changed
- Synced further release-tooling changes from
koha-plugin-template: addedcheck_release_ready.jsas a preflight forrelease:*(aborts before mutating anything unless onmain, the tree is clean, and localmainmatchesorigin/main), added a CIguardjob that skips the duplicate test-matrix run--follow-tagstriggers on every release, trimmed the release job'sissues/pull-requestspermissions from write to read, added an explicitpermissionsblock to the test job, pinned the kpz-builder action to@v3instead of the floating@master, and routed workflow expressions used inside shell steps throughenv:vars to close a workflow-injection class
Fixed
- Corrected
check_release_ready.js's origin-sync check: it compared local andorigin/mainSHAs for exact equality, so it failed on the normal case of releasing with unpushed local commits (whichrelease:*itself pushes). Now usesgit merge-base --is-ancestorand only fails when local is genuinely behind or diverged - Made
Crypt::OpenSSL::RSAan optional dependency inControllers::Auth, matching the existing guard inQZTray.pm. The controller's unconditionalusecaused a hard compile-time failure (and a plugin storeperl_syntaxfailure) on any checkout without the OpenSSL Perl bindings installed;signMessagenow returns a clear 503 if they're unavailable at runtime instead
QZ Tray Integration Plugin for Koha
A Koha plugin that integrates QZ Tray printing functionality for automatic cash drawer opening and receipt printing operations.
Features
- Cash Drawer Integration: Automatically open cash drawers during payment transactions
- Quick Drawer Access: One-click button on POS page to open cash drawer without processing a transaction
- Register-Specific Printer Configuration: Map specific printers to individual cash registers
- Multi-Library Support: Configure printers across multiple library branches
- Secure Certificate Management: Encrypted storage of QZ Tray security certificates
- Smart Printer Selection: Uses form-selected register or falls back to system default
- Visual Configuration Interface: Library-grouped register display with current session highlighting
Requirements
Server-Side Dependencies
The plugin requires OpenSSL cryptographic libraries for secure certificate handling:
# On Debian/Ubuntu systems:
sudo apt update
sudo apt install libcrypt-openssl-x509-perl
Client-Side Requirements
- QZ Tray installed on client workstations
- Modern web browser with JavaScript enabled
- Network connectivity between Koha server and client machines
Koha Requirements
- Koha 22.05 or later
- Cash management permissions enabled
- At least one cash register configured per library
Installation
-
Install server dependencies:
sudo apt install libcrypt-openssl-x509-perl -
Download the plugin:
- Download the latest
.kpzfile from the releases page
- Download the latest
-
Install in Koha:
- Navigate to Administration → Plugins
- Click "Upload plugin"
- Select the downloaded
.kpzfile - Click "Upload"
-
Configure the plugin:
- Click "Configure" next to the QZ Tray Integration plugin
- Upload your QZ Tray security certificate and private key files
- Configure printer mappings for your cash registers
Configuration
1. Security Certificates
QZ Tray requires security certificates for secure communication:
- Generate certificates using QZ Tray's certificate generator
- Upload the certificate file (
.crtor.pem) - Upload the private key file (
.keyor.pem)
2. Printer Configuration
Configure printers for each cash register:
- By Library: Registers are grouped by library branch for easy organization
- Current Session Indicator: Your active register is highlighted in green
- Printer Selection: Choose specific printers or use system default
- Refresh Printer List: Detect available printers on the network
3. Permissions
Ensure users have appropriate cash management permissions:
cash_management→takepaymentfor payment operationscash_management→cashupfor register managementcash_management→anonymous_refundfor refund operations
Usage
Once configured, the plugin automatically:
- Detects Payment Pages: Integrates with POS payment forms
- Selects Appropriate Printer: Uses register-specific or default printer
- Opens Cash Drawer: Sends drawer open commands during transactions
- Handles Errors: Displays user-friendly error messages
Quick Drawer Access
On the Point of Sale page, a toolbar with an "Open cash drawer" button appears above the page heading. This allows staff to open the register for:
- Making change without processing a transaction
- Accessing physical cash for non-sale purposes
- Testing drawer functionality
The button is disabled until QZ Tray initializes, then becomes active with visual feedback during operation.
Supported Pages
- Point of Sale (pos/pay.pl): Quick access button plus automatic drawer opening on payment confirmation
- Register cashup operations
- Member account payments
- Refund transactions
Supported Printers
The plugin includes optimized drawer control codes for:
- Bixolon SRP-350 series
- Epson TM-T88V
- Metapace T-series
- Citizen CBM1000 (all name variations)
- Citizen CT-S2000 (all name variations)
- Other ESC/POS compatible printers (using default codes)
Note for Citizen CT-S2000: If your printer driver settings force drawer opening on every print, consider setting up two printer instances:
- One for receipts (driver set to "Never" open drawer)
- One for drawer control (Generic/Text Only driver) configured in this plugin
Troubleshooting
Common Issues
"QZ Tray not connected"
- Ensure QZ Tray is running on the client machine
- Check network connectivity
- Verify browser allows unsigned applets (if using development certificates)
"Printer not found"
- Click "Refresh Printer List" to detect available printers
- Verify printer is powered on and connected
- Check printer network configuration
"Certificate errors"
- Ensure certificate and private key match
- Verify files are in PEM format
- Check that encryption is configured in Koha
Debug Information
Enable debug logging in Koha to see detailed QZ Tray communication logs:
- Check the
plugin.qztraylog category - Monitor JavaScript console for client-side errors
Development
File Structure
Koha/Plugin/Com/OpenFifth/QZTray/
├── QZTray.pm # Main plugin file
├── templates/
│ └── configure.tt # Configuration template
├── js/
│ ├── qz-config.js # Configuration management
│ ├── qz-drawer.js # Cash drawer operations
│ ├── qz-messaging.js # User messaging
│ ├── qz-auth.js # Authentication handling
│ ├── qz-button-manager.js # UI button replacement
│ ├── qz-page-detector.js # Page detection logic
│ ├── qz-pos-toolbar.js # POS toolbar with quick access button
│ └── qz-tray-integration.js # Main integration
├── api/
│ ├── openapi.json # API specification
│ └── staticapi.json # Static route specification
└── Controllers/
└── Auth.pm # Authentication controller
Support
For issues and bug reports, please use the project's issue tracker.
License
This plugin is released under the GNU General Public License v3.0, consistent with Koha's licensing.
Version History
- v1.1.1: Performance optimization - JavaScript now loads only on required pages instead of system-wide; fixed FOUC (flash of unstyled content) by removing split initialization
- v1.1.0: Added quick cash drawer open button to POS page toolbar; wrapped console.log statements in debug mode checks
- v1.0.12: Rearranged configuration page for better UX
- v1.0.11: Added configurable debug mode for console logging; improved configuration UI with sticky toolbar and updated button styling
- v1.0.10: Critical fix for JavaScript string escaping bug; added comprehensive debug logging for printer selection
- v1.0.8: Fixed invalid CSS selector in printer list refresh functionality
- v1.0.7: Added support for Citizen CT-S2000 printer with optimized drawer control codes
- v1.0.4: Enhanced register-library grouping and session highlighting
- v1.0.3: Improved form-based register detection
- v1.0.2: Added register-specific printer mappings
- v1.0.1: Security and error handling improvements
- v1.0.0: Initial release with basic QZ Tray integration
Technical report — v1.2.2 (what do these checks mean?)
| Check | Required | Result | Message |
|---|---|---|---|
| changelog_format | Advisory | Passed | |
| dependency_allowlist | Required | Passed | |
| docs_presence | Advisory | Passed | |
| gpg_signed_tag | Advisory | Passed | |
| hardcoded_credentials | Advisory | Passed | |
| koha_max_version | Advisory | Passed | |
| manifest_completeness | Required | Passed | |
| perl_critic | Advisory | Passed | |
| perl_syntax | Required | Passed | |
| plugin_template_wrapper | Advisory | Passed | |
| readme_presence | Advisory | Passed | |
| tests_presence | Advisory | Passed | |
| translatable_templates | Advisory | Passed |