Flutter支付插件benefit_pay_flutter的使用

Flutter支付插件benefit_pay_flutter的使用

在您的应用中集成Flutter BenefitPay SDK。

引言

在深入开发流程之前,确保满足必要的前提条件和标准,以确保顺利构建。本步骤将概述iOS/Android的具体要求,包括最低SDK版本和其他重要细节。让我们从一开始就为项目奠定成功的基础。

示例演示

示例演示

步骤1:要求

  • 我们支持从iOS 13.0+开始
  • Dart 3.0.0+
  • Java版本 11
  • 最小Android SDK/API级别为24
  • 为了在您的应用中接受在线支付,您需要在manifest文件中至少添加Internet权限。
    <uses-permission android:name="android.permission.INTERNET" /> // 获取互联网访问权限以完成在线支付
    

步骤2:获取公钥

虽然您可以使用我们的示例应用中的沙盒密钥(通过以下安装过程获得),但强烈建议您访问我们的注册页面,在那里您可以注册您的包名并获取必要的Tap密钥以激活Card-Flutter集成。如果您同时支持iOS和Android,则每个应用需要两个不同的密钥。

步骤3:安装

在您的Flutter项目的pubspec.yaml文件中,添加以下依赖:

dependencies:
  benefit_pay_flutter: ^0.0.5

步骤4:集成BenefitPay-Flutter

集成流程

在Flutter中,您会像使用其他任何小部件一样使用我们的按钮。在创建小部件时,您还需要根据需要传递参数并监听回调。

  1. 您需要创建一个类型为TapBenefitPayWidget的变量。
  2. 在初始化小部件时:
    • 将参数传递给小部件。
    • 实现提供的接口/回调。
  3. 我们的按钮小部件是一个有状态的小部件,依赖于状态变量来监听所有回调。

使用代码创建TapBenefitPayWidget

  1. 前往您想要显示TapBenefitPayWidget的地方。
  2. 如下导入TapBenefitPayWidget
    import 'package:benefit_pay_flutter/benefit_pay_flutter.dart';
    
  3. 下面的代码示例将展示如何在小部件树中嵌入按钮表单。
TapBenefitPayWidget(
  sdkConfiguration: const {},
),

配置BenefitPay-Flutter SDK

在创建小部件时,是时候传递SDK所需的参数,以便按预期工作并正确地满足您的需求。

  1. 将这些参数传递给TapBenefitPayWidget小部件:
sdkConfiguration: const {
  "merchant": {
    "id": "",
  },
  "scope": "charge",
  "redirect": "",
  "customer": {
    "names": [
      {
        "middle": "Middle",
        "last": "Payments",
        "lang": "en",
        "first": "Tap"
      }
    ],
    "contact": {
      "phone": {
        "number": "66178990",
        "countryCode": "965"
      },
      "email": "email@email.com"
    },
    "id":"",
  },
  "locale": "en",
  "edges": "curved",
  "reference": {"transaction": "transaction", "order": "12"},
  "metadata": "",
  "post": {"url": ""},
  "transaction": {
    "amount": "10",
    "currency": "BHD",
  },
  "operator": {
    "hashString": "",
    "publicKey": 'pk_live_********',
  },
},

完整代码片段

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

class BenefitPayScreen extends StatefulWidget {
  final Map<String, dynamic> dictionaryMap;

  const BenefitPayScreen({
    super.key,
    required this.dictionaryMap,
  });

  [@override](/user/override)
  State<BenefitPayScreen> createState() => _BenefitPayScreenState();
}

class _BenefitPayScreenState extends State<BenefitPayScreen> {
  String sdkResponse = "";

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: const Text('插件示例应用'),
      ),
      body: Padding(
        padding: const EdgeInsets.symmetric(
          horizontal: 18,
          vertical: 50,
        ),
        child: SingleChildScrollView(
          child: Center(
            child: SelectableText(
              sdkResponse.isEmpty ? " " : "SDK响应: $sdkResponse",
            ),
          ),
        ),
      ),
      bottomSheet: Padding(
        padding: const EdgeInsets.only(bottom: 20),
        child: TapBenefitPayWidget(
          sdkConfiguration: widget.dictionaryMap,
          onReady: () {
            developer.log(">ON READY >>>>");
          },
          onCancel: () {
            developer.log(">ON CANCEL >>>>");
            setState(() {
              sdkResponse = "已取消";
            });
          },
          onSuccess: (String? value) {
            developer.log(">ON SUCCESS >>>> $value");
            setState(() {
              sdkResponse = value ?? "";
            });
          },
          onError: (String? error) {
            developer.log(">ON ERROR >>>> $error");
            setState(() {
              sdkResponse = error ?? "";
            });
          },
          onClick: () {},
          onOrderCreated: (String? value) {
            developer.log(">ON ORDER CREATED >>>> $value");
            setState(() {
              sdkResponse = value ?? "";
            });
          },
          onChargeCreated: (String? value) {
            developer.log(">ON CHARGE CREATED >>>> $value");
            setState(() {
              sdkResponse = value ?? "";
            });
          },
        ),
      ),
    );
  }
}

