This guide demonstrates how to integrate the PCI widget into your Android application using Java. Follow these steps for successful implementation.

Generate Widget Configuration

Read more about widget config

To generate your widget configuration:

  1. Obtain an OTP (one-time password)
  2. Prepare a URL link to your CSS file
  3. Create a configuration object with your specific settings
  4. Convert this configuration object to a base64-encoded string
private void generateWidgetConfig() {
    Map<String, Object> config = new HashMap<>();
    config.put("token", mOtp);
    config.put("cardId", mCardId);
    config.put("styleUrl", mStyleUrl);
    config.put("cssClass", mCssClass);

    Map<String, Object> cardholderName = new HashMap<>();
    cardholderName.put("display", false);
    config.put("cardholderName", cardholderName);

    try {
        byte[] jsonData = new ObjectMapper().writeValueAsBytes(config);
        String widgetConfig = Base64.getEncoder().encodeToString(jsonData);
    } catch (IOException e) {
        Log.e("Error", e.getMessage());
    }
}

Generate HTML for WebView

The following function creates the HTML string for your WebView. For apiHostPci values, refer to the environments documentation. Important: The traceId must match the one used in your OTP generation request.

private String getHtml() {
    String iframeUrl = apiHostPci + "/card-details/widget?traceId=" + traceId + "&params=" + widgetConfig;

    return "<!DOCTYPE html>\n" +
            "<html>\n" +
            "  <script>\n" +
            "    window.addEventListener('message', function(event) {\n" +
            "      window.Android.handleMessage(JSON.stringify(event.data));\n" +
            "    });\n" +
            "  </script>\n" +
            "  <head>\n" +
            "    <meta charset=\"utf-8\">\n" +
            "    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n" + // Add initial-scale to viewport meta tag
            "    <title>Card</title>\n" +
            "    <style>\n" +
            "      body, html {\n" +
            "        margin: 0;\n" +
            "        padding: 0;\n" +
            "        width: 100vw;\n" +
            "        height: 100vh;\n" +
            "        background-color: transparent;\n" +
            "      }\n" +
            "      iframe {\n" +
            "        width: 100%;\n" +
            "        height: 100%;\n" +
            "        background-color: transparent;\n" +
            "      }\n" +
            "    </style>\n" +
            "  </head>\n" +
            "  <body>\n" +
            "    <iframe\n" +
            "      src=\"" + iframeUrl + "\"\n" +
            "      title=\"Card Details\"\n" +
            "      width=\"100%\"\n" +
            "      height=\"100%\"\n" +
            "      frameBorder=\"0\"\n" +
            "      id=\"card-details-widget-frame\"\n" +
            "      allow=\"clipboard-read; clipboard-write\"\n" +
            "    />\n" +
            "  </body>\n" +
            "</html>";
}

Notice the JavaScript event listener in the HTML. This enables your app to receive messages from the iframe containing event data:

window.addEventListener('message', (event) => {
  window.Android.handleMessage(JSON.stringify(event.data));
});

Configure Your WebView

Set up a basic WebView with transparency and JavaScript support:

WebView wvContent = this.findViewById(R.id.pci_widget_web_view);
wvContent.setBackgroundColor(Color.TRANSPARENT);
wvContent.getSettings().setJavaScriptEnabled(true);

URL baseUrl = new URL("https://localhost");

wvContent.loadDataWithBaseURL(
    baseUrl.toString(),
    getHtml(),
    "text/html",
    "UTF-8",
    null
);

Important configuration requirements:

  • You must enable JavaScript with setJavaScriptEnabled(true)
  • You must specify baseUrl as 'https://localhost'

iframe Events

Configure your WebView to receive and process events from the iframe:

// Define JavaScript interface object
JavaScriptInterface jsInterface = new JavaScriptInterface();

// Add JavaScript interface object to WebView
webView.addJavascriptInterface(jsInterface, "Android");

// Define Java object to serve as JavaScript interface
public class JavaScriptInterface {
    @android.webkit.JavascriptInterface
    public void handleMessage(String message) {
        // Handle message received from JavaScript
        System.out.println("Message received from JavaScript: " + message);
    }
}