Embedding the Funding Page with an iframe

View as Markdown

You can embed the NinjaTrader funding page inside your own web application, so a user adds funds without leaving your product. This page covers what your page needs to do. Unlike the ShortGrantCode handoff, which redirects the browser to a NinjaTrader-hosted page, this flow keeps the user on your page and passes an access token to the embedded frame.

Prerequisites

NinjaTrader provisions and shares three things with you:

  • The iframe host URL, which serves the /transfer-funds route.
  • The token endpoint, which your backend calls with the jwt-bearer grant to obtain a short-lived access token. See Partner Token for the assertion format, claims, and JWKS requirements.
  • The allowed parent origins, meaning the exact scheme, host, and port of every page that will host the iframe. Inbound messages your page sends to the frame are dropped if they come from any other origin.

Register your hosting origin before you integrate. If it is missing, the iframe still loads and still emits its outbound messages, but the inbound channel — messages your page sends to the frame — fails silently.

Warning: The per-partner origin allowlist is not yet wired to the backend configuration, which has two consequences today. Outbound messages from the iframe are posted with a wildcard target origin rather than your registered origin. They carry no sensitive data, but you must still validate event.origin on your side. Inbound messages you send to the iframe are ignored until the allowlist ships, because the frame does not register its parent-message listener without a configured allowlist. Build the listener now and defer relying on the inbound channel until NinjaTrader confirms the allowlist is live for your integration.

Your users must already have NinjaTrader accounts in the organization your partner configuration is bound to. Accounts are never auto-provisioned, and a user resolved outside that organization is rejected at the token endpoint. Coordinate provisioning before go-live.

Obtaining an Access Token

For each user session, your backend calls the token endpoint and returns a short-lived access token to your frontend. Treat it as a bearer credential:

  • Fetch it server side. Never put long-lived secrets in the browser.
  • Fetch a fresh token every time you mount the iframe.
  • Do not log it, store it in localStorage, or include it in analytics events.

Mounting the iframe

Pass the token in the URL fragment, never the query string. Fragments are not sent to servers, so the token stays out of access logs and referrer headers.

1<iframe
2 id="nt-funding"
3 src="https://FUNDING_HOST/transfer-funds#token=ACCESS_TOKEN"
4 style="width: 100%; border: 0;"
5 allow="payment"
6 title="Funding"
7></iframe>

Only the /transfer-funds route is embeddable. Navigating the frame to any other route is blocked and raises a route_blocked error to your page. Once the frame loads, the token is consumed and removed from the URL, so you do not need to scrub it yourself.

Receiving Messages

The frame communicates with window.postMessage. Always validate event.origin against the NinjaTrader funding host before acting on a message, and confirm the message came from your frame.

1const NT_ORIGIN = 'https://FUNDING_HOST';
2const iframe = document.getElementById('nt-funding');
3
4window.addEventListener('message', (event) => {
5 if (event.origin !== NT_ORIGIN) return;
6 if (event.source !== iframe.contentWindow) return;
7
8 const msg = event.data;
9 switch (msg?.type) {
10 case 'auth_ready':
11 // Session established. Safe to reveal the UI.
12 break;
13
14 case 'resize':
15 iframe.style.height = msg.height + 'px';
16 break;
17
18 case 'error':
19 console.error('NinjaTrader iframe error', msg);
20 break;
21
22 default:
23 // Unknown types ship in future protocol versions. Log and ignore.
24 break;
25 }
26});
typePayloadPurpose
auth_ready{ partnerOrgName?: string }The session is established and the frame is safe to show
resize{ height: number }Content height changed, so resize the frame to match
error{ code: string, message?: string, correlationId?: string }Something went wrong, to surface or log per your own design

The set of message types is extensible, so keep a default arm that logs and ignores anything unrecognized.

Error Codes

codeMeaning
no_tokenNo access token was found in the URL fragment
session_expiredThe partner session expired and the refresh token was rejected
unverifiedThe user has not completed verification
route_blockedA navigation to a route other than /transfer-funds was attempted
sim_only_userThe user is not eligible for the funding flow
no_live_accountThe user has no eligible live account for funding
closed_accountThe account is closed, so this surface is unavailable

Treat any unrecognized code defensively by logging it and recovering as described below. Origin mismatches never arrive as an error message, because inbound messages from an unregistered origin are dropped silently.

Sending Messages

You can post messages to the frame. Always pass the NinjaTrader origin as the second argument rather than a wildcard.

1iframe.contentWindow.postMessage(
2 {
3 type: 'handshake',
4 partnerName: 'Sample Brokerage',
5 partnerId: 'samplepartner',
6 theme: { primary: '#0055aa' },
7 protocolVersion: 1
8 },
9 NT_ORIGIN
10);
typePayloadPurpose
handshake{ partnerName, partnerId, theme?, protocolVersion: 1 }Send the protocol version and optional theme overrides after the frame loads
closenoneSignal that the user closed the funding flow on your side

partnerName and partnerId are required and theme is optional. A handshake carrying any protocolVersion other than 1 is ignored. Sending the handshake is recommended for forward compatibility, but as noted above the inbound channel is inactive until the allowlist ships.

Sizing

The frame does not scroll itself in embed mode, so your page is responsible for sizing it. Start at a sensible default height such as 600 pixels and resize on each resize message. Avoid a percentage height unless the frame sits inside a fixed-height container.

Recovering from Errors

When the frame cannot establish a session, whether the token expired, the token was invalid, or the origin is not allowed, you receive an error message. Recovery is usually to discard the frame, fetch a fresh access token from your backend, and mount it again. If errors persist, contact NinjaTrader support with the error code and a timestamp.

Next Steps

  • Partner Token: sign the assertion and exchange it for the access token this flow needs.
  • SSO with ShortGrantCode: the redirect-based alternative, for sending a user to a full NinjaTrader-hosted page.