Credit Passport Webview Integration
Nova Credit supports integrating Credit Passport® into native web applications through the use of a WebView in both iOS and Android.
Minimum iOS version supported: 15.0
Minimum Android version supported: 12.0
Settings
- Javascript content enabled must be set to
true - (Mitek only) Media Inline Playback must be set to
true - (Mitek only) MediaPlaybackRequiresUserGesture (Android only) must be set to
false
React Native
import { WebView } from 'react-native-webview';
<WebView allowsInlineMediaPlayback javascriptEnabled mediaPlaybackRequiresUserAction={false} />;
Swift
webView.configuration.allowsInlineMediaPlayback = true
let preferences = WKWebpagePreferences()
preferences.allowsContentJavaScript = true
webView.configuration.defaultWebpagePreferences = preferences
Kotlin
val webSettings: WebSettings = webView.settings
webSettings.javaScriptEnabled = true
webSettings.mediaPlaybackRequiresUserGesture = false
Permissions
The following permissions must be added for Mitek countries to work properly.
iOS: Info.plist
- Privacy - Camera Usage Description
Android: AndroidManifest.xml
- android.permission.CAMERA
- android.permission.INTERNET
React Native Expo: app.json
{
"android": {
"permissions": ["android.permission.CAMERA", "android.permission.INTERNET"]
},
"ios": {
"infoPlist": {
"NSCameraUsageDescription": "Camera Usage Description"
}
}
}
Additionally, enabling these permissions inside of a Webview requires some additional logic in code to check and grant permissions.
Swift
func webView(_ webView: WKWebView, decideMediaCapturePermissionsFor origin: WKSecurityOrigin,
initiatedBy frame: WKFrameInfo, type: WKMediaCaptureType) async -> WKPermissionDecision {
if type == .camera, await checkCameraPermissions(){
return .grant
}
else{
return .prompt
}
}
func checkCameraPermissions() async -> Bool{
let authStatus = AVCaptureDevice.authorizationStatus(for: .video)
if (authStatus != .authorized){
return await AVCaptureDevice.requestAccess(for: .video)
}
return authStatus == .authorized;
}
Kotlin
val webviewRequest;
val CAMERA_PERMISSION_REQUEST_CODE = 200
override fun onPermissionRequest(request: PermissionRequest?) {
val requestedResources = request?.resources
if (requestedResources != null){
for (resource in requestedResources){
if (resource == PermissionRequest.RESOURCE_VIDEO_CAPTURE){
// Check if camera permission already granted
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
// Request camera permission
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), CAMERA_PERMISSION_REQUEST_CODE);
}
else{
request.grant(arrayOf(Manifest.permission.CAMERA));
}
}
else{
request.deny();
}
}
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
webviewRequest.grant(arrayOf(Manifest.permission.CAMERA))
}
}
}
Callback handling
You can handle client side callbacks onSuccess, onError, and onExit by posting a message to the WebView. More details about client side hooks are available in our Quickstart Guide.
JS registration
// When registering Nova Credit handle the callbacks
window.Nova.register({
env: 'sandbox',
productId: 'productId',
publicId: 'publicId',
onSuccess: function(publicToken, status){
const msg = JSON.stringify({ message:'NOVA_SUCCESS', publicToken, status });
// React Native
window.ReactNativeWebView.postMessage(msg, '*');
// iOS
window.webkit.messageHandlers.native.postMessage(msg, '*');
// Android
window.parent.postMessage(msg, '*');
}
onError: function(publicToken, error){
const msg = JSON.stringify({ message:'NOVA_ERROR', publicToken, error });
// postMessage(msg, '*');
}
onExit: function(){
const msg = JSON.stringify({ message:'NOVA_EXIT'});
// postMessage(msg, '*');
},
});
React Native
<Webview onMessage={event => console.log(event.nativeEvent.data)} />
Swift
let configuration = WKWebViewConfiguration()
configuration.userContentController.add(self, name: "NOVA_MESSAGE")
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "NOVA_MESSAGE" {
// Parse message
}
}
Kotlin
val novaListener = object : WebMessageListener() {
override fun onPostMessage(
view: WebView,
message: WebMessageCompat,
sourceOrigin: Uri,
isMainFrame: Boolean,
replyProxy: JavaScriptReplyProxy
) {
// Parse message
}
}
WebViewCompat.addWebMessageListener(webView, "myObject", rules, novaListener)