authyo_plugin 1.1.1 copy "authyo_plugin: ^1.1.1" to clipboard
authyo_plugin: ^1.1.1 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 initialize AuthyoService with your clientId and clientSecret before 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):

  1. Built-in defaults (Flat, Authyo blue)
  2. 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.
  3. 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 sendOtp response (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)
  • NetworkError
  • TimeoutError
  • UnknownApiError

πŸ“˜ 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.

2
likes
140
points
91
downloads

Documentation

Documentation
API reference

Publisher

verified publisherauthyo.io

Weekly Downloads

Add secure, multi-channel MFA (SMS, WhatsApp, Email, Call) to your Flutter app with Authyo. Fast, simple, and flexible.

Homepage
Repository (GitHub)
View/report issues

License

BSD-3-Clause (license)

Dependencies

dio, flutter, flutter_web_auth_2, plugin_platform_interface, shared_preferences, url_launcher

More

Packages that depend on authyo_plugin

Packages that implement authyo_plugin