Fluid Cashier
The Fluid Cashier (<fluid-widget>) is the full-featured cashier component. It supports deposits, withdrawals, and payment method management, typically presented as a modal overlay on your site.
Loading the script
Section titled “Loading the script”Add the Fluid script after the user has authenticated:
<script src="https://get.fluidpayments.io/index.js"></script>Mounting the widget
Section titled “Mounting the widget”Place the widget element in your page with the required attributes:
<fluid-widget operator-id="your-operator-id" session-id="user-session-id" user-id="user-id" locale="en" currency="EUR" country="MLT"></fluid-widget>The widget renders invisibly until you set the open attribute.
Initialisation approaches
Section titled “Initialisation approaches”The widget can be initialised in one of two ways. Both end in the same state — a configured widget that emits initialised and is ready to open. They differ in what triggers the initialisation and in how the element lives in your DOM:
| Automatic initialisation | Programmatic initialisation | |
|---|---|---|
| Triggered by | Adding the element to the DOM | Calling fluid.init() |
| When it happens | On element mount | Right after the script loads, before any mount |
| Attributes on the element | The full required set | Only the reactive ones |
| The element lives | Permanently, mounted once per session | Wherever your framework puts it, mounted and unmounted freely |
| Use it when | The element sits in a stable part of your page for the whole session | Your framework re-renders or conditionally renders the element — for example, it exists only while the cashier is open, or is recreated on route changes |
Automatic initialisation
Section titled “Automatic initialisation”By default, the widget triggers initialisation as soon as it is added to the DOM. This is the simplest approach and the recommended one in most cases:
// 1. Create the elementconst widget = document.createElement('fluid-widget');
// 2. Set required attributeswidget.setAttribute('operator-id', 'your-operator-id');widget.setAttribute('session-id', 'user-session-id');widget.setAttribute('user-id', 'user-id');widget.setAttribute('locale', 'en');widget.setAttribute('currency', 'EUR');widget.setAttribute('country', 'MLT');
// 3. Attach listeners BEFORE adding to DOMwidget.addEventListener('fluid-info', handleInfo);widget.addEventListener('fluid-error', handleError);widget.addEventListener('fluid-command', handleCommand);
// 4. Add to page — initialisation starts automaticallydocument.body.appendChild(widget);The element then stays in the DOM for the whole session, driven through its reactive attributes. Don’t open it before initialised fires. For the rules that keep a session healthy, see Session Handling.
Programmatic initialisation
Section titled “Programmatic initialisation”Use this approach when the element is not permanent: when it is rendered only while the cashier is open, recreated on navigation, or otherwise injected many times during a session. With automatic initialisation every one of those mounts would start from scratch; fluid.init() moves that work to login time, so each mount finds everything prepared and is instant.
Call fluid.init() right after the script loads. It takes the identity values that would otherwise be set as attributes — note the parameter names countryCode and currencyCode, and that operatorId is a number:
// 1. Prepare the widget — once per user session. This doesn't open any UI.await fluid.init({ operatorId: 123, userId: 'user-id', sessionId: 'user-session-id', locale: 'en', countryCode: 'MLT', currencyCode: 'EUR', // Optional: bonuses, userData});
// 2. Create and mount the widget. Keep session-id on the element// so the widget picks up session rotations.const widget = document.createElement('fluid-widget');widget.setAttribute('session-id', 'user-session-id');// ... attach listenersdocument.body.appendChild(widget);The parameters follow the FluidInitParams type, also available in the @fluidpayments/types package.
Unless specifically intended, call fluid.init() only once per user session. To update widget parameters afterwards, use the reactive attributes. Whenever your page renders the element, it only needs to carry reactive attributes such as transaction, open, balance, withdrawable-balance, bonuses, transaction-limits, success-cta-link and session-id.
When the element is injected after fluid.init():
- If
bonusesare unchanged, the widget doesn’t process them again; likewise, asession-idequal to the one passed tofluid.init()doesn’t trigger re-initialisation. - If any of the required init parameters has changed, the widget re-initialises itself on inject.
Locale validation
Section titled “Locale validation”Both paths normalise POSIX-style underscores, so en_GB is accepted as en-GB. If the result is still not a valid IETF BCP 47 tag, they behave differently:
fluid.init()returns a promise that rejects with anErrorwhose message describes the offending value. Programmatic callers are expected to surface the failure explicitly.- The
localeattribute falls back toenand emits aninvalid-init-attributesfluid-errorevent.
Opening the cashier
Section titled “Opening the cashier”Once the initialised event fires, open the cashier:
// Open to the default viewwidget.setAttribute('open', 'true');
// Open to a specific transaction type: set `transaction` first, then openwidget.setAttribute('transaction', 'withdrawal'); // or 'deposit', 'quick-deposit'widget.setAttribute('open', 'true');open only takes true or false. The transaction attribute is applied only while the cashier is closed, so set it before opening.
Handling events
Section titled “Handling events”Three event types require listeners:
widget.addEventListener('fluid-info', (e) => { const { message } = e.detail;
switch (message) { case 'initialised': // Widget is ready to open break; case 'deposit-success': // Deposit was successful break; case 'withdrawal-success': // Withdrawal was successful break; }});
widget.addEventListener('fluid-error', (e) => { console.error('Fluid error:', e.detail);});
widget.addEventListener('fluid-command', (e) => { const { message } = e.detail;
switch (message) { case 'close': // User requested to close the cashier widget.setAttribute('open', 'false'); break; }});Closing and cleanup
Section titled “Closing and cleanup”Close the cashier by setting open to false:
widget.setAttribute('open', 'false');Remove the widget entirely when the session ends:
widget.remove();Reactive attributes
Section titled “Reactive attributes”The widget observes attribute changes while it is open. For example, you can update the session ID if it rotates:
widget.setAttribute('session-id', 'new-session-id');See the Attributes reference for the full list of supported attributes and which ones are reactive.
Full example
Section titled “Full example”An example of everything that can be injected into your page on user login for automatic initialisation. Only operator-id, session-id, user-id, locale, country and currency are required:
<script src="https://get.fluidpayments.io/index.js"></script><fluid-widget operator-id="<your operator ID>" session-id="<authenticated user session ID>" user-id="<authenticated user ID>" user-data="<authenticated user details>" locale="<locale tag>" country="<authenticated user country>" currency="<user currency code>" transaction="<deposit / withdrawal / quick-deposit>" lock-transaction-type="<false / true>" open="<false / true>" balance="<user current balance>" withdrawable-balance="<user current withdrawable balance>" bonuses="<bonus data>" transaction-limits="<transaction limit data>" success-cta-link="<link to URL/path following a successful transaction>" z-index="<z-index value>" transaction-attributes="<stringified JSON object of key-value pairs for the payment provider>" deposit-amount="<pre-filled deposit amount>" allow-decimal-amounts="<true / false>" prefilled-bonus-code="<bonus code to pre-fill>" two-factor-auth-enabled="<false / true>"></fluid-widget>The element should stay in the DOM for the whole user session. The bonus and user data shapes are documented on the Data Objects page.
Going further
Section titled “Going further”- For cases where the widget needs to request data or trigger an action on your page and receive a typed response, see the Bridge API.
- Feature-specific behaviours, such as the Withdrawal Warning and Manual Bonus Codes, are documented in the Features section.
- Fonts, stacking and style encapsulation are covered on the Styling page.