在 PayPal 中使用 HtmlElementView

Jac*_*ack 2 paypal dart-js-interop flutter flutter-web

我有一个 Flutter Web 项目。我有以下 HTML 脚本需要放入HtmlElementView

<script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID"></script>
<script>paypal.Buttons().render('body');</script>
Run Code Online (Sandbox Code Playgroud)

这里。我试过这个:

Widget build(BuildContext context) {
    // ignore: undefined_prefixed_name
    ui.platformViewRegistry.registerViewFactory(
      'paypal-button',
        (int viewId) => IFrameElement()
        ..width = '500'
        ..height = '500'
        ..src = '''
        <div id="paypal-button-container"></div>
        <script src="https://paypal.com/sdk/js?client-id=MY_CLIENT_ID"></script>
        <script>
        paypal.Buttons({

            // Set up the transaction
            createOrder: function(data, actions) {
                return actions.order.create({
                    purchase_units: [{
                        amount: {
                            value: '0.01'
                        }
                    }]
                });
            },

            // Finalize the transaction
            onApprove: function(data, actions) {
                return actions.order.capture().then(function(details) {
                    // Show a success message to the buyer
                    alert('Transaction completed by ' + details.payer.name.given_name + '!');
                });
            }


        }).render('#paypal-button-container');
    </script>
        '''
    );
    return SizedBox(
      height: 300,
      width: 500,
      child: Center(
        child: HtmlElementView(
          viewType: 'paypal-button',
        ),
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)

注意:此代码来自https://developer.paypal.com/demo/checkout/#/pattern/client

此代码不显示任何按钮并给出以下错误:

坏状态:未来已经完成

其 URL 包含已删除的空格 ( \n, \r, \t) 字符和小于字符 ( <) 的资源请求将被阻止。请从元素属性值等位置删除换行符并编码小于字符以加载这些资源。有关更多详细信息,请参阅https://www.chromestatus.com/feature/5735596811091968

我需要知道的是如何将此代码片段显示为小部件,以便我的 Flutter Web 项目能够接受 Paypal 付款。谢谢你的帮助!

Spa*_*atz 6

目前,将 PayPal 按钮集成flutter web到其中的唯一方法是将它们包装在 IFrame 容器中:

class PayPalWidget extends StatefulWidget {
  @override
  _PayPalState createState() => _PayPalState();
}

class _PayPalState extends State<PayPalWidget> {
  html.IFrameElement _element;

  @override
  void initState() {
    _element = html.IFrameElement()
      ..width = "200px"
      ..height = "200px"
      ..style.border = 'none'
      ..srcdoc = """
        <!DOCTYPE html>
        <html>
          <body>
            <script src="https://www.paypal.com/sdk/js?client-id=sb"></script>
            <script>
              paypal.Buttons(
                {
                  createOrder: function(data, actions) {
                    return actions.order.create({
                      purchase_units: parent.purchase_units
                    });
                  },
                  onApprove: function(data, actions) {
                    return actions.order.capture().then(function(details) {
                      parent.flutter_feedback('Transaction completed by ' + details.payer.name.given_name);
                    });
                  }
                }

              ).render('body');
            </script>
          </body>
        </html>
        """;

    js.context["purchase_units"] = js.JsObject.jsify([
      {
        'amount': {'value': '0.02'}
      }
    ]);
    js.context["flutter_feedback"] = (msg) {
      Scaffold.of(context).showSnackBar(SnackBar(content: Text(msg)));
    };

    // ignore:undefined_prefixed_name
    ui.platformViewRegistry.registerViewFactory(
      'PayPalButtons',
      (int viewId) => _element,
    );

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 220,
      height: 220,
      child: HtmlElementView(viewType: 'PayPalButtons'),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

但请记住,这种方法远非理想,因为每次更新小部件时都会重新创建 IFrame。我添加了代码来演示这种不利影响:

import 'dart:ui' as ui;
import 'dart:js' as js;
import 'package:universal_html/html.dart' as html;
import 'package:flutter/material.dart';

class NextLabPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          leading: BackButton(),
          title: Text('PayPal integration'),
          centerTitle: true,
        ),
        body: Center(
          child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Noise(),
                PayPalWidget(),
              ]),
        ),
      ),
    );
  }
}

class Noise extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: RaisedButton(
        child: Text('Make Noise'),
        onPressed: () {
          Scaffold.of(context).showSnackBar(
            SnackBar(
              content:
                  Text("PayPal buttons will be re-created when I disappear"),
            ),
          );
        },
      ),
    );
  }
}

// PayPalWidget code
// ...

Run Code Online (Sandbox Code Playgroud)

按“发出声音”按钮显示小吃栏 - 当消息消失时,按钮也会消失。或者将鼠标悬停在 AppBar 中的“后退箭头”上并移开以显示相同的效果。