receipt_printer

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.
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 |
|---|---|---|
![]() |
![]() |
![]() |
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.


