react-native-telpo
v1.0.0
Published
Production-ready React Native SDK for Telpo devices — thermal printer (M1/TPS320), QR/barcode scanner, and NFC card reader
Maintainers
Readme
react-native-telpo
Production-ready React Native SDK for Telpo POS and ticket validation devices.
| Module | Feature | Devices |
|---|---|---|
| TelpoPrinter | Thermal receipt & ticket printing | M1, TPS320 |
| TelpoNfc | NFC / contactless card UID reading | T20, TPS320 |
| TelpoScanner | QR code & barcode scanning | T20, M1, TPS320 |
Android only. Telpo devices run Android. iOS is not supported for printing or NFC.
Installation
npm install react-native-telpoRequired peer dependencies
Install all three — only the modules you use will actually load at runtime:
npm install \
@haroldtran/react-native-thermal-printer \
react-native-nfc-manager \
react-native-vision-cameraAndroid Setup
1. android/build.gradle — Add JitPack
allprojects {
repositories {
// ...
maven { url "https://jitpack.io" }
}
}2. android/app/build.gradle — Min SDK
android {
defaultConfig {
minSdkVersion 21 // Required by vision-camera
}
}3. android/app/src/main/AndroidManifest.xml — Permissions
<!-- USB printer (M1 / TPS320 internal printer) -->
<uses-feature android:name="android.hardware.usb.host" />
<!-- NFC (T20 / TPS320) -->
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" android:required="false" />
<!-- Camera (scanner) -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- Bluetooth printer (optional) -->
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />Usage
Printer — Telpo M1 / TPS320
import { TelpoPrinter } from 'react-native-telpo';
// 1. Initialise (once, e.g. in useEffect or app start)
const initResult = await TelpoPrinter.init();
if (!initResult.success) {
console.error(initResult.error.message);
return;
}
// 2. Connect (USB = internal printer, default)
const connectResult = await TelpoPrinter.connect(); // connectionType: 'USB' by default
if (!connectResult.success) {
console.error(connectResult.error.message);
return;
}
// 3. Print a bus ticket
const printResult = await TelpoPrinter.printTicket({
operatorName: 'City Bus Services',
route: 'Route 42 — City Centre → Airport',
passenger: 'John Doe',
ticketId: 'TKT-001234',
fare: 'SLE 5.00',
dateTime: '2025-06-06 14:30:00', // optional, defaults to now
extras: { 'Bus No': 'BUS-007' },
footer: 'Thank you for travelling!',
});
// 4. Disconnect when done
await TelpoPrinter.disconnect();Print custom lines
await TelpoPrinter.printLines([
{ text: 'CITY BUS', alignment: 'CENTER', bold: true, fontSize: 'LARGE' },
{ text: '================================', alignment: 'CENTER' },
{ text: 'Ticket: TKT-001234', alignment: 'LEFT' },
{ text: 'Fare: SLE 5.00', alignment: 'LEFT' },
]);Bluetooth printer
await TelpoPrinter.connect({
connectionType: 'BLUETOOTH',
bluetoothAddress: 'AA:BB:CC:DD:EE:FF',
});NFC — Telpo T20 / TPS320
Single tap (one-shot read)
import { TelpoNfc } from 'react-native-telpo';
// Initialise once
await TelpoNfc.init();
// Wait for a card tap — resolves when card is detected
const result = await TelpoNfc.readTag();
if (result.success) {
const { uid, technology } = result.data;
console.log('Card UID:', uid); // "04:AB:12:CD:EF:01:23"
console.log('Technology:', technology); // "NfcA" | "IsoDep" | ...
// → now do YOUR validation logic with uid
} else {
console.error(result.error.message);
}Continuous listening (validation gate)
import { TelpoNfc } from 'react-native-telpo';
// Start listening — fires callback on every tap
TelpoNfc.startListening((result) => {
if (result.success) {
const uid = result.data.uid;
// → call your API, update state, play sound, etc.
console.log('Card tapped:', uid);
} else {
console.error('NFC error:', result.error.message);
}
});
// Later, when unmounting:
await TelpoNfc.stopListening();With timeout
// Auto-cancel if no card tapped within 10 seconds
const result = await TelpoNfc.readTag({}, 10_000);Scanner — QR / Barcode
Hook + View (recommended)
import { useTelpoScanner, TelpoScannerView } from 'react-native-telpo';
import type { ScanResult } from 'react-native-telpo';
function ValidatorScreen() {
const scanner = useTelpoScanner({
onResult: (result) => {
if (result.success) {
const { value, format, timestamp } = result.data;
console.log('Scanned:', value);
// → value is the raw ticket ID / QR content
// → do YOUR lookup logic here
}
},
options: {
formats: ['QR_CODE', 'CODE_128'], // filter to specific formats
deduplicateMs: 1500, // ignore same code for 1.5s
},
});
return (
<TelpoScannerView
scanner={scanner}
style={{ flex: 1 }}
showOverlay={true}
overlayColor="#00FF88"
/>
);
}Result Pattern
Every async method returns TelpoResult<T>:
type TelpoResult<T> =
| { success: true; data: T }
| { success: false; error: { code: TelpoErrorCode; message: string } };Always check result.success before accessing result.data:
const result = await TelpoPrinter.printTicket({ ticketId: 'TKT-001' });
if (result.success) {
// result.data is void for print methods
console.log('Printed!');
} else {
// result.error.code is a TelpoErrorCode enum value
switch (result.error.code) {
case 'PRINTER_NO_PAPER':
alert('Out of paper!');
break;
case 'PRINTER_NOT_CONNECTED':
alert('Printer not connected!');
break;
default:
console.error(result.error.message);
}
}Error Codes
| Code | Module | Meaning |
|---|---|---|
| PRINTER_NOT_CONNECTED | Printer | connect() not called or failed |
| PRINTER_NO_PAPER | Printer | Paper out |
| PRINTER_INIT_FAILED | Printer | init() failed or iOS |
| PRINTER_PRINT_FAILED | Printer | Print job failed |
| PRINTER_PERMISSION_DENIED | Printer | USB permission denied |
| NFC_NOT_SUPPORTED | NFC | Device has no NFC chip |
| NFC_DISABLED | NFC | NFC is off in settings |
| NFC_SCAN_CANCELLED | NFC | User/timeout cancelled |
| NFC_READ_FAILED | NFC | Tag read error |
| NFC_ALREADY_LISTENING | NFC | startListening() already active |
| SCANNER_CAMERA_PERMISSION_DENIED | Scanner | Camera access denied |
| SCANNER_NOT_ACTIVE | Scanner | Library not loaded |
TypeScript
The SDK is fully typed. Import types from the root:
import type {
TelpoResult,
TelpoError,
TelpoErrorCode,
PrintTicket,
PrintLine,
NfcTag,
ScanResult,
} from 'react-native-telpo';License
MIT
