> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://amer.developers.trustly.com/llms.txt.
> For full documentation content, see https://amer.developers.trustly.com/llms-full.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://amer.developers.trustly.com/_mcp/server.

# React Native

The Trustly Lightbox JavaScript library allows you to quickly build a bank authorization workflow in your React Native app. Integrate the Trustly Lightbox to retrieve bank authorization data that can be used with other Trustly APIs.

To use an example project for testing and learning, see the [React Native Example](https://github.com/TrustlyInc/trustly-react-native-example) in GitHub.

If you need help with your integration, contact your Trustly representative or send your request to <a href="mailto:us.integrations@trustly.com">[us.integrations@trustly.com](mailto:us.integrations@trustly.com)</a>.

## OAuth configuration

Banks that use OAuth login pages often have strict security policies which prohibit access to their login urls from WebViews. Trustly client libraries include functionality that simplifies OAuth handling. For more information about using OAuth login authorization flows with the Trustly Lightbox, see [About OAuth Authentication](../../Security/about-oauth-authentication).

## Add the React Native components

1. Run the following command to add [react-native-webview](https://github.com/react-native-webview/react-native-webview) to your application or alternative WebView package:

   ```bash
   npm install react-native-webview --save
   ```

2. Run the following command to add the [react-native-inappbrowser](https://github.com/proyecto26/react-native-inappbrowser) component to your application or alternative in-app browser package:

   ```bash
   npm install react-native-inappbrowser-reborn --save
   ```

3. Configure a deep link for your application. See the [React Native linking documentation](https://reactnative.dev/docs/linking). Typically, the format for a deep link or URL scheme in your application is: `my_app://`.

## Launch the Lightbox

The Lightbox is launched by using the `establishData` variable. The variable must include a `metadata` object with the following properties:

* `urlScheme` - the URL you want the user to return to after completing an OAuth or “App-to-App” user flow. For example, `my_app://` or `my_app://path/success`.
* `integrationContext` - one of *InAppBrowser* or *InAppBrowserNotify*. *InAppBrowserNotify*  posts a message to the WebView element and is recommended by Trustly. *InAppBrowser* triggers a `window.open` event using a target url that is opened in a secure in-app browser.

If your web page containing the Lightbox serves both web browser users <i>and</i> mobile app users, the default Lightbox web browser behavior does not function when the `integrationContext` property is included. Trustly recommends adding the metadata properties dynamically. See the [Trustly WebView Example app](https://github.com/TrustlyInc/OAuth-webview-iOS-sample) for an example implementation

In the following example,  a number of the required `establishData` variable properties are omitted for simplicity. For a complete list of the required properties, see [Establish Data](/integrate/core-concepts/the-establish-data-object).

```jsx
const establishData = {
  accessId: 'YOUR_ACCESS_ID',
  merchantId: 'YOUR_MERCHANT_ID',
  metadata: {
    urlScheme: "YOUR_APP://",
    integrationContext: "InAppBrowserNotify",
  }
};
```

## Render the Lightbox in a WebView

You can open the Lightbox in a separately hosted web page or raw html. The following example uses the [react-native-webview](https://github.com/react-native-webview/react-native-webview) package to open the `myapp.com/checkout` URL where the Trustly Lightbox is rendered:

```jsx
import { WebView } from 'react-native-webview';

class TrustlyWebview extends Component () {
  render(){
    return (
      <WebView
        source={{ uri: 'https://myapp.com/checkout' }}
        javaScriptEnabled=&#123;true&#125;
        startInLoadingState
      />);
  }  
}
```

> **Note:** For this package, the property `javaScriptEnabled={true}` must be passed to allow the Lightbox to communicate with your app’s WebView.

## Set up Window Message Listener

Errors can occur when a user selects an OAuth-enabled bank and then selects their login URL within the WebView.  You can use the `window.ReactNativeWebview.postMessage` method to simplify error handling in React Native apps.

1. Add the `window.ReactNativeWebview.postMessage` method to inject a listener in the WebView. For example:

   ```javascript
   import { WebView } from 'react-native-webview';

   const postMessageForOauth = `
     window.addEventListener(
     "message",
     function (event) {
       var data = (event || {}).data || {}
       window.ReactNativeWebView.postMessage(event.data);
     },
     false
     );
   `;

   class TrustlyWebview extends Component () {
     render(){
       return (
         <WebView
           source={{ uri: 'https://myapp.com/checkout' }}
           javaScriptEnabled=&#123;true&#125;
           injectedJavaScript=&#123;postMessageForOauth&#125;
           startInLoadingState
         />);
     }  
   }
   ```

2. Configure your app to listen for these messages. The following is an example of an OAuth login window message:

   ```json
   {
       "nativeEvent": {
           "canGoBack": true,
           "canGoForward": false,
           "data": "PayWithMyBank.ExternalBrowserIntegration|open|https://sandbox.paywithmybank.com/step/oauth/login/1024436793?ts=1691778330867&lbid=1691778325518|oauth:_FIOAuthWindow",
           "loading": false,
           "target": 3,
           "title": "Trustly",
           "url": "about:blank"
       }
   }
   ```

3. Create a message handler function to filter and verify the messages your application receives and then pass them to the `onMessage` property of the `WebView` component. For example:

   ```javascript
   import { WebView } from 'react-native-webview';

   const postMessageForOauth = `
     window.addEventListener(
     "message",
     function (event) {
       var data = (event || {}).data || {}
       window.ReactNativeWebView.postMessage(event.data);
     },
     false
     );
   `;

     messageHandler = (message: any) => {
       const data = message.nativeEvent.data
       var [command, ...params] = data.split("|")
       
       // check for correct message content
       if(command.includes("ExternalBrowserIntegration")) {
         var messageUrl = params[1]
         // user selected an OAuth bank
         console.log("Trustly URL", messageUrl)
       }
     }

   class TrustlyWebview extends Component () {
     render(){
       return (
         <WebView
           source={{ uri: 'https://myapp.com/checkout' }}
           javaScriptEnabled=&#123;true&#125;
           injectedJavaScript=&#123;postMessageForOauth&#125;
           startInLoadingState
           onMessage={this.messageHandler}
         />);
     }  
   }
   ```

If you set the `integrationContext` property to `InAppBrowser`, use the `onNavigationStateChange` property instead of `onMessage` and use `navigationChangeHandler` instead of the `messageHandler` function.

## Open the external link

Many banks consider WebViews an insecure method for accepting and authenticating user credentials. Following the completion of this step, when a customer opens the Trustly Lightbox and selects an OAuth-required Bank, a secure in-app-browser layer opens over the Lightbox. This layer contains information about the selected bank and a button that a customer can select to authenticate with their bank’s mobile app or through the bank’s OAuth login web page. After a customer is successfully authenticated, they are directed back to your app.

There are several packages that provide abstractions for the iOS and Android APIs. The following example uses the [react-native-inappbrowser-reborn](https://github.com/proyecto26/react-native-inappbrowser) package:

```jsx
import { InAppBrowser } from 'react-native-inappbrowser-reborn';

class TrustlyWebview extends Component () {
  
  openOAuthLink = async link => {
    try {
      await InAppBrowser.openAuth(link, '', { modalPresentationStyle: "fullscreen"})
        .then(response => {
        // handle user action in auth session
        
      });
    } catch (err) {
      console.log(err);
    }
  }
  
  messageHandler = (message: any) => {
    const data = message.nativeEvent.data
    var [command, ...params] = data.split("|")
    
    // check for correct message content
    if(command.includes("ExternalBrowserIntegration")) {
      var messageUrl = params[1]
      // user selected an OAuth bank
      console.log("Trustly URL", messageUrl)
      this.openOAuthLink(messageUrl)
    }
  }
  
  // render function ommitted for brevity

}
```

This example shows a simplified [InAppBrowser](https://github.com/proyecto26/react-native-inappbrowser) function. For more information, see the documentation and the API specification for your preferred in-app browser package

## Return to the Lightbox

To complete the authentication process, the `InAppBrowser.openAuth()` function is used to handle the Promise  and notify the Trustly Lightbox that the customer has returned from their OAuth session. Within this callback, you add a function to inject the JavaScript that calls the `Trustly.proceedToChooseAccount()` function in the WebView. For example:

```jsx
import { InAppBrowser } from 'react-native-inappbrowser-reborn';

class TrustlyWebview extends Component () {
  
  const postMessageForOauth = `
    window.addEventListener(
    "message",
    function (event) {
      var data = (event || {}).data || {}
      window.ReactNativeWebView.postMessage(event.data);
    },
    false
    );
  `;

	openOAuthLink = async link => {
	  try {
			await InAppBrowser.openAuth(link, '', { modalPresentationStyle: "fullscreen"})
				.then(response => {
					if (response.type === 'success') {
						// notify Trustly object of user return
			      this.webview.injectJavaScript('window.Trustly.proceedToChooseAccount();');
			    } else {
						console.log(response);
				});
	  } catch (err) {
	    console.log(err);
	  }
	}
	
	//messageHandler ommitted for brevity

	render(){
		return (
	    <WebView 
	      source={{ uri: 'https://myapp.com/checkout' }}
	      javaScriptEnabled=&#123;true&#125;
        injectedJavaScript=&#123;postMessageForOauth&#125;
	      startInLoadingState
        onMessage={this.messageHandler}
	    />);
	}  
}
```

<br />