Flutter支付功能插件adjeminpay_flutter的使用

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

Flutter支付功能插件adjeminpay_flutter的使用

通过AdjeminPay,将移动货币支付集成到您的Flutter应用中变得非常简单,几乎没有任何不便。

使用

该包生成一个支付网关,当用户完成支付后,支付网关会返回支付结果。

请按照以下步骤操作:

步骤 1. 获取并存储您的凭证

请在AdjeminPay上注册并免费创建一个商户应用,以获取apiKey和applicationId。

然后将其存储在一个配置文件(如config/constants/env)中,用于保存其他常量数据。

class Constants {
  static final String ADJEMINPAY_CLIENT_ID = "CLIENT_ID";
  static final String ADJEMINPAY_CLIENT_SECRET = "CLIENT_SECRET";
  static final String ADJEMINPAY_NOTIFICATION_URL = "https://your.backend.api/notifyUrl";
}

步骤 2. 导入包

pubspec.yaml文件中添加adjeminpay_flutter作为依赖项。

dependencies:
  flutter:
    sdk: flutter
  adjeminpay_flutter: ^1.1.107

然后在您的购物车屏幕中导入它。

import 'package:adjeminpay_flutter/adjeminpay_flutter.dart';

您的cart_screen是向用户展示他们将要支付的商品的地方。

步骤 3. 构建您的购物车屏幕

构建一个购物车屏幕以完成支付。

您可以从Academind的Maximilian Schwarzmüller那里找到一个漂亮的购物车屏幕示例,位于示例文件中。

步骤 4. 准备订单/交易数据

存储用户即将进行的支付的数据。

注意:建议您在执行支付函数之前将支付数据存储在数据库中。

此示例使用基本的Map来存储有关订单的数据,但这可以是任何东西,从交易到支付,任何需要在线支付的东西。

Map<String, dynamic> myOrder = {
  // ! 必须的transactionId或orderId
  'transaction_id': "UniqueTransactionId",
  // ! 必须的总金额
  'total_amount': 1000,
  // 可选的订单商品数据
  'items': [
    {
      'id': '1',
      'productId': 'prod1',
      'price': 100,
      'quantity': 1,
      'title': '产品1标题',
    },
    {
      'id': '2',
      'productId': 'prod9',
      'price': 300,
      'quantity': 3,
      'title': '产品9标题',
    },
  ],
  'currency_code': "XOF",
  'designation': "订单标题",
  'client_name': "客户名称",
};

步骤 5. 添加一个函数以启动支付网关并处理支付结果

复制粘贴此函数,该函数接受订单数据并提取支付API所需的字段。

必需字段:

以下字段是必需的:

  • clientId :您可以在步骤1中获得。
  • clientSecret :您可以在步骤1中获得。
  • merchantTransactionId :每个支付的独特ID。
  • designation :用户将看到的支付内容。
  • amount :金额,显然。
  • currencyCode :支付货币。 注意:截至版本^0.1,仅支持XOF,所以请继续关注更多货币。
  • notificationUrl :您在web后台设置的URL。 当支付完成后(成功、失败、取消、过期),将向该URL发送带有支付结果的POST请求(包含{transactionId, status, message}的JSON),以便您直接从后端更新订单/交易状态。此字段是可选的,因为您可以通过回调从您的Flutter应用中进行此类更新。 注意:如果您想使用notificationUrl,请查看我们的PHP SDK以了解如何捕获通知。

可选字段:

这些字段是可选的:

  • buyerName :您的用户名。 注意:建议您在支付数据中提供它,因为它可以节省用户的麻烦,无需在支付网关中输入。

现在让我们实现支付处理函数。

注意:此函数和回调将在未来版本中直接包含在库中。

