authyo_plugin 1.1.0
authyo_plugin: ^1.1.0 copied to clipboard
Add secure, multi-channel MFA (SMS, WhatsApp, Email, Call) to your Flutter app with Authyo. Fast, simple, and flexible.
Authyo Flutter Plugin #
A Flutter plugin for integrating Authyo β a powerful multi-channel MFA service supporting WhatsApp, SMS, Email, and Call for OTP verification.
This plugin enables developers to implement OTP-based authentication for both legacy systems and modern, passwordless solutions with minimal configuration.
π Features #
- π± Multi-channel support (WhatsApp, SMS, Email, Call)
- π§© Plug-and-play OTP UI (or bring your own)
- π§Ύ Works for both new and legacy systems
- π Configurable channel priority (no redeploy needed)
- π JWT-based login for new systems
- π§ REST API Support
- π Transparent billing & usage dashboard
- π Free trial for all new accounts
- π€ Affiliate support built-in
π§ Installation #
Add the dependency in your pubspec.yaml:
dependencies:
authyo_flutter: <latest_version>
Run:
flutter pub get
π οΈ Usage #
1. Legacy Systems (UI Provided) #
2. Modern Systems (Passwordless) #
Process #
π οΈ Getting Started #
1. Install #
Add to your pubspec.yaml:
dependencies:
authyo_plugin: ^1.0.0 //Latest versions may vary
Import in your Dart code:
import 'package:authyo_plugin/authyo_plugin.dart';
2. Initialize #
Important:
You must initializeAuthyoServicewith yourclientIdandclientSecretbefore making any requests.
//Get AuthyoService Instance
final AuthyoService authyoService = AuthyoService.instance;
//Initialize AuthyoService using your Authyo credentials
authyoService.init(clientId: "YOUR_CLIENT_ID", clientSecret: "YOUR_CLIENT_SECRET");
π¦ Usage #
π Send OTP #
// Call sendOtp function using AuthyoService
AuthyoResult otpResult = await authyoService.sendOtp(
ctx: context,
to: β+1234567890β, // or βuser@email.comβ
otpLength: 6, // optional, defaults to 6
expiry: 180, // optional, in seconds
authWay: AuthwayEnum.SMS, // optional, can be SMS, Whatsapp, Email, Voice
onVerificationComplete: (authyoResult) {
// This callback is optional and only necessary if plugin's default OTP verification dialog is used.
// If custom UI for OTP verification is used, you can omit this callback.
// Check for result.
if (authyoResult.result?.error == null) {
// Verification successful.
}
});
bool success = otpResult.result?.data?.results?.firstWhere((element) => element.success == true, orElse: () => Results(success: false)).success;
if (success == true) {
print("β
OTP Sent: ${otpResult.result?.message}");
} else {
print("β Error: ${otpResult.error?.message}");
}
π‘οΈ Verify OTP #
// Call verifyOtp function using AuthyoService instance
AuthyoResult otpResult = await AuthyoService.instance.verifyOtp(maskId: "Mask ID",otp: "Received OTP");
if(otpResult.result!=null){
print("Success: ${otpResult.result?.message}");
}
else{
print("Error: ${otpResult.error?.message}");
}
π¨ Design styles & dashboard customization #
The built-in dialog can be rendered in seven design languages. The look is resolved in this order (later wins):
- Built-in defaults (Flat, Authyo blue)
- Your Authyo dashboard β design style, colours, logo, button shape, layout, resend timer, enabled channels and social logins are fetched once (
GET /api/v1/authyoclient/mobileconfig), cached on device and refreshed in the background. - Overrides passed to
init()/sendOtp()
AuthyoDesignStyle |
Look |
|---|---|
flat (default) |
Solid colours, crisp borders β the 1.0.x look |
flat2 |
Flat with soft elevation |
minimalism |
Monochrome, underline input, thin outlines |
skeuomorphism |
Glossy gradients, bevels, recessed input |
claymorphism |
Pastel, puffy, large radii |
glassmorphism |
Frosted translucent card over a blurred backdrop |
neumorphism |
Extruded / pressed-in surfaces on one background colour |
authyoService.init(
clientId: "YOUR_CLIENT_ID",
clientSecret: "YOUR_CLIENT_SECRET",
// Optional β pin a style instead of following the dashboard:
designStyle: AuthyoDesignStyle.glassmorphism,
// Optional β partial theme override (anything unset comes from the dashboard / defaults):
theme: const AuthyoTheme(primary: Color(0xFF0EA5E9), hideBranding: true),
);
// Per-call override:
await authyoService.sendOtp(ctx: context, to: '+1234567890', designStyle: AuthyoDesignStyle.claymorphism);
// Or change at runtime:
authyoService.setDesignStyle(AuthyoDesignStyle.neumorphism);
authyoService.setDesignStyle(null); // follow the dashboard again
AuthyoTheme fields map 1:1 to the dashboard customization: buttonColor, buttonTextColor, inputBackground, inputBorder, inputText, smButton* (social buttons), headerText/bodyText + colours, logoUrl, hideBranding, resendButtonTimer, buttonStyle (rectangular / rounded / pill), mainLayout (left / centre / right) and socialMediaLayout (top / bottom).
Reading the remote config yourself #
final cfg = await authyoService.loadConfig(); // cached β instant
cfg.designStyle; // AuthyoDesignStyle? (null if the dashboard has none)
cfg.authMethods; // ["Sms", "Whatsapp", "Email"]
cfg.socialLogins; // [AuthyoSocialLogin(provider: google, id: "123"), ...]
cfg.otpLength;
Showing the dialog for an OTP you already sent #
final res = await authyoService.requestOtp(to: '+1234567890', authWay: AuthwayEnum.sms); // no UI
await authyoService.showVerificationDialog(context, sendResult: res, to: '+1234567890',
onVerificationComplete: (r) { /* ... */ });
π Social login (Google, Microsoft, GitHub, LinkedIn) #
Providers you enable on the dashboard (Application β Social Media Login) appear automatically in the dialog. Tapping one opens the provider in the system browser; the Authyo callback redirects to authyo://oauth/callback and the result is delivered to onVerificationComplete with the session JWT in result.data?.token.
You can also trigger it without the dialog:
final cfg = await authyoService.loadConfig();
final result = await authyoService.socialLogin(cfg.socialLogins.first);
πͺ Same flow as the web widget #
The dialog behaves exactly like the Authyo web widget (auth-sdk.js) on the same application:
| Step | Web widget | Flutter dialog |
|---|---|---|
| Top-left back button | returns to the identity form | closes the dialog (your form is behind it) |
| "OTP sent to: β¦ Change" | rebuilds the identity form | closes the dialog |
| OTP entry | one box per digit, auto-advance, paste fills all | same (otpLength boxes) |
| Verify | automatic on the last digit (no button) | same |
| Countdown | OTP will expire in m:ss from the server's expireTime |
same; falls back to the dashboard resend timer |
| After expiry | red notice + Resend (email) / Sms Β· Whatsapp Β· VoiceCall (phone, only enabled channels) | same, styled as primary buttons |
| Resend | passes the dashboard resend timer as the new expiry | same (expiry) |
| Social logins | icon row under an OR divider (or on top) |
same |
| Success | green ring + check + "Verified successfully" inside the card | same, then the dialog closes and onVerificationComplete fires |
| Footer | Terms & Privacy Policy links, "Powered by Authyo" | same (hideBranding hides the second line) |
| Hide OTP | digits masked | same (isOtpHide) |
| Remember me | checkbox shown only when enabled on the dashboard; ticked β longer session token + identity prefilled next visit | same: checkbox in the dialog, rememberMe sent on verify, identity kept on device β read it with authyoService.rememberedIdentity() to prefill your form, clear with forgetIdentity(). Off β no checkbox, nothing sent, nothing stored |
One-time platform setup (required for social login) #
Android β add to android/app/src/main/AndroidManifest.xml inside <application>:
<activity android:name="com.linusu.flutter_web_auth_2.CallbackActivity" android:exported="true">
<intent-filter android:label="authyo_oauth_callback">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="authyo" />
</intent-filter>
</activity>
iOS β add to ios/Runner/Info.plist:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key><string>Editor</string>
<key>CFBundleURLName</key><string>io.authyo.oauth</string>
<key>CFBundleURLSchemes</key><array><string>authyo</string></array>
</dict>
</array>
Using your own native sign-in SDKs instead #
authyoService.init(
clientId: ..., clientSecret: ...,
onSocialLogin: (login, authUrl) async {
// e.g. run google_sign_in here, or open authUrl yourself and
// return AuthyoService.parseSocialCallback(callbackUri, login);
},
);
π API Reference #
Methods
init
init({required String clientId, required String clientSecret, Duration? connectTimeout, Duration? receiveTimeout,
bool? showVerificationDialog, AuthyoDesignStyle? designStyle, AuthyoTheme? theme,
AuthyoSocialLoginHandler? onSocialLogin, bool prefetchConfig = true})
sendOtp
Future<AuthyoResult> sendOtp({
required String to,
int otpLength = 6,
int? expiry,
AuthwayEnum? authWay,
void Function(AuthyoResult authyoResult)? onVerificationComplete,
AuthyoDesignStyle? designStyle,
AuthyoTheme? theme,
});
- to: Phone number or email (required)
- otpLength: Length of OTP (optional, defaults to 6)
- expiry: OTP expiry in seconds (optional)
- authWay: Channel to send OTP (optional, defaults to dashboard preference)
- onVerificationComplete: Optional callback function which provide if authentication is successful or not. Only required when plugin's default OTP verification dialog is being used.
- designStyle / theme: Optional per-call overrides of the dialog look (see Design styles).
Returns: AuthyoResult
verifyOtp
Future<AuthyoResult> verifyOtp({required String maskId, required String otp})
- maskId: Received from
sendOtpresponse (required) - otp: The OTP entered by the user (required)
Returns: AuthyoResult
Pointing at another server
authyoService.init(clientId: ..., clientSecret: ..., baseUrl: 'https://staging.authyo.io');
Other methods
requestOtp({to, expiry, otpLength, authWay})β send an OTP with no UI.showVerificationDialog(context, {sendResult, to, onVerificationComplete, designStyle, theme, otpLength})β open the dialog for an already-sent OTP.loadConfig({forceRefresh})/currentConfig/clearConfigCache()β dashboard configuration.setDesignStyle(style)/setTheme(theme)/setShowVerificationDialog(bool)β runtime switches.socialLogin(AuthyoSocialLogin)β run a social provider sign-in.
AuthyoResult #
A wrapper for API responses.
class AuthyoResult {
final AuthyoResponseModel? result;
final AuthyoError? error;
AuthyoResult.success(this.result) : error = null;
AuthyoResult.failure(this.error) : result = null;
}
AuthyoBaseResponse #
For sendOtp:
{
"success": true,
"message": "submited successfully",
"data": {
"isTried": 1,
"isSent": 1,
"results": [
{ "success": true,
"message": "message submitted successfully",
"to": "919898******",
"authtype": "WHATSAPP",
"maskId": "36eeb3a16fAaAab49b48de0d729b9a35",
"createdTime": 1747312374,
"expiretime": 1747312434
}
]
}
}
For verifyOtp:
{
"success": true,
"message": "OTP Verified Successfully",
"status": "verified",
"data": {
"tokenType": "Bearer",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJGYTh6bE92N2FMUTdRcEl6enVkQnh3R0VxMVhTZUFCalRvcXdjcE0zM2w4PSIsImlzcyI6Imh0dHBzOi8vYXV0aHlvLmlvIiwiYXVkIjoiYWVhNWRhYzBlMjNDhiZmJjYzhjMTdmMDM2ZDlhZjgiLCJpYXQiOiIxNzUxOTA0MzkyIiwiZXhwIjoiMTc1MTkwNDY5MiIsInVzZXJJZCI6IkFZLUZhOHpsT3Y3YUxRN1FwSXp6dWRCeHdHRXExWFNlQUJqVG9xd2NwTTMzbDg9IiwicGhvbmUiOiI5MTc0MDUwODkwOTkifQ.6U3gFxTqSTuHNtsA77pRfvo8i9f0wfgvqbWb088v8Lg",
"expiresIn": 300,
"user": {
"phone": "9174050*****",
"userId": "AY-Fa8zlOv7aLQ7QpIzzudBGEq1XSeABjToqwcpM33l8="
}
}
}
β Error Handling #
All errors are subclasses of AuthyoError, including:
BadRequestError(400)UnauthorizedError(401)ForbiddenError(403)NotFoundError(404)TooManyRequestsError(429)InternalServerError(500)ServiceUnavailableError(503)NetworkErrorTimeoutErrorUnknownApiError
π Documentation #
Read the full documentation for implementation steps, API tokens, dashboard configuration, and more.
π§ͺ Try It Free #
Sign up at authyo.io and get free credits to test MFA in your app.
π§ Affiliate Program #
Promote Authyo and earn revenue. Details on your Authyo Dashboard.
π« Support #
For issues, feature requests, or contributions, file a GitHub issue or contact support via authyo.io.