Refreshing Accounts

For efficiency, HQ and UUX cache a user’s accounts for the duration of a session. This means from the moment your end user logs in until they log out, their account list will not change. Most of the time, this leads to a snappier front end experience, since calculating accounts is an expensive operation, often involving real time calls to the Core. However, if your workflow involves updating or linking an account, this is a hindrance. Fortunately, the SDK provides a way of refreshing these accounts outside of the normal login flow.

Warning

This only applies to workflows where the end user logs into the Online environment

The accounts are cached in both UUX and HQ. So you need to clear the cache in HQ and UUX for account changes to show up. Let’s first cover the HQ cache clearing using HqCommands.

Backend Process

class q2_sdk.hq.models.hq_commands.HqCommands(reload_type, accounts_to_reload, force_success_response=False, disclaimer_id_to_skip=None)[source]

For use with sending special instructions to HQ via an execute_request_as_xml response

Parameters:
  • reload_type (AccountReloadType) – Reload from either Q2’s database or the Host Adapter

  • accounts_to_reload (list) – List of account numbers (host account ids HAIDs). If blank, will reload ALL accounts (This can be expensive and is not recommended)

  • force_success_response – Must be set to True to allow Disclaimers to move on with their flow

  • disclaimer_id_to_skip (Optional[int]) – Q2_DisclaimerFormData.DisclaimerFormDataID. If set, will mark the disclaimer viewed for the duration of the online session

To understand the use of this method, let’s review a typical SDK workflow:

Q2Online -> HQ -> SDK -> HQ -> Q2Online
  1. The end user does something in the online environment. Perhaps clicking on a submit button in your SDK form.

  2. This tells HQ to find the registered SDK extension. HQ then POSTs to your extension with a blob of XML including the user’s information, such as their email, SSN, Account List, etc.

  3. It is the responsibility of your extension to generate some HTML to return back to HQ, which the SDK framework wraps in an appropriate SOAP response before returning.

Step 3 returns something like this:

<FormRsp xmlns="http://tempuri.org/FormRsp.xsd">
<FormResp>
    <TargetUrl/>
    <PrependVirtualDirToUrl>false</PrependVirtualDirToUrl>
    <MessageToEndUser/>
    <NewFormData>{form_data}</NewFormData>
    <NewFormShortName/>
    {hq_commands_xml}
</FormResp>
</FormRsp>

{form_data} is substituted with whatever you return from your extension. Meanwhile, {hq_commands_xml} can give HQ special instructions. This is the hook that allows us to refresh the accounts during an active session.

In practice it looks something like this:

from q2_sdk.hq.models.hq_commands import HqCommands
...

async def submit(self):
    ...
    html = self.generate_html()  # Imagine this does some magic to generate your form
    accounts_to_refresh = []
    for acct in self.account_list:
        accounts_to_refresh.append(acct.host_acct_id)

    self.set_hq_commands(
        HqCommands(
            HqCommands.AccountReloadType.FROM_HOST,  # Host means Core in this case
            accounts_to_refresh
        )
    )
    return html

You are returning your HTML as you normally would, but calling self.set_hq_commands will inject an appropriately formatted {hq_commands_xml} string into Step 3 above.

Note

You cannot utilize the refreshed accounts in the same call in which self.hq_commands is set. The accounts are not refreshed until the method is returned. A common mistake is try to act on the refreshed account list during the same call in which self.hq_commands is set. Until that call is returned, HQ has not been given the instruction to refresh the accounts from the core.

HQ Timing Constraint

HQ processes HqCommands asynchronously — the account reload from the Core does not happen instantly. By the time your frontend code receives the response and proceeds to clear the frontend cache, HQ may still be in the process of reloading accounts. If the frontend re-fetches account data before HQ has finished, the response will still contain stale data.

This is a known timing constraint. In practice, it means that account balances may not update on the first attempt and may require a short delay or a subsequent refresh to reflect the latest data. Consider adding a brief delay before clearing the frontend cache to give HQ additional time to complete the reload.

Caliper API Limitation

