receipt_printer

Isometric illustration of receipt printers, customization controls and tickets

Tactile receipt UI for Flutter. Build receipts, admission tickets and coupons with shaped paper, nine printer presets, pull-to-tear motion and copyable Dart. This is a visual component, not a hardware driver or payment processor.

Quick start · Usage guide · Interactive Gallery · Contributing

  • Compose typed documents with exact minor-unit money and optional QR / Code 128.
  • Style printer housing, paper contours, shadows and bundled typography.
  • Use touch, mouse or keyboard to tear; respect reduced-motion preferences.
  • Capture receipt-only or printer-preview PNGs with explicit memory limits.
  • Preview and copy the same public API used by the Gallery.

The Studio/playground lives in example/ and is called Gallery. Choose a preset, edit Printer / Paper / Receipt / Interaction controls, then copy the Dart expression into your app. Add the imports shown below; the export does not include an app scaffold or dependencies.

Receipt Ticket Coupon
Classic receipt preset Cinema ticket preset Discount coupon preset

Open the live Receipt Printer Gallery, or run it locally:

cd example
flutter pub get --enforce-lockfile
flutter run -d chrome

The Gallery is at /; #/gallery redirects to it. Documentation lives in this repository, not at an in-app /docs route. Edits are session-only: refreshing or switching presets discards them. Copy the API before leaving. Receipt content is not uploaded. The GitHub badge makes a public API request for its star count; external links open only on request. No analytics or browser draft storage.

Install

Install the stable package from pub.flutter-io.cn:

flutter pub add receipt_printer

For local package development:

dependencies:
  receipt_printer:
    path: ../receipt-printer

Requires Dart 3.13 and Flutter 3.47 or newer.

import 'package:flutter/material.dart';
import 'package:receipt_printer/receipt_printer.dart';

Basic receipt

ReceiptView(
  receipt: Receipt(
    title: 'Your business',
    items: [ReceiptItem(title: 'Coffee', unitPrice: 450)],
  ),
  formatter: ReceiptFormatter(currency: 'USD'),
)

Prices are integer minor units. quantityMillis: 1500 means 1.5 units. The model calculates subtotal; display totals remain caller-owned.

Nine printer presets

Preset Character Output
classicThermal Dark, familiar POS housing Restaurant receipt
modern Low matte shell, minimal controls Café receipt
posCounter Deep commercial body, display, controls Retail transaction
cinemaTicket Narrow stepped burgundy housing Tinted admission ticket
discountToken Compact green shell Scalloped coupon with QR
kitchenOrder Rugged expo housing Kitchen order
mobileTerminal Handheld shell Mobile checkout
parkingPass Kiosk housing Parking/transit pass
artisanBakery Rounded cream shell Bakery label
ReceiptPrinter(
  preset: ReceiptPrinterPreset.cinemaTicket,
  child: ReceiptView(receipt: ReceiptPrinterPreset.cinemaTicket.receipt),
)

Presets are public package objects. Shell geometry, paper contours, typography, sample receipts, rip physics and confetti all come from the same source used by the Gallery. These generic designs do not represent specific manufacturers.

Customization

Start from a preset and override only the properties you need:

ReceiptPrinter(
  preset: ReceiptPrinterPreset.modern,
  paper: ReceiptPrinterPreset.modern.paper.copyWith(
    bottomEdge: const ReceiptPaperEdge(
      shape: ReceiptPaperEdgeShape.deckled,
    ),
  ),
  receiptTheme: ReceiptPrinterPreset.modern.theme.copyWith(
    backgroundColor: const Color(0xFFFFF3C4),
  ),
  child: ReceiptView(
    receipt: ReceiptPrinterPreset.modern.receipt.copyWith(title: 'Your café'),
    formatter: ReceiptFormatter(currency: 'USD'),
  ),
)

style overrides the shell; paper overrides sheet geometry; receiptTheme overrides typography, ink and paper color. The child inherits these defaults. An explicit ReceiptView.theme or paperStyle takes precedence locally. Use copyWith to retain the selected preset's other values.

Receipt supports optional title, subtitle, footer, items, totals, metadata, custom labelled sections and ReceiptCode. Tickets and coupons need no totals. ReceiptBuilders and ReceiptPaper remain available for custom composition. QR and Code 128 encoding use barcode_widget; invalid payloads are rejected.

The package bundles Roboto Mono and Vazirmatn under OFL licenses for its presets; no additional font setup is needed for the default Gallery designs. Custom fonts remain application-owned. Use textDirection: TextDirection.rtl and the Persian formatter for RTL content.

Paper

Content height is the default. Place the printer in an outer scroll view for long receipts. The paper never needs an internal scrollbar. Fixed mode reserves a minimum height and grows if the content exceeds it.

