Flutter支付集成插件bootpay_webview_flutter_wkwebview的使用

Flutter支付集成插件bootpay_webview_flutter_wkwebview的使用

在本教程中,我们将展示如何在Flutter应用中使用bootpay_webview_flutter_wkwebview插件。此插件基于webview_flutter,并提供了WKWebView的实现,用于在iOS设备上显示网页内容。

使用方法

首先,确保你已经在你的pubspec.yaml文件中添加了依赖项:

dependencies:
  bootpay_webview_flutter_wkwebview: ^版本号

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

完整示例代码

以下是一个完整的示例代码,展示了如何使用bootpay_webview_flutter_wkwebview插件来加载一个网页,并处理一些基本的导航和交互事件。

// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:bootpay_webview_flutter_platform_interface/bootpay_webview_flutter_platform_interface.dart';
import 'package:bootpay_webview_flutter_wkwebview/bootpay_webview_flutter_wkwebview.dart';

void main() {
  runApp(const MaterialApp(home: WebViewExample()));
}

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

  [@override](/user/override)
  State<WebViewExample> createState() => _WebViewExampleState();
}

class _WebViewExampleState extends State<WebViewExample> {
  late final PlatformWebViewController _controller;

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

    _controller = PlatformWebViewController(
      WebKitWebViewControllerCreationParams(allowsInlineMediaPlayback: true),
    )
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setBackgroundColor(const Color(0x80000000))
      ..setPlatformNavigationDelegate(
        PlatformNavigationDelegate(
          const PlatformNavigationDelegateCreationParams(),
        )
          ..setOnProgress((int progress) {
            debugPrint('WebView is loading (progress : $progress%)');
          })
          ..setOnPageStarted((String url) {
            debugPrint('Page started loading: $url');
          })
          ..setOnPageFinished((String url) {
            debugPrint('Page finished loading: $url');
          })
          ..setOnHttpError((HttpResponseError error) {
            debugPrint('Error occurred on page: ${error.response?.statusCode}');
          })
          ..setOnWebResourceError((WebResourceError error) {
            debugPrint('''
Page resource error:
  code: ${error.errorCode}
  description: ${error.description}
  errorType: ${error.errorType}
  isForMainFrame: ${error.isForMainFrame}
  url: ${error.url}
          ''');
          })
          ..setOnNavigationRequest((NavigationRequest request) {
            if (request.url.startsWith('https://www.youtube.com/')) {
              debugPrint('blocking navigation to ${request.url}');
              return NavigationDecision.prevent;
            }
            debugPrint('allowing navigation to ${request.url}');
            return NavigationDecision.navigate;
          })
          ..setOnUrlChange((UrlChange change) {
            debugPrint('url change to ${change.url}');
          })
          ..setOnHttpAuthRequest((HttpAuthRequest request) {
              openDialog(request);
            }),
      )
      ..setOnJavaScriptAlertDialog((JavaScriptAlertDialogRequest request) async {
          await _showAlert(context, request.message);
        })
      ..setOnJavaScriptConfirmDialog(
              (JavaScriptConfirmDialogRequest request) async {
            final bool result = await _showConfirm(context, request.message);
            return result;
          })
      ..setOnJavaScriptTextInputDialog(
              (JavaScriptTextInputDialogRequest request) async {
            final String result =
            await _showTextInput(context, request.message, request.defaultText);
            return result;
          })
      ..addJavaScriptChannel(JavaScriptChannelParams(
        name: 'Toaster',
        onMessageReceived: (JavaScriptMessage message) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text(message.message)),
          );
        },
      ))
      ..setOnPlatformPermissionRequest(
            (PlatformWebViewPermissionRequest request) {
          debugPrint(
            'requesting permissions for ${request.types.map((WebViewPermissionResourceType type) => type.name)}',
          );
          request.grant();
        },
      )
      ..loadRequest(LoadRequestParams(
        uri: Uri.parse('https://www.naver.com'),
      ))
      ..setOnScrollPositionChange((ScrollPositionChange scrollPositionChange) {
        debugPrint(
          'Scroll position change to x = ${scrollPositionChange.x}, y = ${scrollPositionChange.y}',
        );
      });
  }

  Future<void> _showAlert(BuildContext context, String message) async {
    return showDialog<void>(
        context: context,
        builder: (BuildContext ctx) {
          return AlertDialog(
            content: Text(message),
            actions: <Widget>[
              TextButton(
                  onPressed: () {
                    Navigator.of(ctx).pop();
                  },
                  child: const Text('OK'))
            ],
          );
        });
  }

  Future<bool> _showConfirm(BuildContext context, String message) async {
    return await showDialog<bool>(
        context: context,
        builder: (BuildContext ctx) {
          return AlertDialog(
            content: Text(message),
            actions: <Widget>[
              TextButton(
                  onPressed: () {
                    Navigator.of(ctx).pop(false);
                  },
                  child: const Text('Cancel')),
              TextButton(
                  onPressed: () {
                    Navigator.of(ctx).pop(true);
                  },
                  child: const Text('OK')),
            ],
          );
        }) ??
        false;
  }

  Future<String> _showTextInput(
      BuildContext context, String message, String? defaultText) async {
    return await showDialog<String>(
        context: context,
        builder: (BuildContext ctx) {
          return AlertDialog(
            content: Text(message),
            actions: <Widget>[
              TextButton(
                  onPressed: () {
                    Navigator.of(ctx).pop('Text test');
                  },
                  child: const Text('Enter')),
            ],
          );
        }) ??
        '';
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter WebView example'),
        actions: <Widget>[
          NavigationControls(webViewController: _controller),
        ],
      ),
      body: PlatformWebViewWidget(
        PlatformWebViewWidgetCreationParams(controller: _controller),
      ).build(context),
    );
  }
}