void payWithAdjeminPay(dynamic orderData) async {
  // paymentResult将返回{transactionId, status, message}
  // 一旦用户关闭了支付网关
  // ! 重要:确保在调用此函数之前先将orderData保存在您的数据库中
  Map<String, dynamic> paymentResult = await Navigator.push(
    context,
    new MaterialPageRoute(
      builder: (context) => 
        // AdjeminPay类
        AdjeminPay(
          // ! 必需的clientId
          clientId: Constants.ADJEMINPAY_CLIENT_ID,
          // ! 必需的clientSecret
          clientSecret: Constants.ADJEMINPAY_CLIENT_SECRET,
          // ! 必需的transactionId
          // 用于跟踪交易
          // 或稍后检索
          // 应为长度小于191的字符串,并且对于您的应用程序来说是唯一的
          merchantTransactionId: "${orderData['transaction_id']}",
          // ! 必需的designation
          // 用户将看到的支付内容
          designation: orderData['designation'],
          // notifyUrl用于您的web后台
          notificationUrl: Constants.ADJEMINPAY_NOTIFICATION_URL,
          // amount: int.parse("${orderData['totalAmount']}"),
          // ! 必需的amount
          // 用户将要支付的金额
          // 应为整数
          amount: int.parse("${orderData['total_amount']}"),
          // 货币代码
          // 目前支持的货币是XOF
          currencyCode: orderData['currency_code'],
          // designation: widget.element.title,
          // 用户的名字
          buyerName: orderData['client_name'], // 可选
        ),
    ));

  print(">>> ADJEMINPAY PAYMENT RESULTS <<<");
  print(paymentResult);
  // * 定义您的回调
  // 如果paymentResult为null
  // 支付网关意外关闭而未发送任何数据
  if (paymentResult == null) {
    print("<<< 支付网关意外关闭");
    return;
  }
  Scaffold.of(context).showSnackBar(SnackBar(content: Text("支付状态是 ${paymentResult['status']}")));
  // 支付成功的回调
  if (paymentResult['status'] == "SUCCESSFUL") {
    print("<<< AdjeminPay 成功");
    print(paymentResult);
    // 重定向到或显示另一个屏幕
    return;
  }
  // 支付失败的回调
  if (paymentResult['status'] == "FAILED") {
    print("<<< AdjeminPay 失败");
    print(paymentResult);
    // 原因将在paymentResult['message']中提及
    print("原因: " + paymentResult['message']);
    // 重定向到或显示另一个屏幕
    return;
  }
  // 支付取消的回调
  if (paymentResult['status'] == "CANCELLED") {
    print("<<< AdjeminPay 取消");
    print(paymentResult);
    // 原因将在paymentResult['message']中提及
    print("原因: " + paymentResult['message']);
    // 重定向到或显示另一个屏幕
    return;
  }
  // 支付超时的回调
  if (paymentResult['status'] == "EXPIRED") {
    print("<<< AdjeminPay 超时");
    print(paymentResult);
    // 用户花了太长时间批准或拒绝付款
    print("原因: " + paymentResult['message']);
    // 重定向到或显示另一个屏幕
    return;
  }
  // 初始化错误的回调
  if (paymentResult['status'] == "INVALID_PARAMS") {
    print("<<< AdjeminPay 初始化错误");
    // 您没有指定必需的字段
    print(paymentResult);
    return;
  }

  if (paymentResult['status'] == "INVALID_CREDENTIALS") {
    print("<<< AdjeminPay 初始化错误");
    // 您没有指定必需的字段
    // 或您的clientId或clientSecret无效
    print(paymentResult);
    return;
  }
  // AdjeminPay请求未完成的回调
  if (paymentResult['status'] == "ERROR_HTTP") {
    return;
  }
}

步骤 6. 将上述函数传递给“立即订购”按钮

FlatButton(
  child: _isLoading
      ? CircularProgressIndicator()
      : Text('立即订购'),
  onPressed: (myOrder['total_amount'] == null ||
          myOrder['total_amount'] <= 0 ||
          _isLoading)
      ? null
      : () {
          // **** 支付管理在这里
          // 您首先需要在数据库中存储订单数据
          // 并创建一个唯一的交易ID
          // 例如:await storeOrderData(myOrder);
          // 然后调用支付函数
          payWithAdjeminPay(myOrder);
        },
  textColor: Theme.of(context).primaryColor,
);