参数参考

以下是每个参数的详细说明,这些参数将帮助您轻松集成BenefitPay-Flutter SDK。

operator

  1. 定义:它将支付网关链接到您的Tap商户账户,以便知道您的业务名称、徽标等…
  2. 类型:字符串(必需)
  3. 字段:
    • publicKey
      • 定义:这是您在Tap创建账户后收到的一个唯一公共密钥,作为识别您为商户的参考。您将收到两个公共密钥,一个用于沙箱/测试环境,另一个用于生产环境。
    • 示例:
      { "operator":{"publicKey":"pk_test_YhUjg9PNT8oDlKJ1aE2fMRz7", "hashString":""} }
      

transaction

  1. 定义:这定义了您尝试购买的订单的详细信息,您需要指定一些详细信息,如参考、范围等。
  2. 类型:字典(可选)
  3. 字段:
    • currency
      • 定义:与正在付款的订单关联的货币。
    • amount
      • 定义:客户需要支付的订单金额。
      • 注意:最小金额必须为0.1。
    • 示例:
      "transaction": { "amount": 1.0, "currency": "BHD", }
      

customer

  1. 定义:在这里,您将收集支付客户的详细信息。
  2. 类型:字典(必需)
  3. 字段:
    • id

      • 定义:这是一个可选字段,在处理费用之前您可能还没有。但是,在费用处理之后,您将在响应中收到客户的ID,可以在onSuccess回调函数中处理。
    • name

      • 定义:支付客户的全名。
      • 字段:
        • lang
          • 定义:选择用于书写客户姓名的语言。
        • first
          • 定义:客户的名。
        • middle
          • 定义:客户的中间名。
        • last
          • 定义:客户的姓。
    • contact

      • 定义:客户的联系信息,如电子邮件地址和电话号码。
      • 注意:联系信息必须包含客户的电子邮件地址或电话详情,或者两者都有,但不能为空。
      • 字段:
        • email
          • 定义:客户的电子邮件地址。
          • 注意:电子邮件是字符串类型。
        • phone
          • 定义:客户的电话号码详情。
            • countryCode
            • number
    • 示例:

      { "customer": { 
        "id": customerIdController.text, 
        "names": const [ 
          { 
            "first": "TAP", 
            "middle": "", 
            "last": "PAYMENTS", 
            "lang": "en", 
          } 
        ], 
        "contact": const { 
          "email": "tap@tap.company", 
          "phone": { 
            "countryCode": "+965", 
            "number": "88888888" 
          } 
         }, 
        }, 
      }
      

interface

  1. 定义:这将帮助您控制支付表单的布局(UI),例如更改主题(浅色到深色)、使用的语言(en或ar)等。
  2. 类型:字典(可选)
  3. 字段:
    • locale
      • 定义:支付按钮的语言。目前接受的值有:
        • en(英语)
        • ar(阿拉伯语)。
    • edges
      • 定义:控制支付表单的边角。
        • curved
        • flat
    • 示例:
      "interface":  {  "locale": "en", "edges": "straight", }
      

post

  1. 定义:在这里,您可以传递您拥有的webhook URL,以便接收有关您应用程序上发生的每笔交易结果的通知。
  2. 类型:字典(可选)
  3. 字段:
    • url
      • 定义:您希望接收通知的webhook服务器的URL。
      • 示例:
        { "post":{"url":""} }
        

生成哈希字符串

  1. 添加依赖 crypto: Latest version
  2. 复制此辅助方法代码:
