React-Native Mobile Widget

Generate widget config

Read more about widget config

  1. Need to get otp
  2. Prepare link to css file
  3. Create config object with specific configuration
  4. Get base64 string from config object
import { Buffer } from 'buffer';

function getWidgetConfig() {
 const config = {
      token: <otp>,
      cardId,
      styleUrl: <css_file_url>,
      cssClass: 'virtual-card', // example
      cardholderName: {
        display: false,
      },
    };

    return Buffer.from(JSON.stringify(config)).toString('base64');
}

Generate HTML for WebView

This is an example of a function to get a string with html. For API_HOST check this link. traceId should be the same as for OTP generation request.

function getHtml() {
  return `
    <!DOCTYPE html>
    <html>
      <script>
        window.addEventListener('message', (event) => {
          window.ReactNativeWebView.postMessage(JSON.stringify(event.data));
        });
      </script>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width">
        <title>Card</title>
        <style>
          body {
            margin: 0;
            padding: 0;
            width: 100vw;
            height: 100vh;
            background-color: transparent;
          }
        </style>
      </head>
      <body>
        <iframe
          src="${API_HOST}/card-details/widget?traceId=${traceId}&params=${widgetConfig}"
          title="Card Details"
          width="100%"
          height="100%"
          frameBorder="0"
          id="card-details-widget-frame"
          allow="clipboard-read; clipboard-write" 
        />
      </body>
    </html>
    `;
}

Take a look on this code. It will allow you to receive messages from iframe with some events

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

Configure WebView

Example:

<WebView
  style={style}
  source={{
    baseUrl: 'https://localhost',
    html,
  }}
  originWhitelist={['*']}
  javaScriptEnabled
  scrollEnabled={false}
  onMessage={onMessage}
/>

Keep in mind, you:

  • need to enable javaScriptEnabled
  • need to specify baseUrl: 'https://localhost'
  • need to add originWhitelist={['*']}
  • may add onMessage={onMessage} callback to receive events from iframe

iFrame Events

Example of onMessage callback:

export const checkProp = <T extends string | number>(
  input: unknown,
  prop: T,
): input is { [t in T]: unknown } => {
  return typeof input === 'object' && input !== null && prop in input;
};

const onMessage = useCallback((event: WebViewMessageEvent) => {
  const parsedData = JSON.parse(event.nativeEvent.data);

  if (
    checkProp(parsedData, 'eventType') &&
    parsedData.eventType === 'CARD_DATA_CLEARED'
  ) {
    // Example: navigation.goBack();
  }
}, []);