将 MPG 与 flutter 集成时出错

问题描述 投票:0回答:1

我在使用 MPG 时遇到问题。 支付源首先提供了 HTML 代码,我通过 API 请求获取了季节 ID。 https://mcb.gateway.mastercard.com/api/rest/version/75/merchant/{merchant-id}/session

HTML 读取会话 ID,但我在 Web 视图应该显示付款表单时遇到了这些错误

I/flutter (17252): JavaScript Console: Uncaught SecurityError: Failed to read the 'sessionStorage' property from 'Window': Access is denied for this document.

I/flutter (17252): JavaScript Console: Possible Unhandled Promise Rejection: SecurityError: Failed to read the 'sessionStorage' property from 'Window': Access is denied for this document.

造成这种情况的问题是什么?

代码

 InAppWebView(
                                
       initialUrlRequest: URLRequest(
        url: Uri.parse(''),
        ),
        initialOptions: InAppWebViewGroupOptions(
        crossPlatform: InAppWebViewOptions(
        cacheEnabled: true,
        useShouldOverrideUrlLoading: true,
        javaScriptEnabled: true,
        javaScriptCanOpenWindowsAutomatically: true,
        mediaPlaybackRequiresUserGesture: false,
        ),
        android: AndroidInAppWebViewOptions(
        useHybridComposition: true,
        domStorageEnabled: true,
        ),
        ios: IOSInAppWebViewOptions(
        allowsInlineMediaPlayback: true,
        )),
        androidOnPermissionRequest: (controller, origin, resources)          async {
        return PermissionRequestResponse(
               resources: resources,
               action: PermissionRequestResponseAction.GRANT,
                );
                 },
         onWebViewCreated: (controller) async {
         webView = controller;
         await webView?.loadData(
    //html content
         data: '''
         <html>
         <head>
         <meta name="viewport" content="width=device-width, initial-         scale=1">
        <script src="https://mcb.gateway.mastercard.com/static/checkout/checkout.min.js" data-error="errorCallback" data-cancel="cancelCallback"></script>
        <script type="text/javascript">
            function errorCallback(error) {
                  console.log(JSON.stringify(error));
            }
            function cancelCallback() {
                  console.log('Payment cancelled');
            }
            Checkout.configure({
              session: { 
                id: '${state.id}'
                }
            });
        </script>
    </head>
    <body>
       ...
      <div id="embed-target"> </div> 
      <input type="button" value="Pay with Embedded Page" onclick="Checkout.showEmbeddedPage('#embed-target');" />
      <input type="button" value="Pay with Payment Page" onclick="Checkout.showPaymentPage();" />
       ...
    </body>
</html>
             ''',
    mimeType: 'text/html',
                                    );
                                 
                                  },
         onLoadError: (controller, url, code, message) {
         print('Error loading $url: $code, $message');
         },
         onLoadStop: (controller, url) {},
         onConsoleMessage: (controller, consoleMessage) {
         final logMessage = consoleMessage.message;
         print('JavaScript Console: $logMessage');
                                  },
                                );
flutter webview flutterwebviewplugin mastercard mpgs-session-js
1个回答
0
投票

我了解我们都在致力于将 MPGS 支付集成到 Flutter 中。

在我最近的工作中,我还遇到了flutter_inappwebview包不支持本地存储的限制。您可以通过在 Github 上打开的此问题来确定。

为了解决这个问题,我评估了一些我尝试过的解决方案,可能会帮助您推进项目:

解决方案1:

我创建了一个 HTML 页面,其中包含加载 MPGS 集成所需的脚本和数据。

<html>
<head>
    <script
            src="https://test-gateway.mastercard.com/static/checkout/checkout.min.js"
            data-error="errorCallback"
            data-cancel="cancelCallback"
    ></script>
    <script type="text/javascript">

       const params = new URLSearchParams(document.location.search);
       const sessionId = params.get("session_id");

      function errorCallback(error) {
        console.log(JSON.stringify(error));
      }
      function cancelCallback() {
        console.log("Payment cancelled");
      }

      Checkout.configure({
        session: {
          id: `${sessionId}`,
        },
      }).then(() => {
        Checkout.showPaymentPage();
      });
    
    </script>
</head>
</html>

此页面已上传到我们的服务器。

从移动端,我从服务器请求 HTML 页面,并将会话 ID 作为 URL 中的查询参数传递。 例如:

www.example.com/mpgs.html?session_id=xxxxxxxx

HTML 页面上的 MPGS 脚本可以从查询字符串中检索会话 ID 以初始化支付流程。 这允许我从我们自己的服务器上的远程 URL 加载 MPGS webview 内容,同时仍然从移动应用程序传递必要的会话 ID。然后,网络视图可以传达退款状态和令牌。

解决方案2:

我已将上述页面添加到应用程序资产项目中,并使用应用程序内本地主机服务器在本地托管页面HTML,像上面一样传递session_id(查询参数)并加载脚本。

我已经实现了以下代码:

定义变量

  final InAppLocalhostServer localhostServer = InAppLocalhostServer();

然后初始化它

    Future.microtask(() async => await localhostServer.start());

之后,添加了以下小部件

InAppWebView(
      initialUrlRequest: URLRequest(
          url: Uri.parse(
              "http://localhost:8080/assets/html_files/paymentGateWay.html?session_id=SESSION0002174711341F46647517L2")),
   
      initialOptions: uiController.webViewOptions,
      onProgressChanged: (controller, progress) =>
          uiController.setLoadingProgress(progress / 100),
      androidOnPermissionRequest: (controller, origin, resources) =>
          uiController.getPermissionRequestResponse(resources),
      onLoadError: (controller, url, code, message) {
        print('Error loading $url: $code, $message');
      },
      onUpdateVisitedHistory: (controller, url, androidIsReload) {
        print('sadsdasad');
        print(url);
      },
      onLoadStop: (controller, url) {},
      onConsoleMessage: (controller, consoleMessage) {
        final logMessage = consoleMessage.message;
        print('JavaScript Console: $logMessage');
      },
    );

虽然在本地托管 HTML 页面并重定向到 MPGS 是一个可行的解决方案,但 我认为存在需要考虑的限制: 应用程序需要允许 HTTP URL 方案才能在本地托管 HTML 页面。但是,出于安全和隐私原因,大多数应用程序默认不允许非 HTTPS 方案。

请告诉我您对解决方案 2 的看法。

© www.soinside.com 2019 - 2024. All rights reserved.