set_hq_commands() is only available on handlers that extend Q2HqRequestHandler (or its subclasses like Q2TectonClientRequestHandler and Q2TectonServerRequestHandler). Handlers that extend Q2BaseRequestHandler directly, such as the Caliper API handler, do not have access to set_hq_commands() and cannot trigger an account refresh.

If your workflow involves the Caliper API and needs accounts refreshed afterward, you will need to make a separate call from your frontend to an HQ-facing extension route that triggers the HqCommands. For example, your extension could have a dedicated refresh_accounts route that only sets HqCommands, which can be called via requestExtensionData from the frontend after the Caliper API workflow completes.

Frontend Process

After initiating the HqCommand on the backend to refresh accounts in HQ, you need to clear the frontend cache in UUX so that fresh data is fetched on the next request. There are two Tecton capabilities available for this: clearCache and notifyRefetchAccounts.

clearCache

clearCache clears the frontend HTTP data cache for entries matching a given prefix. When used with the account cache prefix, it also notifies the platform that account data needs to be refreshed.

tecton.actions.clearCache('mobilews/accounts');

The correct cache key for refreshing account balance data is mobilews/accounts. Other cache keys are valid for their own purposes (e.g., clearing account group data) but will not trigger an account refresh.

Extensions can listen for cache clear events using tecton.sources.cacheCleared:

tecton.sources.cacheCleared('mobilews/accounts', function() {
    // React to accounts being cleared from the cache
});

notifyRefetchAccounts

notifyRefetchAccounts is specifically designed for account refresh scenarios. In addition to clearing the account data from the frontend cache, it also clears the transfer cache.

tecton.actions.notifyRefetchAccounts();

Note

notifyRefetchAccounts does not trigger tecton.sources.cacheCleared events. If your extensions need to respond to cache clear notifications, use tecton.sources.refetchRequired instead:

tecton.sources.refetchRequired('mobilews/accounts', function() {
    // React to account data being invalidated
});

Which to Use

Both capabilities clear the frontend account cache and notify the platform that account data should be re-fetched. The key differences are:

  • Use clearCache('mobilews/accounts') when your extensions need to receive cacheCleared events, or when you need to clear cache entries for a custom prefix beyond account data.

  • Use notifyRefetchAccounts() when your workflow involves transfers and you need the transfer cache cleared as well.

  • Both can be called together if you need the benefits of each.

Both capabilities also notify extensions listening via tecton.sources.refetchRequired.

Dashboard Behavior

When either clearCache('mobilews/accounts') or notifyRefetchAccounts() is called while the user is on the landing page, the account list will update in-place without requiring a page navigation. However, this is subject to the HQ timing constraint described above — if HQ has not finished reloading accounts from the Core, the in-place update will display stale data.

Navigating away from and back to the landing page also triggers a fresh data fetch, but is equally subject to this timing constraint.

Examples

Here’s an example of a possible workflow that can be applied to both Server Side Rendered (SSR) and Client Side Rendered (CSR) extensions:

function clickHandler(event) {
    tecton.connected.then(() => {
        // First, call a route in your extension that triggers the HqCommand to refresh accounts
        tecton.sources.requestExtensionData(
            {
                route: 'submit'
            }
        ).then((xhr) => {
            // Once the backend responds, clear the frontend cache
            tecton.actions.notifyRefetchAccounts();
        });
    });
}

const myButton = document.getElementById("my-button");
myButton.addEventListener("click", clickHandler);

Another example could be to add a script tag to the HTML template being returned:

<script>
    tecton.connected.then(() => {
        tecton.actions.notifyRefetchAccounts();
    });
</script>

UUX Payload Script Pattern

Account refresh can also be triggered from a UUX Payload Script. A common use case is refreshing accounts after an SSO overpanel closes (e.g., after a third-party transfer). The payload script listens for the OVERPANEL_CLOSED event, calls the backend to trigger the HqCommand, and then clears the frontend cache.

For a full code example of this pattern, including cache invalidation and platform event filtering, see the Cache Invalidation section of the UUX JavaScript Payload guide.