步骤 7. 完成

恭喜!您已经将移动货币支付集成到了您的Flutter应用中。祝您编码愉快!

完整示例

您可以在示例中找到一个基本示例。

请帮助我们改进并提交问题


示例代码

以下是example/lib/main.dart文件的示例代码:

import 'package:adjeminpay_flutter/adjeminpay_flutter.dart';
import 'package:flutter/material.dart';
import 'package:uuid/uuid.dart';

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final uuid = Uuid();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text('您已经按下了按钮很多次:'),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          runTransaction();
        },
        tooltip: '增加',
        child: const Icon(Icons.add),
      ),
    );
  }

  void runTransaction() async {
    final Map<String, dynamic> paymentResult = await Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) => AdjeminPay(
          // ! 必需的clientId
          clientId: Constants.ADJEMINPAY_CLIENT_ID,
          // ! 必需的clientSecret
          clientSecret: Constants.ADJEMINPAY_CLIENT_SECRET,
          // ! 必需的transactionId
          // 用于跟踪交易
          // 或稍后检索
          // 应为长度小于191的字符串,并且对于您的应用程序来说是唯一的
          merchantTransactionId: uuid.v4(),
          // ! 必需的designation
          // 用户将看到的支付内容
          designation: '支付订单',
          // notifyUrl用于您的web后台
          notificationUrl: Constants.ADJEMINPAY_NOTIFICATION_URL,
          // amount: int.parse("${orderData['totalAmount']}"),
          // ! 必需的amount
          // 用户将要支付的金额
          // 应为整数
          amount: 100,
          // 货币代码
          // 目前支持的货币是XOF
          currencyCode: 'XOF',
          // designation: widget.element.title,
          // 用户的名字
          buyerName: "Ange Bagui", // 可选
        ),
      ),
    );

    print(">>> ADJEMINPAY PAYMENT RESULTS <<<");
    print(paymentResult);
    // * 定义您的回调
    // 如果paymentResult为null
    // 支付网关意外关闭而未发送任何数据
    if (paymentResult == null) {
      print("<<< 支付网关意外关闭");
      return;
    }
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("支付状态是 ${paymentResult['status']}")));
    // 支付成功的回调
    if (paymentResult['status'] == "SUCCESSFUL") {
      print("<<< AdjeminPay 成功");
      print(paymentResult);
      // 重定向到或显示另一个屏幕
      return;
    }
    // 支付失败的回调
    if (paymentResult['status'] == "FAILED") {
      print("<<< AdjeminPay 失败");
      print(paymentResult);
      // 原因将在paymentResult['message']中提及
      print("原因: " + paymentResult['message']);
      // 重定向到或显示另一个屏幕
      return;
    }
    // 支付取消的回调
    if (paymentResult['status'] == "CANCELLED") {
      print("<<< AdjeminPay 取消");
      print(paymentResult);
      // 原因将在paymentResult['message']中提及
      print("原因: " + paymentResult['message']);
      // 重定向到或显示另一个屏幕
      return;
    }
    // 支付超时的回调
    if (paymentResult['status'] == "EXPIRED") {
      print("<<< AdjeminPay 超时");
      print(paymentResult);
      // 用户花了太长时间批准或拒绝付款
      print("原因: " + paymentResult['message']);
      // 重定向到或显示另一个屏幕
      return;
    }
    // 初始化错误的回调
    if (paymentResult['status'] == "INVALID_PARAMS") {
      print("<<< AdjeminPay 初始化错误");
      // 您没有指定必需的字段
      print(paymentResult);
      return;
    }

    if (paymentResult['status'] == "INVALID_CREDENTIALS") {
      print("<<< AdjeminPay 初始化错误");
      // 您没有指定必需的字段
      // 或您的clientId或clientSecret无效
      print(paymentResult);
      return;
    }
    // AdjeminPay请求未完成的回调
    if (paymentResult['status'] == "ERROR_HTTP") {
      return;
    }
  }
}