class NavigationControls extends StatelessWidget {
  const NavigationControls({super.key, required this.webViewController});

  final PlatformWebViewController webViewController;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Row(
      children: <Widget>[
        IconButton(
          icon: const Icon(Icons.arrow_back_ios),
          onPressed: () async {
            if (await webViewController.canGoBack()) {
              await webViewController.goBack();
            } else {
              if (context.mounted) {
                ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(content: Text('No back history item')),
                );
              }
            }
          },
        ),
        IconButton(
          icon: const Icon(Icons.arrow_forward_ios),
          onPressed: () async {
            if (await webViewController.canGoForward()) {
              await webViewController.goForward();
            } else {
              if (context.mounted) {
                ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(content: Text('No forward history item')),
                );
              }
            }
          },
        ),
        IconButton(
          icon: const Icon(Icons.replay),
          onPressed: () => webViewController.reload(),
        ),
      ],
    );
  }
}

Future<void> openDialog(HttpAuthRequest httpRequest) async {
  final TextEditingController usernameTextController = TextEditingController();
  final TextEditingController passwordTextController = TextEditingController();

  return showDialog(
    context: context,
    barrierDismissible: false,
    builder: (BuildContext context) {
      return AlertDialog(
        title: Text('${httpRequest.host}: ${httpRequest.realm ?? '-'}'),
        content: SingleChildScrollView(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              TextField(
                decoration: const InputDecoration(labelText: 'Username'),
                autofocus: true,
                controller: usernameTextController,
              ),
              TextField(
                decoration: const InputDecoration(labelText: 'Password'),
                controller: passwordTextController,
              ),
            ],
          ),
        ),
        actions: <Widget>[
          TextButton(
            onPressed: () {
              httpRequest.onCancel();
              Navigator.of(context).pop();
            },
            child: const Text('Cancel'),
          ),
          TextButton(
            onPressed: () {
              httpRequest.onProceed(
                WebViewCredential(
                  user: usernameTextController.text,
                  password: passwordTextController.text,
                ),
              );
              Navigator.of(context).pop();
            },
            child: const Text('Authenticate'),
          ),
        ],
      );
    },
  );
}

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

1 回复

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


bootpay_webview_flutter_wkwebview 是一个用于在 Flutter 应用中集成 Bootpay 支付功能的插件。它基于 WKWebView,适用于 iOS 平台。以下是如何使用 bootpay_webview_flutter_wkwebview 插件的步骤:

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  bootpay_webview_flutter_wkwebview: ^最新版本

请替换 ^最新版本 为插件的最新版本号。

2. 导入插件

在你的 Dart 文件中导入插件:

import 'package:bootpay_webview_flutter_wkwebview/bootpay_webview_flutter_wkwebview.dart';

3. 初始化 Bootpay

在需要使用 Bootpay 支付的地方,初始化 Bootpay 并设置相关参数:

void startBootpay() async {
  Bootpay bootpay = Bootpay();
  
  // 设置 Bootpay 参数
  await bootpay.requestPayment(
    applicationId: '你的应用ID',
    price: 1000, // 支付金额
    orderName: '测试订单', // 订单名称
    orderId: '订单ID', // 订单ID
    userInfo: BootpayUser(
        username: '用户姓名',
        email: '用户邮箱',
        phone: '用户电话'
    ),
    items: [
      BootpayItem(
          itemName: '商品名称',
          qty: 1,
          price: 1000
      )
    ],
    extra: BootpayExtra(
        openType: 'redirect',
        cardQuota: '0,2,3' // 分期付款选项
    )
  );

  // 监听支付结果
  bootpay.onDone.listen((event) {
    print('支付完成: $event');
  });

  bootpay.onCancel.listen((event) {
    print('支付取消: $event');
  });

  bootpay.onError.listen((event) {
    print('支付错误: $event');
  });
}

4. 调用支付

在你需要触发支付的地方调用 startBootpay 方法:

ElevatedButton(
  onPressed: () {
    startBootpay();
  },
  child: Text('开始支付'),
);
回到顶部