Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/hxmz-axfn07/qr-printing-sfw/llms.txt

Use this file to discover all available pages before exploring further.

QR Print Station supports two printing workflows: staff can print files manually by downloading them from the dashboard, or the server can run a shell print command automatically the moment staff click Mark Printing. Both paths converge on the same status lifecycle — the only difference is whether a shell command is executed in between.

Manual Printing

When PRINT_COMMAND is left empty in .env, clicking Mark Printing does nothing more than advance the order status from ready to printing. No shell command runs. Staff are responsible for opening the uploaded files from the dashboard and sending them to a printer themselves.
1

Approve the order

After reviewing the order, click Approve. The order moves to Ready.
2

Open and print the files

Click each document link in the order card to open the file in a new browser tab, then print it from your operating system or print dialogue.
3

Mark Printing

Click Mark Printing in the dashboard. The order moves to Printing to reflect that the job is underway.
4

Confirm completion

Once the physical print job is finished and collected, click Printed. The order moves to Printed and the lifecycle is complete.
If PRINT_COMMAND is empty, clicking Mark Printing only transitions the order status — no shell command is run. Staff must open and print the files manually from the dashboard.

Automated Printing with PRINT_COMMAND

Set PRINT_COMMAND in .env to a shell command that your operating system’s print subsystem understands. When staff click Mark Printing, the server calls POST /api/orders/:id/print, transitions the order to Printing, then runs PRINT_COMMAND once for every document in the order.

How It Works

1

Staff click Mark Printing

The dashboard sends POST /api/orders/:id/print with the admin token in the X-Admin-Token header.
2

Server checks order status

The server verifies the order is in ready status. If not, it returns 400 Bad Request.
3

Status transitions to Printing

The server immediately moves the order to printing before running any commands.
4

PRINT_COMMAND runs per document

For each document in the order, the server formats PRINT_COMMAND with the document’s placeholders and runs it via the shell. Commands execute sequentially.
5

Non-zero exit code means Failed

If any command exits with a non-zero return code, the server immediately transitions the order to failed and stores the command’s stderr output as the failure_reason. No further documents in the order are printed.
6

Success — staff confirm completion

If all commands succeed, the order remains in printing. Staff click Printed in the dashboard to finalize the order once the physical job is collected.

Available Placeholders

The server substitutes the following placeholders in your PRINT_COMMAND string before executing it. Placeholders that are not used are silently ignored.
PlaceholderValue
{file}Absolute path to the uploaded file on disk
{copies}Number of copies requested by the customer
{paper}Paper size (e.g. A4, A3, Letter)
{color}Color mode: bw or color
{style}Print style: single or double

Example Commands

# Standard CUPS lp command
PRINT_COMMAND=lp -n {copies} -o media={paper} "{file}"

# lpr with multiple options
PRINT_COMMAND=lpr -# {copies} "{file}"
For double-sided printing you can pass the {style} placeholder through to CUPS:
PRINT_COMMAND=lp -n {copies} -o media={paper} -o sides={style}-sided "{file}"
To test your command without a real printer, use a script that simply logs the arguments:
#!/bin/bash
echo "Print job: file=$1 copies=$2 paper=$3 color=$4 style=$5" >> /tmp/print.log
PRINT_COMMAND=/path/to/test-print.sh "{file}" {copies} {paper} {color} {style}

Command Timeout

The server runs each print command with a 60-second timeout:
result = subprocess.run(command, shell=True, capture_output=True, text=True, timeout=60)
If the command does not exit within 60 seconds, Python raises a TimeoutExpired exception, which propagates as a 500 error. The order is not automatically failed on a timeout — check your print daemon if commands are hanging.
PRINT_COMMAND is executed with shell=True. This means shell metacharacters in the command string are interpreted by the shell. Only set PRINT_COMMAND from your .env file or other trusted server-side configuration — never construct it from user-supplied input. Customer-controlled values like filenames are inserted at fixed placeholder positions and are not passed through the shell directly, but the base command itself must come from a trusted source.

Build docs developers (and LLMs) love