2

我正在尝试使用这篇文章在我的 Flutter App 中实现Instamojo Payment:

我正在使用Flutter Webview 插件。现在问题出在付款过程中,Instamojo 会打开另一个选项卡进行 OTP 验证。但是这个新标签不会显示在应用程序内。

如何在颤动中处理这些多个选项卡?我找不到任何支持多个浏览器选项卡的 WebView 插件。

这是代码:

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
import 'package:http/http.dart' as http;

class Insta extends StatefulWidget {
  @override
  _InstaState createState() => _InstaState();
}

class _InstaState extends State<Insta> {
  FlutterWebviewPlugin flutterWebviewPlugin = FlutterWebviewPlugin();

  @override
  void initState() {
    super.initState();
    createRequest(); //creating the HTTP request
// Add a listener on url changed
    flutterWebviewPlugin.onUrlChanged.listen((String url) {
      if (mounted) {
        if (url.contains('http://www.example.com/redirect')) {
          Uri uri = Uri.parse(url);
//Take the payment_id parameter of the url.
          String paymentRequestId = uri.queryParameters['payment_id'];
//calling this method to check payment status
          _checkPaymentStatus(paymentRequestId);
        }
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text('data'),
    );
  }

  _checkPaymentStatus(String id) async {
    var response = await http.get(
        Uri.encodeFull("https://t7+st.instamojo.com/api/1.1/payments/$id/"),
        headers: {
          "Accept": "application/json",
          "Content-Type": "application/x-www-form-urlencoded",
          "X-Api-Key": "**Hidden for security reasons**",
          "X-Auth-Token": "**Hidden for security reasons**"
        });
    var realResponse = json.decode(response.body);
    print(realResponse);
    if (realResponse['success'] == true) {
      if (realResponse["payment"]['status'] == 'Credit') {
        print('sucesssssssssssful');
//payment is successful.
      } else {
        print('failed');
//payment failed or pending.
      }
    } else {
      print("PAYMENT STATUS FAILED");
    }
  }

  static const kAndroidUserAgent =
      "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Mobile Safari/537.36";
  Future createRequest() async {
    Map<String, String> body = {
      "amount": "9", //amount to be paid
      "purpose": "Advertising",
      "buyer_name": '',
      "email": '',
      "phone": '',
      "allow_repeated_payments": "true",
      "send_email": "false",
      "send_sms": "false",
      "redirect_url": "http://www.example.com/redirect/",
      //Where to redirect after a successful payment.
      "webhook": "http://www.example.com/webhook/",
    };
//First we have to create a Payment_Request.
//then we'll take the response of our request.
    var resp = await http.post(
        Uri.encodeFull("https://www.instamojo.com/api/1.1/payment-requests/"),
        headers: {
          "Accept": "application/json",
          "Content-Type": "application/x-www-form-urlencoded",
          "X-Api-Key": "**Hidden for security reasons**",
          "X-Auth-Token": "**Hidden for security reasons**"
        },
        body: body);
    if (json.decode(resp.body)['success'] == true) {
//If request is successful take the longurl.
      String selectedUrl =
          json.decode(resp.body)["payment_request"]['longurl'].toString() +
              "?embed=form";
      flutterWebviewPlugin.close();
//Let's open the url in webview.
      flutterWebviewPlugin.launch(selectedUrl,
          rect: new Rect.fromLTRB(
              5.0,
              MediaQuery.of(context).size.height / 7,
              MediaQuery.of(context).size.width - 5.0,
              7 * MediaQuery.of(context).size.height / 7),
          userAgent: kAndroidUserAgent);
    } else {
      print(json.decode(resp.body)['message'].toString());
//If something is wrong with the data we provided to
//create the Payment_Request. For Example, the email is in incorrect format, the payment_Request creation will fail.
    }
  }
}
4

1 回答 1

0

作为一种解决方法,您可以在这里做的是让外部浏览器处理正在打开的链接。为此,您可以navigationDelegate在 WebView 上进行设置以处理特定的 URL。我建议使用Flutter 的官方 WebView 插件

WebView(
  ...
  navigationDelegate: (NavigationRequest request) {
    // open URL on external browser if matches root URL for OTP
    if (request.url.startsWith("OTP root URL goes here")) {
      _launchURL(request.url);
      return NavigationDecision.prevent;
    } else {
      return NavigationDecision.navigate;
    }
  },
),

您可以使用url_launcher插件来处理外部 URL 的打开。

_launchURL(String url) async {
  if (await canLaunch(url)) {
    await launch(url);
  } else {
    debugPrint('Could not launch $url');
  }
}
于 2021-07-13T14:27:40.633 回答