Independent top and bottom cuts, deterministic grain, borders and shadows use one contour. The Gallery curates straight, torn, serrated, perforated, zigzag, ticket, scalloped and deckled edges. ReceiptPaperShadowStyle.presets provides soft, natural and floating shadows, with optional opacity, blur, spread and offset overrides.

Pull to rip

ReceiptPrinter(
  preset: ReceiptPrinterPreset.classicThermal,
  interaction: ReceiptRipConfig.presets['snappy'],
  child: ReceiptView(receipt: receipt),
)

Drag the lower strip. Short pulls spring back; threshold travel or a forward fling tears the sheet. Detached motion follows release velocity. The rest of the paper remains available for outer scrolling. Focus the paper and use Enter or Space for a keyboard alternative. Platform reduced-motion preferences apply. Attach ReceiptPrinterController to call ripReceipt() or resetReceipt().

Audio

Audio is off by default. audio: const ReceiptAudioConfig(enabled: true) enables the bundled web tear sound, synchronized with separation. Web Audio requires a user gesture and may be blocked by browser settings. Audio errors never stop the visual tear. Supply onError to display failures.

Use ReceiptSound.asset('assets/tear.wav') for an app-declared custom asset. On native platforms, supply ReceiptAudioConfig.onPlay to use your existing player; native playback is not bundled. The package uses web for browser playback. The sound is an original synthesized effect; see assets/README.md.

Confetti

Optional ReceiptConfettiConfig fires at separation. The Gallery offers Off, Subtle and Celebration. Classic and POS defaults are quiet; ticket and coupon presets include celebration. Capture excludes confetti. Reduced motion suppresses particle motion.

Capture

final controller = ReceiptPrinterController();
// Pass controller: controller to ReceiptPrinter and wait for it to paint.
final png = await controller.captureReceipt();
// Or: await controller.capturePrinterPreview();
// Dispose the controller when its owner is removed.

Capture returns PNG bytes with explicit dimension and pixel budgets. See capture example and interaction docs.

API at a glance

API Purpose
Receipt, ReceiptItem, ReceiptTotal Immutable document and caller-owned totals
ReceiptFormatter Exact amounts, fractional quantities and Persian digits
ReceiptView / .scrollable Full document / explicitly bounded lazy viewport
ReceiptPrinter, ReceiptPrinterStage Shell and parent-controlled visual feed stages
ReceiptPrinterPreset Shared housing, paper, theme and interaction defaults
ReceiptThemeData, ReceiptPaperStyle, ReceiptPrinterStyle Independent styling groups
ReceiptBuilders, ReceiptPaper Custom composition with app-owned semantics
ReceiptRipConfig, ReceiptConfettiConfig, ReceiptAudioConfig Optional effects
ReceiptPrinterController, ReceiptCaptureOptions Tear/reset commands and bounded PNG capture

See the usage guide for totals, stages, RTL, theme precedence, custom builders and troubleshooting, and migration notes for the existing 0.3 preset-ID changes.

Deployment

Relevant pushes to main run formatting, analysis, package/Gallery tests, generated API parity and a production web build before deploying to GitHub Pages. Pull requests run the same checks without deployment. Enable Settings → Pages → Build and deployment → Source → GitHub Actions once the repository exists. Manual runs: Actions → Gallery — Verify and deploy → Run workflow on main. No hosting secrets, paid services or generated build commits are needed.

See deployment and troubleshooting.

Validation and release

flutter pub get --no-example
cd example
flutter pub get --enforce-lockfile
cd ..
dart format --output=none --set-exit-if-changed lib test example/lib example/test example/integration_test example/test_driver
flutter analyze --no-pub
flutter test --no-pub
cd example
flutter analyze --no-pub
flutter test --no-pub
flutter test --no-pub .dart_tool/gallery_generated/parity_test.dart
flutter build web --release --no-web-resources-cdn --base-href /receipt_printer/
cd ..
python3 -m unittest discover -s tool -p 'test_*.py'
python3 tool/pages.py ariaramin/receipt_printer --build-dir example/build/web
dart pub publish --dry-run

API tests compile generated snippets and compare their pixels to the Gallery. Purposeful goldens cover all nine presets plus desktop and mobile Gallery views. See validation, migration, release checklist, and deployment. Local validation does not prove publication, live deployment, physical-device performance, or native audio integration.

Contributing

Read CONTRIBUTING.md for local checks and reviewed golden updates. Report reproducible issues using synthetic data. Follow the Code of Conduct; report vulnerabilities according to the security policy, never in public issues.

License

MIT for the package and original tear effect. Bundled fonts retain their OFL notices. The banner is generated conceptual art; the Gallery preview above is a rendered application screenshot.

Libraries

receipt_printer
Composable receipt UI, exact formatting, and an animated printer shell.