Skip to main content

Web Integration

This guide covers how to integrate the Hubble SDK into a web application using an iframe. The web integration is the simplest approach and gives you full access to SDK events via the browser's postMessage API.

1. Setup

No dependencies or SDKs are required. The Hubble SDK is a hosted web application that you embed in an iframe. All you need is your staging credentials (clientId, appSecret) and a valid SSO token for the current user.

2. SDK URL Parameters

ParameterRequiredDescription
clientIdYesClient ID provided by the Hubble team
appSecretYesApp secret provided by the Hubble team
tokenConditionalSSO token for the current user. Required unless lazy login is enabled.
appVersionNoApp version string. Defaults to "10000".
deviceIdNoDevice identifier for analytics.

The wrap-plt parameter is not required for web integrations.

3. Loading the SDK

Embedding in an iframe gives you full control over the SDK lifecycle and allows you to receive events via postMessage.

<iframe
id="hubble-sdk"
src="https://sdk.dev.myhubble.money/?clientId=xxx&appSecret=yyy&token=YOUR_SSO_TOKEN"
style="width:100%;height:100%;border:none;"
allow="clipboard-write *"
></iframe>

Make sure the iframe takes up the full width and height of its container. The SDK is designed to fill the available space and manages its own scrolling internally.

Option B: Open in a New Window

window.location.href = "https://sdk.dev.myhubble.money/?clientId=...&appSecret=...&token=...";
No Events in New Window Mode

If you open in a new window, you will NOT receive SDK events (postMessage only works across iframes, not across tabs). The iframe approach is strongly recommended.

4. Handling Navigation

When the SDK is embedded in an iframe, all navigation stays within the iframe by default. No additional URL handling is required on the web. External links (brand websites, help pages) will open in a new browser tab automatically.

This includes UPI: on mobile, the SDK opens UPI apps by navigating to schemes such as upi://, phonepe:// and tez://, and in a normal browser this works out of the box — Chrome and Safari hand these URLs to the OS themselves. There is no equivalent of the Android WebViewClient or iOS Info.plist configuration for you to add. See Section 6 for the two exceptions.

Recommended: Loading Pattern

Keep the iframe hidden until the SDK fires the app_ready event. This prevents users from seeing a blank white screen while the SDK loads. Show a loading spinner in place of the iframe, then swap visibility when app_ready fires.

5. Handling Events

The SDK communicates with your application by sending events. There are two types:

Action Events

SDK lifecycle and navigation:

ActionWhen It FiresWhat You Should Do
app_readySDK has finished loadingShow the WebView / iframe. Hide your loading spinner.
closeUser tapped the close or back button in the SDKDismiss the WebView / iframe. Navigate the user back.
errorSDK failed to load (invalid credentials, network error, SSO failure)Hide the WebView. Show a user-friendly error with a retry option.
Always Handle the close Event

The close action is the only way the SDK tells your application that the user wants to leave. If you do not handle it, the user will be stuck inside the SDK with no way to navigate back. This is one of the most common integration issues.

Analytics Events

User interaction tracking:

{ "type": "analytics", "event": "payment_success", "properties": { "amount": 500 } }

Forward analytics events to your analytics provider (Mixpanel, CleverTap, Amplitude, etc.) to track SDK usage.

For a complete list of events, see the Full Events Reference.

Setting Up the Event Listener

Add a message event listener to your page. Set this up BEFORE loading the SDK URL into the iframe, so you do not miss any events:

// Set up the listener BEFORE setting the iframe src
window.addEventListener("message", function (event) {
if (event.data.type === "action") {
const action = event.data.action;
if (action === "app_ready") {
document.getElementById("hubble-sdk").style.display = "block";
document.getElementById("loading-spinner").style.display = "none";
}
if (action === "close") {
document.getElementById("hubble-sdk").style.display = "none";
}
if (action === "error") {
document.getElementById("hubble-sdk").style.display = "none";
document.getElementById("error-state").style.display = "block";
}
}

if (event.data.type === "analytics") {
const eventName = event.data.event;
const properties = event.data.properties || {};
analytics.track(eventName, properties); // your analytics provider
}
});

// Now load the SDK
document.getElementById("hubble-sdk").src = sdkUrl;

Complete Example with Loading State

<div id="sdk-container" style="width:100%;height:100%;position:relative;">
<div id="loading-spinner" style="position:absolute;top:50%;left:50%;
transform:translate(-50%,-50%);">Loading gift cards...</div>
<div id="error-state" style="display:none;text-align:center;padding:40px;">
<p>Unable to load gift cards. Please try again.</p>
<button onclick="reloadSDK()">Retry</button>
</div>
<iframe id="hubble-sdk" style="width:100%;height:100%;border:none;
display:none;" allow="clipboard-write *"></iframe>
</div>

<script>
const sdkUrl = "https://sdk.dev.myhubble.money/"
+ "?clientId=YOUR_CLIENT_ID&appSecret=YOUR_APP_SECRET&token=YOUR_TOKEN";

window.addEventListener("message", function (event) {
if (event.data.type !== "action") return;
const sdk = document.getElementById("hubble-sdk");
const loader = document.getElementById("loading-spinner");
const error = document.getElementById("error-state");

if (event.data.action === "app_ready") {
sdk.style.display = "block"; loader.style.display = "none";
} else if (event.data.action === "close") {
sdk.style.display = "none";
} else if (event.data.action === "error") {
sdk.style.display = "none"; loader.style.display = "none";
error.style.display = "block";
}
});

document.getElementById("hubble-sdk").src = sdkUrl;
</script>
Debugging Events in Development

Add a console.log inside your event listener to see all messages:

window.addEventListener("message", (e) => console.log("SDK:", e.data));

6. Payment Configuration

The Hubble SDK supports UPI and credit/debit card payments. Credit/debit card payments are not enabled by default - contact Hubble support to enable them.

UPI on Web

On desktop browsers, UPI payments use UPI ID entry or QR codes, which work without additional configuration. On mobile browsers, UPI Intent can be triggered by the system to open installed UPI apps — the browser handles this itself, so a plain web integration needs no extra setup.

There are two cases where you do need to do something.

If you embed the SDK in a sandboxed iframe

The plain iframe shown in Section 3 is fine. But if you add a sandbox attribute, the browser blocks the SDK from launching external apps unless you explicitly re-grant that ability. A sandboxed iframe needs permission to open popups and to trigger top-level navigation on user activation, in addition to scripts, forms and same-origin access — otherwise tapping a UPI app does nothing.

If you do not have a specific reason to sandbox the iframe, leave the attribute off.

If your web page runs inside your own native WebView

This is the important one. If your "web integration" is actually a hybrid app — a Capacitor, Cordova, or hand-rolled WebView shell rendering your web page — then the browser handling those upi:// links is your WebView, and the native configuration is required after all:

  • Android: your WebViewClient must send non-Hubble URLs out via an ACTION_VIEW intent, and your AndroidManifest.xml needs the <queries> block. See the Android Integration Guide.
  • iOS: your WKNavigationDelegate must send non-Hubble URLs to UIApplication.shared.open, and your Info.plist needs LSApplicationQueriesSchemes. See the iOS Integration Guide.

In both cases the rule is the same as for the native platforms: let myhubble.money and razorpay.com load inside the WebView, and hand everything else to the OS.

Not Sure Which Case You Are In?

If your users reach the page through a mobile browser, you need nothing extra. If they reach it through an app you ship to the App Store or Play Store, you need the native configuration above.