Skip to navigation

Sentinel Web Integration Guide

This guide covers how to add Persona Sentinel iFrame in your webpage.

Integration

Setup

Ask your Persona Account Team to set up a Sentinel transaction type and client token.

Instructions

1. Load Sentinel Collection URL

Embed a link to the Sentinel collection endpoint, with your client token and transaction type ID substituted as shown below. The following optional parameters are supported:

  • context is a string that represents any contextual enrichment you’d like to provide for the event such as “onboardingEvent” etc.
  • account-reference-id is a string parameter for including the user’s reference ID. Usage of this parameter will ensure that information from the Sentinel event is synced to Graph, if being used.
  • auto-create-account is an optional boolean string (true or false) that controls whether an account is auto-created when one does not already exist for the given account-reference-id. Set to false to opt out of auto-creation; any other value is treated as true.
  • auto-create-account-type-id is an optional account type token (prefix acttp_) that specifies the account type to use when auto-creating an account. If omitted, defaults to the transaction type’s configured default account type.
  • identifiers is an optional array parameter for including identifiers that are sent with the transaction when collection is triggered. Add values to the array by appending &identifiers[<index>]=<value> to the Sentinel collection URL (e.g. &identifiers[0]=...&identifiers[1]=...), with the index starting at 0.
jsx
https://withpersona.com/sentinel?client-token={{CLIENT_TOKEN}}&transaction-type-id={{TXN_TYPE_ID}}&context={{CONTEXT}}&account-reference-id={{REFERENCE_ID}}&auto-create-account=true&auto-create-account-type-id={{ACCOUNT_TYPE_ID}}

To verify this is working, you visit the URL above. This should result in 3 network calls

A blank page should load (Inspect Page → Network tab to verify).

2. Create the transaction

To trigger Transaction creation, which sends the device information, context, identifiers, etc. to Persona, post a message to the content window containing the sentinel page.

If the page was opened directly in the main window, open console and use:

jsx
window.postMessage({'type':'persona/passive/collect', 'origin':'https://withpersona.com'})

If the page is embedded within the iframe, use:

jsx
document.getElementById('{{MY_IFRAME_ID}}').contentWindow.postMessage(
{'type':'persona/passive/collect', 'origin':'{{MY_ORIGIN}}'},
'https://withpersona.com'
);

Embed the Sentinel URL in an iFrame, only load the iFrame and send the transaction as needed.

jsx
import React, {
useState,
useRef,
useMemo,
useEffect
} from "https://esm.sh/react@18";
import ReactDOM from "https://esm.sh/react-dom@18";
import TypesReact from "https://esm.sh/@types/react";
import TypesReactDom from "https://esm.sh/@types/react-dom";
function SentinelContainer() {
const [iframeLoaded, setIframeLoaded] = useState(false);
const [sentinelCollecting, setSentinelCollecting] = useState(false);
// To store the callback result from Sentinel
const [postResult, setPostResult] = useState(null);
const iframeRef = useRef(null);
const memoizedIframe = useMemo(
() => (
<iframe
style={{ display: "none" }}
ref={iframeRef}
id="sentinel"
src="https://withpersona.com/sentinel?client-token={CLIENT_TOKEN}&transaction-type-id= {TXN_TYPE_ID}&context=referenceImplementation&account-reference-id={REFERENCE_ID}"
/>
),
[]
);
const handleIframeLoad = () => {
setIframeLoaded(true);
};
const handleMessage = (message) => {
if (message.origin === "https://withpersona.com") {
setPostResult(message.data);
setSentinelCollecting(false);
}
};
useEffect(() => {
// Add a message event listener to your application to handle postMessage callbacks
window.addEventListener("message", handleMessage);
const iframeElement = iframeRef.current;
if (iframeElement) {
// Add a load event listener to the iframe to detect when it has finished loading
iframeElement.addEventListener("load", handleIframeLoad);
}
// Return value is used to provide a cleanup function for React's useEffect
return () => {
window.removeEventListener("message", handleMessage);
if (iframeElement) {
iframeElement.removeEventListener("load", handleIframeLoad);
}
};
}, []);
const handleClick = () => {
if (iframeRef.current && iframeRef.current.contentWindow) {
setSentinelCollecting(true);
// Post a message to the Sentinel iframe to begin collection
iframeRef.current.contentWindow.postMessage(
// The origin refers to the domain in which the iframe is being embedded
{ type: "persona/passive/collect", origin: "https://mywebpage.com" },
// The second parameter is the target origin, this should be https://withpersona.com
// (or the domain matching the Sentinel endpoint being used for the iframe)
"https://withpersona.com/"
);
}
};
return (
<>
{memoizedIframe}
<h1>Hello World</h1>
<p>Iframe loaded: {iframeLoaded.toString()}</p>
<p>Sentinel result: {sentinelCollecting ? "Loading..." : ""}</p>
<pre>
{postResult ? JSON.stringify(postResult, null, 2) : "No data available"}
</pre>
<button
onClick={handleClick}
disabled={!iframeLoaded || sentinelCollecting}
>
Click Me
</button>
</>
);
}
// Tells React to attach the HelloWorld component to the 'root' HTML div
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<SentinelContainer />);
// ReactDOM.render(<SentinelContainer />, document.getElementById("root"));

Other parameters

Routing country

For end users & customers on the DE shard, taking advantage of geographical routing may be desired to reduce client-facing latencies. Since the /sentinel endpoint is fetched via a GET request (when loaded via iframe), one can specify an additional query string parameter:

jsx
https://withpersona.com/sentinel?client-token={{CLIENT_TOKEN}}&transaction-type-id={{TXN_TYPE_ID}}&routing-country=US

One can specify either US or DE for the routing-country query string parameter. Subsequent API calls made to Persona will be routed accordingly.

Note that this parameter will primarily affect the Create Transaction API call. The initial /sentinel page load may still be served from a US-based server.