beon_otp_sdk 1.0.0 copy "beon_otp_sdk: ^1.0.0" to clipboard
beon_otp_sdk: ^1.0.0 copied to clipboard

BeOn OTP SDK for Flutter — send, verify, and zero-tap auto-fill one-time passwords via Android SMS Retriever and iOS keyboard suggestions.

example/lib/main.dart

import 'package:beon_otp_sdk/beon_otp_sdk.dart';
import 'package:flutter/material.dart';

import 'pin_otp_widget/pin_otp_widget.dart';

void main() => runApp(const DemoApp());

class DemoApp extends StatelessWidget {
  const DemoApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Beon OTP SDK demo',
      theme: ThemeData(useMaterial3: true, colorSchemeSeed: Colors.indigo),
      home: const DemoScreen(),
    );
  }
}

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

  @override
  State<DemoScreen> createState() => _DemoScreenState();
}

class _DemoScreenState extends State<DemoScreen> {
  final _phone = TextEditingController(text: '01070809633');
  final _name = TextEditingController(text: 'Ahmed Fadlallah');
  final _code = TextEditingController();

  String token = "Beon_Token";
  OtpMethods _method = OtpMethods.sms;

  BeonOtpClient? _sdk;
  String? _lastBuiltToken;

  String? _expectedCode;
  String _status = '';
  String _result = '';
  bool _sending = false;
  bool _verifying = false;

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

  void _rebuildSdk() {
    _sdk?.autofilledCode.removeListener(_onAutofill);
    _sdk?.dispose();
    _sdk = BeonOtpClient(token: token, enableAutofill: true);
    _lastBuiltToken = token;
    _sdk!.autofilledCode.addListener(_onAutofill);
    _sdk!.getAndroidAppSignature().then((sig) {
      if (sig != null) debugPrint('Beon Android app signature: $sig');
    });
  }

  void _onAutofill() {
    final code = _sdk?.autofilledCode.value;
    if (code != null) _code.text = code;
  }

  BeonOtpClient _client() {
    if (_sdk == null || _lastBuiltToken != token) {
      _rebuildSdk();
    }
    return _sdk!;
  }

  Future<void> _send() async {
    setState(() {
      _sending = true;
      _status = 'Sending…';
      _result = '';
      _code.clear();
    });
    try {
      final sdk = _client();
      final res = await sdk.sendOtp(
        phoneNumber: _phone.text.trim(),
        name: _name.text.trim(),
        method: _method,
        otpLength: 6,
      );
      _expectedCode = res.code;
      if (mounted) {
        setState(() {
          _status = 'OTP sent (debug code: ${res.code})';
        });
      }
    } on BeonOtpException catch (e) {
      if (mounted) {
        setState(() {
          _status = 'Error (${e.statusCode ?? '-'}): ${e.message}';
        });
      }
    } finally {
      if (mounted) setState(() => _sending = false);
    }
  }

  void _verify() {
    setState(() => _verifying = true);
    final ok = BeonOtpClient.verifyOtp(
      expected: _expectedCode ?? '',
      input: _code.text,
    );
    setState(() {
      _result = ok ? '✅ Verified' : '❌ Wrong code';
      _verifying = false;
    });
  }

  @override
  void dispose() {
    _sdk?.autofilledCode.removeListener(_onAutofill);
    _sdk?.dispose();
    _phone.dispose();
    _name.dispose();
    _code.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Beon OTP SDK demo')),
      body: SafeArea(
        child: SingleChildScrollView(
          padding: const EdgeInsets.all(16),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              const SizedBox(height: 8),
              TextField(
                controller: _phone,
                decoration: const InputDecoration(
                  labelText: 'Phone (e.g. +20…)',
                ),
                keyboardType: TextInputType.phone,
              ),
              const SizedBox(height: 8),
              TextField(
                controller: _name,
                decoration: const InputDecoration(labelText: 'Name'),
              ),
              const SizedBox(height: 12),
              SegmentedButton<OtpMethods>(
                segments: const [
                  ButtonSegment(value: OtpMethods.sms, label: Text('SMS')),
                  ButtonSegment(
                    value: OtpMethods.whatsapp,
                    label: Text('WhatsApp'),
                  ),
                ],
                selected: {_method},
                onSelectionChanged: (s) => setState(() => _method = s.first),
              ),
              const SizedBox(height: 16),
              FilledButton(
                onPressed: _sending ? null : _send,
                child: Text(_sending ? 'Sending…' : '1. Send OTP'),
              ),
              if (_status.isNotEmpty) ...[
                const SizedBox(height: 12),
                Text(_status),
              ],
              const SizedBox(height: 24),
              PinOtpWidget(
                controller: _code,
                length: 6,
                onComplete: (_) {
                  if (_expectedCode != null && !_verifying) _verify();
                },
              ),
              const SizedBox(height: 16),
              FilledButton(
                onPressed: _verifying || _expectedCode == null ? null : _verify,
                child: const Text('2. Verify'),
              ),
              if (_result.isNotEmpty) ...[
                const SizedBox(height: 12),
                Text(_result, style: Theme.of(context).textTheme.titleMedium),
              ],
            ],
          ),
        ),
      ),
    );
  }
}
2
likes
80
points
41
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

BeOn OTP SDK for Flutter — send, verify, and zero-tap auto-fill one-time passwords via Android SMS Retriever and iOS keyboard suggestions.

Topics

#otp #authentication #sms #autofill

License

MIT (license)

Dependencies

dio, equatable, flutter, otp_autofill

More

Packages that depend on beon_otp_sdk