WebView

Add the Trustly UI to multi-platform apps with WebView

⚠️

WebView Notice

Trustly recommends using the Trustly iOS and Android SDKs to integrate the Trustly UI within mobile applications rather than WebView.

You can use a WebView to integrate the Lightbox in applications built with a multiplatform architecture and a web-based checkout flow.

For testing and learning, see the Trustly WebView Example application in GitHub.

If you need help with your integration, contact your Trustly representative or send your request to [email protected].

Note: The Swift and Kotlin languages are shown as examples. For iOS and Android, see the example app repository.

Prerequisites

Launch the Lightbox in a WebView

Use JavaScript to initialize and display the Trustly Lightbox in the web content loaded by your WebView.

🚧

Multi-platform Users

If your web page containing the Lightbox serves both web browser users and mobile app users, the default Lightbox web browser behavior does not function when the integrationContext="InAppBrowser" property is included. Trustly recommends adding the metadata properties dynamically. See the Trustly WebView Example app for an example implementation.

  1. To load the Trustly JavaScript library, add a script tag to the <head> section of the web page that will be loaded in the WebView. For example:

    <html>
      <head>
        ...
        <script src="https://sandbox.trustly.one/start/scripts/trustly.js?accessId=%REACT_APP_TRUSTLY_ACCESS_ID%"></script>
        <title>Trustly Starter App</title>
      </head>
        ...
    </html>
  2. Optional. In production environments, replace sandbox.trustly.one with trustly.one.

  3. Replace REACT_APP_TRUSTLY_ACCESS_ID with your Trustly Access ID.

  4. To initialize and launch the Lightbox, add a metadata object with the following properties to the establishData variable:

    • urlScheme - the URL you expect the user to return to after completing an OAuth or “App-to-App” user flow. For example,my_app://checkout/bank/oauth_success
    • integrationContext - one of InAppBrowser, InAppBrowserNotify, or ExternalBrowser. In order for OAuth to work in the manner described in this guide, the string InAppBrowser must be provided.

    For example:

    let establishData = {
      accessId: 'YOUR_ACCESS_ID',
      merchantId: 'YOUR_MERCHANT_ID',
      ...
      metadata: {
        urlScheme: "YOUR_APP://SOME_RESOURCE",
        integrationContext: "InAppBrowser",
      }
    };
    
    // define options if needed
    let trustlyOptions = {};
    
    window.Trustly.establish(establishData, trustlyOptions)

Launch the WebView in Your Mobile App

Configure your app to to enable interaction between the WebView and the Lightbox web page. For example:

import Foundation
import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate, WKUIDelegate {

  override func viewDidLoad() {
   	super.viewDidLoad()
        
		// replace this URL with the web page that is rendering the Trustly Lightbox (can be localhost for testing purposes)
    let url = URL(string: "https://myapp.com/pay-with-Trustly")!
    let reqApp = URLRequest(url: url);

    self.WebView = WKWebView(
      frame: self.view.bounds,
      configuration: self.getWKWebViewConfiguration()
    )

    // allow navigation events in the WebView
    WebView.navigationDelegate = self
    WebView.uiDelegate = self

    // load and render the URL request defined above
    WebView.load(reqApp)
    self.view.addSubview(self.WebView)
  }

	// this function returns all the necessary configurations for Lightbox behavior
	private func getWKWebViewConfiguration() -> WKWebViewConfiguration {
    let userController = WKUserContentController()
    let configuration = WKWebViewConfiguration()
    let wkPreferences = WKPreferences()
    wkPreferences.javaScriptCanOpenWindowsAutomatically = true
    configuration.preferences = wkPreferences
    configuration.userContentController = userController
    return configuration
	}
}
class WebViewClientActivity : AppCompatActivity() {
  
    lateinit var WebView: WebView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_WebViewclient)

        WebView = findViewById(R.id.WebView)

        WebView.settings.apply {
            javaScriptEnabled = true
            domStorageEnabled = true
            javaScriptCanOpenWindowsAutomatically = true
        }
      
        WebView.loadUrl("https://myapp.com/pay-with-Trustly")
    }
  
}

Listen for Navigation Events

When a user selects a bank requiring OAuth, the Trustly Lightbox uses window.open() to navigate to a Trustly-hosted URL. Since WebView cannot open new windows like a regular browser, your app must handle this navigation.

Within your WebView, add a function to check for window navigation events to the Trustly URL.

class ViewController: UIViewController, WKNavigationDelegate, WKUIDelegate {

	private var WebView: WKWebView!

	override func viewDidLoad() {
  	super.viewDidLoad()
		...
    WebView.load(reqApp)
    self.view.addSubview(self.WebView)
  }

	private func getWKWebViewConfiguration() -> WKWebViewConfiguration {
    ...
	}

