Flutter插件skipcash的介绍与使用

Flutter插件skipcash的介绍与使用

skipcash-flutter 是一个用于在你的 Flutter 应用中集成 Skipcash 的插件。通过此插件,用户可以通过苹果支付(Apple Pay)或嵌入式网页视图(WebView)进行支付。

步骤 1: 添加依赖

首先,在 pubspec.yaml 文件中添加 skipcash-flutter 依赖:

dependencies:
  skipcash-flutter:

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

步骤 2: 初始化插件

接下来,你需要初始化 skipcash-flutter 插件,并设置一些必要的参数。以下是示例代码:

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

import 'package:flutter/services.dart';
import 'package:skipcash/payment_response_class.dart';
import 'package:skipcash/payment_page_response_class.dart';
import 'package:skipcash/skipcash.dart';

void main() {
  runApp(const MaterialApp(
    home: MyApp(), // Wrap MyApp with MaterialApp
  ));
}

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

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

class _MyAppState extends State<MyApp> {

  final _newPayment = Skipcash(
    merchantIdentifier: "merchant.vendex.skipcash.payme", // iOS - required when integrating (in-app applepay) here you should pass your merchantIdentifier
    createPaymentLinkEndPoint: "", /* required only if you're using the webview embedded with this package otherwise leave it empty - this is an endpoint you should setup at your backend server,
    it basically sends the customer data your endpoint from where you will be creating a new payment by calling skipcash server
    then the same endpoint should return skipcash server response back for the plugin to complete the process.
    */
    authorizationHeader: "" // optional - set your endpoint authorization header
  );

  StreamSubscription<dynamic>? _applePayResponseSubscription; // iOS - applepay
  StreamSubscription<dynamic>? responseScPaymentDataSubscription; // Android/iOS - pay via webview 

  final TextEditingController _firstNameController = TextEditingController();
  final TextEditingController _lastNameController  = TextEditingController();
  final TextEditingController _phoneController     = TextEditingController();
  final TextEditingController _emailController     = TextEditingController();
  final TextEditingController _amountController    = TextEditingController();

  var loadingIndicator;

  [@override](/user/override)
  void initState() {
    super.initState();
    loadingIndicator = false;
    _setupApplePayResponseListener(); // iOS - in-app applepay
    scPaymentDataResponseListener(); // Android/iOS - pay via webview
  }

  [@override](/user/override)
  void dispose() {
    // release resources upon exiting the screen

    _applePayResponseSubscription?.cancel(); // iOS - in-app applepay
    responseScPaymentDataSubscription?.cancel(); // Android/iOS - pay via webview
    super.dispose();
  }

