Flutter支付集成插件flutter_bkash的使用

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

Flutter支付集成插件flutter_bkash的使用

简介

flutter_bkash 是一个用于集成bKash支付网关的Flutter包。该插件可以帮助你在Flutter项目中实现bKash支付功能。本文将介绍如何使用这个插件,并提供完整的示例代码。

安装

首先,你需要在你的项目中添加 flutter_bkash 依赖。运行以下命令:

$ flutter pub add flutter_bkash

这将在你的 pubspec.yaml 文件中添加如下依赖:

dependencies:
    flutter_bkash: ^0.2.0

然后,在你的Dart代码中导入该包:

import 'package:flutter_bkash/flutter_bkash.dart';

功能

  • 在没有协议的情况下进行支付
  • 创建未来支付的bKash协议
  • 使用协议进行支付

使用方法

初始化 FlutterBkash 实例

沙箱环境

final flutterBkash = FlutterBkash();

生产环境

final flutterBkash = FlutterBkash(
  credentials: BkashCredentials(
    username: "app_username",
    password: "app_password",
    appKey: "app_key",
    appSecret: "app_secret",
    isSandbox: false,
  ),
);

请确保替换为你自己的bKash沙箱或生产凭证。

支付(不使用协议)

要进行不使用协议的支付,请使用 pay 方法:

final result = await flutterBkash.pay(
  context: context, // BuildContext context
  amount: 100.0, // 金额作为double类型
  merchantInvoiceNumber: "invoice123",
);

创建协议

要创建一个新的协议,请使用 createAgreement 方法:

final result = await flutterBkash.createAgreement(context: context);

使用协议支付

要使用现有的协议进行支付,请使用 payWithAgreement 方法:

final result = await flutterBkash.payWithAgreement(
  context: context, // BuildContext context
  amount: 100.0, // 类型为double
  agreementId: "agreement123",
  merchantInvoiceNumber: "invoice123",
);

错误处理

上述方法可能会抛出 BkashFailure 异常。你可以使用 try-catch 块来捕获和处理异常:

try {
  // 进行支付或创建协议
} on BkashFailure catch (e) {
  // 处理错误
  print(e.message);
}

示例代码

以下是完整的示例代码,展示了如何在Flutter应用中集成 flutter_bkash 插件:

import 'dart:developer' as dev;
import 'package:flutter/material.dart';
import 'package:flutter_bkash/flutter_bkash.dart';

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.pink,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      debugShowCheckedModeBanner: false,
      home: const HomePage(title: 'bKash Demo'),
    );
  }
}

enum PaymentType { payWithAgreement, payWithoutAgreement, createAgreement }

class HomePage extends StatefulWidget {
  final String title;

  const HomePage({Key? key, required this.title}) : super(key: key);

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

class HomePageState extends State<HomePage> {
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
  final TextEditingController _amountController = TextEditingController();
  final TextEditingController _agreementIdController = TextEditingController();

