Skip to main content

halo_sdk_ui 0.1.0 copy "halo_sdk_ui: ^0.1.0" to clipboard
halo_sdk_ui: ^0.1.0 copied to clipboard

Halo Dot tap-on-phone payments for Flutter. Wraps the native sdk_ui library behind one Dart class, so an app can take a card payment on the phone itself without writing native code. Android only.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:halo_sdk_ui/halo_sdk_ui.dart';

/// Every call the plugin offers, on one screen.
///
/// The reads that need no SDK — its version, the NFC state, this device's
/// installation id — are shown first, then the bring-up runs behind them, and
/// the buttons drive the rest. Bring-up needs a real Halo JWT, which this app
/// takes from `--dart-define=HALO_JWT=…`; without one `init` fails and the
/// buttons that need a live SDK do nothing, while everything above still reads.
void main() => runApp(const ExampleApp());

class ExampleApp extends StatefulWidget {
  const ExampleApp({super.key});

  @override
  State<ExampleApp> createState() => _ExampleAppState();
}

class _ExampleAppState extends State<ExampleApp> {
  final _halo = HaloSdkUi();

  String _sdkVersion = 'unknown';
  bool? _nfc;
  String _installationId = 'not registered';
  String _lastOutcome = '—';

  @override
  void initState() {
    super.initState();
    _start();
  }

  Future<void> _start() async {
    final sdkVersion = await _read(_halo.sdkInfo) ?? 'unknown';
    final nfc = await _read(_halo.nfc);
    final installationId =
        await _read(_halo.deviceInstallationId) ?? 'not registered';

    // Shown before the slow half: `init` suspends until the SDK settles, so
    // waiting for it here would leave the screen empty until it did.
    if (!mounted) return;
    setState(() {
      _sdkVersion = sdkVersion;
      _nfc = nfc;
      _installationId = installationId;
    });

    _halo.setTokenProvider(() async {
      return const String.fromEnvironment('HALO_JWT');
    });

    await _read(_halo.prepare);
    final outcome = await _read(_halo.init);
    debugPrint('init → $outcome');
  }

  /// One call, with the platform's refusals logged rather than thrown: on a
  /// platform the plugin does not serve, every one of these is a
  /// `MissingPluginException`.
  Future<T?> _read<T>(Future<T?> Function() call) async {
    try {
      return await call();
    } on PlatformException catch (error) {
      debugPrint('${error.code}: ${error.message}');
    } on MissingPluginException {
      debugPrint('halo_sdk_ui serves Android only');
    }
    return null;
  }

  Future<void> _charge({String? amount, String? presentation}) async {
    final result = await _read(
      () => _halo.transact(
        amount,
        'ZAR',
        reference: 'example-${DateTime.now().millisecondsSinceEpoch}',
        presentation: presentation,
      ),
    );
    debugPrint('transact → $result');
    if (!mounted) return;
    setState(() => _lastOutcome = result?['resultType'] ?? 'no result');
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(title: const Text('halo_sdk_ui')),
        body: ListView(
          padding: const EdgeInsets.all(16),
          children: [
            Text(
              'SDK $_sdkVersion\n'
              'NFC ${switch (_nfc) {
                null => 'no hardware',
                true => 'on',
                false => 'off',
              }}\n'
              'Installation $_installationId\n'
              'Last outcome $_lastOutcome',
            ),
            const Divider(height: 32),
            FilledButton(
              onPressed: () => _charge(amount: '10.00'),
              child: const Text('Charge R10.00'),
            ),
            FilledButton(
              onPressed: () => _charge(amount: '10.00', presentation: 'SHEET'),
              child: const Text('Charge R10.00, as a sheet'),
            ),
            FilledButton(
              onPressed: _charge,
              child: const Text("Charge on the SDK's own keypad"),
            ),
            const SizedBox(height: 16),
            OutlinedButton(
              onPressed: () => _read(_halo.openNfcSettings),
              child: const Text('Open NFC settings'),
            ),
            OutlinedButton(
              onPressed: () => _read(() => _halo.language('af')),
              child: const Text('Speak Afrikaans'),
            ),
            OutlinedButton(
              onPressed: () => _read(
                () => _halo.browser('https://docs.halodot.io'),
              ),
              child: const Text('Open the docs in a browser'),
            ),
            OutlinedButton(
              onPressed: () async {
                // The handshake a scanner sits inside: the kernel cancels a
                // transaction when something else takes the camera unannounced.
                await _read(() => _halo.camera(true));
                await _read(() => _halo.camera(false));
              },
              child: const Text('Borrow and return the camera'),
            ),
            OutlinedButton(
              onPressed: () => _read(_halo.forgetRegistration),
              child: const Text('Forget this terminal registration'),
            ),
          ],
        ),
      ),
    );
  }
}
1
likes
0
points
1.15k
downloads

Documentation

Documentation

Publisher

verified publisherhalodot.io

Weekly Downloads

Halo Dot tap-on-phone payments for Flutter. Wraps the native sdk_ui library behind one Dart class, so an app can take a card payment on the phone itself without writing native code. Android only.

Repository (GitHub)
View/report issues

Topics

#payments #nfc #android #point-of-sale

License

unknown (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on halo_sdk_ui

Packages that implement halo_sdk_ui