Loading the Banxa checkout in a mobile WebView requires specific configuration to support camera access, payment methods, and KYC flows.
If your integration includes Google Pay, use Custom Chrome Tabs instead of a standard WebView. Standard WebView does not support GPAY or ACH.
import androidx.browser.customtabs.CustomTabsIntent
val customTabsIntent = CustomTabsIntent.Builder().build()
customTabsIntent.launchUrl(context, Uri.parse(checkoutUrl))If you are not using Google Pay, you can use a WebView with the following configuration:
webView.settings.apply {
javaScriptEnabled = true
domStorageEnabled = true // Required: enables local storage
mediaPlaybackRequiresUserGesture = false // Required: enables video instructions
allowFileAccess = true
setSupportZoom(false)
}
// Enable camera access
webView.webChromeClient = object : WebChromeClient() {
override fun onPermissionRequest(request: PermissionRequest) {
request.grant(request.resources) // Grant camera/microphone
}
// Required for HTML5 video playback
override fun onShowCustomView(view: View, callback: CustomViewCallback) {
// Handle fullscreen video
}
}Declare permissions in AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />Use SFSafariViewController when your integration includes KYC liveness checks (Sumsub). Liveness checks cannot complete in a standard WKWebView.
import SafariServices
let safariVC = SFSafariViewController(url: URL(string: checkoutUrl)!)
present(safariVC, animated: true)If liveness checks are not required, WKWebView can be used with the following configuration:
import WebKit
let config = WKWebViewConfiguration()
config.allowsInlineMediaPlayback = true // Required
config.mediaTypesRequiringUserActionForPlayback = [] // Required: allow autoplay for video instructions
let webView = WKWebView(frame: .zero, configuration: config)
// Request camera permission
webView.uiDelegate = self // Implement WKUIDelegateImplement WKUIDelegate to handle permission requests:
func webView(_ webView: WKWebView,
requestMediaCapturePermissionFor origin: WKSecurityOrigin,
initiatedByFrame frame: WKFrameInfo,
type: WKMediaCaptureType,
decisionHandler: @escaping (WKPermissionDecision) -> Void) {
decisionHandler(.grant)
}Add to Info.plist:
<key>NSCameraUsageDescription</key>
<string>Required for identity verification</string>
<key>NSMicrophoneUsageDescription</key>
<string>Required for identity verification</string>Use react-native-webview with the following props:
import { WebView } from 'react-native-webview';
<WebView
source={{ uri: checkoutUrl }}
allowsInlineMediaPlayback={true} // Required: inline video for instructions
mediaPlaybackRequiresUserAction={false} // Required: allow autoplay
domStorageEnabled={true} // Required: local storage (Android)
enableApplePay={true} // Required: Apple Pay on iOS
onNavigationStateChange={(navState) => {
// Detect redirect to your redirectUrl
if (navState.url.startsWith('https://yourapp.com/order-complete')) {
// Dismiss WebView and check order status
}
}}
/>Camera and microphone access is controlled by OS-level permissions — set in AndroidManifest.xml and Info.plist as shown below, not via WebView props.
Use webview_flutter with the following configuration:
import 'package:webview_flutter/webview_flutter.dart';
late final WebViewController controller;
controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setNavigationDelegate(NavigationDelegate(
onNavigationRequest: (NavigationRequest request) {
if (request.url.startsWith('https://yourapp.com/order-complete')) {
// Dismiss WebView
return NavigationDecision.prevent;
}
return NavigationDecision.navigate;
},
))
..loadRequest(Uri.parse(checkoutUrl));For camera access on Android, add to AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA" />iDEAL, Klarna, and PayPal cannot complete inside a WebView. When a customer selects one of these methods, they will be redirected to an external browser to complete their payment. After payment, the customer is returned to the Banxa order status page — they will not be returned automatically to your WebView.
Design your post-payment UX accordingly: a confirmation screen with a link back to your app is the recommended pattern.
| Requirement | Android | iOS |
|---|---|---|
| Local storage | domStorageEnabled = true | Enabled by default in WKWebView |
| Camera access | onPermissionRequest grant | WKUIDelegate + Info.plist |
| Video playback | WebChromeClient + mediaPlaybackRequiresUserGesture = false | allowsInlineMediaPlayback = true |
| KYC liveness | Custom Chrome Tabs or WebView | SFSafariViewController required |
| Google Pay | Custom Chrome Tabs required | Supported in WKWebView |