Skip to main content

Platform Details

For the full feature list, see Current Features.


File Types & Upload

Supported Formats (Platform-Wide)

The same file types are supported everywhere: backend upload/calculate-cost, frontend customer dashboard, customer Flutter app, and shopkeeper app (including print conversion).

TypeExtensionsPage/slide count (billing)Notes
PDF.pdfFrom filePassthrough; no conversion
Images.png, .jpg, .jpeg1 per fileConverted to single-page PDF (fit to paper) when printing
Word.doc, .docxDOC: OLE SummaryInformation "Page Count"; DOCX: app.xml or document.xmlConverted to PDF via LibreOffice (shopkeeper Windows)
PowerPoint.ppt, .pptxSlide count (PPTX: slide XMLs; PPT: binary)Converted to PDF via LibreOffice (shopkeeper Windows)
  • Page count not available: When the backend cannot determine page/slide count (e.g. .doc without summary, empty or non-standard file), the API returns 400 with: "Page count not available for this file. Please convert to PDF and upload."
  • Max 20MB per file, 100MB total per upload batch.
  • Other formats are rejected with a clear “Supported: PDF, images (PNG/JPG/JPEG), Word (DOC/DOCX), PowerPoint (PPT/PPTX)” message.

Converter Engine (Shopkeeper Windows)

The shopkeeper Windows app uses a converter engine to turn non-PDF files into PDF before printing:

  • PDF → passthrough
  • Images → image→PDF (fit to paper, preserve aspect ratio)
  • Word / PPT → LibreOffice headless→PDF (optional; requires LibreOffice portable). On Windows, LibreOffice is run via cmd.exe with cd /d outdir && soffice ... so the output PDF is written to the correct folder.

Pre-convert cache: When the queue loads, the app starts background pre-convert (download + LibreOffice convert) for each file. At print time it uses the cached PDF if ready, otherwise waits (up to 90s) or falls back to on-demand download and convert. After a successful print, local temp files for that file are deleted.

See Windows Printing for setup and details.

Payment System

Flow

  1. Customer uploads file → calculates cost
  2. Customer creates payment order → Razorpay order created
  3. Customer pays via Razorpay → webhook updates status
  4. File becomes available for printing
  5. Shopkeeper receives payout (for queue prints)

Commission Calculation

platformCommission := amount * commissionRate  // e.g., 10%
shopkeeperAmount := amount - platformCommission

File Storage

Local Storage (Default)

  • Files stored in backend/uploads/
  • File paths: uploads/{unique_code}_{filename}

S3 Storage (Production)

  • Set AWS_S3_BUCKET, AWS_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
  • File paths: s3://bucket-name/{unique_code}_{filename}

Switching

  • Set USE_LOCAL_STORAGE=true to force local
  • Remove USE_LOCAL_STORAGE and set AWS vars for S3

Email Service

  • Works on free tier hosting (Render, etc.)
  • Set RESEND_API_KEY
  • No SMTP ports needed

SMTP (Alternative)

  • Set SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD
  • Requires open SMTP ports (not available on free tier)

Queue System

Queue Print Flow

  1. Customer selects shopkeeper
  2. Uploads file → added to shop queue
  3. Shopkeeper sees file in queue with position
  4. Shopkeeper prints → status updates
  5. Customer sees status update

Queue Position

  • Calculated based on existing queue size
  • Updates when files are processed
  • When the shopkeeper starts a print (tap Print), the backend is notified via POST /queue/:fileId/print-started (or POST /file/:code/print-started for private). File status becomes printing.
  • Customer withdraw is disabled while status is printing (no refund after the shop has committed to printing). The customer app and web show "Printing at shop..." and hide the Withdraw button.
  • If the print fails or times out, the shopkeeper app calls print-failed; status returns to uploaded and the customer can withdraw again (with refund).
  • Verification timeout is page-based: 60 + (15 × num_pages) seconds (no cap), so large jobs get enough time before the system treats them as failed.
  • See PRINT_AND_WITHDRAW_FINAL_DESIGN.md in the project root for the full design.

Location Services

Distance Calculation

  • Uses Euclidean distance (can be enhanced with Haversine)
  • Shopkeepers sorted by distance
  • Requires lat and long for shopkeepers

Windows Printing (Shopkeeper App)

On Windows, the shopkeeper app prints silently (no dialogs) using SumatraPDF CLI with advanced features:

  1. File → Converter by extension → PDF (passthrough or convert)
  2. Printer availability check → Validates printer before sending
  3. SumatraPDF CLI → printer with options (copies, duplex, color, paper size)
  4. Print verification → Monitors job status via WMI until completion
  5. Backend confirmation → Only confirms after successful verification (accepts status uploaded or printing)

Key Features

  • SumatraPDF (required): used to send PDFs to the printer. Setup via scripts/setup_sumatra.ps1 or build_windows.bat.
  • LibreOffice (optional): used for Word/PPT→PDF conversion. Setup via scripts/setup_libreoffice.ps1 or build_windows.bat. If missing, only PDF and image printing work.
  • Print Queue System: Non-blocking queue allows multiple prints, per-job printer selection, real-time status updates
  • Printer Verification: WMI-based status checking ensures prints complete before confirming
  • Optimized Loading: Cached printer lists, lazy loading, timeout protection for better performance

Build: Run build_windows.bat from shopkeeper_app for a clean build with SumatraPDF (and optional LibreOffice) setup, then flutter run -d windows --release.

Full details, troubleshooting, and manual install steps: Windows Printing.

Admin System

Creating Admin User

cd backend
go run cmd/create_admin/main.go

Admin Features

  • User management — View users, user details, delete accounts
  • Order tracking — View all payment orders
  • Payout management — Single/bulk update status, export payouts
  • Manage payments — Per-shop payout history, mark as paid
  • App download links — Set Windows (shopkeeper), Android (customer), iOS (customer) download URLs and "coming soon" flags; shown on the public Download Apps page (/download-apps). Available in main frontend (/admin/downloads) and admin frontend (/downloads)
  • Dashboard statistics — Platform analytics

Shop Auto-Close (Sweeper)

The backend runs a background sweeper that auto-closes shop status when both app heartbeat and web activity are stale. Configurable via SHOP_APP_HEARTBEAT_TIMEOUT_MINUTES (default 12) and SHOP_WEB_ACTIVITY_TIMEOUT_MINUTES (default 25). Shopkeeper app sends POST /shop/heartbeat; web dashboard sends X-Platform: web (tracked by ShopkeeperActivity middleware).

GDPR — Delete Data Page

Public GET /delete-data (and frontend /delete-data) provides a page for the Google Play "Delete data" link requirement: explains how users can delete their data (login and use Delete Account, or contact support).