  bool isLoading = false;
  PaymentType _paymentType = PaymentType.payWithoutAgreement;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(title: Text(widget.title)),
      body: Stack(
        children: [
          if (isLoading)
            const Center(child: CircularProgressIndicator(color: Colors.pink))
          else
            SingleChildScrollView(
              padding: const EdgeInsets.all(40),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  if (_paymentType != PaymentType.createAgreement) ...[
                    const Text('Amount :', style: TextStyle(fontWeight: FontWeight.bold)),
                    const SizedBox(height: 10),
                    TextFormField(
                      controller: _amountController,
                      decoration: const InputDecoration(
                        hintText: "1240",
                        contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
                        border: OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(5))),
                        focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.pink, width: 2.0)),
                      ),
                      keyboardType: TextInputType.number,
                      maxLines: 1,
                      minLines: 1,
                    ),
                    if (_paymentType == PaymentType.payWithAgreement) ...[
                      const SizedBox(height: 20),
                      const Text('AgreementID :', style: TextStyle(fontWeight: FontWeight.bold)),
                      const SizedBox(height: 10),
                      TextFormField(
                        controller: _agreementIdController,
                        decoration: const InputDecoration(
                          hintText: "User Agreement Id",
                          contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
                          border: OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(5))),
                          focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.pink, width: 2.0)),
                        ),
                        keyboardType: TextInputType.text,
                        maxLines: 1,
                        minLines: 1,
                      ),
                    ],
                    const SizedBox(height: 20.0),
                  ],
                  const Divider(),
                  ListTile(
                    title: const Text('Pay (without agreement)'),
                    leading: Radio(
                      value: PaymentType.payWithoutAgreement,
                      groupValue: _paymentType,
                      onChanged: (value) => setState(() => _paymentType = value!),
                    ),
                    dense: true,
                  ),
                  ListTile(
                    title: const Text('Pay with Agreement'),
                    leading: Radio(
                      value: PaymentType.payWithAgreement,
                      groupValue: _paymentType,
                      onChanged: (value) => setState(() => _paymentType = value!),
                    ),
                    dense: true,
                  ),
                  ListTile(
                    title: const Text('Create agreement'),
                    leading: Radio(
                      value: PaymentType.createAgreement,
                      groupValue: _paymentType,
                      onChanged: (value) => setState(() => _paymentType = value!),
                    ),
                    dense: true,
                  ),
                  const Divider(),
                  Center(
                    child: TextButton(
                      style: TextButton.styleFrom(
                        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(3.0)),
                        backgroundColor: Colors.pink,
                      ),
                      child: const Text("Checkout", style: TextStyle(color: Colors.white)),
                      onPressed: () async {
                        setState(() => isLoading = true);

                        final flutterBkash = FlutterBkash();

                        if (_paymentType == PaymentType.createAgreement) {
                          try {
                            FocusManager.instance.primaryFocus?.unfocus();
                            final result = await flutterBkash.createAgreement(context: context);
                            dev.log(result.toString());
                            _showSnackbar("(Success) AgreementId: ${result.agreementId}");
                          } on BkashFailure catch (e, st) {
                            dev.log(e.message, error: e, stackTrace: st);
                            _showSnackbar(e.message);
                          } catch (e, st) {
                            dev.log("Something went wrong", error: e, stackTrace: st);
                            _showSnackbar("Something went wrong");
                          }
                          setState(() => isLoading = false);
                          return;
                        }

                        if (_paymentType == PaymentType.payWithoutAgreement) {
                          final amount = _amountController.text.trim();
                          if (amount.isEmpty) {
                            ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Amount is empty. Without amount you can't pay. Try again")));
                            setState(() => isLoading = false);
                            return;
                          }
                          FocusManager.instance.primaryFocus?.unfocus();
                          try {
                            final result = await flutterBkash.pay(
                              context: context,
                              amount: double.parse(amount),
                              merchantInvoiceNumber: "tranId",
                            );
                            dev.log(result.toString());
                            _showSnackbar("(Success) tranId: ${result.trxId}");
                          } on BkashFailure catch (e, st) {
                            dev.log(e.message, error: e, stackTrace: st);
                            _showSnackbar(e.message);
                          } catch (e, st) {
                            dev.log("Something went wrong", error: e, stackTrace: st);
                            _showSnackbar("Something went wrong");
                          }
                          setState(() => isLoading = false);
                          return;
                        }

                        if (_paymentType == PaymentType.payWithAgreement) {
                          final amount = _amountController.text.trim();
                          final agreementId = _agreementIdController.text.trim();
                          if (amount.isEmpty) {
                            ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Amount is empty. Without amount you can't pay. Try again")));
                            setState(() => isLoading = false);
                            return;
                          }
                          if (agreementId.isEmpty) {
                            ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("AgreementId is empty. Without AgreementId you can't pay. Try again")));
                            setState(() => isLoading = false);
                            return;
                          }
                          FocusManager.instance.primaryFocus?.unfocus();
                          try {
                            final result = await flutterBkash.payWithAgreement(
                              context: context,
                              amount: double.parse(amount),
                              agreementId: agreementId,
                              marchentInvoiceNumber: "merchantInvoiceNumber",
                            );
                            dev.log(result.toString());
                            _showSnackbar("(Success) tranId: ${result.trxId}");
                          } on BkashFailure catch (e, st) {
                            dev.log(e.message, error: e, stackTrace: st);
                            _showSnackbar(e.message);
                          } catch (e, st) {
                            dev.log("Something went wrong", error: e, stackTrace: st);
                            _showSnackbar("Something went wrong");
                          }
                          setState(() => isLoading = false);
                          return;
                        }
                      },
                    ),
                  ),
                ],
              ),
            ),
        ],
      ),
    );
  }

  void _showSnackbar(String message) {
    ScaffoldMessenger.of(context)..hideCurrentSnackBar()..showSnackBar(SnackBar(content: Text(message)));
  }
}

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

