easy2sms_otp 1.0.0
easy2sms_otp: ^1.0.0 copied to clipboard
A powerful and easy-to-use Flutter package for sending and verifying OTPs using the Easy2SMS API. Supports customizable OTP length, custom message templates, and delivery status tracking.
example/lib/main.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:easy2sms_otp/easy2sms_otp.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(primarySwatch: Colors.blue, useMaterial3: true),
home: const OTPScreen(),
);
}
}
class OTPScreen extends StatefulWidget {
const OTPScreen({super.key});
@override
State<OTPScreen> createState() => _OTPScreenState();
}
class _OTPScreenState extends State<OTPScreen> {
// Replace with your actual credentials for testing
final easy2sms = Easy2SMSOTP(
authKey: 'YOUR_AUTH_KEY',
templateId: 'YOUR_TEMPLATE_ID',
);
final TextEditingController _numberController = TextEditingController(text: '8059290641');
final TextEditingController _otpController = TextEditingController();
String _status = 'Idle';
bool _isSending = false;
int _secondsRemaining = 30;
Timer? _timer;
bool _canResend = false;
void _startTimer() {
setState(() {
_secondsRemaining = 30;
_canResend = false;
});
_timer?.cancel();
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
setState(() {
if (_secondsRemaining > 0) {
_secondsRemaining--;
} else {
_canResend = true;
_timer?.cancel();
}
});
});
}
void _sendOTP() async {
setState(() {
_isSending = true;
_status = 'Sending OTP...';
});
String? msgId = await easy2sms.sendOTP(number: _numberController.text);
setState(() {
_isSending = false;
if (msgId != null) {
_status = 'OTP Sent! (ID: $msgId)';
_startTimer();
} else {
_status = 'Failed to send OTP';
}
});
}
void _resendOTP() async {
setState(() {
_isSending = true;
_status = 'Resending OTP...';
});
String? msgId = await easy2sms.resendOTP(number: _numberController.text);
setState(() {
_isSending = false;
if (msgId != null) {
_status = 'OTP Resent! (ID: $msgId)';
_startTimer();
} else {
_status = 'Failed to resend OTP';
}
});
}
void _verifyOTP() {
bool isValid = easy2sms.verifyOTP(_otpController.text);
setState(() {
_status = isValid ? '✅ OTP Verified Successfully!' : '❌ Invalid OTP. Try again.';
});
}
@override
void dispose() {
_timer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Easy2SMS OTP Example'), centerTitle: true),
body: SingleChildScrollView(
padding: const EdgeInsets.all(24.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Text("Enter Mobile Number", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
TextField(
controller: _numberController,
keyboardType: TextInputType.phone,
decoration: InputDecoration(
hintText: '8059290641',
border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
prefixIcon: const Icon(Icons.phone),
),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: _isSending ? null : _sendOTP,
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 16),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
),
child: _isSending
? const SizedBox(height: 20, width: 20, child: CircularProgressIndicator(strokeWidth: 2))
: const Text('Send OTP', style: TextStyle(fontSize: 16)),
),
const SizedBox(height: 32),
const Divider(),
const SizedBox(height: 32),
const Text("Enter OTP", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
TextField(
controller: _otpController,
keyboardType: TextInputType.number,
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 24, letterSpacing: 8),
decoration: InputDecoration(
hintText: '00000',
border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
),
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TextButton(
onPressed: _canResend && !_isSending ? _resendOTP : null,
child: Text(_canResend ? "Resend OTP" : "Resend in $_secondsRemaining s"),
),
ElevatedButton(
onPressed: _verifyOTP,
style: ElevatedButton.styleFrom(backgroundColor: Colors.green, foregroundColor: Colors.white),
child: const Text('Verify OTP'),
),
],
),
const SizedBox(height: 40),
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(8),
),
child: Text(
'Status: $_status',
textAlign: TextAlign.center,
style: const TextStyle(fontWeight: FontWeight.w500),
),
),
],
),
),
);
}
}