  // 监听苹果支付响应
  void _setupApplePayResponseListener() { // iOS - native applepay
    _applePayResponseSubscription = _newPayment.applePayResponseStream.listen((response) {
      setState(() {
        loadingIndicator = false;
      });

      PaymentResponse paymentResponse = PaymentResponse.fromJson(response);
      showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: const Text('SkipCash In-App ApplePay'),
            content: Text(
                "IsSuccess: ${paymentResponse.isSuccess} | transactionId: ${paymentResponse.transactionId}  | errorMessage: ${paymentResponse.errorMessage} | returnCode: ${paymentResponse.returnCode}"
            ),
            actions: [
              TextButton(
                onPressed: () {
                  Navigator.of(context).pop();
                },
                child: const Text('OK'),
              ),
            ],
          );
        },
      );
    });
  }

  // 嵌入式 WebView 示例。
  void scPaymentDataResponseListener() { // Android/iOS - pay via webview 
    _applePayResponseSubscription = _newPayment.responseScPaymentPageStream.listen((response) {
      setState(() {
        loadingIndicator = false;
      });
      PaymentPageResponse paymentPageResponse = PaymentPageResponse.fromJson(response);
      debugPrint(response.toString());
      showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: const Text('SkipCash PaymentPage Response'),
            content: Text(
                "id: ${paymentPageResponse.id} | statusId: ${paymentPageResponse.statusId} | status: ${paymentPageResponse.status} | transId: ${paymentPageResponse.transId} |  custom1: ${paymentPageResponse.custom1}"
            ),
            actions: [
              TextButton(
                onPressed: () {
                  Navigator.of(context).pop();
                },
                child: const Text('OK'),
              ),
            ],
          );
        },
      );
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('skipcash package - example app'),
      ),
      body: Center(
        child: Stack(
          children: [
            Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  SizedBox(
                    width: 280,
                    child:
                    TextField(
                      controller: _firstNameController,
                      decoration: const InputDecoration(labelText: 'First Name'),
                    ),
                  ),
                  SizedBox(
                    width: 280,
                    child:
                    TextField(
                      controller: _lastNameController,
                      decoration: const InputDecoration(labelText: 'Last Name'),
                    ),
                  ),
                  SizedBox(
                    width: 280,
                    child:
                    TextField(
                      controller: _phoneController,
                      decoration: const InputDecoration(labelText: 'Phone Number'),
                    ),
                  ),
                  SizedBox(
                    width: 280,
                    child:
                    TextField(
                      controller: _emailController,
                      decoration: const InputDecoration(labelText: 'Email'),
                    ),
                  ),
                  SizedBox(
                    width: 300,
                    child:
                    TextField(
                      controller: _amountController,
                      decoration: const InputDecoration(
                          labelText: 'Amount',
                          hintText: "ex.valid values format: 1 and 1.2 and 1.25"
                      ),
                    ),
                  ),
                  const SizedBox(
                    height: 30,
                  ),
                  SizedBox(
                    width: 220,
                    child: ElevatedButton(
                      onPressed: () async {
                        bool hasCards;
                        try {
                          // 检查钱包中是否有卡片
                          hasCards = await _newPayment.isWalletHasCards() ?? false;

                          if(hasCards){
                            // 如果有卡片,则设置支付详情
                            String firstName = _firstNameController.text;
                            String lastName = _lastNameController.text;
                            String phone = _phoneController.text;
                            String email = _emailController.text;
                            String amount = _amountController.text;

                            if(firstName.isEmpty || lastName.isEmpty || phone.isEmpty
                                || email.isEmpty || amount.isEmpty || amount == "0.0"){
                              showDialog(
                                context: context,
                                builder: (BuildContext context) {
                                  return AlertDialog(
                                    title: const Text('Invalid Details'),
                                    content: const Text(
                                        "Please fill all of the fields, Also amount must be above 0.0, i.e 1.0  at least."
                                    ),
                                    actions: [
                                      TextButton(
                                        onPressed: () {
                                          Navigator.of(context).pop();
                                        },
                                        child: const Text('OK'),
                                      ),
                                    ],
                                  );
                                },
                              );

                              return;
                            }

                            _newPayment.setFirstName(firstName);
                            _newPayment.setLastName(lastName);
                            _newPayment.setEmail(email);
                            _newPayment.setPhone(phone);
                            _newPayment.setAmount(amount);
                            
                            _newPayment.setProcessApplePayEndPoint(""); // 你的处理支付的端点
                            _newPayment.setMerchantName(""); // 官方业务名称 - 苹果要求,将在支付表单中出现
                            _newPayment.setTransactionId(""); // 交易 (应唯一) 跟踪内部系统中的订单交易
                            _newPayment.setWebhookUrl(""); // 可选 - 推荐你阅读关于webhooks的相关文档
                            // -> 这里 https://dev.skipcash.app/doc/api-integration/web-hooks/

                            _newPayment.setCustom1(""); _newPayment.setCustom2(""); // 可选
                            _newPayment.setCustom3(""); _newPayment.setCustom4(""); // 可选
                            _newPayment.setCustom5(""); _newPayment.setCustom6(""); // 可选
                            _newPayment.setCustom7(""); _newPayment.setCustom8(""); // 可选
                            _newPayment.setCustom9(""); _newPayment.setCustom10(""); // 可选

                            _newPayment.clearPaymentSummaries(); // 清除摘要后添加新的
                            _newPayment.addPaymentSummaryItem("Tax", "0.0"); // 可选 - 为客户提供支付摘要

                            setState(() {
                              loadingIndicator = true;
                            });
                            _newPayment.startPayment(); // 开始支付 (applepay)
                          } else {
                            /*
                             如果钱包中没有可用的卡片,则提示客户添加一张新卡。
                            */
                            _newPayment.setupNewCard();
                          }

                        } on PlatformException {
                          hasCards = false;
                        }
                      },
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Image.asset(
                            'assets/skipcash.png',
                            width: 24,
                            height: 24,
                          ),
                          const SizedBox(width: 8),
                          const Text(
                            "Pay Using ApplePay",
                            style: TextStyle(color: Color.fromRGBO(1, 125, 251, 1.0)),
                          )
                        ],
                      ),
                    ),
                  ),
                  SizedBox(
                    width: 220,
                    child: ElevatedButton(
                      onPressed: () async {
                        _newPayment.setupNewCard();
                      },
                      child: const Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Text(
                            "Setup new card in wallet",
                            style: TextStyle(color: Color.fromRGBO(1, 125, 251, 1.0)),
                          )
                        ],
                      ),
                    ),
                  ),
                  SizedBox(
                    width: 300,
                    child: ElevatedButton(
                      onPressed: (){

                        String firstName  = _firstNameController.text;
                        String lastName   = _lastNameController.text;
                        String phone      = _phoneController.text;
                        String email      = _emailController.text; // 如果电子邮件不是平台要求的
                        // 你可以使用这种格式 phone@yourdomain.com
                        String amount     = _amountController.text;

                        if(firstName.isEmpty || lastName.isEmpty || phone.isEmpty
                            || email.isEmpty || amount.isEmpty || amount == "0.0"){
                          showDialog(
                            context: context,
                            builder: (BuildContext context) {
                              return AlertDialog(
                                title: const Text('Invalid Details'),
                                content: const Text(
                                    "Please fill all of the fields, Also amount must be above 0.0, i.e 1.0  at least."
                                ),
                                actions: [
                                  TextButton(
                                    onPressed: () {
                                      Navigator.of(context).pop();
                                    },
                                    child: const Text('OK'),
                                  ),
                                ],
                              );
                            },
                          );

                          return;
                        }

                        _newPayment.setFirstName(firstName);
                        _newPayment.setLastName(lastName);
                        _newPayment.setEmail(email);
                        _newPayment.setPhone(phone);
                        _newPayment.setAmount(amount);
                        _newPayment.setTransactionId("TX1TEST"); // 你的内部订单ID (唯一)
                        _newPayment.setWebhookUrl(""); // 可选但重要
                        // 阅读关于webhooks的相关文档 -> 这里 https://dev.skipcash.app/doc/api-integration/web-hooks/

                        _newPayment.setCustom1(""); _newPayment.setCustom2(""); // 可选
                        _newPayment.setCustom3(""); _newPayment.setCustom4(""); // 可选
                        _newPayment.setCustom5(""); _newPayment.setCustom6(""); // 可选
                        _newPayment.setCustom7(""); _newPayment.setCustom8(""); // 可选
                        _newPayment.setCustom9(""); _newPayment.setCustom10("");// 可选

                        _newPayment.setSubject("Creating a payment from example app."); // 可选 - 出现在支付页面
                        _newPayment.setDescription("Please pay to complete the orderX!"); // 可选 - 出现在支付页面

                        // 下面是一些选项用于调整WEBVIEW屏幕头部 (安卓)
                        /*
                          对于颜色,请使用完整的十六进制表示法
                          而不是缩写表示法;因为它可能会导致一些问题。

                          示例:
                          (全十六进制)    #FFFFFF - 白色 (正确 ✅)
                          (缩写十六进制)   #FFF    - 白色 (错误 ❌)

                        */
                        _newPayment.setPaymentModalTitle("Test Payment"); // 支付模态窗口标题
                        _newPayment.setCancelColour("#000000"); // 安卓专用
                        _newPayment.setHeaderBackgroundColour("#FFFFFF"); // 安卓专用
                        _newPayment.setHeaderTitleColour("#000000"); // 安卓专用

                        if(_newPayment.createPaymentLinkEndPoint.isNotEmpty){
                          if(_newPayment.getFirstName().isNotEmpty && _newPayment.getLastName().isNotEmpty && _newPayment.getEmail().isNotEmpty && _newPayment.getPhone().isNotEmpty && _newPayment.getAmount().isNotEmpty){

                            setState(() {
                              loadingIndicator = true;
                            });
                            // 安卓 - 为了检查错误,过滤日志使用关键字 'showPaymentModal'
                            _newPayment.showPaymentModal(
                              "", // 返回URL可以是任何正确的URL,
                              // 它主要由SkipCash服务器用来将客户端重定向回您的网站,带有与
                              // 客户所做的交易相关的参数。在这里它用于获取交易详情传递给你的flutter代码的响应监听器
                              // 以完成你的*(订单)过程。
                            );
                          }
                        }
                      },
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Image.asset(
                            'assets/skipcash.png',
                            width: 24,
                            height: 24,
                          ),
                          const SizedBox(width: 8),
                          const Text(
                            "Android/iOS - Native WebView",
                            style: TextStyle(color: Color.fromRGBO(1, 125, 251, 1.0)),
                          )
                        ],
                      ),
                    ),
                  ),
                ],
              ),
            ),
            if (loadingIndicator)
              Container(
                color: Colors.black54,
                child: Center(
                  child: Container(
                    padding: const EdgeInsets.all(20),
                    decoration: BoxDecoration(
                      color: Colors.white,
                      borderRadius: BorderRadius.circular(10),
                    ),
                    child: const CircularProgressIndicator(),
                  ),
                ),
              ),
          ],
        )
      ),
    );
  }
}

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