1 回复

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


在Flutter中集成支付插件,如flutter_bkash(假设这是一个假想的插件名称,因为实际上可能没有一个叫做flutter_bkash的官方插件,但原理类似),通常涉及到几个关键步骤:添加依赖、配置原生代码、以及实现支付流程。以下是一个简化的代码案例,展示如何在Flutter项目中集成和使用一个假设的支付插件。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加对支付插件的依赖。请注意,这里的flutter_bkash是假设的,你需要替换为实际的插件名称。

dependencies:
  flutter:
    sdk: flutter
  flutter_bkash: ^x.y.z  # 替换为实际版本号

然后运行flutter pub get来安装依赖。

2. 配置原生代码(如果需要)

某些支付插件可能需要在iOS和Android的原生代码中做一些额外的配置。这一步取决于具体的插件文档,但通常涉及修改Info.plist(iOS)和AndroidManifest.xml(Android)。

由于flutter_bkash是假设的,这里不提供具体的原生配置代码。你需要参考实际插件的文档。

3. 实现支付流程

在你的Dart代码中,你可以按照以下方式使用支付插件:

import 'package:flutter/material.dart';
import 'package:flutter_bkash/flutter_bkash.dart';  // 假设的导入路径

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

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

class PaymentScreen extends StatefulWidget {
  @override
  _PaymentScreenState createState() => _PaymentScreenState();
}

class _PaymentScreenState extends State<PaymentScreen> {
  final FlutterBkash _flutterBkash = FlutterBkash();

  void _initiatePayment() async {
    try {
      // 假设这些参数是必需的
      String merchantId = "your_merchant_id";
      double amount = 100.0;  // 支付金额
      String currencyCode = "BDT";  // 货币代码
      String transactionDesc = "Product Purchase";  // 交易描述

      // 发起支付请求
      var result = await _flutterBkash.initiatePayment(
        merchantId: merchantId,
        amount: amount,
        currencyCode: currencyCode,
        transactionDesc: transactionDesc,
      );

      // 处理支付结果
      if (result.status == "success") {
        showDialog(
          context: context,
          builder: (context) => AlertDialog(
            title: Text("Payment Successful"),
            content: Text("Transaction ID: ${result.transactionId}"),
            actions: <Widget>[
              TextButton(
                child: Text("OK"),
                onPressed: () {
                  Navigator.of(context).pop();
                },
              ),
            ],
          ),
        );
      } else {
        showDialog(
          context: context,
          builder: (context) => AlertDialog(
            title: Text("Payment Failed"),
            content: Text("Error: ${result.errorMessage}"),
            actions: <Widget>[
              TextButton(
                child: Text("OK"),
                onPressed: () {
                  Navigator.of(context).pop();
                },
              ),
            ],
          ),
        );
      }
    } catch (e) {
      // 处理异常
      print("Error initiating payment: $e");
      showDialog(
        context: context,
        builder: (context) => AlertDialog(
          title: Text("Error"),
          content: Text("An error occurred while initiating payment."),
          actions: <Widget>[
            TextButton(
              child: Text("OK"),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
          ],
        ),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Flutter BKash Payment Demo"),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: _initiatePayment,
          child: Text("Initiate Payment"),
        ),
      ),
    );
  }
}

注意事项

  1. 插件文档:务必参考实际支付插件的官方文档,因为每个插件可能有不同的API和配置要求。
  2. 安全性:确保在生产环境中妥善处理敏感信息,如商户ID和支付密钥。
  3. 错误处理:在实际应用中,添加更详细的错误处理和用户反馈机制。
  4. 测试:在上线前,务必进行充分的测试,包括正常支付流程和异常情况处理。

由于flutter_bkash是假设的插件名称,以上代码仅用于演示如何在Flutter中集成和使用支付插件的一般流程。你需要根据实际的插件文档进行调整。

回到顶部