	// this function will run on any navigation event that happens inside the WebView
	func WebView(_ WebView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
    // Check that URL is external and expected	
    if navigationAction.targetFrame == nil, let url = navigationAction.request.url {
      if url.description.lowercased().range(of: "/step/oauth/login") != nil {
        // this is where we will open the secure browser session
      }
    }
    return nil
	}
}
class WebViewClientActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        
        WebView.WebViewClient = object : WebViewClient() {
            override fun shouldOverrideUrlLoading(
                view: WebView,
                request: WebResourceRequest
            ): Boolean {
                val url = request.url.toString()
                if (url.contains("/step/oauth/login"))
                    launchUrl(this@WebViewClientActivity, url)
                return true
            }
        }
      
        WebView.loadUrl("https://myapp.com/pay-with-Trustly")
    }
  
}
📘

OAuth Login URLs

The URL verification example verifies the expected URL path variables for the Trustly Lightbox URL. To implement more specific verification rules, consider adding the following URLs:

Sandbox www.sandbox.paywithmybank.com/step/oauth/login/{transactionId} https://sandbox.paywithmybank.com/step/oauth/login/{transactionId} www.sandbox.trustly.one/step/oauth/login/{transactionId} https://sandbox.trustly.one/step/oauth/login/{transactionId}

Production www.paywithmybank.com/step/oauth/login/{transactionId} https://paywithmybank.com/step/oauth/login/{transactionId} www.trustly.one/step/oauth/login/{transactionId} https://trustly.one/step/oauth/login/{transactionId}

Additionally, an epoch timestamp is attached as a query parameter. For example:

www.trustly.one/step/oauth/login/{transactionId}?ts=1519211809934

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.

For iOS, the secure in-app browser class ASWebAuthenticationSession is preferred. If you're using iOS 12 or earlier, your app might need to support SFAuthenticationSession.

For Android, use Chrome Custom Tabs.

  1. Add a function to open a secure in-app browser. For example:

    import AuthenticationServices
    
    ...
    
    private var webSession: ASWebAuthenticationSession!
    
    ...
    
    private func buildASWebAuthenticationSession(url: URL, callbackURL: String){
      webSession = ASWebAuthenticationSession(url: url, callbackURLScheme: callbackURL)
      // add basic configurations
      webSession.prefersEphemeralWebBrowserSession = true
      // assign the ASWebAuthentication 
      webSession.presentationContextProvider = self
      webSession.start()
    }
    fun launchUrl(context: Context, url: String) {
        val customTabsIntent = CustomTabsIntent.Builder().build()
        customTabsIntent.intent.setPackage("com.android.chrome")
        customTabsIntent.launchUrl(context, Uri.parse(url))
    }

    The parameter callbackURL provides the destination to redirect the user to when the authentication session is complete. The value of this parameter must be identical to the urlScheme parameter that is passed into the establishData.metadata object when the Lightbox is launched.

  2. Import the WebKit framework and display a web page for authentication. For example:

    import WebKit
    
    ...
    
    class ViewController: UIViewController, WKNavigationDelegate, WKUIDelegate {
    
      private var WebView: WKWebView!
    
      override func viewDidLoad() {
        ...
        WebView.load(URLRequest(url: URL(string: "YOUR_WEB_PAGE_WITH_TRUSTLY_JS")))
      }
    
      func WebView(_ WebView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
        // Check that URL is external and expected	
        if navigationAction.targetFrame == nil, let url = navigationAction.request.url {
          if url.description.lowercased().range(of: "http") != nil {
            // OPEN THE EXTERNAL URL
            if #available(iOS 13, *) {
              self.buildASWebAuthenticationSession(url: url, callbackURL: "YOUR_APP://checkout/trustly/oauth_return")
            } else {
              // handle iOS <12 with SFAuthenticationSession
            }
          }
        }
        return nil
      }
    }

Return to the Lightbox

To complete the authentication process, you need to modify the buildASWebAuthenticationSession so that when the session is complete, the WebView calls the proceedToChooseAccount() method which is built in to the Trustly Lightbox. For example:

private func buildASWebAuthenticationSession(url: URL, callbackURL: String) {
	webSession = ASWebAuthenticationSession(url: url, callbackURLScheme: callbackURL, completionHandler: { (url, error) in
		// upon completion execute JavaScript function for Lightbox to proceed
	  self.WebView.evaluateJavaScript("window.Trustly.proceedToChooseAccount();", completionHandler: nil)
                                                                                                       })
 	webSession.prefersEphemeralWebBrowserSession = true
  webSession.presentationContextProvider = self
  webSession.start()
}
override fun onResume() {
  	super.onResume()

  	WebView.loadUrl("javascript:window.Trustly.proceedToChooseAccount();")
}