WebView
Add the Trustly UI to multi-platform apps with WebView
WebView NoticeTrustly 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
- The mobile application rendering the WebView must have at least one universal or deep link configured to return customers from the OAuth login to the mobile application. To learn more about universal and deep links, see Defining a custom URL scheme for your app (iOS) and Create Deep Links to App Content (Android).
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 UsersIf 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.
-
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>
-
Optional. In production environments, replace
sandbox.trustly.one
withtrustly.one
. -
Replace
REACT_APP_TRUSTLY_ACCESS_ID
with your Trustly Access ID. -
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 ofInAppBrowser
,InAppBrowserNotify
, orExternalBrowser
. 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 URLsThe 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.
-
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 theurlScheme
parameter that is passed into theestablishData.metadata
object when the Lightbox is launched. -
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();")
}
Updated 1 day ago