Skip to content

Common Pitfalls

These are the issues that come up most often during integrations. Reviewing this list before you start can save significant debugging time.

The wallet never becomes ready and an initialisation-failure error fires. The session-id is empty, a placeholder, or not a real session ID. Pass the real, current session ID of the authenticated user.

initialisation-failure fires with code: 'SESSION_REJECTED': Fluid didn’t accept the session. The operator-id isn’t the one for this environment, the session-id isn’t current, or user-id, country or currency isn’t the player’s own. Check those attributes against what your platform holds. See A refused session.

Ensure session-id remains stable across renders and only changes during legitimate session rotation. Use a stable value; mount and initialise once.

Failed transactions after platform refresh

Section titled “Failed transactions after platform refresh”

Update the session-id attribute whenever your platform rotates the session. It is observed even while the cashier is open, so there is no need to re-mount.

Changing an identity attribute (operator-id, user-id, locale, country or currency) on a live element does nothing: these are read only at initialisation. Remove the element and mount a fresh one with the new values. See Session Handling.

The element must be removed from the DOM upon session termination.

There is no such event — session refresh is automatic. Don’t wait for one; handle initialisation-failure for genuine failures only.

Ensure initialisation runs in every browser tab. Sessions are tab-specific and don’t share across tabs.

Verify the Fluid script loaded successfully via network inspection. Confirm customElements.get('fluid-widget') returns a function.

This indicates incomplete operator configuration (for example payment methods or orchestrator configuration not yet provisioned), not an embedding issue. Check the operator’s Operator Payment Methods in the Back Office; if they look right, contact Fluid Payments to complete the operator setup.

fluid.init() prepares the widget but does not open the UI. After initialised, set open="true" on the element.

Wait for the initialised event before opening the UI. See the sequence in the Quick Start.

The widget works, but your initialised listener never runs. Listeners were attached too late — after an await, inside a timeout, or in a late framework lifecycle hook. Attach event listeners synchronously in the same script block that adds the element.

Bridge handlers were registered before the script finished loading. Register them within the script.onload callback. See the Bridge API.

More than one Fluid element is mounted, or the script was loaded twice. Maintain exactly one Fluid element in the DOM at a time and guard the script injection, as shown in Loading the script.

fluid.init() is throttled to roughly once every two seconds; a call made too soon rejects its promise with Function call is throttled. Please wait. Call it once per session, right after loading the script.

An invalid-user-data, invalid-bonus-data or invalid-transaction-attributes error usually means an object was passed directly instead of stringified JSON. Objects must be stringified using JSON.stringify() before passing as attributes (see Data Objects):

// Bad: passing an object directly
widget.setAttribute('user-data', userData);
// Good: stringified JSON
widget.setAttribute('user-data', JSON.stringify(userData));

Locale values must follow IETF BCP 47 (e.g. en-GB, es-MX), with en and ar as exceptions. An invalid locale attribute makes the widget fall back to en, and an invalid-init-attributes error accompanies the fallback.

Type mismatches between init and attributes

Section titled “Type mismatches between init and attributes”

fluid.init() uses countryCode and currencyCode, while HTML attributes use country and currency.

The transaction attribute defaults to deposit. Explicitly set it for other flows:

<fluid-widget transaction="withdrawal" ...></fluid-widget>