Widget for web

Fast and responsive widget for web applications, in vanilla JavaScript, Angular, React, or Vue 🖥.

👍

Widget Overview

If you'd like to have a general overview of how the widget works, make sure to check out our Connect Widget Overview article.

1. Embed the Connect widget snippet

To embed the widget code in your application, add one of the following code elements to the page where the Connect Widget should appear.

If you are working in Angular, React, or Vue, just select the relevant code tab for you.

<!-- To embed the Connect widget statically, just use the following code. -->
<head>
  ...
  <script src="https://cdn.belvo.io/belvo-widget-1-stable.js" async></script>
  ...
<head>
<body>
  ...
  <div id="belvo"></div> <!-- anywhere inside the body -->
  ...
</body>
  
 
<!-- To embed the Connect widget dynamically, just use the following code in your <body>. -->
  
<body>
...
  <script type="text/javascript">
     const widget = document.createElement('script');
     widget.setAttribute('src','https://cdn.belvo.io/belvo-widget-1-stable.js');
     document.body.appendChild(widget);
  </script>
...
</body>
import { Component, OnInit } from '@angular/core';

  // Implement the OnInit interface to be able to load the script
  @Component({
    selector: 'app-root',
   template: `
     <div class="content" role="main">
        <div id="belvo"></div>
     </div>
   `,
    styleUrls: ['./app.component.css']
  })
  export class AppComponent implements OnInit {
    title = 'widget-angular';
    // implemented method
    ngOnInit(): void {
      loadScript('https://cdn.belvo.io/belvo-widget-1-stable.js');
    }
  }

// Please add the code from Step 3 here.
import './App.css';
import { useEffect } from "react";
function App() {
  useScript('https://cdn.belvo.io/belvo-widget-1-stable.js');
  return (
      <div id="belvo" />
  );
}
export default App;
// Hook
function useScript(src) {
  useEffect(
      () => {
        // Create script
        const node = document.createElement('script');
        node.src = src;
        node.type = 'text/javascript';
        node.async = true;
        node.onload = createWidget
        // Add script to document body
        document.body.appendChild(node);
      },
      [src] // Only re-run effect if script src changes
  )
}
<template>
  <div id="app">
    <div id="belvo" />
  </div>
</template>
<script>
  export default {
      name: 'App',
      mounted () {
        // Executing the function to load the widget after mount, since we need
        // the template to be loaded
        this.loadScript('https://cdn.belvo.io/belvo-widget-1-stable.js');
      },
      methods: {
        // Please add the code from Step 3 here.
      }
  }
</script>

🚧

Make sure you include the reference to https://cdn.belvo.io/belvo-widget-1-stable.js. Otherwise, the widget will not load in your app!

✳️ Done! Next, you need to make a request from your server-side to Belvo to generate an access_token.

2. Generate an access_token

In order for the widget to appear to your end users, you need to generate an access_token in your server-side and send it to Belvo. Once we receive the request, you'll receive an object with two elements: access and refresh. Pass the value of the access element to your client-side, and you'll be able to start the widget.

The returned values are valid for 60 minutes and can be sent to your frontend to start the Connect Widget. We invalidate the token as soon as a user successfully connects their account.

❗️

Server-side request

The access_token request must be done from your server-side in order to protect your API keys secretId and secretPassword). So if you're using a framework like Vue or React, please make sure that you generate the request from your server-side.

To generate an access_token, simply make a call from your server-side to Belvo (see the examples below).

curl -X POST \
  https://sandbox.belvo.co/api/token/ \
  -H 'Content-Type: application/json' \
  -H 'Host: sandbox.belvo.com' \
  -d '{
    "id": "SECRET_ID",
    "password": "SECRET_PASSWORD",
    "scopes": "read_institutions,write_links,read_links"
  }'
// check our node package on github
// https://github.com/belvo-finance/belvo-js
var belvo = require('belvo').default;

var client = new belvo(
  'my-secret-key-id',
  'my-secret-key-password',
  'https://sandbox.belvo.com'
);

client.connect()
  .then(function () {
        client.widgetToken.create()
      .then((response) => {
      res.json(response);
        })
      .catch((error) => {
      res.status(500).send({
        message: error.message
      });
    });
});
# check our python-client library on github
# https://github.com/belvo-finance/belvo-python
from belvo.client import Client

client = Client("my-secret-key-id", "my-secret-key-password", "https://sandbox.belvo.com")

token = client.WidgetToken.create()
# check our Ruby gem on github
# https://github.com/belvo-finance/belvo-ruby
require 'belvo'

client = Belvo::Client.new(
  "my-secret-key-id", 
  "my-secret-key-password", 
  "https://sandbox.belvo.com"
)

client.widget_token.create()

📘

Scopes

If you are not using one of our official libraries, remember to pass the scopes parameter when generating your access token otherwise the widget will not start correctly. Those scopes are necessary to give the right permissions to the token for the widget to work.

"scopes": "read_institutions,write_links,read_links"

If you are using Belvo official libraries, the scopes are already managed automatically.

After you make your call, Belvo returns an object from which you'll need the value from the access key. You'll send this value to your client-side so that the widget can actually start.

