fl_openpay 0.0.1 copy "fl_openpay: ^0.0.1" to clipboard
fl_openpay: ^0.0.1 copied to clipboard

Flutter plugin for Openpay payment gateway. Supports card tokenization, device fingerprinting, and 3D Secure for iOS and Android.

example/lib/main.dart

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

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Openpay Example',
      theme: ThemeData(
        colorSchemeSeed: Colors.blue,
        useMaterial3: true,
      ),
      home: const OpenpayDemoPage(),
    );
  }
}

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

  @override
  State<OpenpayDemoPage> createState() => _OpenpayDemoPageState();
}

class _OpenpayDemoPageState extends State<OpenpayDemoPage> {
  final _openpay = FlOpenpay();
  final _formKey = GlobalKey<FormState>();

  final _merchantIdController = TextEditingController();
  final _apiKeyController = TextEditingController();
  final _holderNameController = TextEditingController();
  final _cardNumberController = TextEditingController();
  final _monthController = TextEditingController();
  final _yearController = TextEditingController();
  final _cvvController = TextEditingController();

  bool _productionMode = false;
  OpenpayCountry _country = OpenpayCountry.mexico;
  String _status = '';
  bool _loading = false;

  @override
  void dispose() {
    _merchantIdController.dispose();
    _apiKeyController.dispose();
    _holderNameController.dispose();
    _cardNumberController.dispose();
    _monthController.dispose();
    _yearController.dispose();
    _cvvController.dispose();
    super.dispose();
  }

  Future<void> _initialize() async {
    if (_merchantIdController.text.isEmpty || _apiKeyController.text.isEmpty) {
      _setStatus('Enter Merchant ID and API Key first.');
      return;
    }
    setState(() => _loading = true);
    try {
      await _openpay.initialize(
        merchantId: _merchantIdController.text.trim(),
        publicApiKey: _apiKeyController.text.trim(),
        productionMode: _productionMode,
        country: _country,
      );
      _setStatus('SDK initialized successfully.');
    } on OpenpayException catch (e) {
      _setStatus('Init error: ${e.message}');
    } catch (e) {
      _setStatus('Init error: $e');
    } finally {
      setState(() => _loading = false);
    }
  }

  Future<void> _tokenize() async {
    if (!_formKey.currentState!.validate()) return;
    if (!_openpay.isInitialized) {
      _setStatus('Initialize SDK first.');
      return;
    }
    setState(() => _loading = true);
    try {
      final token = await _openpay.tokenizeCard(
        OpenpayCard(
          holderName: _holderNameController.text.trim(),
          cardNumber: _cardNumberController.text.trim(),
          expirationMonth: _monthController.text.trim(),
          expirationYear: _yearController.text.trim(),
          cvv2: _cvvController.text.trim(),
        ),
      );
      _setStatus('Token: ${token.id}\nBrand: ${token.brand}\nCard: ${token.cardNumberMasked}');
    } on OpenpayGatewayException catch (e) {
      _setStatus('Bank declined [${e.code}]: ${e.message}');
    } on OpenpayRequestException catch (e) {
      _setStatus('Request error [${e.code}]: ${e.message}');
    } on OpenpayException catch (e) {
      _setStatus('Error [${e.code}]: ${e.message}');
    } catch (e) {
      _setStatus('Error: $e');
    } finally {
      setState(() => _loading = false);
    }
  }

  Future<void> _getSessionId() async {
    if (!_openpay.isInitialized) {
      _setStatus('Initialize SDK first.');
      return;
    }
    setState(() => _loading = true);
    try {
      final sessionId = await _openpay.createDeviceSessionId();
      _setStatus('Device Session ID:\n$sessionId');
    } on OpenpayException catch (e) {
      _setStatus('Session error: ${e.message}');
    } catch (e) {
      _setStatus('Error: $e');
    } finally {
      setState(() => _loading = false);
    }
  }

