Integrate the UI SDK (Frontend Web)
Tingee provides a Web SDK (Frontend) library that lets you embed the bank linking interface directly into your website as a Popup (Modal) or display it Inline on the page.
1. Embed the SDK library
Add the following <script> tag to your web page's HTML (e.g. index.html or your main template file):
UAT environment:
<script src="https://uat-bank-link.tingee.vn/js/tingee-bank-link.js"></script>
Production environment:
<script src="https://bank-link.tingee.vn/js/tingee-bank-link.js"></script>
2. Configure & listen for events (Setup)
Before opening the bank linking screen, register callbacks to listen for the result with TingeeBankLink.Setup(config).
TingeeBankLink.Setup({
// Default popup window size
size: 'large',
// Customize the primary color
theme: {
primaryColor: '#1E88E5'
},
// Event: bank account linked successfully
onSuccess: function(data) {
console.log("Linked successfully!", data);
// Example: refresh the account list or show a success message
},
// Event: linking failed (e.g. a business error from the bank)
onFailed: function(data) {
console.error("Linking failed:", data.errorMessage);
},
// Event: the user cancelled linking (e.g. clicked the X button to close the popup)
onCancelled: function(data) {
console.log("User cancelled linking:", data);
},
// Event: a system error occurred in the SDK
onError: function(data) {
console.error("SDK system error:", data);
},
// Event: the popup closed (runs after the success/failure/cancel callbacks)
onClose: function() {
console.log("SDK window closed.");
}
});
3. Display the linking interface
After calling your backend and receiving the url (the SDK URL from the OpenAPI), call TingeeBankLink.Url.Open(url, options) to launch the SDK interface.
// url received from your backend via OpenAPI v1/create-bank-link-session
const bankLinkUrl = "https://uat-bank-link.tingee.vn?token=...";
// Open the SDK
TingeeBankLink.Url.Open(bankLinkUrl);
[!TIP] If you need per-session customization, you can pass callbacks and size settings in the second parameter of
Opento override the global configuration (Global Setup).
4. Customize size & display mode
4.1. Size presets
The SDK supports these preset popup window sizes:
| Value | Description |
|---|---|
small | Small modal. |
medium | Medium modal (default). |
large | Large modal. |
You can also configure a detailed custom size:
TingeeBankLink.Url.Open(url, {
size: {
width: 960,
height: '92%',
maxWidth: 'calc(100vw - 32px)',
maxHeight: 820,
borderRadius: 24
}
});
4.2. Inline display mode (Inline Container)
If you prefer not to use a popup and want to embed the interface directly into an existing container on your web page:
<!-- Declare the container -->
<div id="bank-link-container" style="width: 100%; height: 760px;"></div>
<script>
// Render the SDK directly into the container specified by ID
TingeeBankLink.Url.Open(url, {
containerId: 'bank-link-container'
});
</script>
5. Framework integration examples
- React
- Angular
- Vue 3
import React, { useEffect } from 'react';
// Declare the global TypeScript type to avoid compiler errors
declare global {
interface Window {
TingeeBankLink: any;
}
}
export default function BankLinkButton() {
useEffect(() => {
if (window.TingeeBankLink) {
window.TingeeBankLink.Setup({
size: 'large',
onSuccess: (data: any) => {
console.log("Linked successfully", data);
// Update the UI or call an API to reload the account data
},
onCancelled: () => console.log("Customer closed the SDK"),
});
}
}, []);
const handleOpenSDK = async () => {
try {
// Call your internal API to generate the bank link URL
const response = await fetch('/api/bank-link/session', { method: 'POST' });
const { url } = await response.json();
if (window.TingeeBankLink) {
window.TingeeBankLink.Url.Open(url);
} else {
alert("The SDK failed to load!");
}
} catch (error) {
console.error("Failed to start bank linking", error);
}
};
return (
<button onClick={handleOpenSDK} className="btn-link">
Link your bank account now
</button>
);
}
import { Component, OnInit } from '@angular/core';
declare var TingeeBankLink: any; // Declare the global variable
@Component({
selector: 'app-bank-link',
template: `
<button (click)="startLinking()">Link bank account</button>
`
})
export class BankLinkComponent implements OnInit {
ngOnInit() {
if (typeof TingeeBankLink !== 'undefined') {
TingeeBankLink.Setup({
size: 'large',
onSuccess: (data: any) => {
console.log("Linked successfully", data);
},
onCancelled: () => console.log("Customer cancelled")
});
}
}
async startLinking() {
try {
// Call your backend service to get the bank link URL
const url = await this.bankLinkService.createSession();
TingeeBankLink.Url.Open(url);
} catch (error) {
console.error("Bank linking error", error);
}
}
}
<script setup>
import { onMounted } from 'vue';
onMounted(() => {
if (window.TingeeBankLink) {
window.TingeeBankLink.Setup({
size: 'large',
onSuccess: (data) => {
console.log("Linked successfully", data);
},
onCancelled: () => console.log("Customer cancelled"),
});
}
});
const startLinking = async () => {
try {
const response = await fetch('/api/bank-link/session', { method: 'POST' });
const { url } = await response.json();
if (window.TingeeBankLink) {
window.TingeeBankLink.Url.Open(url);
}
} catch (error) {
console.error("Failed to create bank link session", error);
}
};
</script>
<template>
<button @click="startLinking">Link bank account</button>
</template>
6. Callback payload format
6.1. On success (onSuccess)
Returns a JSON object with the details of the successfully linked bank account:
{
"status": "success",
"bankName": "BIDV",
"merchantAccountNumberId": 456,
"vaAccountNumber": "1234567890",
"shopId": 123
}
6.2. On failure (onFailed)
Returns the detailed business error code:
{
"status": "failed",
"errorCode": "BANK_CONFIG_NOT_EXIST",
"errorMessage": "Cấu hình ngân hàng không tồn tại"
}
6.3. When the user closes the SDK (onCancelled)
{
"status": "cancelled",
"errorCode": "USER_CLOSED"
}
7. Handle the result via Redirect URL
If you provided the redirectUrl parameter when creating the session on the backend, the SDK automatically redirects the customer's whole browser to that address, with the result as query parameters:
https://merchant.example.vn/bank-link/callback?status=success&bankName=BIDV&merchantAccountNumberId=456&shopId=123
You can read the information on this callback URL to show the corresponding result message.
8. Sync the result via Webhook (recommended)
Although the SDK and the Redirect URL give immediate feedback in the user interface (client-side), using a Webhook (server-side) is the safest and most reliable way to sync the bank account link status to your system.
Tingee automatically sends a POST request with the details of the successfully linked bank account right after the event occurs.
For details on configuration, the data format (payload) and how to verify the security signature, see Bank link webhook.