{
  "access": "{access_token_for_widget}", // You'll need this value to send to your client-side
  "refresh": "{refresh_token}"
}

✳️ Done! Now that you can generate access_token, you can start the widget!

3. Start the Connect widget

Using this access_token you can now start the Connect widget:

// Code to be included within your <script type="text/javascript"> tag

function successCallbackFunction(link, institution) {
    // Do something with the link and institution,
    // such as associate it with your registered user in your database.
}

function onExitCallbackFunction(data) {
    // Do something with the exit data.
}

function onEventCallbackFunction(data) {
    // Do something with the event data.
}

// Function to call your server-side to generate the access_token and retrieve the your access token
function getAccessToken () { 
  // Make sure to change /get-access-token to point to your server-side.
  return fetch('/get-access-token', { method: 'GET' }) 
    .then(response => response.json())
    .then((data) => data.access)
    .catch(error => console.error('Error:', error))
}

function openBelvoWidget(accessToken) {
    belvoSDK.createWidget(accessToken, {

        // Add your startup configuration here.

        callback: (link, institution) => successCallbackFunction(link, institution),

    }).build();
}

getAccessToken().then(openBelvoWidget) // Once the access token is retrieved, the widget is started.
// Insert the following code after AppComponent() class from Step 1.
async function createWidget() {
    // Function to call your server-side to generate the access_token and retrieve the your access token
    function getAccessToken() {
        // Make sure to change /get-access-token to point to your server-side.
        return fetch('http://localhost:3001/auth/token', {
                method: 'GET'
            })
            .then(response => response.json())
            .then((data) => data)
            .catch(error => console.error('Error:', error))
    }
    const successCallbackFunction = (link, institution) => {
        // Do something with the link and institution,
        // such as associate it with your registered user in your database.
    }
    const onExitCallbackFunction = (data) => {
        // Do something with the exit data.
    }
    const onEventCallbackFunction = (data) => {
        // Do something with the exit data.
    }

    const config = {

        // Add your startup configuration here.

        callback: (link, institution) => successCallbackFunction(),
        onExit: (data) => onExitCallbackFunction(),
        onEvent: (data) => onEventCallbackFunction(),
        show_intro: true
    }
    const { access } = await getAccessToken();
    // @ts-ignore
    window.belvoSDK.createWidget(access, config).build();
}

function loadScript(src: string) {
    let node = document.createElement('script');
    node.src = src;
    node.type = 'text/javascript';
    node.async = true;
    // Assign the callback which will create the Widget
    node.onload = createWidget;
    document.getElementsByTagName('head')[0].appendChild(node);
}
// Insert the following code after useScript() function from Step 1.
async function createWidget() {
  // Function to call your server-side to generate the access_token and retrieve the your access token
    function getAccessToken() { 
    // Make sure to change /get-access-token to point to your server-side.
        return fetch('http://localhost:3001/auth/token', {
                method: 'GET'
            }) 
            .then(response => response.json())
            .then((data) => data)
            .catch(error => console.error('Error:', error))
    }
    const callback = () => {}
    const successCallbackFunction = (link, institution) => {
        // Do something with the link and institution,
        // such as associate it with your registered user in your database.
    }
    const onExitCallbackFunction = (data) => {
        // Do something with the exit data.
    }
    const onEventCallbackFunction = (data) => {
        // Do something with the exit data.
    }
    const config = {

        // Add your startup configuration here.

        callback: (link, institution) => successCallbackFunction(),
        onExit: (data) => onExitCallbackFunction(),
        onEvent: (data) => onEventCallbackFunction(),
        show_intro: true
    }
    const { access } = await getAccessToken();
    window.belvoSDK.createWidget(access, config).build()
}
// Insert the following code after mounted() function from Step 1.
async createWidget() {
        // Function to call your server-side to generate the access_token and retrieve the your access token
        function getAccessToken() {
            // Make sure to change /get-access-token to point to your server-side.
            return fetch('/get-access-token', {
                    method: 'GET'
                })
                .then(response => response.json())
                .then((data) => data)
                .catch(error => console.error('Error:', error))
        }
        const successCallbackFunction = (link, institution) => {
            // Do something with the link and institution,
            // such as associate it with your registered user in your database.
        }
        const onExitCallbackFunction = (data) => {
            // Do something with the exit data.
        }
        const onEventCallbackFunction = (data) => {
            // Do something with the exit data.
        }

        const config = {

            // Add your startup configuration here.

            callback: (link, institution) => successCallbackFunction(),
            onExit: (data) => onExitCallbackFunction(),
            onEvent: (data) => onEventCallbackFunction(),
            show_intro: true
        }
        const { access } = await getAccessToken();
        window.belvoSDK.createWidget(access, config).build()
    },
    loadScript(src) {
        const node = document.createElement('script');
        node.src = src;
        node.type = 'text/javascript';
        node.async = true;
        // Assign the callback which will create the Widget
        node.onload = this.createWidget;
        // Add script to document body
        document.body.appendChild(node);
    }
}

👍

Customize the branding and startup configuration

You can add custom branding as well as configure what information (countries, institutions) the widget should display when it is started.

