Zipup SDK

zipup_partners

Flutter plugin for the Zipup SDK. It integrates the native Android AAR and iOS framework to show a WebView-based flow with real-time events between the WebView and your Flutter app.

Features

  • Android & iOS: Uses the native Zipup SDK (AAR on Android, XCFramework on iOS).
  • Init, open, close: Initialize with credentials, open the SDK WebView, and close it from Dart.
  • Event stream: Receive events (e.g. ready, onClose, onOpen) via a single callback.
  • Ready timeout: If the WebView does not send ready within 10 seconds, the SDK is closed automatically.
  • External URLs: onOpen events with a URL are opened in the external browser via url_launcher.

Installation

Add the dependency to your pubspec.yaml:

dependencies:
  zipup_partners:
    git:
      url: https://github.com/your-org/zipup_sdk_flutter.git
      # or use a local path:
      # path: ../zipup_sdk_flutter

Then run:

flutter pub get

iOS

From your project root:

cd ios
pod install

Usage

1. Initialize the SDK

Call init with your credentials before opening the WebView:

import 'package:zipup_partners/zipup_sdk_flutter.dart';

final zipupSdk = ZipupSdk();

await zipupSdk.init(
  'your_user_key',
  'your_user_phone',
  'your_proxy_url',
);

2. Register for events (before opening)

Use addEventListener so you receive ready, onClose, onOpen, etc. Register before calling open() so you do not miss the ready event.

zipupSdk.addEventListener(({required String event, data}) {
  switch (event) {
    case 'ready':
      // WebView is ready.
      break;
    case 'onClose':
      // User or flow closed the WebView.
      break;
    case 'onOpen':
      // data may contain a URL to open externally (handled by the plugin).
      break;
    default:
      break;
  }
});

3. Open the SDK

Opening the WebView starts a 10-second timer. If the WebView does not send a ready event within 10 seconds, the plugin calls close() automatically.

await zipupSdk.open();

4. Close the SDK

You can close the WebView from your app:

await zipupSdk.close();

5. Clean up

When you are done (e.g. in dispose):

zipupSdk.removeEventListener();

Complete example

import 'package:flutter/material.dart';
import 'package:zipup_partners/zipup_sdk_flutter.dart';
import 'dart:async';

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

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final _zipupSdk = ZipupSdk();
  String _status = 'Ready';
  StreamSubscription<Map<String, dynamic>>? _eventSubscription;

  @override
  void initState() {
    super.initState();
    _eventSubscription = _zipupSdk.addEventListener(({required event, data}) {
      if (mounted) {
        setState(() => _status = 'Event: $event${data != null ? ' - $data' : ''}');
      }
    });
  }

  @override
  void dispose() {
    _eventSubscription?.cancel();
    _zipupSdk.removeEventListener();
    super.dispose();
  }

  Future<void> _initSdk() async {
    setState(() => _status = 'Initializing...');
    final result = await _zipupSdk.init(
      'your_user_key',
      'your_user_phone',
      'your_proxy_url',
    );
    if (mounted) setState(() => _status = result ?? 'Init failed');
  }

  Future<void> _openSdk() async {
    setState(() => _status = 'Opening...');
    final result = await _zipupSdk.open();
    if (mounted) setState(() => _status = result ?? 'Open failed');
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Zipup SDK Example')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(_status, style: const TextStyle(color: Colors.grey)),
              const SizedBox(height: 24),
              ElevatedButton(onPressed: _initSdk, child: const Text('Initialize SDK')),
              const SizedBox(height: 16),
              ElevatedButton(onPressed: _openSdk, child: const Text('Open Zipup SDK')),
            ],
          ),
        ),
      ),
    );
  }
}

API reference

ZipupSdk

Method / getter Description
Future<String?> init(String userKey, String userPhone, String proxyUrl) Initialize the SDK. Must be called before open().
Future<String?> open() Open the SDK WebView. Starts a 10-second timer; if ready is not received in time, close() is called.
Future<String?> close() Close the SDK WebView and cancel the ready timeout.
Stream<Map<String, dynamic>>? getEventStream() Raw event stream. Prefer addEventListener for a single callback.
StreamSubscription<Map<String, dynamic>>? addEventListener(ZipupEventCallback callback) Subscribe to events with a callback. Call before open() so ready is not missed. Returns the subscription (optional to store).
void removeEventListener() Cancel the internal event subscription. Call from dispose or when no longer needed.

Events

  • ready – WebView has sent that it is ready. The 10-second timeout is cancelled.
  • onClose – WebView was closed (e.g. by user). The plugin calls close() when this is received.
  • onOpen – Contains a URL; the plugin opens it in the external browser (via url_launcher).

Callback type

typedef ZipupEventCallback = void Function({required String event, dynamic data});

Requirements

  • Flutter >= 3.3.0
  • Dart >= 3.11.0
  • iOS: see native Zipup SDK requirements
  • Android: see native Zipup SDK (AAR) requirements

Loading UI

Loading UI (e.g. overlay until ready) is implemented inside the native Android AAR and iOS framework, not in this Flutter plugin. No extra Flutter code is required for the built-in loading behavior.

License

See the LICENSE file.

Support

For issues or questions, please open an issue in the repository.