Sorry, you need to enable JavaScript to visit this website.
Skip to main content

Integrating FastLink 4 for Flutter

Integration Steps

Follow the steps to integrate FastLink into a Flutter application.

Step 1: Add WebView Dependancy in the pubspec File

Add webview_flutter dependancy in pubspec.yaml file. For more information, refer to the webview_flutter installation guide.

Step 2: Add the WebView Widget in the Parent Widget

Add the WebView widget in the parent widget of your application. As WebView currently does not support the POST call, FastLink will be loaded using the HTML form.

class FastLinkView extends StatelessWidget {
  late final WebViewController webViewController;
  configureWebView() async {

    webViewController = WebViewController();

    webViewController
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setBackgroundColor(Colors.white)
      ..setNavigationDelegate(
        NavigationDelegate(
          onProgress: (int progress) {
            print(progress);
          },

        ),
      )
      ..addJavaScriptChannel(
        'YWebViewHandler',
        onMessageReceived: (JavaScriptMessage message) {
          _handleEventsFromJS(message.message);
        },
      )
      
      ..loadRequest(Uri.parse(Uri.dataFromString(await _loadFastLink(),
          mimeType: 'text/html', encoding: Encoding.getByName('utf-8'))
          .toString()));
  }

  @override
  Widget build(BuildContext context) {
   configureWebView();
    return Scaffold(
      appBar: AppBar(
        title: Text('FastLink'),
      ),
      body: WebViewWidget(
        controller: webViewController,
      ),
    );
  }
}

Step 3: Load FastLink in the WebView

To load the FastLink application in the WebView, create the HTML form that has to be posted to the FastLink server.
Following is the implementation of the _loadFastLink method that is called in the ..loadRequest method of the WebView.

_loadFastLink() async {
    return '''<html>
            <body>
                  <form name="fastlink-form" action="$fastLinkURL" method="POST">
                        <input name="accessToken" value="Bearer $accessToken" hidden="true" >
                        <input name="extraParams" value="$extraParams" hidden="true" />
                  </form>
                  <script type="text/javascript">
                        window.onload = function () {
                           document.forms["fastlink-form"].submit();
                        }
                  </script>
            </body>
            </html>''';
  }
}

Passing Additional Params to FastLink

While loading FastLink in the WebView, additional params like deep-linking flow attributes, callback details, etc., can be passed as query parameters along with the mandatory configName parameter. Following is a sample code snippet for the add deep-link flow.

...
<input name="accessToken" value="Bearer " hidden="true" />
<input name="extraParams" value="configName=<config-name-from-config-tool>&flow=add&providerId=16441" hidden="true" />
...

For more details, refer to the Additional Params section in FastLink 4 Advanced Integration.

Handling Open Banking Sites

The intentUrl attribute is used to get the control back to the native app from an external application. For example, native browser.

Passing intentUrl as part of extraParams

let postData =
    'accessToken=Bearer {{ACCESS_TOKEN}}&amp;extraParams=' +
    encodeURIComponent('configName=<config-name-from-config-tool>&intentUrl=<protocol://domainname>')

When the user selects an Open Banking site, FastLink will send a post message with the site's OAuth URL, which needs to be opened in a native browser.

Post Message - OPEN_EXTERNAL_URL

{
    "type": "OPEN_EXTERNAL_URL",
    "data": {
        "url": "<OAUTH URL>"
    }
}

Once the user logs in, authorizes consent, and completes the flow, use intentUrl as callback URL.

Native app should listen to this intentUrl by which the control comes back to the native app.

Handling Callback

Android

Entries in AndroidManifest.xml.

<meta-data android:name="flutter_deeplinking_enabled" android:value="true" />
    <activity
        android:name="com.yodlee.fastlink.InAppBrowserActivity"
        android:configChanges="keyboardHidden|orientation|screenSize"
        android:label="@string/app_name"
        android:windowSoftInputMode="adjustResize|adjustPan">
            <intent-filter>
                <data
                        android:host="<domainname>"
                        android:scheme="<protocol>" />

                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

iOS

Entries in info.plist.

<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleURLTypes</key>
	<array>
		<dict>
			<key>CFBundleURLName</key>
			<string><protocol://domainname></string>
			<key>CFBundleURLSchemes</key>
			<array>
				<string><protocol></string>
			</array>
		</dict>
	</array>
</dict>
</plist>

Handling Events from FastLink

To communicate the events from FastLink, your application has to listen for the javascriptChannels prop of the WebView. Refer to the Step 2 code snippet where the javascriptChannels prop is added to the WebView. Note that the name should be YWebViewHandler as FastLink will check for the YWebViewHandler name to send the events.

Post Message Events

The FastLink application shares the account addition status to your application using the POST_MESSAGE events.

{
    "type": "POST_MESSAGE",
    "data": {
        //Post Message data
    }
}

External URL

When the user clicks or taps on any external URL within the FastLink application, a native event will be triggered. You can open the URL in the SFSafariViewController or in the default browser.

{
    "type": "OPEN_EXTERNAL_URL",
    "data": {
        "url": "<External URL>"
    }
}

Sample code to handle the events that can be used inside the onMessageReceived method.

_handleEventsFromJS(message) {
    Map<String, dynamic> eventData = jsonDecode(message);

    EventsInfoMap.add(eventData);
    if (eventData["type"] == "OPEN_EXTERNAL_URL") {
        String url = eventData["data"]["url"];
        _launchURL(url);
    }

    if (eventData["type"] == "POST_MESSAGE") {
        String action = eventData["data"]["action"];

        if (action == "exit") {
            //User has clicked the close button
            //You can close the WebView and navigate to the other screens
        }
    }
}

To open the external URL, use the url_launcher plugin.

_launchURL(url) async {
    if (await canLaunch(url)) {
        await launch(
            url,
            forceSafariVC: false,
            forceWebView: false,
        );
    } else {
        print('Could not launch ');
    }
}