Flutter预付费功能插件prepaid_lib_flutter的使用

Flutter预付费功能插件prepaid_lib_flutter的使用

简介

prepaid_lib_flutter 是一个用于实现预付费功能的 Flutter 插件。它提供了与 NFC 卡交互的能力,例如读取卡信息、更新余额等操作。


使用步骤

1. 初始化插件

在应用启动时,调用 UnikLibFlutter.initUnikLib 方法初始化插件,并传入商户 ID 和其他必要的参数。

void initLibrary() async {
  print("mid : 1bdaf34aef1656dcb2abe461255d8f57");
  isSuccessInit =
      await UnikLibFlutter.initUnikLib("1bdaf34aef1656dcb2abe461255d8f57", 1);
  print("isSuccessInit $isSuccessInit");
}

2. 获取卡信息

通过调用 UnikLibFlutter.getCardInfo 方法获取 NFC 卡的信息,包括卡号、余额、银行名称等。

void getCardInfo() async {
  _setStateDefault();

  List<String> cardUid = [''];
  List<String> cardNumber = [''];
  List<String> balance = [''];
  List<String> bankName = [''];

  bool isSuccess = await UnikLibFlutter.getCardInfo(
      cardUid, cardNumber, balance, bankName,
      startPooling: true,
      callbackTimeout: (bool isTimeout) {
        print("timeout $isTimeout");
        return false;
      },
      errorNfc: (bool nfcIsNotDetected) {
        print("--> errorNfc $nfcIsNotDetected");
        return false;
      },
      callbackState: (String value) => print(value));

  if (isSuccess) {
    UnikLibFlutter.stopReader(messageSuccess: "Cek saldo berhasil");

    _setStateCard(true, cardNumber[0], balance[0], bankName[0]);
  } else {
    print("Terjadi kesalahan");
    _setStateDefault();
    if (Platform.isAndroid) Navigator.pop(context);
  }
}

3. 更新余额

通过调用 UnikLibFlutter.updateBalance 方法更新卡的余额。

void updateBalance() async {
  _setStateDefault();
  List<String> status = [null];
  List<String> cardNumber = [null];
  List<String> balance = [null];
  List<String> bankName = [null];

  bool isSuccess = await UnikLibFlutter.updateBalance(
      status, cardNumber, balance, bankName, beforeBalance, "085735442829", "developer@mdd.co.id",
      callbackState: (String stateOperation) =>
          (stateOperation == UnikLibFlutter.WAITING_STATUS)
              ? UnikLibFlutter.setIosMessage("Mohon tunggu, jangan lepaskan kartu")
              : print("state operation DONE"),
      callbackTimeout: (bool isTimeout) => print("timeout $isTimeout"),
      errorNfc: (bool value) => print("error nfc $value"),
      reffNo: "23488");

  if (isSuccess) {
    UnikLibFlutter.stopReader(messageSuccess: "Update balance berhasil");
    _setStateCard(true, cardNumber[0], balance[0], bankName[0]);
  } else {
    print("Terjadi kesalahan");
    UnikLibFlutter.stopReader(messageError: "Update balance gagal");
    _setStateCard(false, cardNumber[0], balance[0], bankName[0]);
  }
}

4. 界面展示

以下是一个完整的界面示例,展示了如何使用上述方法并展示卡信息。

class NfcScan extends StatefulWidget {
  NfcScan({Key key}) : super(key: key);

  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<NfcScan> {
  String _balance = "0", _cardNumber = "000000000000000", _status = "Unknown";
  String _bgCard = "images/mandiri_bg.png";
  bool _isLoading = false;
  List<dynamic> listHistory;

  [@override](/user/override)
  void initState() {
    super.initState();
    initLibrary();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        height: MediaQuery.of(context).size.height,
        width: MediaQuery.of(context).size.width,
        child: SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Container(
                width: MediaQuery.of(context).size.width,
                height: 200,
                decoration: BoxDecoration(
                  image: DecorationImage(
                    fit: BoxFit.fill,
                    image: AssetImage('images/bg_home.png'),
                  ),
                ),
                child: Align(
                  alignment: Alignment(0, 17),
                  child: Container(
                    padding: EdgeInsets.only(left: 20, right: 20),
                    decoration: BoxDecoration(
                      image: DecorationImage(
                        fit: BoxFit.fill,
                        image: AssetImage(_bgCard),
                      ),
                      borderRadius: BorderRadius.circular(25),
                      boxShadow: [
                        BoxShadow(
                          color: Colors.grey.withOpacity(0.3),
                          spreadRadius: 2,
                          blurRadius: 2,
                          offset: Offset(3, 3),
                        ),
                      ],
                    ),
                    width: 322,
                    height: 190,
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        SizedBox(height: 70),
                        DefaultTextStyle(
                          style: TextStyle(color: Colors.white),
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Text(
                                _cardNumber.replaceAllMapped(
                                  RegExp(r".{4}"),
                                  (match) => "${match.group(0)} ",
                                ),
                                style: TextStyle(
                                  color: Colors.white,
                                  fontSize: 18,
                                ),
                              ),
                              SizedBox(height: 17),
                              Text("Saldo", style: TextStyle(color: Colors.white38, fontSize: 15)),
                              SizedBox(height: 3),
                              Text(
                                NumberFormat.simpleCurrency(locale: 'id_ID').format(int.parse(_balance) ?? 0),
                                style: TextStyle(color: Colors.white),
                              ),
                            ],
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ),
              SizedBox(height: 100),
              Container(
                width: 300,
                child: ElevatedButton.icon(
                  label: Text('Update'),
                  icon: Icon(Icons.update_rounded),
                  onPressed: () {
                    updateBalance();
                  },
                ),
              ),
              SizedBox(height: 30),
              Align(
                alignment: Alignment.center,
                child: _isLoading
                    ? CircularProgressIndicator()
                    : Text(_status ?? "Unknown"),
              ),
              SizedBox(height: 10),
              (listHistory != null)
                  ? listViewBuilder(listHistory)
                  : SizedBox(width: 1),
            ],
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          getCardInfo();
        },
        child: Icon(Icons.cached),
        backgroundColor: Colors.blue,
      ),
    );
  }
}

