Flutter二维码生成与解析插件emvqrcode的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter二维码生成与解析插件emvqrcode的使用

简介

emvqrcode 是一个用于解码和编码 EMVCO 标准二维码的 Dart 包。EMVCO(EMV Contactless)是一个国际标准组织,负责制定和维护非接触式支付技术的标准。

安装

使用 Flutter

$ flutter pub add emvqrcode

使用 Dart

$ dart pub add emvqrcode

pubspec.yaml 中添加依赖

dependencies:
  emvqrcode: ^1.0.5

使用方法

MPM (Merchant Present Mode)

解码

import 'package:emvqrcode/emvqrcode.dart';

void main() {
  String emvqr = "00020001021203200002IT0103abc0203def04200002IT0103abc0203def624601050qwea1006tax id1103cha1202135003123510312364410002LA0102MW0209Vientaine0304asfg0404asfg6503bbc6603bbb89230003abs0104qw120204qw1281230003sdf0504ffff0604ffff63042E4E";
  final emvdecode = EMVMPM.decode(emvqr);

  // 打印解码后的 JSON 模型
  debugPrint("emv decode -------> ${emvdecode.toJson()}");
}

生成

import 'package:emvqrcode/emvqrcode.dart';

void main() {
  final emv = EMVQR();

  emv.setPayloadFormatIndicator("00");
  emv.setPointOfInitiationMethod("12");

  // 商户账户信息
  final mAccountInfo = MerchantAccountInformation();
  mAccountInfo.setGloballyUniqueIdentifier("IT");
  mAccountInfo.addPaymentNetworkSpecific(id: "01", value: "abc");
  mAccountInfo.addPaymentNetworkSpecific(id: "02", value: "def");
  emv.addMerchantAccountInformation(id: "03", value: mAccountInfo);

  // 另一个商户账户信息
  final mAccountInfo2 = MerchantAccountInformation();
  mAccountInfo2.setGloballyUniqueIdentifier("IT");
  mAccountInfo2.addPaymentNetworkSpecific(id: "01", value: "abc");
  mAccountInfo2.addPaymentNetworkSpecific(id: "02", value: "def");
  emv.addMerchantAccountInformation(id: "04", value: mAccountInfo2);

  // 额外字段
  final additionalData = AdditionalDataFieldTemplate();
  additionalData.setBillNumber("0qwea");
  additionalData.setMerchantTaxID("tax id");
  additionalData.setMerchantChannel("cha");
  additionalData.addRfuForEMVCo(id: "12", value: "00");
  additionalData.addRfuForEMVCo(id: "13", value: "13");
  additionalData.addPaymentSystemSpecific(id: "50", value: "123");
  additionalData.addPaymentSystemSpecific(id: "51", value: "123");
  emv.setAdditionalDataFieldTemplate(additionalData);

  // 商户信息语言模板
  final mInfoLang = MerchantInformationLanguageTemplate();
  mInfoLang.setLanguagePreferencer("LA");
  mInfoLang.setMerchantCity("Vientaine");
  mInfoLang.setMerchantName("MW");
  mInfoLang.addRfuForEMVCo(id: "03", value: "asfg");
  mInfoLang.addRfuForEMVCo(id: "04", value: "asfg");
  emv.setMerchantInformationLanguageTemplate(mInfoLang);

  emv.addRfuForEMVCo(id: "65", value: "bbc");
  emv.addRfuForEMVCo(id: "66", value: "bbb");

  final unreserved1 = UnreservedTemplate();
  unreserved1.setGloballyUniqueIdentifier("abs");
  unreserved1.addContextSpecificData(id: "01", value: "qw12");
  unreserved1.addContextSpecificData(id: "02", value: "qw12");
  emv.addUnreservedTemplate(id: "89", value: unreserved1);

  // 编码数据为 EMVCo
  final emvEncode = EMVMPM.encode(emv);

  // 打印编码后的 JSON 模型
  debugPrint("emv encode -------> ${emvEncode.toJson()}");
}

验证 CRC EMVCO

import 'package:emvqrcode/emvqrcode.dart';

void main() {
  final wrongData = "00020101021138670016A00526628466257701082771041802030010324ZPOSUALNJBWWVYSEIRIESGFE6304D1B9";

  // 验证 EMVQR
  final verified = verifyEmvQr(wrongData);

  if (verified) {
    debugPrint("emvCo corrected");
  } else {
    debugPrint("emvCo incorrect");
  }
}

CPM (Consumer Present Mode)

生成

import 'package:emvqrcode/emvqrcode.dart';