1 回复

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


SkipCash 是一个可能用于处理支付或金融交易的 Flutter 插件,但关于它的具体功能和使用方式,目前没有公开的详细文档或广泛的使用案例。以下是一些关于如何探索和使用未知 Flutter 插件(如 SkipCash)的潜在方法和步骤:


1. 查找插件的来源

  • Pub.dev 搜索: 在 pub.dev 上搜索 SkipCash,查看是否有相关的插件发布。如果有,可以查看其文档、版本、依赖和示例代码。
  • GitHub 搜索: 在 GitHub 上搜索 SkipCash,看是否有开源的代码库。开源项目通常会有 README 文件和使用说明。
  • 联系开发者: 如果插件是某个公司或开发者发布的,尝试通过他们的官网或联系方式获取更多信息。

2. 分析插件的功能

  • 插件名称推测: SkipCash 可能是一个与支付、金融或跳过某些流程相关的插件。例如:
    • 支付网关集成(如信用卡、移动支付)。
    • 跳过某些验证步骤或简化流程。
    • 现金管理或财务相关的功能。
  • 查看源代码: 如果插件是开源的,下载其源代码,查看 README 文件和主要功能类,了解其设计目的和使用方法。

3. 集成插件到 Flutter 项目

  • pubspec.yaml 中添加依赖:
    dependencies:
      skipcash: ^1.0.0  # 替换为实际版本号
    
  • 运行 flutter pub get 安装插件。
  • 导入插件并尝试使用其提供的 API:
    import 'package:skipcash/skipcash.dart';
    

4. 测试和调试

  • 运行示例代码(如果有)。
  • 尝试调用插件的 API,观察其行为和返回值。
  • 使用 print 或调试工具检查插件的输出和日志。

5. 处理未知问题

  • 错误处理: 如果插件抛出错误或异常,查看错误信息并尝试解决。
  • 社区支持: 在 Flutter 社区(如 Stack Overflow、GitHub Issues)中提问,寻求帮助。
  • 替代方案: 如果 SkipCash 无法满足需求,可以寻找其他类似的插件或自行实现所需功能。

6. 假设使用案例

假设 SkipCash 是一个支付插件,以下是一个可能的使用示例:

import 'package:skipcash/skipcash.dart';

void main() async {
  // 初始化插件
  await SkipCash.initialize(apiKey: 'YOUR_API_KEY');

  // 发起支付
  final paymentResult = await SkipCash.makePayment(
    amount: 100.0,
    currency: 'USD',
    description: 'Test Payment',
  );

  if (paymentResult.isSuccess) {
    print('Payment successful: ${paymentResult.transactionId}');
  } else {
    print('Payment failed: ${paymentResult.errorMessage}');
  }
}
回到顶部