完整示例代码

以下是完整的示例代码,包含了初始化、获取卡信息、更新余额以及界面展示的完整逻辑。

import 'dart:convert';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:prepaid_lib_flutter/unik_lib_flutter.dart';
import 'package:intl/intl.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(child: NfcScan()),
      ),
    );
  }
}

class NfcScan extends StatefulWidget {
  NfcScan({Key key}) : super(key: key);

  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<NfcScan> {
  String _balance = "0", _cardNumber = "000000000000000", _status = "Unknown";
  String _bgCard = "images/mandiri_bg.png";
  bool _isLoading = false;
  List<dynamic> listHistory;

  [@override](/user/override)
  void initState() {
    super.initState();
    initLibrary();
  }

  void initLibrary() async {
    print("mid : 1bdaf34aef1656dcb2abe461255d8f57");
    bool isSuccessInit = await UnikLibFlutter.initUnikLib(
        "1bdaf34aef1656dcb2abe461255d8f57", 1);
    print("isSuccessInit $isSuccessInit");
  }

  void getCardInfo() async {
    _setStateDefault();

    List<String> cardUid = [''];
    List<String> cardNumber = [''];
    List<String> balance = [''];
    List<String> bankName = [''];

    bool isSuccess = await UnikLibFlutter.getCardInfo(
        cardUid, cardNumber, balance, bankName,
        startPooling: true,
        callbackTimeout: (bool isTimeout) {
          print("timeout $isTimeout");
          return false;
        },
        errorNfc: (bool nfcIsNotDetected) {
          print("--> errorNfc $nfcIsNotDetected");
          return false;
        },
        callbackState: (String value) => print(value));

    if (isSuccess) {
      UnikLibFlutter.stopReader(messageSuccess: "Cek saldo berhasil");
      _setStateCard(true, cardNumber[0], balance[0], bankName[0]);
    } else {
      print("Terjadi kesalahan");
      _setStateDefault();
      if (Platform.isAndroid) Navigator.pop(context);
    }
  }

  void updateBalance() async {
    _setStateDefault();
    List<String> status = [null];
    List<String> cardNumber = [null];
    List<String> balance = [null];
    List<String> bankName = [null];

    bool isSuccess = await UnikLibFlutter.updateBalance(
        status, cardNumber, balance, bankName, ["0"], "085735442829", "developer@mdd.co.id",
        callbackState: (String stateOperation) =>
            (stateOperation == UnikLibFlutter.WAITING_STATUS)
                ? UnikLibFlutter.setIosMessage("Mohon tunggu, jangan lepaskan kartu")
                : print("state operation DONE"),
        callbackTimeout: (bool isTimeout) => print("timeout $isTimeout"),
        errorNfc: (bool value) => print("error nfc $value"),
        reffNo: "23488");

    if (isSuccess) {
      UnikLibFlutter.stopReader(messageSuccess: "Update balance berhasil");
      _setStateCard(true, cardNumber[0], balance[0], bankName[0]);
    } else {
      print("Terjadi kesalahan");
      UnikLibFlutter.stopReader(messageError: "Update balance gagal");
      _setStateCard(false, cardNumber[0], balance[0], bankName[0]);
    }
  }

  void _setStateCard(bool isSuccess, String cardNumber, String balance, String bankName) {
    setState(() {
      _cardNumber = cardNumber ?? "0000000000000000";
      _balance = balance ?? "0";
      _bgCard = (bankName == "BNI") ? "images/bni_bg.png" : "images/mandiri_bg.png";
    });
  }

  void _setStateDefault() {
    setState(() {
      _cardNumber = "0000000000000000";
      _balance = "0";
      _bgCard = "images/mandiri_bg.png";
      listHistory = null;
      _status = "Unknown";
    });
  }

  Widget listViewBuilder(List<dynamic> list) {
    return Container(
      height: 300,
      child: ListView.builder(
        itemBuilder: (context, index) {
          return Column(
            children: [
              Text("amount : ${list[index]["amount"]}"),
              Text("date : ${list[index]["date"]}"),
              Text("type : ${list[index]["type"]}"),
              SizedBox(height: 10),
            ],
          );
        },
        itemCount: list.length,
      ),
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        height: MediaQuery.of(context).size.height,
        width: MediaQuery.of(context).size.width,
        child: SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Container(
                width: MediaQuery.of(context).size.width,
                height: 200,
                decoration: BoxDecoration(
                  image: DecorationImage(
                    fit: BoxFit.fill,
                    image: AssetImage('images/bg_home.png'),
                  ),
                ),
                child: Align(
                  alignment: Alignment(0, 17),
                  child: Container(
                    padding: EdgeInsets.only(left: 20, right: 20),
                    decoration: BoxDecoration(
                      image: DecorationImage(
                        fit: BoxFit.fill,
                        image: AssetImage(_bgCard),
                      ),
                      borderRadius: BorderRadius.circular(25),
                      boxShadow: [
                        BoxShadow(
                          color: Colors.grey.withOpacity(0.3),
                          spreadRadius: 2,
                          blurRadius: 2,
                          offset: Offset(3, 3),
                        ),
                      ],
                    ),
                    width: 322,
                    height: 190,
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        SizedBox(height: 70),
                        DefaultTextStyle(
                          style: TextStyle(color: Colors.white),
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Text(
                                _cardNumber.replaceAllMapped(
                                  RegExp(r".{4}"),
                                  (match) => "${match.group(0)} ",
                                ),
                                style: TextStyle(
                                  color: Colors.white,
                                  fontSize: 18,
                                ),
                              ),
                              SizedBox(height: 17),
                              Text("Saldo", style: TextStyle(color: Colors.white38, fontSize: 15)),
                              SizedBox(height: 3),
                              Text(
                                NumberFormat.simpleCurrency(locale: 'id_ID').format(int.parse(_balance) ?? 0),
                                style: TextStyle(color: Colors.white),
                              ),
                            ],
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ),
              SizedBox(height: 100),
              Container(
                width: 300,
                child: ElevatedButton.icon(
                  label: Text('Update'),
                  icon: Icon(Icons.update_rounded),
                  onPressed: () {
                    updateBalance();
                  },
                ),
              ),
              SizedBox(height: 30),
              Align(
                alignment: Alignment.center,
                child: _isLoading
                    ? CircularProgressIndicator()
                    : Text(_status ?? "Unknown"),
              ),
              SizedBox(height: 10),
              (listHistory != null)
                  ? listViewBuilder(listHistory)
                  : SizedBox(width: 1),
            ],
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          getCardInfo();
        },
        child: Icon(Icons.cached),
        backgroundColor: Colors.blue,
      ),
    );
  }
}