void main() {
  final qr = CPM();

  qr.setDataPayloadFormatIndicator("CPV01");

  final appTemplate1 = ApplicationTemplate();
  appTemplate1.setBerTvl(
    BerTvl(
      dataApplicationDefinitionFileName: "A0000000555555",
      dataApplicationLabel: "Product1",
    ),
  );
  qr.addApplicationTemplate(appTemplate1);

  final appTemplate2 = ApplicationTemplate();
  appTemplate2.setBerTvl(
    BerTvl(
      dataApplicationDefinitionFileName: "A0000000666666",
      dataApplicationLabel: "Product2",
    ),
  );
  qr.addApplicationTemplate(appTemplate2);

  final cdt = CommonDataTemplate();
  cdt.setBerTvl(
    BerTvl(
      dataApplicationPan: "1234567890123458",
      dataCardholderName: "CARDHOLDER/EMV",
      dataLanguagePreference: "ruesdeen",
    ),
  );
  cdt.addCommonDataTransparentTemplates(
    BerTvl(
      dataIssuerApplicationData: '06010A03000000',
      dataApplicationCryptogram: "584FD385FA234BCC",
      dataApplicationTransactionCounter: "0001",
      dataUnpredictableNumber: "6D58EF13",
    ),
  );
  qr.addCommonDataTemplate(cdt);

  final cpm = EMVCPM();

  // 生成 CPM EMVCo
  final value = cpm.generatePayload(qr);

  debugPrint("cpm emvCo -------> $value");
}

待办事项

  • 添加解码 CPM
  • 重写生成 CPM EMVCO 的 API

致谢

希望这些示例能帮助你更好地理解和使用 emvqrcode 插件。如果有任何问题或建议,请随时联系我。


更多关于Flutter二维码生成与解析插件emvqrcode的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter二维码生成与解析插件emvqrcode的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,emvqrcode 插件可以用于生成和解析EMV二维码。尽管具体的插件实现细节可能因版本而异,但以下是一个基本的示例,展示了如何使用该插件进行二维码的生成和解析。

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

dependencies:
  flutter:
    sdk: flutter
  emvqrcode: ^最新版本号  # 请替换为实际的最新版本号

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

接下来是一个示例代码,展示如何使用 emvqrcode 插件来生成和解析二维码:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('EMV QR Code Example'),
        ),
        body: QRCodeExample(),
      ),
    );
  }
}

class QRCodeExample extends StatefulWidget {
  @override
  _QRCodeExampleState createState() => _QRCodeExampleState();
}

class _QRCodeExampleState extends State<QRCodeExample> {
  String qrCodeData = '';
  String parsedData = '';

  void generateQRCode() async {
    // 假设我们有一些EMV二维码数据
    String emvData = '{"pan": "1234567812345670", "expMonth": "12", "expYear": "25", "cvn": "123"}';

    // 生成二维码数据
    String qrCodeString = await EMVQRCode.generateQRCode(emvData);

    // 更新状态以显示二维码
    setState(() {
      qrCodeData = qrCodeString;
    });
  }

  void parseQRCode() async {
    // 假设我们已经有一个二维码字符串(通常从扫描器获得)
    String qrCodeString = qrCodeData; // 在实际应用中,这将是从扫描器获取的字符串

    // 解析二维码数据
    Map<String, dynamic> parsedResult = await EMVQRCode.parseQRCode(qrCodeString);

    // 更新状态以显示解析结果
    setState(() {
      parsedData = parsedResult.toString();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('Generated QR Code Data:', style: TextStyle(fontSize: 18)),
          SizedBox(height: 8),
          ElevatedButton(
            onPressed: generateQRCode,
            child: Text('Generate QR Code'),
          ),
          SizedBox(height: 16),
          if (qrCodeData.isNotEmpty)
            QrCodeWidget(
              qrCodeData: qrCodeData,
              size: 200,
            ),
          SizedBox(height: 16),
          Text('Parsed QR Code Data:', style: TextStyle(fontSize: 18)),
          SizedBox(height: 8),
          ElevatedButton(
            onPressed: parseQRCode,
            child: Text('Parse QR Code'),
          ),
          SizedBox(height: 16),
          Text(parsedData),
        ],
      ),
    );
  }
}

// 一个简单的QrCodeWidget来显示二维码
class QrCodeWidget extends StatelessWidget {
  final String qrCodeData;
  final double size;

  QrCodeWidget({required this.qrCodeData, required this.size});

  @override
  Widget build(BuildContext context) {
    return QrCode(
      value: qrCodeData,
      size: size,
    );
  }
}

注意事项

  1. 依赖版本:确保你使用的 emvqrcode 插件版本是最新的,因为API可能会随着版本更新而变化。
  2. 错误处理:在实际应用中,你应该添加错误处理逻辑来处理可能发生的异常,例如二维码生成或解析失败的情况。
  3. 安全性:处理敏感信息(如EMV数据)时,请确保你的应用遵循适当的安全实践,以防止数据泄露。

这个示例代码提供了一个基本的框架,展示了如何在Flutter中使用 emvqrcode 插件来生成和解析EMV二维码。根据你的具体需求,你可能需要进一步定制和扩展这个示例。

回到顶部