Before you begin: your server must generate a
patToken for each session and make it available to your page. See Set up your server.1. Load the widget script
Add this loader to your page. It injects the widget script and resolves onceFluzEmbedded is ready, so the rest of your code never runs before the widget exists.
2. Initialize the widget
Once the script has loaded, callinit() with the transaction details and the patToken from your server.
init() takes transaction_type in snake case. The claim inside the signed patToken is transactionType. Both must describe the same transaction.3. Open the widget
Choose how the user launches the widget. Both options run afterinit().
Init options
init() checks only what the script itself needs: patToken, transaction_type, and a resolvable container. Everything else is validated against your signed token, so a bad transaction_type or a missing amount reaches you through onError, not a console message your code can’t see.Methods
Handle the outcome
onOpen and onClose only tell you the widget appeared and went away, not whether the user finished. To know how the flow ended, pass onSuccess and onError. Both are optional; if you pass neither, the widget still works, you just won’t receive outcomes.
How the callbacks behave
onSuccessis final. It fires at most once, and no outcome is delivered after it, so a completed flow never also reports an error.onErrorreports an attempt, not a verdict. A user whose identity check fails or whose payment is declined is still in the widget and can try again.onErrorcan fire more than once in a session, and a lateronSuccesscan still arrive.- Neither callback closes the widget. The user stays on screen until they dismiss it, which fires
onClose.
onSuccess fires or the user closes the widget.
What the callbacks receive
Both callbacks include, when known, the ids that tie the session to your records and the contact details on the Fluz account that ran it. Fluz fills these in server-side from your signed token and the user’s session, so they’re the values Fluz recorded, not anything the page assembled.
Read each field on its own; don’t assume the set is complete.
externalReferenceIdcomes from your token, so it survives failures that happen before a user signs in.- The other four come from the Fluz account and only appear once the session got that far.
- A failure before your token validates (an expired token, a missing app permission) carries nothing.
onErrorreceives onlycodeandmessage.
email and phoneNumber describe the Fluz account the user signed into, which may differ from the values you passed in the patToken.
These fields identify the session; they aren’t a record of what happened. Use externalReferenceId to find the right row in your system, then confirm the outcome with a webhook or API call before acting on it.
Error codes
onError receives a stable code to branch on and a human-readable message to log. US-0005 and G-0004 are failed attempts the user can retry; every other code means the session can’t continue.
Treat any unrecognized code like
G-0001. New codes ship over time without a breaking change.
Render the widget inline (staging only)
By default, the widget mounts a fixed, full-viewport overlay on your page. Pass acontainer and it renders inside an element you position and size yourself, with no overlay, scroll lock, or page takeover.
Sizing
The widget fills your container at 100% width and height and never resizes it. Content taller than the container scrolls inside the widget, not your page.- Set an explicit width and height on the container in your CSS. Without a height, the widget falls back to the browser’s default iframe height of 150px, the most common mistake in this integration. The script logs a console warning if the container is too small when the widget opens.
- Minimum supported size is 320 × 480 px. Every screen, including document capture, 2FA, and PIN entry, is supported at that size. Smaller layouts aren’t supported.
- There’s no maximum. Wide containers get the desktop layout, including the transaction summary pane; narrow ones get the mobile layout.
Differences from the modal
Plan for that last row: when the user closes an inline widget,
onClose fires and your container is emptied, so render its replacement from onClose.
Container errors
If the container can’t be used, nothing renders,onOpen doesn’t fire, and the script logs an error:
- At
init():containeris neither an element nor a non-empty string. The widget stays unconfigured, and a lateropen()refuses. - At
open(): the selector matches nothing, isn’t valid CSS, or the element isn’t attached to the document.
A
container selector is resolved when open() is called, not at init(), so it’s fine to call init() before the element exists.