Flutter支付集成插件viva_wallet_pos的使用

Flutter支付集成插件viva_wallet_pos的使用

Viva Logo

Pub Pub Pub Pub Star on Github License: BSD 3

这是一个用于Android集成的Flutter插件,与Viva终端进行交互。

您可以从官方的Google Play商店下载POS应用程序。

为了获取演示访问权限,您必须使用Viva.com终端应用程序的演示版本。请联系Viva.com以获取演示访问权限。目前,该插件仅支持Android平台。

如果您愿意,请在GitHub上为本项目贡献您的力量。

开始使用

使用库

请查看示例项目以了解如何使用库的基本功能。

您可以参考官方开发页面:Viva Wallet开发者文档

插件中的所有函数和参数名称都与官方文档一致。

示例:普通销售
import 'package:viva_wallet_pos/viva_wallet_pos.dart';

VivaWalletPos pos = VivaWalletPos();

try {
  TransactionResponse response = await pos.sale(
    clientTransactionId: 'Invoice 1234',
    amount: 10.00,
    showRating: false,
    showReceipt: true,
    showTransactionResult: false,
  );
  _resultMessage(response.message);
} catch (e) {
  debugPrint(e.toString());
}
示例:ISV销售
import 'package:viva_wallet_pos/viva_wallet_pos.dart';

VivaWalletPos pos = VivaWalletPos();

try {
  final response = await pos.isvSale(
    amount: 10.0,
    tipAmount: 0.2,
    isvAmount: 0.1,
    clientTransactionId: 'CLIENT_TRANS_ID',
    isvClientId: 'ISV_CLIENT_ID',
    isvClientSecret: 'ISV_CLIENT_SECRET',
    isvMerchantId: 'ISV_MERCHANT_ID',
    isvClientTransactionId: 'ISV_CLIENT_TRANS_ID',
  );
  _resultMessage(response.message);
} catch (e) {
  debugPrint(e.toString());
}

