androidandroid-keypad3d-securepayfort

Payfort with 3-D Secure Credit Cards


I'm using Payfort sdk for online payments using my application, everything is fully integrated and working fine, when coming to payment, I can do the payment using Normal cards without any concerns, but using 3-D secure cards I have to enter a password for verification, hence, a (verified by Visa) webview with the password field automatically opens with the required details.

the problem here is when tapping the password field it getting the focus but the keyboard doesn't open to write the password, the webview which is opened is not a view from my application and I don't any control over it but closing.

I don't even know how to figure out it is now opened as I'm not receiving any corresponding callbacks.

enter image description here

Navigating Through Payfort code, I discovered they issuing an AlertDialog with a layout contains a webView that takes the verification page link to be displayed:

 private Dialog showVerificationDialog(Context context, String url, VerificationDialogDismissListener onDialogListener) {
    LayoutInflater layoutInflater = LayoutInflater.from(context); // context here is MyActivity context
    View view = layoutInflater.inflate(R.layout.web_dialog, null);
    DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();

    // just to display the Dialog at 80% of the screen
    view.setMinimumHeight((int) (displayMetrics.heightPixels * 0.8f));
    view.setMinimumWidth((int) (displayMetrics.widthPixels * 0.8f));

    // setting the webView
    WebView webView = (WebView) view.findViewById(R.id.webView);
    webView.setWebViewClient(new WebViewClient());
    webView.getSettings().setJavaScriptEnabled(true);
    webView.loadUrl(url);

    // setting the Dialog
    AlertDialog.Builder builder = new AlertDialog.Builder(context)
            .setView(view)
            .setOnCancelListener(onDialogListener);
    if (Build.VERSION.SDK_INT >= 17) {
        builder.setOnDismissListener(onDialogListener);
    }
    Dialog dialog = builder.create();
    dialog.show();

    return dialog;
}

This Dialog contains the webView for the verification process, hence the problem is there but I can't find any issues with that code any everything is link straight forward.


Solution

  • finally discovered the issue, it's a Bug in a Payfort Layout called R.layout.web_dialog which has a webview to be accessed by the method showVerificationDialog() inside payfort Start class.

    The problem is that the layout R.layout.web_dialog can't take the focus as the layout contains only the webView and there is nothing else that can give the focus to the layout so that it would be able to initiate the KB (have a look here), and as stated in the previous question link it is a well-known Android Bug.

    So, to solve that issue I had to copy & paste the whole Start class and access payfort from the new copied version directly after applying changes to showVerificationDialog() method. And regarding the changes that would help to overcome that issue, look at this answer (which is didn't work in my case), or you can just provide a new webView layout that contains a dummy & hidden EditText as stated in my answer at the same question link, Then inflate your new layout instead of the default one initiated by Payfort at showVerificationDialog() method:

    private Dialog showVerificationDialog(Context context, String url, PayfortStarter.VerificationDialogDismissListener onDialogListener) {
        isVerifying = true;
        isOTP = true;
        LayoutInflater layoutInflater = LayoutInflater.from(context);
        View view = layoutInflater.inflate(R.layout.webview_dialog, null);
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
        view.setMinimumHeight((int) (displayMetrics.heightPixels * WEB_VIEW_SCREEN_PERCENTS));
        view.setMinimumWidth((int) (displayMetrics.widthPixels * WEB_VIEW_SCREEN_PERCENTS));
    
        WebView webView = (WebView) view.findViewById(R.id.webView);
        webView.setWebViewClient(new WebViewClient());
        webView.getSettings().setJavaScriptEnabled(true);
        webView.loadUrl(url);
    
        AlertDialog.Builder builder = new AlertDialog.Builder(context)
                .setView(view)
                .setOnCancelListener(onDialogListener);
        if (Build.VERSION.SDK_INT >= 17) {
            builder.setOnDismissListener(onDialogListener);
        }
        Dialog dialog = builder.create();
        dialog.show();
    
        return dialog;
    }
    

    webview_dialog.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <EditText
            android:id="@+id/kb_holder"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:inputType="text"
            android:maxLines="1"
            android:visibility="gone" />
    
        <WebView
            android:id="@+id/webView"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
    </FrameLayout>