import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:go_router/go_router.dart'; import 'package:qpay/screens/gateway/gateway_controller.dart'; import 'package:webview_flutter/webview_flutter.dart'; class GatewayScreen extends StatefulWidget { final String url; const GatewayScreen({super.key, required this.url}); @override State createState() => _GatewayScreenState(); } class _GatewayScreenState extends State { late WebViewController _webViewController; late GatewayController controller; bool integrationStarted = false; @override void initState() { super.initState(); _initWebView(widget.url); controller = GatewayController(context); bool simulate = bool.parse(dotenv.env['SIMULATE_PAYMENT_SUCCESS']!); if(simulate) { sleep(Duration(seconds: 10)); String url = widget.url.replaceAll("/pay/", "/receipt/"); _webViewController.loadRequest(Uri.parse(url)); } } void _initWebView(String url) { _webViewController = WebViewController() ..setJavaScriptMode(JavaScriptMode.unrestricted) ..setNavigationDelegate( NavigationDelegate( onProgress: (int progress) { // Update loading bar. }, onPageStarted: (String url) { controller.startLoading(); }, onPageFinished: (String url) { controller.finishLoading(); }, onHttpError: (HttpResponseError error) {}, onWebResourceError: (WebResourceError error) {}, onUrlChange: (UrlChange url) async { print("URL Changed to ${url.url!}"); if(url.url!.contains("/checkout/receipt/")){ if(integrationStarted) { return; } ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text("Payment was successful, please wait while we process your order."), behavior: SnackBarBehavior.floating, backgroundColor: Colors.black87, duration: const Duration(seconds: 5), ), ); setState(() { integrationStarted = true; }); await controller.poll(controller.transactionController.model.receiptData?['id']); WidgetsBinding.instance.addPostFrameCallback((_) { context.go('/integration'); }); } } ), ) ..loadRequest(Uri.parse(url)); } @override void dispose() { controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Complete your payment'), leading: context.canPop() ? IconButton( onPressed: () { context.pop(); }, icon: const Icon(Icons.arrow_back), ) : SizedBox.shrink(), ), body: ListenableBuilder( listenable: controller, builder: (context, child) { if (controller.model.status == 'SUCCESS') { WidgetsBinding.instance.addPostFrameCallback((_) { context.go('/integration'); }); } return controller.model.isLoading ? const Center(child: CircularProgressIndicator(strokeWidth: 5)) : WebViewWidget(controller: _webViewController); }, ), ); } }