支持的方法

  • ✅ activatePos
  • ✅ getActivationCode
  • ✅ setMode
  • ✅ setDecimalAmountMode
  • ✅ resetTerminal
  • ✅ batch
  • ✅ transactionDetails
  • ✅ fastRefund
  • ✅ setPrintingSettings
  • ✅ reprintTransaction
  • ✅ sendLogs
  • ✅ sale
  • ✅ isvSale (感谢jousis9的贡献,参见PR #1)
  • ✅ cancel
  • ✅ abort

不支持的方法 - 开发中

  • ❌ preauth request
  • ❌ capture pre-auth request
  • ❌ rebate request

版权

所有商标、徽标和品牌名称均为其各自所有者的财产。使用这些名称、商标和品牌并不暗示任何背书。


完整示例代码

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

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

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

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

class _MyAppState extends State<MyApp> {
  final _pos = VivaWalletPos.instance;

  String _message = 'Select action';
  Color _color = Colors.green;

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

  void _resultMessage(String message, TransactionStatus status) {
    setState(() {
      _message = message;
      switch (status) {
        case TransactionStatus.success:
          _color = Colors.green;
          break;
        case TransactionStatus.userCanceled:
          _color = Colors.orange;
          break;
        case TransactionStatus.fail:
          _color = Colors.red;
          break;
      }
    });
  }

  void _activatePos() async {
    try {
      ActivationResponse response =
          await _pos.activatePos(apikey: 'API KEY', apiSecret: 'API SECRET');
      _resultMessage(response.message, response.status);
    } catch (e) {
      _resultMessage(e.toString(), TransactionStatus.fail);
    }
  }

  void _getActivationCode() async {
    try {
      GetActivationCodeResponse response = await _pos.getActivationCode();
      _resultMessage(response.message, response.status);
    } catch (e) {
      _resultMessage(e.toString(), TransactionStatus.fail);
    }
  }

  void _sale() async {
    try {
      TransactionResponse response = await _pos.sale(
        clientTransactionId: 'Invoice 1234',
        amount: 10.00,
        showRating: false,
        showReceipt: false,
        showTransactionResult: false,
      );
      _resultMessage(response.message, response.status);
    } catch (e) {
      _resultMessage(e.toString(), TransactionStatus.fail);
    }
  }

  void _cancel() async {
    try {
      TransactionResponse response = await _pos.cancel(
        amount: 10.00,
        showRating: false,
        showReceipt: false,
        showTransactionResult: false,
      );
      _resultMessage(response.message, response.status);
    } catch (e) {
      _resultMessage(e.toString(), TransactionStatus.fail);
    }
  }

  void _fastRefund() async {
    try {
      FastRefundResponse response = await _pos.fastRefund(
        amount: 10.00,
        showRating: false,
        showReceipt: false,
        showTransactionResult: false,
      );
      _resultMessage(response.message, response.status);
    } catch (e) {
      _resultMessage(e.toString(), TransactionStatus.fail);
    }
  }

  void _transactionDetails() async {
    try {
      TransactionResponse response = await _pos.transactionDetails(
        clientTransactiodId: '1234567890123456789',
        sourceTerminalId: '12345',
      );
      _resultMessage(response.message, response.status);
    } catch (e) {
      _resultMessage(e.toString(), TransactionStatus.fail);
    }
  }

  void _reprintTransaction() async {
    try {
      ReprintTransactionResponse response = await _pos.reprintTransaction(
        orderCode: '1234567890123456789',
      );
      _resultMessage(response.message, response.status);
    } catch (e) {
      _resultMessage(e.toString(), TransactionStatus.fail);
    }
  }

  void _batch() async {
    try {
      BatchResponse response = await _pos.batch(
        command: BatchCommand.open,
      );
      _resultMessage(response.message, response.status);
    } catch (e) {
      _resultMessage(e.toString(), TransactionStatus.fail);
    }
  }

  void _abort() async {
    try {
      AbortResponse response = await _pos.abort();
      _resultMessage(response.message, response.status);
    } catch (e) {
      _resultMessage(e.toString(), TransactionStatus.fail);
    }
  }

  void _setMode() async {
    try {
      SetModeResponse response = await _pos.setMode(
        mode: ApplicationMode.attended,
        pin: '1234',
      );
      _resultMessage(response.message, response.status);
    } catch (e) {
      _resultMessage(e.toString(), TransactionStatus.fail);
    }
  }

  void _setDecimalAmountMode() async {
    try {
      SetDecimalAmountModeResponse response = await _pos.setDecimalAmountMode(
        decimalMode: false,
      );
      _resultMessage(response.message, response.status);
    } catch (e) {
      _resultMessage(e.toString(), TransactionStatus.fail);
    }
  }

  void _resetTerminal() async {
    try {
      ResetTerminalResponse response = await _pos.resetTerminal(
        softReset: true,
      );
      _resultMessage(response.message, response.status);
    } catch (e) {
      _resultMessage(e.toString(), TransactionStatus.fail);
    }
  }

  void _setPrintingSettings() async {
    try {
      SetPrintingSettingsResponse response = await _pos.setPrintingSettings(
        businessDescriptionEnabled: true,
        businessDescriptionType: BusinessDescriptionType.storeName,
      );
      _resultMessage(response.message, response.status);
    } catch (e) {
      _resultMessage(e.toString(), TransactionStatus.fail);
    }
  }

  void _sendLogs() async {
    try {
      SendLogsResponse response = await _pos.sendLogs();
      _resultMessage(response.message, response.status);
    } catch (e) {
      _resultMessage(e.toString(), TransactionStatus.fail);
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('VW Pos Plugin example'),
        ),
        body: ListView(children: [
          Padding(
            padding: const EdgeInsets.all(10),
            child: Container(
              height: 80,
              color: _color,
              padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
              child: Center(
                child: SingleChildScrollView(
                  scrollDirection: Axis.vertical,
                  child: Text(_message),
                ),
              ),
            ),
          ),
          Container(
            height: 70,
            padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
            child: ElevatedButton(
              child: const Text('Activate POS', style: TextStyle(fontSize: 18)),
              onPressed: () async {
                _activatePos();
              },
            ),
          ),
          Container(
            height: 70,
            padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
            child: ElevatedButton(
              child: const Text('Get Activation Code',
                  style: TextStyle(fontSize: 18)),
              onPressed: () async {
                _getActivationCode();
              },
            ),
          ),
          Container(
            height: 70,
            padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
            child: ElevatedButton(
              child: const Text('Sale 10.00', style: TextStyle(fontSize: 18)),
              onPressed: () {
                _sale();
              },
            ),
          ),
          Container(
            height: 70,
            padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
            child: ElevatedButton(
              child: const Text('Cancel/refund -10.00',
                  style: TextStyle(fontSize: 18)),
              onPressed: () {
                _cancel();
              },
            ),
          ),
          Container(
            height: 70,
            padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
            child: ElevatedButton(
              child: const Text('Fast refund -10.00',
                  style: TextStyle(fontSize: 18)),
              onPressed: () {
                _fastRefund();
              },
            ),
          ),
          Container(
            height: 70,
            padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
            child: ElevatedButton(
              child: const Text('Transaction details',
                  style: TextStyle(fontSize: 18)),
              onPressed: () {
                _transactionDetails();
              },
            ),
          ),
          Container(
            height: 70,
            padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
            child: ElevatedButton(
              child: const Text('Reprint transaction',
                  style: TextStyle(fontSize: 18)),
              onPressed: () {
                _reprintTransaction();
              },
            ),
          ),
          Container(
            height: 70,
            padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
            child: ElevatedButton(
              child: const Text('Open / close batch',
                  style: TextStyle(fontSize: 18)),
              onPressed: () {
                _batch();
              },
            ),
          ),
          Container(
            height: 70,
            padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
            child: ElevatedButton(
              child:
                  const Text('Abort request', style: TextStyle(fontSize: 18)),
              onPressed: () {
                _abort();
              },
            ),
          ),
          Container(
            height: 70,
            padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
            child: ElevatedButton(
              child: const Text('Set Mode', style: TextStyle(fontSize: 18)),
              onPressed: () {
                _setMode();
              },
            ),
          ),
          Container(
            height: 70,
            padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
            child: ElevatedButton(
              child: const Text('Set Decimal Amount Mode',
                  style: TextStyle(fontSize: 18)),
              onPressed: () {
                _setDecimalAmountMode();
              },
            ),
          ),
          Container(
            height: 70,
            padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
            child: ElevatedButton(
              child: const Text('Send logs', style: TextStyle(fontSize: 18)),
              onPressed: () {
                _sendLogs();
              },
            ),
          ),
          Container(
            height: 70,
            padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
            child: ElevatedButton(
              child: const Text('Set printing settings',
                  style: TextStyle(fontSize: 18)),
              onPressed: () {
                _setPrintingSettings();
              },
            ),
          ),
          Container(
            height: 70,
            padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
            child: ElevatedButton(
              child:
                  const Text('Reset Terminal', style: TextStyle(fontSize: 18)),
              onPressed: () {
                _resetTerminal();
              },
            ),
          ),
        ]),
      ),
    );
  }
}

