After we bumped targetSdkVersion to 34 for Play Store compliance, our Flutter payment flow started white-screening on Android 14 devices. Users could reach the checkout screen, tap Pay, and the embedded WebView would go blank. No crash in Crashlytics — just a silent failure that killed conversion.
- Flutter 3.16.x, webview_flutter 4.4.x
- Android 14 (API 34), Pixel 7 and Samsung S23
- Payment gateway: Razorpay hosted checkout in WebView
- targetSdk 34, minSdk 24
Two issues stacked together. First, Android 14 enforces stricter WebView multiprocess and lifecycle rules — our WebView was created before the Activity was fully resumed and got torn down on configuration changes. Second, the payment URL loaded mixed HTTP assets on an HTTPS page, which Android 14 blocks by default unless mixed content mode is explicitly set on the native WebView.
We moved WebView initialization to after the first frame and configured the Android platform explicitly:
// Delay WebView creation until widget is mounted
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => _initWebView());
}
Future<void> _initWebView() async {
late final PlatformWebViewControllerCreationParams params;
if (WebViewPlatform.instance is WebKitWebViewPlatform) {
params = WebKitWebViewControllerCreationParams();
} else {
params = AndroidWebViewControllerCreationParams();
}
final controller = WebViewController.fromPlatformCreationParams(params);
if (controller.platform is AndroidWebViewController) {
await (controller.platform as AndroidWebViewController)
.setMixedContentMode(MixedContentMode.alwaysAllow);
await (controller.platform as AndroidWebViewController)
.setMediaPlaybackRequiresUserGesture(false);
}
await controller.setJavaScriptMode(JavaScriptMode.unrestricted);
await controller.loadRequest(Uri.parse(paymentUrl));
setState(() => _controller = controller);
}
We also added a NavigationDelegate to detect blank loads and retry once with a cache-busted URL.
- Always test payment WebViews on physical Android 14 devices before targetSdk bumps
- Enable WebView debugging in staging:
if (kDebugMode) WebView.enableDebugging(true);
- Log WebView onPageFinished and onWebResourceError to your analytics pipeline
- Prefer official SDK over raw WebView when the gateway provides one
Payment completion rate recovered from 91.2% to 99.6% within 48 hours of the hotfix. Zero WebView-related support tickets in the following sprint.