rootfi_tap_to_pay 0.1.1
rootfi_tap_to_pay: ^0.1.1 copied to clipboard
Official RootFi SDK: NFC phone-to-phone tap-to-pay between RootFi accounts, plus a typed client for the RootFi Cards API. One key, sandbox and live.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:rootfi_tap_to_pay/rootfi_tap_to_pay.dart';
void main() => runApp(const ExampleApp());
class ExampleApp extends StatelessWidget {
const ExampleApp({super.key});
@override
Widget build(BuildContext context) => MaterialApp(
title: 'RootFi Tap-to-Pay',
theme: ThemeData(useMaterial3: true),
home: const HomePage(),
);
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
late final RootFiTapToPay tap;
// Replace with the signed-in user's RootFi account number.
static const myAccount = '0110000001';
String _msg = 'Idle';
TapStatus _status = TapStatus.idle;
bool _receiving = false;
@override
void initState() {
super.initState();
// Use your sandbox key while testing.
tap = RootFiTapToPay(apiKey: 'rf_test_xxx');
tap.onStatus = (s) {
setState(() => _status = s);
};
tap.onScanning = () {
setState(() => _msg = 'Reading the other phone…');
};
tap.onSuccess = (r) {
setState(
() => _msg = 'Paid ${r.recipientName ?? ''} ✓ (${r.transferId})',
);
};
tap.onFailure = (e) {
setState(() => _msg = 'Failed: $e');
};
}
Future<void> _toggleReceive() async {
if (_receiving) {
await tap.stop();
setState(() {
_receiving = false;
_msg = 'Stopped';
});
} else {
setState(() {
_receiving = true;
_msg = 'Waiting for a payer to tap…';
});
await tap.startReceiving(accountNumber: myAccount);
}
}
Future<void> _pay() async {
setState(() => _msg = 'Hold your phone near the payee…');
await tap.startPaying(
debitAccountNumber: myAccount,
amount: 1500,
narration: 'Tap-to-pay demo',
);
}
@override
void dispose() {
tap.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: const Text('RootFi Tap-to-Pay')),
body: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Status: ${_status.name}',
style: const TextStyle(fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
Text(_msg, textAlign: TextAlign.center),
const SizedBox(height: 32),
FilledButton.icon(
onPressed: _toggleReceive,
icon: const Icon(Icons.nfc),
label: Text(_receiving ? 'Stop receiving' : 'Receive payment'),
),
const SizedBox(height: 16),
FilledButton.icon(
onPressed: _pay,
icon: const Icon(Icons.contactless),
label: const Text('Pay (scan a phone)'),
),
const SizedBox(height: 16),
OutlinedButton(
onPressed: () => tap.stop(),
child: const Text('Stop'),
),
],
),
),
);
}