Once your backend can obtain Spotnana access tokens, configure your frontend to load the Spotnana iframe and handle the token exchange.
When loading the iframe, include the idp=token-exchange-auth query parameter in the URL. This instructs the Spotnana system to initiate the token exchange authentication flow.
For example, the URL containing the query parameter may look like this:
https://<spotnana-embed-url>/path?idp=token-exchange-auth&orgId=<your-org-id>
Note: This query parameter clears all previous session storage and starts a fresh authentication. This is also important to capture any changes that may have happened to the user's status within your system since the last session (e.g., a user's access may have been revoked if they've left the organization).
When the iframe loads, Spotnana and your application exchange messages through the browser's postMessage API. Here's how the process works:
- Spotnana sends a
TOKEN_EXCHANGE_REQUESTmessage to your application. Here's a sample message you may receive:
{
"type": "TOKEN_EXCHANGE_REQUEST",
"from": "spotnana-embed"
}- Your application listens for this message. Then, it fetches the access token and refresh token from your backend setup, and responds with the following
TOKEN_EXCHANGE_RESPONSE.
{
"type": "TOKEN_EXCHANGE_RESPONSE",
"payload": {
"accessToken": "<spotnana-access-token>",
"refreshToken": "<spotnana-refresh-token>"
}
}Note: If the token exchange fails, Spotnana sends a TOKEN_EXCHANGE_ERROR message as shown below:
{
"from": "spotnana-embed",
"type": "TOKEN_EXCHANGE_ERROR",
"payload": {
"errorCode": "INVALID_TOKEN",
"errorMessage": "<error description>"
}
}Your application must be designed to listen for this event and handle authentication failures appropriately (e.g., redirecting the user to a login page or displaying an error message).
The following HTML sample demonstrates the frontend integration. This code will render the Spotnana iframe upon the click of a button (i.e., in this code, clicking the Launch Spotnana button will initiate the rendering). This code also handles the frontend token exchange.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Spotnana Embed</title>
<style>
html, body { height: 100%; margin: 0; padding: 0 20px; }
.iframe-wrapper {
height: calc(100% - 100px);
width: 100%;
border: 1px solid #ccc;
}
</style>
</head>
<body>
<h1>Spotnana Integration</h1>
<button id="renderIframe">Launch Spotnana</button>
<div class="iframe-wrapper" id="iframeWrapper"></div>
<script>
const spotnanaDomain = 'https://sboxmeta-embed-app.partners.spotnana.com';
const orgId = '<YOUR_ORG_ID>';
// Listen for token exchange requests from the iframe
window.addEventListener('message', async (event) => {
if (event.origin !== spotnanaDomain) return;
const { data, source } = event;
if (data.type === 'TOKEN_EXCHANGE_REQUEST') {
try {
// Fetch tokens from your backend
const response = await fetch('/api/spotnana/tokens');
const { accessToken, refreshToken } = await response.json();
source.postMessage({
type: 'TOKEN_EXCHANGE_RESPONSE',
payload: { accessToken, refreshToken }
}, spotnanaDomain);
} catch (error) {
console.error('Token fetch failed:', error);
}
}
if (data.type === 'TOKEN_EXCHANGE_ERROR') {
console.error('Token exchange error:', data.payload);
// Handle authentication failure
}
});
// Render iframe on button click
document.getElementById('renderIframe').addEventListener('click', () => {
const wrapper = document.getElementById('iframeWrapper');
const params = new URLSearchParams({
'idp': 'token-exchange-auth',
'orgId': orgId,
// Add other parameters as needed
});
const iframe = document.createElement('iframe');
iframe.src = `${spotnanaDomain}/hotels/search?${params}`;
iframe.width = '100%';
iframe.height = '100%';
iframe.title = 'Spotnana';
wrapper.innerHTML = '';
wrapper.appendChild(iframe);
});
</script>
</body>
</html>