Payfast 支付集成 Flutter

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

我正在实施 payfast 付款集成,因此我创建了一个表单,用户在其中填写金额和商品名称,然后我想通过 http 调用将这些详细信息发送到 Payfast 付款页面以显示在 Web 视图上。所以现在,当我按下支付按钮时,它不会导航或显示网络视图,并且没有错误。请有人帮助我如何使用下面的代码实现此目的

请检查下面我的代码:

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

  @override
  _PayfastPaymentState createState() => _PayfastPaymentState();
}

class _PayfastPaymentState extends State<PayfastPayment> {
  GlobalKey<FormState> formstate = new GlobalKey<FormState>();
  TextEditingController amountController = TextEditingController();
  TextEditingController itemNameController = TextEditingController();
  PaymentViewModel? model;
  var client = http.Client();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(centerTitle: true, title: const Text("Payment Page")),
      body: Form(
        key: formstate,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            TextFormField(
              controller: amountController,
              decoration: const InputDecoration(
                border: UnderlineInputBorder(),
                labelText: 'Amount',
              ),
            ),
            const SizedBox(
              height: 100,
            ),
            TextFormField(
              controller: itemNameController,
              decoration: const InputDecoration(
                border: UnderlineInputBorder(),
                labelText: 'Item Name',
              ),
            ),
            SizedBox(
              width: 220,
              height: 100,
              child: InkWell(
                onTap: () {
                  print(
                      "Amount: ${amountController.text} Item: ${itemNameController.text}");
                  model?.payment(
                      amountController.text, itemNameController.text);
                },
                child: Container(
                  alignment: Alignment.center,
                  color: Colors.blue,
                  child: const Center(
                      child: Text("Pay",
                          style: TextStyle(fontSize: 22, color: Colors.white))),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

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

  @override
  WebViewPageState createState() => WebViewPageState();
}

class WebViewPageState extends State<WebViewPage> {
  PaymentViewModel? model;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text("Web View"),
        ),
        body: Column(children: [
          Expanded(
              child: WebView(
            initialUrl: model?.payFast,
            javascriptMode: JavascriptMode.unrestricted,
            onPageFinished: _onUrlChange,
            debuggingEnabled: true,
          ))
        ]));
  }

  _onUrlChange(String url) {
    print('Page finished loading: $url');
    if (mounted) {
      setState(() {
        if (url.contains("http://localhost:8080/#/onSuccess")) {
          Navigator.pushNamed(context, "/onSuccess");
        } else if (url.contains("http://localhost:8080/#/onCancel")) {
          Navigator.pushNamed(context, "/onCancel");
        }
      });
    }
  }
}

class PaymentViewModel {
  TextEditingController amountController = TextEditingController();
  TextEditingController itemNameController = TextEditingController();
  API? api;
  String? errorMessage;
  String? payFast;

  void payment(String? amount, String? item_name) {
    //amount = amountController.text;
    item_name = itemNameController.text;
    api
        ?.payFastPayment(amount: amount, item_name: item_name)
        .then((createdPayment) {
      if (createdPayment == null) {
        errorMessage = "Something went wrong. Please try again.";
      } else {
        payFast = createdPayment;
      }
      print("It reaches here");
    }).catchError((error) {
      errorMessage = '${error.toString()}';
    });
  }
}

class API {
  static String baseURL = 'https://sandbox.payfast.co.za';

  var client = new http.Client();

  Future<String> payFastPayment({
    String? amount,
    String? item_name,
  }) async {
    Map<String, String>? requestHeaders;

    final queryParameters = {
      'merchant_key': '46f0cd694581a',
      'merchant_id': '10000100',
      'amount': '$amount',
      'item_name': '$item_name',
      'return_url': 'http://localhost:8080/#/onSuccess',
      'cancel_url': 'http://localhost:8080/#/onCancel',
    };
    Uri uri = Uri.https(baseURL, "/eng/process", queryParameters);
    print("URI ${uri.data}");
    final response = await client.put(uri, headers: requestHeaders);
    print("Response body ${response.body}");
    if (response.statusCode == 200 ||
        response.statusCode == 201 ||
        response.statusCode == 203 ||
        response.statusCode == 204) {
      return response.body;
    } else if (response.body != null) {
      return Future.error(response.body);
    } else {
      return Future.error('${response.toString()}');
    }
  }
}

class OnSuccess extends StatelessWidget {
  const OnSuccess({Key? key}) : super(key: key);
  static const String route = 'onSuccess';
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
          child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: const [
          Text(
            "This is on Success",
            style: TextStyle(fontWeight: FontWeight.bold, fontSize: 33),
          ),
          SizedBox(width: 15),
          Icon(
            Icons.check,
            color: Colors.green,
            size: 40,
          )
        ],
      )),
    );
  }
}

class OnCancel extends StatelessWidget {
  const OnCancel({Key? key}) : super(key: key);
  static const String route = 'OnCancel';
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
          child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: const [
          Text(
            "This is on Cancel",
            style: TextStyle(fontWeight: FontWeight.bold, fontSize: 33),
          ),
          SizedBox(width: 15),
          Icon(
            Icons.close,
            color: Colors.red,
            size: 40,
          )
        ],
      )),
    );
  }
}
flutter payment-gateway payfast
2个回答
0
投票

您的初始网址似乎为空。您已创建名为 model 的 paymentViewModel 实例。并在 webview 的初始 url 中调用它。在 paymentViewModel 中 payFast 只是一个可为空的字符串。所以 url 可能为空。请检查


0
投票
class PaymentProvider with ChangeNotifier {
  final String merchantId = 'xxxxx';
  final String merchantKey = 'xxxxx';
  final String passphrase = 'xxxx';
  final String returnUrl = 'YourWeb';
  final String cancelUrl = 'YourWeb';
  final String notifyUrl = 'YourWeb';
  String webviewUrl = '';
  bool testingMode = true;
  double cartTotal = 20.0;

  Future<String> createPaymentRequest(String paymentId, String firstName,
      String lastName, String emailAddress) async {
    try {
      Map<String, String> data = {
        'merchant_id': merchantId,
        'merchant_key': merchantKey,
        'return_url': returnUrl,
        'cancel_url': cancelUrl,
        'notify_url': notifyUrl,
        'name_first': firstName,
        'name_last': lastName,
        'email_address': emailAddress,
        'm_payment_id': paymentId,
        'amount': cartTotal.toStringAsFixed(2),
        'item_name': 'Order#$paymentId',
      };

      String signature = await generateSignature(data, passphrase);
      data['signature'] = signature;
      String pfHost =
          testingMode ? 'sandbox.payfast.co.za' : 'www.payfast.co.za';
      String paymentUrl = 'https://$pfHost/eng/process?';
      data.forEach((key, value) {
        paymentUrl += '$key=${Uri.encodeComponent(value)}&';
      });

      webviewUrl = paymentUrl;
      notifyListeners();
      return paymentUrl;
    } catch (e) {
      log('error at createPaymentRequest: ${e.toString()}');
      return '';
    }
  }

  Future<String> generateSignature(Map<String, String> data, String passphrase) async {
   
    return 'signature_placeholder';
  }
}

之后你可以在flutetr webview(WebViewWidget)中使用webviewUrl

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