更多关于Flutter预付费功能插件prepaid_lib_flutter的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter预付费功能插件prepaid_lib_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


prepaid_lib_flutter 是一个用于处理预付费功能的 Flutter 插件,通常用于移动应用中的支付、订阅或充值功能。以下是如何使用该插件的基本步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 prepaid_lib_flutter 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  prepaid_lib_flutter: ^1.0.0  # 请根据实际情况使用最新版本

然后运行 flutter pub get 来获取依赖。

2. 初始化插件

在你的 Dart 代码中,首先需要初始化插件。通常这一步会在 main.dart 或应用的入口文件中完成。

import 'package:prepaid_lib_flutter/prepaid_lib_flutter.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await PrepaidLibFlutter.initialize();
  runApp(MyApp());
}

3. 使用插件的功能

prepaid_lib_flutter 插件通常提供了一些方法来处理预付费功能,比如充值、查询余额、购买订阅等。以下是一些常见的使用示例:

3.1 充值

Future<void> recharge(String userId, double amount) async {
  try {
    await PrepaidLibFlutter.recharge(userId, amount);
    print('Recharge successful');
  } catch (e) {
    print('Recharge failed: $e');
  }
}

3.2 查询余额

Future<double> getBalance(String userId) async {
  try {
    double balance = await PrepaidLibFlutter.getBalance(userId);
    print('Balance: $balance');
    return balance;
  } catch (e) {
    print('Failed to get balance: $e');
    return 0.0;
  }
}

3.3 购买订阅

Future<void> purchaseSubscription(String userId, String subscriptionId) async {
  try {
    await PrepaidLibFlutter.purchaseSubscription(userId, subscriptionId);
    print('Subscription purchased successfully');
  } catch (e) {
    print('Subscription purchase failed: $e');
  }
}

4. 处理回调

某些操作可能需要处理回调,比如支付成功或失败的回调。你可以使用 PrepaidLibFlutter 提供的回调方法来处理这些事件。

PrepaidLibFlutter.setPaymentCallback((PaymentResult result) {
  if (result.isSuccess) {
    print('Payment successful: ${result.transactionId}');
  } else {
    print('Payment failed: ${result.errorMessage}');
  }
});

5. 处理错误

在使用插件时,可能会遇到各种错误,比如网络错误、支付失败等。你需要妥善处理这些错误,以提供更好的用户体验。

try {
  await PrepaidLibFlutter.recharge(userId, amount);
} catch (e) {
  print('Error: $e');
  // 显示错误消息给用户
}
回到顶部