onramper_flutter 1.1.1 copy "onramper_flutter: ^1.1.1" to clipboard
onramper_flutter: ^1.1.1 copied to clipboard

PlatformiOS

Official Flutter plugin for the Onramper crypto on-ramp. Configures, initializes, and embeds a native SwiftUI checkout button. iOS-only, requires iOS 16+ and App Attest.

example/lib/main.dart

// Minimal example demonstrating the four-step onramper_sdk integration:
//
//   1. Create an OnramperClient with your API key, client ID, and a
//      sessionExpirationHandler that mints credentials from your backend.
//   2. Call client.initialize() with a fresh (sessionId, sessionToken) pair.
//   3. Call client.getCheckoutRequirements() to fetch the quote + requirements.
//   4. Embed OnramperCheckoutButton — it handles login, finalize, and payment.
//
// Credentials are injected at build time via --dart-define-from-file=.env.
// See the README for setup instructions.

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

import 'ios_diagnostics.dart';
import 'session_token_service.dart';

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

class ExampleApp extends StatelessWidget {
  const ExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Onramper SDK example',
      home: ExampleHome(),
    );
  }
}

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

  @override
  State<ExampleHome> createState() => _ExampleHomeState();
}

class _ExampleHomeState extends State<ExampleHome> {
  late final OnramperClient _client;
  CheckoutRequirementsResult? _requirements;
  String? _statusMessage;
  String? _errorMessage;
  bool _busy = false;
  IosAppIdentifiers? _appIdentifiers;

  static const _apiKey = String.fromEnvironment(
    'ONRAMPER_API_KEY',
    defaultValue: '',
  );
  static const _clientId = String.fromEnvironment(
    'ONRAMPER_CLIENT_ID',
    defaultValue: '',
  );
  static const _demoAuthToken = String.fromEnvironment(
    'ONRAMPER_DEMO_AUTH_TOKEN',
    defaultValue: '',
  );
  static const _walletAddress = String.fromEnvironment(
    'ONRAMPER_WALLET_ADDRESS',
    defaultValue: 'Br2jjHYskB1JJikv3Qw2QcmWVQGfZvkJFng4ZEwiGSjv',
  );

  @override
  void initState() {
    super.initState();
    _client = OnramperClient(
      configuration: const OnramperConfiguration(
        apiKey: _apiKey,
        clientId: _clientId,
        environment: OnramperEnvironment.development,
        logLevel: OnramperLogLevel.debug,
      ),
      sessionExpirationHandler: () =>
          SessionTokenService.fetch(authToken: _demoAuthToken),
    );
    _client.events.listen(_onEvent);
    _loadAppIdentifiers();
  }

  Future<void> _loadAppIdentifiers() async {
    try {
      final ids = await IosDiagnostics.readAppIdentifiers();
      debugPrint(
        'App launched with bundleId=${ids.bundleId} teamId=${ids.teamId}',
      );
      if (mounted) setState(() => _appIdentifiers = ids);
    } catch (e) {
      debugPrint('readAppIdentifiers failed: $e');
    }
  }

  @override
  void dispose() {
    _client.dispose();
    super.dispose();
  }

  void _onEvent(CheckoutEvent event) {
    setState(() => _statusMessage = 'event: ${event.kind.name}');
  }

  Future<void> _prepareCheckout() async {
    setState(() {
      _busy = true;
      _errorMessage = null;
      _statusMessage = 'minting session…';
    });
    try {
      final credentials =
          await SessionTokenService.fetch(authToken: _demoAuthToken);
      setState(() => _statusMessage = 'initializing…');
      await _client.initialize(
        sessionId: credentials.sessionId,
        sessionToken: credentials.sessionToken,
      );
      setState(() => _statusMessage = 'fetching checkout requirements…');
      final requirements = await _client.getCheckoutRequirements(
        const CheckoutIntentRequest(
          transactionData: OnramperTransactionData(
            source: 'usd',
            destination: 'sol',
            amount: 100,
            type: TransactionType.buy,
            country: 'us',
            subdivision: 'us-ca',
            paymentMethod: 'applepay',
            wallet: WalletInfo(network: 'solana', address: _walletAddress),
          ),
        ),
      );
      setState(() {
        _requirements = requirements;
        _statusMessage = 'ready — tap Buy';
      });
    } on OnramperError catch (e) {
      setState(() {
        _errorMessage = '${e.kind.name}: ${e.message}';
        _statusMessage = null;
      });
    } catch (e) {
      setState(() {
        _errorMessage = e.toString();
        _statusMessage = null;
      });
    } finally {
      if (mounted) setState(() => _busy = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Onramper SDK example')),
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.all(16),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              if (_appIdentifiers != null)
                _IdentifiersBanner(identifiers: _appIdentifiers!),
              if (_appIdentifiers != null) const SizedBox(height: 12),
              _buildHeader(),
              const SizedBox(height: 24),
              if (_requirements == null)
                ElevatedButton(
                  onPressed: _busy ? null : _prepareCheckout,
                  child: Text(_busy ? 'Preparing…' : 'Prepare checkout'),
                )
              else
                OnramperCheckoutButton(
                  requirements: _requirements!,
                ),
              const SizedBox(height: 24),
              if (_statusMessage != null) Text('Status: $_statusMessage'),
              if (_errorMessage != null) ...[
                const SizedBox(height: 8),
                Text(_errorMessage!, style: const TextStyle(color: Colors.red)),
              ],
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildHeader() {
    if (_apiKey.isEmpty || _clientId.isEmpty || _demoAuthToken.isEmpty) {
      return const _MissingEnvBanner();
    }
    return const Text(
      'Buy 100 USD of SOL via Apple Pay (sandbox). Tap "Prepare checkout" to '
      'mint a demo session and fetch requirements.',
      style: TextStyle(fontSize: 14),
    );
  }
}

class _IdentifiersBanner extends StatelessWidget {
  const _IdentifiersBanner({required this.identifiers});

  final IosAppIdentifiers identifiers;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(10),
      decoration: BoxDecoration(
        color: Colors.blueGrey.shade50,
        borderRadius: BorderRadius.circular(6),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            'Bundle: ${identifiers.bundleId}',
            style: const TextStyle(fontSize: 12, fontFamily: 'Courier'),
          ),
          Text(
            'Team:   ${identifiers.teamId}',
            style: const TextStyle(fontSize: 12, fontFamily: 'Courier'),
          ),
        ],
      ),
    );
  }
}

class _MissingEnvBanner extends StatelessWidget {
  const _MissingEnvBanner();

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(12),
      decoration: BoxDecoration(
        color: Colors.amber.shade100,
        borderRadius: BorderRadius.circular(8),
      ),
      child: const Text(
        'Pass ONRAMPER_API_KEY, ONRAMPER_CLIENT_ID, and ONRAMPER_DEMO_AUTH_TOKEN '
        'via --dart-define before running. The demo auth token authorises the '
        'session-minting endpoint at demo-stg.onramper.dev.',
        style: TextStyle(fontSize: 12),
      ),
    );
  }
}
0
likes
150
points
20
downloads

Documentation

Documentation
API reference

Publisher

verified publisheronramper.com

Weekly Downloads

Official Flutter plugin for the Onramper crypto on-ramp. Configures, initializes, and embeds a native SwiftUI checkout button. iOS-only, requires iOS 16+ and App Attest.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter, url_launcher

More

Packages that depend on onramper_flutter

Packages that implement onramper_flutter