// 这是一个辅助方法,展示了如何生成哈希字符串,当进行实时收费时
// 参数:
// - publicKey: 您作为商户的Tap公共密钥 pk_.....
// - secretKey: 您作为商户的Tap秘密密钥 sk_.....
// - amount: 您传递给SDK的金额,或在创建订单前使用的金额。
// - currency: 您传递给SDK的货币代码,或在创建订单前使用的货币代码。PS: 这是ISO国家代码的大写形式,例如SAR,KWD。
// - post: 您传递给SDK的webhook URL,或在Charge API中传递的webhook URL。如果您不使用webhook URL,请将其传递为空字符串。
// - transactionReference: 您传递给SDK的参考.transaction(并非所有SDK都支持此功能),或在Charge API中传递的参考.transaction。如果您不使用参考.transaction,请将其传递为空字符串
String generateTapHashString(
      String publicKey,    
      String secretKey,
      double amount,        
      String currency, {        
      String postUrl = "",        
      String transactionReference = "",        
   ) {        
     // 让我们生成我们的加密密钥        
     var key = utf8.encode(secretKey);        
     // 对于金额,您需要确保它们具有正确的位数。对于BHD,我们需要它们有三位小数        
     var formattedAmount = amount.toStringAsFixed(3);        
     // 让我们格式化我们将要哈希的字符串        
     var toBeHashed = 'x_publickey$publicKey'        
     'x_amount$formattedAmount'        
     'x_currency$currency'        
     'x_transaction$transactionReference'        
     'x_post$postUrl';        
     // 让我们现在使用HMAC SHA256算法生成哈希字符串        
     var hmacSha256 = Hmac(sha256, key);        
     var signature = hmacSha256.convert(utf8.encode(toBeHashed));        
     var hashedString = signature.toString();        
     return hashedString;
}
  1. 如下调用它:
String hashString = generateTapHashString(publicKey: publicKey, secretKey: secretString, amount: amount, currency: currency, postUrl: postUrl,transactionReference:transactionReference);
  1. 在操作模型中传递它:
{ "operator": {"publicKey": "pk_test_HJN863LmO15EtDgo9cqK7sjS", "hashString": hashString } }

完整的示例代码

完整的示例代码可以在这里找到。

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

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

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

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

class _MyAppState extends State<MyApp> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        useMaterial3: true,
        bottomSheetTheme: const BottomSheetThemeData(
          backgroundColor: Colors.white,
          elevation: 0,
        ),
      ),
      home: const ConfigSettingsScreen(),
    );
  }
}

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

1 回复

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


当然,下面是一个关于如何在Flutter项目中使用benefit_pay_flutter支付插件的示例代码。请注意,实际使用中你可能需要根据具体的支付需求和平台配置进行进一步调整。

1. 添加依赖

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

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

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

2. 配置Android和iOS

Android

android/app/src/main/AndroidManifest.xml中可能需要添加一些必要的权限和配置,具体参考benefit_pay_flutter的官方文档。

iOS

在iOS项目中,你可能需要在Info.plist中添加一些配置,并且确保你的项目已经正确配置了支付相关的证书和权限。同样,具体步骤请参考官方文档。

3. 初始化插件

在你的Flutter项目的主要Dart文件中(例如main.dart),你可以这样初始化并使用benefit_pay_flutter插件:

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

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  BenefitPayFlutter? _benefitPay;

  @override
  void initState() {
    super.initState();
    _initBenefitPay();
  }

  Future<void> _initBenefitPay() async {
    // 初始化插件
    _benefitPay = BenefitPayFlutter();

    // 配置支付参数(这里仅为示例,实际参数请根据需求配置)
    final Map<String, dynamic> payConfig = {
      'appId': '你的APP ID',
      'privateKey': '你的私钥',
      'publicKey': '你的公钥',
      'sandbox': true, // 沙盒环境,生产环境请设置为false
    };

    try {
      await _benefitPay!.init(payConfig);
      print('BenefitPay initialized successfully');
    } catch (e) {
      print('Failed to initialize BenefitPay: $e');
    }
  }

  Future<void> _startPayment() async {
    if (_benefitPay == null) return;

    // 配置支付订单信息
    final Map<String, dynamic> orderInfo = {
      'orderId': '订单ID',
      'amount': '金额', // 单位:分
      'currency': 'CNY',
      'subject': '商品描述',
      'body': '商品详情',
    };

    try {
      final Map<String, dynamic> result = await _benefitPay!.startPayment(orderInfo);
      print('Payment result: $result');

      // 根据返回结果处理支付成功或失败逻辑
      if (result['success']) {
        // 支付成功
      } else {
        // 支付失败
      }
    } catch (e) {
      print('Payment failed: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('BenefitPay Flutter Example'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: _startPayment,
            child: Text('Start Payment'),
          ),
        ),
      ),
    );
  }
}

注意事项

  1. 支付参数:在实际使用中,请确保payConfig中的参数(如appId, privateKey, publicKey等)配置正确。
  2. 订单信息orderInfo中的订单信息需要根据你的支付需求进行配置。
  3. 错误处理:在真实应用中,应添加更完善的错误处理逻辑。
  4. 沙盒环境:在开发测试阶段,通常使用沙盒环境;发布到生产环境时,请确保将sandbox设置为false,并配置好相应的生产环境参数。

总结

以上示例展示了如何在Flutter项目中使用benefit_pay_flutter插件进行支付初始化与支付请求。请根据实际需求调整代码,并仔细阅读官方文档以获取更多详细信息和配置指南。

回到顶部