  void _setStatus(String message) {
    setState(() => _status = message);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Openpay Demo')),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: Form(
          key: _formKey,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              // -- Configuration --
              Text('Configuration', style: Theme.of(context).textTheme.titleMedium),
              const SizedBox(height: 8),
              TextFormField(
                controller: _merchantIdController,
                decoration: const InputDecoration(
                  labelText: 'Merchant ID',
                  border: OutlineInputBorder(),
                ),
              ),
              const SizedBox(height: 8),
              TextFormField(
                controller: _apiKeyController,
                decoration: const InputDecoration(
                  labelText: 'Public API Key',
                  border: OutlineInputBorder(),
                ),
              ),
              const SizedBox(height: 8),
              Row(
                children: [
                  Expanded(
                    child: DropdownButtonFormField<OpenpayCountry>(
                      initialValue: _country,
                      decoration: const InputDecoration(
                        labelText: 'Country',
                        border: OutlineInputBorder(),
                      ),
                      items: OpenpayCountry.values
                          .map((c) => DropdownMenuItem(value: c, child: Text(c.name)))
                          .toList(),
                      onChanged: (v) => setState(() => _country = v!),
                    ),
                  ),
                  const SizedBox(width: 12),
                  Column(
                    children: [
                      const Text('Production'),
                      Switch(
                        value: _productionMode,
                        onChanged: (v) => setState(() => _productionMode = v),
                      ),
                    ],
                  ),
                ],
              ),
              const SizedBox(height: 8),
              FilledButton(
                onPressed: _loading ? null : _initialize,
                child: const Text('Initialize SDK'),
              ),

              const Divider(height: 32),

              // -- Card Data --
              Text('Card Data', style: Theme.of(context).textTheme.titleMedium),
              const SizedBox(height: 8),
              TextFormField(
                controller: _holderNameController,
                decoration: const InputDecoration(
                  labelText: 'Holder Name',
                  border: OutlineInputBorder(),
                ),
                validator: (v) => (v == null || v.isEmpty) ? 'Required' : null,
              ),
              const SizedBox(height: 8),
              TextFormField(
                controller: _cardNumberController,
                decoration: const InputDecoration(
                  labelText: 'Card Number',
                  border: OutlineInputBorder(),
                ),
                keyboardType: TextInputType.number,
                validator: (v) => (v == null || v.length < 15) ? 'Invalid card number' : null,
              ),
              const SizedBox(height: 8),
              Row(
                children: [
                  Expanded(
                    child: TextFormField(
                      controller: _monthController,
                      decoration: const InputDecoration(
                        labelText: 'Month (MM)',
                        border: OutlineInputBorder(),
                      ),
                      keyboardType: TextInputType.number,
                      validator: (v) => (v == null || v.isEmpty) ? 'Required' : null,
                    ),
                  ),
                  const SizedBox(width: 8),
                  Expanded(
                    child: TextFormField(
                      controller: _yearController,
                      decoration: const InputDecoration(
                        labelText: 'Year (YY)',
                        border: OutlineInputBorder(),
                      ),
                      keyboardType: TextInputType.number,
                      validator: (v) => (v == null || v.isEmpty) ? 'Required' : null,
                    ),
                  ),
                  const SizedBox(width: 8),
                  Expanded(
                    child: TextFormField(
                      controller: _cvvController,
                      decoration: const InputDecoration(
                        labelText: 'CVV',
                        border: OutlineInputBorder(),
                      ),
                      keyboardType: TextInputType.number,
                      obscureText: true,
                      validator: (v) => (v == null || v.length < 3) ? 'Invalid' : null,
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 12),
              Row(
                children: [
                  Expanded(
                    child: FilledButton(
                      onPressed: _loading ? null : _tokenize,
                      child: const Text('Tokenize Card'),
                    ),
                  ),
                  const SizedBox(width: 8),
                  Expanded(
                    child: OutlinedButton(
                      onPressed: _loading ? null : _getSessionId,
                      child: const Text('Get Session ID'),
                    ),
                  ),
                ],
              ),

              const Divider(height: 32),

              // -- Status --
              if (_loading) const Center(child: CircularProgressIndicator()),
              if (_status.isNotEmpty)
                Container(
                  padding: const EdgeInsets.all(12),
                  decoration: BoxDecoration(
                    color: Theme.of(context).colorScheme.surfaceContainerHighest,
                    borderRadius: BorderRadius.circular(8),
                  ),
                  child: SelectableText(
                    _status,
                    style: Theme.of(context).textTheme.bodyMedium,
                  ),
                ),
            ],
          ),
        ),
      ),
    );
  }
}
0
likes
150
points
84
downloads

Publisher

unverified uploader

Weekly Downloads

Flutter plugin for Openpay payment gateway. Supports card tokenization, device fingerprinting, and 3D Secure for iOS and Android.

Repository (GitHub)
View/report issues

Topics

#payments #openpay #tokenization #subscriptions

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on fl_openpay

Packages that implement fl_openpay