更多关于Flutter支付集成插件viva_wallet_pos的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter支付集成插件viva_wallet_pos的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中集成并使用viva_wallet_pos插件来进行支付操作的示例代码。请注意,实际使用时,你需要确保已经按照viva_wallet_pos插件的官方文档完成了相关的配置,比如添加依赖、设置API密钥等。

1. 添加依赖

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

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

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

2. 初始化插件

在你的Flutter应用的入口文件(通常是main.dart)中,进行插件的初始化。这里假设你已经从Viva Wallet获取了必要的API密钥等信息。

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

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  // 初始化Viva Wallet POS插件
  VivaWalletPos.initialize(
    apiKey: '你的API密钥',
    merchantId: '你的商户ID',
    environment: Environment.sandbox, // 或者 Environment.production
  );
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

3. 创建支付页面

接下来,创建一个页面来处理支付操作。在这个页面中,我们将展示一个简单的按钮,当用户点击该按钮时,将触发支付流程。

import 'package:flutter/material.dart';
import 'package:viva_wallet_pos/viva_wallet_pos.dart';
import 'package:viva_wallet_pos/models/payment_request.dart';

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('支付集成示例'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () async {
            // 创建支付请求
            PaymentRequest paymentRequest = PaymentRequest(
              amount: 100.0, // 支付金额,单位:分(例如100代表1欧元)
              currency: 'EUR',
              description: '商品描述',
              // 其他可选参数,如订单ID、商品详情等
            );

            try {
              // 发起支付请求
              PaymentResult result = await VivaWalletPos.startPayment(paymentRequest);
              // 处理支付结果
              if (result.status == PaymentStatus.success) {
                showDialog(
                  context: context,
                  builder: (context) => AlertDialog(
                    title: Text('支付成功'),
                    content: Text('支付金额: ${result.amount} ${result.currency}'),
                    actions: <Widget>[
                      TextButton(
                        onPressed: () => Navigator.of(context).pop(),
                        child: Text('确定'),
                      ),
                    ],
                  ),
                );
              } else {
                showDialog(
                  context: context,
                  builder: (context) => AlertDialog(
                    title: Text('支付失败'),
                    content: Text('错误代码: ${result.errorCode}, 错误信息: ${result.errorMessage}'),
                    actions: <Widget>[
                      TextButton(
                        onPressed: () => Navigator.of(context).pop(),
                        child: Text('确定'),
                      ),
                    ],
                  ),
                );
              }
            } catch (e) {
              // 处理异常
              showDialog(
                context: context,
                builder: (context) => AlertDialog(
                  title: Text('发生错误'),
                  content: Text('错误信息: $e'),
                  actions: <Widget>[
                    TextButton(
                      onPressed: () => Navigator.of(context).pop(),
                      child: Text('确定'),
                    ),
                  ],
                ),
              );
            }
          },
          child: Text('发起支付'),
        ),
      ),
    );
  }
}

注意事项

  1. API密钥和商户ID:确保你在代码中使用了正确的API密钥和商户ID。
  2. 测试环境:在开发阶段,建议使用沙盒环境(Environment.sandbox)进行测试。上线前,切换到生产环境(Environment.production)。
  3. 错误处理:实际应用中,应增加更详细的错误处理和用户提示。
  4. 支付金额单位:注意支付金额的单位是分,例如1欧元应传入100。

这个示例代码展示了如何在Flutter应用中集成并使用viva_wallet_pos插件进行支付操作。根据你的具体需求,你可能需要调整支付请求的参数和处理逻辑。

回到顶部