> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stackra.figentra.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 0458 — Sunmi terminals: the built-in printer, drawer and scanner through the Sunmi SDK

> Proposed · 2026-10-27

> [!NOTE]
>
> Proposed (batch stackra-50, STA-1097, STA-904). The vendor-SDK ADR that 0442 decision 4 and 0253
> decision 3 ask for, for the `sunmi` family. Certification pending: written from Sunmi's public SDK
> documents, not yet checked on a certified model.

> [!NOTE]
>
> Amended by
> [0478](https://docs.stackra.figentra.com/adr/0478-native-code-lives-only-in-expo-module-packages-one-per-capability-behind-a-port.md)
> (2026-10-28): decision 2's Kotlin moves out of the till app's `src/native-sources/sunmi/` into the
> printer, drawer and scanner module packages, split by capability, and the drivers move with it.
> The rest of this page stands.

## Context

0442 (accepted by the owner on
2026-10-27, decision D4 of the Stackra finish plan; its page still waits to land here) gives the commerce till an
Android target and asks for one ADR per vendor SDK before a family's first build (0442 decision 4,
[0253](https://docs.stackra.figentra.com/adr/0253-peripherals-web-api-first-and-device-presets.md) decision 3). Sunmi's terminals have a built-in
printer, a drawer port and a built-in scanner that no Web API or LAN path reaches; only Sunmi's SDK does
([0339](https://docs.stackra.figentra.com/adr/0339-point-of-sale-peripherals-printers-labels-drawer-scanner-display-and-the-native-bluetooth-driver.md)
open detail 2).

## Decision

1. **Driver name `sunmi`.** `@stackra/peripherals` ships `SunmiReceiptPrinterDriver`,
   `SunmiCashDrawerDriver` and `SunmiBarcodeScannerDriver` in its `./native` entry, behind the
   unchanged `ReceiptPrinter`, `CashDrawer` and `BarcodeScanner` ports, selected by `peripherals.printer`, `.drawer`
   and `.scanner` set to `sunmi`.
2. **One Expo module, `StackraSunmi`, a pass-through.** The till app links an Expo module named `StackraSunmi` only when its
   runway lists `device:sunmi` (0442 decision 3). It exposes `printerStatus()`, `printLines(lines)`, `openDrawer()`
   and an `onScan` event carrying `{ code }`, each a direct call to the Sunmi printer service (`woyou.aidlservice.jiuiv5`, bound through Sunmi's printer library):
   `updatePrinterState()` for the status, text printing with a line feed and the paper cut on models with a cutter,
   and `openDrawer()` on models with a drawer port; the built-in scan head's decoded-code broadcast for the
   scanner. The module maps nothing: it returns the
   SDK's own status number and the decoded text. Its Kotlin lives in the till app's `src/native-sources/sunmi/`
   ([0345](https://docs.stackra.figentra.com/adr/0345-native-code-generation-and-the-native-shared-layer.md) decision 6).
3. **Readiness in the driver.** `updatePrinterState()` answers 1 when the printer is normal; every other value (out of paper, overheated, cover open, no printer) refuses, with capability `print` (ADR 0250 decision 3). The drawer is driven by the
   printer, so it checks the same status before each kick; the kick is one-way.
4. **Text, not commands.** Receipt lines go to the SDK as text with control characters removed; the SDK draws them.
   Arabic shaping is the SDK font's and is a certification row. A raster or code-page path is not built.
5. **Absent means refused.** In a build without `StackraSunmi` (web, desktop, another family) the printer and drawer
   refuse with `print` and the scanner with `scanner`; a subscription there does nothing. No call throws at the till.
6. **The SDK stays the vendor's.** The SDK artefacts come from Sunmi's developer portal and its Maven artefacts under Sunmi's terms and are linked by the till
   app's build only; this repository holds no Sunmi binary or source.

## Consequences

* The till drives a Sunmi terminal's printer, drawer and scanner with the same ports and settings as the desktop till.
* The status table is one line of `POS_DEVICE_FAMILIES`; the tests replay transcribed SDK answers until certified
  models are recorded (STA-739), and a wrong code shows there first.
* The Kotlin module, the config plugin that removes it from other families' builds, and the model list are the till
  template's and Runway's work (0442 decisions 3 and 5), not this package's.
* Card payment, the label printer and the scale on these terminals are not covered; an acquirer SDK is its own ADR
  (0442 decision 6). The second screen stays the `external` customer display (0430).

## Enforcement

* `packages/experience/peripherals/src/native/**/__tests__/*.test.ts` replay the `sunmi` fixture through a stand-in
  `StackraSunmi` module.
* planned — a certification run on each certified Sunmi model (STA-739) records the fixture again; Runway refuses an
  Android till build listing `device:sunmi` without this ADR (0442 enforcement).

## Supersedes and sources

`Supersedes: none`. Sources: owner decision D4 of 2026-10-27 (`notes/handover/batches/STACKRA-FINISH.md`), the 0442
draft (`notes/handover/app-shells/adr/0442-native-android-till-for-pos-terminals-from-the-commerce-till-template.mdx`),
Sunmi's public SDK documents, STA-904, STA-1097.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.