React Native

This guide demonstrates how to integrate the PCI widget into your React Native application. 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
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

The following function creates the HTML string for your WebView. For API_HOST values, refer to the environments documentation. Important: The traceId must match the one used in your 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>
    `;
}

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.ReactNativeWebView.postMessage(JSON.stringify(event.data));
});

Configure WebView

Set up a basic WebView component with the required properties:

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

Important configuration requirements:

  • You must enable JavaScript with javaScriptEnabled
  • You must specify baseUrl as 'https://localhost'
  • You must add originWhitelist={['*']} to allow the iframe to load
  • Optionally add onMessage={onMessage} callback to handle events from the iframe

iframe Events

Create a callback function to process messages from the iframe:

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();
  }
}, []);