Skip to content

SDK Flutter

Plugin de Flutter basado en los SDKs nativos de iOS / Android, expone un único CaptchalaClient en Dart para ambas plataformas móviles (con soporte de escritorio en Linux / macOS / Windows mediante WebView integrado).

Demo en GitHub

📦

Captcha-La/flutter-demo — ejemplo completo y ejecutable con cada paso de integración.

Instalación

Añade el paquete desde pub.dev:

yaml
# pubspec.yaml
dependencies:
  captchala: ^1.3.2
  http: ^1.2.0          # used by the demo's token-fetch helpers
bash
flutter pub get
flutter run               # auto-picks the foreground device
# or:
flutter run -d <device-id>

En iOS / macOS, la primera compilación ejecuta pod install automáticamente. Asegúrate de que ios/Podfile declare platform :ios, '13.0' (o superior).

Inicio rápido

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

class LoginScreen extends StatefulWidget {
  const LoginScreen({super.key});
  @override
  State<LoginScreen> createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  String _status = 'Tap to verify';
  bool _verifying = false;

  Future<void> _runVerify() async {
    setState(() { _verifying = true; _status = 'Fetching server_token...'; });

    // 1. Fetch a one-shot server_token from YOUR backend.
    final initialToken = await fetchServerTokenFromYourBackend();

    // 2. Build config from your business action.
    final config = CaptchalaConfig(
      appKey: 'YOUR_APP_KEY',
      action: 'login',                  // login, register, pay, …
      lang: 'en',                       // en, zh-CN, zh-TW, ja, ko, ms, vi, id
      theme: 'light',                   // 'light' | 'dark'
      enableVoice: true,
      enableOfflineMode: true,
      maskClosable: false,
      serverToken: initialToken,
    );

    // 3. Initialize, register callbacks, then call verify().
    final client = await CaptchalaClient.instance.initialize(config);
    client.setCallbacks(
      onSuccess: (r) async {
        // Send r.passToken to YOUR backend for validation.
        if (!mounted) return;
        setState(() { _status = 'OK: ${r.passToken}'; _verifying = false; });
      },
      onFail:    (e) { if (mounted) setState(() { _status = 'fail: ${e.code}'; _verifying = false; }); },
      onError:   (e) { if (mounted) setState(() { _status = 'error: ${e.code} ${e.message}'; _verifying = false; }); },
      onClose:   () { if (mounted && _verifying) setState(() { _status = 'closed'; _verifying = false; }); },
      onServerTokenExpired: () => fetchServerTokenFromYourBackend(),
    );
    await client.verify();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(mainAxisSize: MainAxisSize.min, children: [
          ElevatedButton(
            onPressed: _verifying ? null : _runVerify,
            child: Text(_verifying ? 'Verifying...' : 'Verify with CAPTCHA'),
          ),
          const SizedBox(height: 12),
          Text(_status, style: const TextStyle(fontFamily: 'monospace')),
        ]),
      ),
    );
  }
}

Superficie de la API

SímboloPropósito
CaptchalaClient.instanceAcceso singleton al plugin.
CaptchalaConfig(...)Registro Dart sencillo: appKey, action, lang, theme, enableVoice, enableOfflineMode, maskClosable, serverToken.
await client.initialize(config)Aplica la configuración. Devuelve la misma instancia del cliente para encadenar setCallbacks.
setCallbacks(...)Registra los callbacks onSuccess, onFail, onError, onClose, onServerTokenExpired.
await client.verify()Abre la vista nativa del CAPTCHA (Android: Activity sobre Flutter; iOS: UIViewController sobre Flutter).
CaptchalaResultEntregado a onSuccess. Campos: passToken, challengeId, ttl, isOffline, isClientOnly.

Validación en el servidor

Reenvía result.passToken (o result.token) a tu backend y valídalo contra la API de CaptchaLa. Nunca expongas X-App-Secret en el código del cliente.

bash
POST https://apiv1.captcha.la/v1/validate
X-App-Key: YOUR_APP_KEY
X-App-Secret: YOUR_APP_SECRET
Content-Type: application/json

{ "pass_token": "<result.passToken>", "client_ip": "<end-user IP>" }

Consulta la Referencia de la API para el endpoint de validación completo y el flujo de X-App-Key / X-App-Secret.

Solución de problemas

  • Falla pod install en iOS
    En ios/Podfile ajusta platform :ios, '13.0' (o superior). Ejecuta flutter clean && flutter pub get && cd ios && pod install tras cambiar la versión del plugin.

  • Discordancia de minSdkVersion en Android
    Sube android/app/build.gradle a minSdkVersion 21. El SDK nativo de Android no compilará por debajo de ese nivel.

  • Los callbacks se disparan en un isolate en segundo plano
    Protege siempre setState con if (mounted) antes de mutar el estado de la UI dentro de los callbacks. La demo envuelve cada callback que actualiza el estado con esa comprobación.

  • Targets de escritorio (Linux / Windows / macOS)
    Linux requiere GTK3 + WebKitGTK + libcurl. Windows necesita el Edge WebView2 Runtime (Win 10 1809+). El escritorio de macOS usa el WebView del sistema automáticamente.

Requisitos

  • Flutter 3.10+ / Dart 3.0+
  • Android: minSdkVersion 21 (Android 5.0+)
  • iOS: 13.0+ con CocoaPods
  • Escritorio (opcional): GTK3 + WebKitGTK en Linux, WebView2 Runtime en Windows 10 1809+

MIT-licensed examples · CaptchaLa is operated independently