class Constants {
  static final String ADJEMINPAY_CLIENT_ID = '191';
  static final String ADJEMINPAY_CLIENT_SECRET = "RVHbP3X3UJBz9IMQdLuir0BOsCdx2RSYePtB6E2G";
  static final String ADJEMINPAY_NOTIFICATION_URL = "https://your.backend.api/notifyUrl";
}

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

1 回复

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


当然,以下是如何在Flutter项目中集成和使用adjeminpay_flutter插件的示例代码。这个示例将展示如何初始化插件、发起支付请求和处理支付结果。

1. 添加依赖

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

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

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

2. 导入插件

在你的Dart文件中(例如main.dart),导入adjeminpay_flutter插件:

import 'package:adjeminpay_flutter/adjeminpay_flutter.dart';

3. 初始化插件

在应用的初始化阶段(例如在MainActivity.ktAppDelegate.swift中,如果你需要处理原生平台初始化),确保插件已经正确初始化。不过,大多数Flutter插件在Dart代码中初始化就足够了。

4. 配置支付参数

你需要在你的Flutter应用中配置支付所需的参数。以下是一个示例:

void configurePayment() async {
  // 假设这些是你从后端获取的支付参数
  String appId = "你的AppID";
  String publicKey = "你的公钥";
  String privateKey = "你的私钥"; // 注意:私钥通常不应该在客户端代码中硬编码,这里仅为示例
  String orderId = "订单ID";
  double amount = 100.0; // 支付金额
  String currency = "CNY"; // 货币类型
  String description = "商品描述";

  // 创建支付参数对象
  AdjeminPayConfig config = AdjeminPayConfig(
    appId: appId,
    publicKey: publicKey,
    privateKey: privateKey,
    orderId: orderId,
    amount: amount,
    currency: currency,
    description: description,
  );

  // 初始化插件
  await AdjeminPayFlutter.init(config);
}

5. 发起支付请求

配置完成后,你可以发起支付请求:

void startPayment() async {
  try {
    // 发起支付请求
    AdjeminPayResult result = await AdjeminPayFlutter.startPayment();

    // 处理支付结果
    if (result.success) {
      print("支付成功: ${result.message}");
      // 更新UI或处理支付成功逻辑
    } else {
      print("支付失败: ${result.message}");
      // 更新UI或处理支付失败逻辑
    }
  } catch (e) {
    print("支付过程发生错误: $e");
  }
}

6. 完整示例

以下是一个完整的示例,将上述步骤整合在一起:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('AdjeminPay Flutter Example'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () async {
              await configurePayment();
              startPayment();
            },
            child: Text('发起支付'),
          ),
        ),
      ),
    );
  }

  void configurePayment() async {
    String appId = "你的AppID";
    String publicKey = "你的公钥";
    String privateKey = "你的私钥";
    String orderId = "订单ID";
    double amount = 100.0;
    String currency = "CNY";
    String description = "商品描述";

    AdjeminPayConfig config = AdjeminPayConfig(
      appId: appId,
      publicKey: publicKey,
      privateKey: privateKey,
      orderId: orderId,
      amount: amount,
      currency: currency,
      description: description,
    );

    await AdjeminPayFlutter.init(config);
  }

  void startPayment() async {
    try {
      AdjeminPayResult result = await AdjeminPayFlutter.startPayment();

      if (result.success) {
        print("支付成功: ${result.message}");
      } else {
        print("支付失败: ${result.message}");
      }
    } catch (e) {
      print("支付过程发生错误: $e");
    }
  }
}

请确保你已经从AdjeminPay平台获取了正确的appIdpublicKeyprivateKey,并且这些值在你的代码中正确配置。此外,orderIdamountcurrencydescription等参数也应根据你的实际需求进行填充。

注意

  • 私钥(privateKey)不应该在客户端代码中硬编码,这里仅为示例。在实际应用中,你应该通过安全的方式从服务器获取私钥。
  • 插件的具体接口和参数可能会随着版本更新而变化,请参考插件的官方文档获取最新信息。
回到顶部