Please see our dedicated guides for more information:

4. Implement widget callbacks

You need to implement callback functions to handle the success, error, and exit data that Belvo sends.

Belvo's API can send you:

  • Success data, which contains the link_id and the institution that a user connected to
  • Event data, which contains information about different events, such as errors, that occur during the use of the widget.
  • Exit data, which contains information about when a user exits the widget, if they encountered any errors, and what institution they had selected.

👍

Even and exit real-world use cases

We strongly recommend that you implement event logging functions to handle Belvo's event and error data for diagnostic purposes.

We regularly see our clients use these functions to create logs. What they do is capture the entirety of the response and then store it for troubleshooting purposes.

Success callback

Once a user successfully connects their account, Belvo sends a data object with the institution and the link ID (which you'll need in your further requests for data).

{
    "link": "link_id",
    "institution": "the_institution_that_the_user_connected_to"
}

Parameter

Description

link
String

The link_id created in the widget

institution
String

The name of the institution for this created link

To handle this data, you need to create a callback function.

🚧

Mandatory

You must create a callback function to handle the object that Belvo sends back. Otherwise, the widget will not start and you will receive an error message.

Here is an example of success callback usage:

<script type="text/javascript">
  function successCallbackFunction(link, institution) {
      // Do something with the link and institution, 
      // such as associate it with your registered user in your database. 
    }

function openBelvoWidget(accessToken) {
  ...
    belvoSDK.createWidget(accessToken, {
    ...
      callback: (link, institution) => successCallbackFunction(link, institution),
    ...

    }).build();
}   
</script>

Event callback

When users encounter certain events in the widget, we'll send you a some data to explain what's going on. The data object will contain an eventName and meta_data object.

data = {
  "eventName": "ERROR",
  "meta_data": {
    "error_code": "login_error",
    "error_message": "Invalid credentials provided to login to the institution",
    "institution_name": "bancoazteca_mx_retail",
    "timestamp": "2020-04-27T19:09:23.918Z"
  }
}

event_name
A string representing the name of event that has just occurred in the widget.

Event type

Description

ERROR

When a recoverable error occurred in the widget, see the error_code and error_message in the meta_data

meta_data
An object containing more information about the event that has just occurred in the widget.
The meta_data object can have the following properties:

Parameter

Description

error_code

The error code that the user encountered. See the Exit callback for the list of possible error codes.

error_message

The error message that the user encountered.
See the Exit callback for the list of possible error messages.

institution_name

The selected institution

timestamp

A timestamp of when the event occurred

<script type="text/javascript">
  function onEventCallbackFunction (data) {
    
    // Do something with the event data
  }
  
  function openBelvoWidget() {
    ...
    belvoSDK.createWidget(access_token, {
      ...
      onEvent: (data) => this.onEventCallbackFunction(data),
      ...
    }).build();
  }    
</script>

Exit callback

When users decide to close the widget, we'll send you some data to explain what's going on. The data object will contain an last_encountered_error object and meta_data object.

👍

Real-world use case

Monitoring for the Exit callback is useful as based on the event, you can redirect your user to a particular screen after they close the widget.

data = {
  "last_encountered_error": {
    "message": "Link already exists.",
    "code": "invalid"
  },
  "meta_data": {
    "institution_name": "erebor_mx_retail",
    "step": "abandon-survey"
  }
}

last_encountered_error

The last_encountered_error object is only sent if an error occurred. See the table below for a list of possible error codes and their messages.

Error code

Error message

duplicated

Link already exists.

institution_down

The financial institution is down, try again later

login_error

The possible error messages for a login_error are:

  • Invalid credentials provided to login to the institution
  • The user account is locked, user needs to contact the institution to unlock it
  • The user account access was forbidden by the institution
  • Impossible to login, something unexpected happened while logging into the institution. Try again later.

too_many_sessions

Impossible to login, a session is already opened with the institution for these credentials

unexpected_error

Belvo is unable to process the request due to an internal system issue or to an unsupported response from an institution

meta_data

The meta_data object is sent whenever a user exits the widget. See the table below for a list of possible values.

Parameter

Description

step

Sent when the user exits the widget at the initial screen. The value of the parameter is always abandon-survey.

institution_name

Sent when the user exits the widget after selecting an institution. The value will be Belvo's institution code, for example banamex_mx_retail.

Here is an example of onExit usage:

<script type="text/javascript">
  function onExitCallbackFunction (data) {
    
    // Do something with the Exit data
  }
  
  function openBelvoWidget() {
    ...
    belvoSDK.createWidget(access_token, {
      ...
      onExit: (data) => this.onExitCallbackFunction(data),
      ...
    }).build();
  }    
</script>

5. Use the link_id to get data

Once your user successfully connects their bank account, you'll receive the link_id in the Success callback. You can then use this link_id to make calls, from your server-side, to retrieve the following operations (among others):

Connect widget update mode

The Connect widget can be configured in “update mode” to restore a link that has temporarily stopped working because:

  • the password connected with the Link has been changed by the user
  • a new MFA token is required

For more information, check our guide to Update a link using the Connect widget.


Did this page help you?