Wallet & Accounts
Use this component to show a customer's Nium multicurrency wallet in your application. It shows the total balance, a card for each currency, and the account details for each currency. Customers can also withdraw money to a beneficiary and move funds between currencies without leaving your page.
The createElement type is wallet and the role is mcy-wallet-dashboard. The component is the customer's wallet home. It doesn't onboard customers or create beneficiaries.
The component:
- Shows the total balance in USD and a card with the balance for each currency.
- Shows account numbers, routing details, and other payment instructions for the selected currency. Customers can copy each field, copy all details, or download a PDF.
- Lets customers add a new account and rename an account with a nickname.
- Opens the payout flow from Withdraw Money and the currency conversion flow from Move Funds. Both run inside the same iFrame, with a back-to-wallet control.
- Hides any section or button through
customizations.
Configurations
The component has one createElement type, wallet. Nearly every flag is on by default, so you mostly turn items off. Feature flags lists every flag and the two opt-in exceptions. These four configurations are common.
A dedicated wallet screen with balances, account management, and built-in actions in one place.
no overrides neededEvery section is shown. Keep all flags at their defaults.
A compact balance summary for an existing app screen.
Set these to false:
showAddCurrencyAccount: falseshowAddAccount: falseshowWithdrawButton: falseshowFXConversionButton: falseBalances and account details stay visible. Account management and money movement are hidden.
Let customers open and manage currency accounts, without moving money.
Set these to false:
showWithdrawButton: falseshowFXConversionButton: falseAdd, rename, copy, and PDF download stay on. Withdraw and move funds are hidden.
A consumer wallet screen focused on moving money, not managing accounts.
Set these to false:
showAddCurrencyAccount: falseshowAddAccount: falseBalances, withdraw, and move funds stay on. Account-opening controls are hidden.
Live preview
This is the component running against the Nium sandbox with test data. Select Withdraw Money, Move Funds, or a currency card to try the flows.
Before you begin
- Complete the Quick start to set up PKCE authorization. Use the scope
["mcy-wallet-dashboard"]when your server requests the authorization code. Confirm the role name with your Nium integration contact for your environment. - Have the
customerHashIdof the customer whose wallet you show. The wallet, its currencies, and its accounts all resolve from this identifier. You don't pass a wallet identifier.
The mcy-wallet-dashboard role covers everything in the dashboard. That includes the inline Withdraw Money and Move Funds actions and beneficiary addition during withdraw. You need the conversionForm role only if you mount Move Wallet Funds as a standalone component outside the dashboard.
Quick example
After you call init(), create the wallet element, mount it, and clean up when you're done.
- JavaScript
- React
<div id="wallet-container"></div>
const { createElement } = await import('@nium/nium-sdk')
const element = await createElement('wallet', {
customerHashId: '<customer-hash-id>', // required
customizations: { // optional
showTransactionHistory: true,
},
})
element.on('ready', () => setLoading(false))
element.on('submit', (e) => refreshAccountState(e.result.transactionId))
element.on('error', (e) => showErrorToast(e.error.message))
element.mount('#wallet-container')
// When you're done, for example on a route change
element.destroy()
import { useEffect } from 'react'
export function WalletDashboard({ customerHashId }: { customerHashId: string }) {
useEffect(() => {
let element: { destroy(): void } | undefined
let cancelled = false
;(async () => {
const { createElement } = await import('@nium/nium-sdk')
element = await createElement('wallet', {
customerHashId,
customizations: { showTransactionHistory: true },
})
if (cancelled) return element.destroy()
element.on('submit', (e) => refreshAccountState(e.result.transactionId))
element.on('error', (e) => showErrorToast(e.error.message))
element.mount('#wallet-container')
})()
return () => {
cancelled = true
element?.destroy()
}
}, [customerHashId])
return <div id="wallet-container" />
}
Options
customerHashId is required. payout, customizations, and theme are optional.
interface NiumWalletProperties {
customerHashId: string; // Required: customer whose wallet is shown
payout?: NiumWalletPayoutDefaults; // Optional: defaults for the embedded withdraw flow
customizations?: NiumWalletCustomizations; // Optional: feature flags and sizing
theme?: NiumTheme; // Optional: custom theming
}
Feature flags
NiumWalletCustomizations hides any section or button. Set a flag to false to hide it. All flags default to true except showTransactionHistory and showInlineAccountDetails, which are opt-in.
| Flag | Default | Description |
|---|---|---|
minHeight | 400 | Minimum iFrame height in px. |
maxHeight | None | Maximum iFrame height. Omit to grow with content. |
showTotalBalanceUSD | true | Total balance (USD equivalent). |
showCurrencyWallets | true | Currency card grid. |
showAccountDetails | true | Account details when the user selects a currency. |
showInlineAccountDetails | false | Details replace the grid instead of opening beneath it. Opt-in. |
showAddCurrencyAccount | true | Add Currency card. |
showAddAccount | true | Add account button. |
showAccountDetailsCopyButton | true | Per-field copy buttons. |
showCopyAllDetailsButton | true | Copy all details button. |
showDownloadPDFButton | true | Download PDF button. |
showWithdrawButton | true | Withdraw Money action. |
showFXConversionButton | true | Move Funds action. |
showTransactionHistory | false | Transaction history section. Opt-in. |
Payout defaults
When the withdraw action is on, NiumWalletPayoutDefaults pre-fills and locks parts of the payout flow it opens. All fields are optional. A value pre-fills the control and makes it read-only.
interface NiumWalletPayoutDefaults {
beneficiaryHashId?: string; // Pre-select and lock the beneficiary
destinationAmount?: string | number; // Fixed destination amount
sourceAmount?: string | number; // Fixed source amount
defaultSourceCurrency?: string; // ISO 4217 code to pre-select
purposeCode?: string; // Pre-select a remittance purpose code
comment?: string; // Pre-fill the comment/notes field
}
destinationAmount and sourceAmount are mutually exclusive. Pass one or the other, not both.
This example sets a default source currency and purpose code, and hides the controls that add accounts.
const element = await createElement('wallet', {
customerHashId,
payout: {
defaultSourceCurrency: 'USD',
purposeCode: 'IR001',
},
customizations: {
showAddCurrencyAccount: false,
showAddAccount: false,
},
})
Events
Listen to events with element.on(eventName, handler). It returns a function that removes that listener. Call it when you remove the component to prevent memory leaks.
ready: The iFrame is fully rendered. Remove loading states or reveal the container.resize: The iFrame content height changed. Use it to size the container when you don't setmaxHeight. Payload:{ height: number }.submit: A payout was submitted from the embedded withdraw flow. Payload:{ result: { transactionId: string } }.error: The token exchange failed, the session expired (AUTH_EXPIRED), the iFrame failed to load, or a payout failed in the embedded withdraw flow. Other dashboard failures, such as a wallet load or an account action, appear inside the iFrame only. Always handle this event. Payload:{ error: { message: string, code: string } }.
submit fires for withdraw onlysubmit fires only when the customer completes a payout through the embedded withdraw flow. A currency conversion from Move Funds returns to the dashboard and refreshes the balances. It doesn't emit submit.
Clean up
Remove the iFrame with destroy() or unmount(). Both remove the iFrame from the DOM and clear all event listeners. The difference is whether you can reuse the instance.
element.destroy(): The instance can't be reused. Use it when you navigate away from the page. To show the dashboard again, create a new element.element.unmount(): Keeps the instance. Use it to hide the dashboard temporarily, for example behind a tab switch. Callelement.mount('#wallet-container')to restore it.
Mount each instance only once at a time.
How the component loads
The component renders Nium's UI inside the iFrame, with no redirect to a hosted form. On load, the iFrame does the following:
- Exchanges the token. It exchanges the PKCE authorization code for an access token through
/api/niam-service/oauth2/token. - Loads the wallet. It loads the customer's wallet and per-currency balances through
GET /api/wallet-service/api/v1/client/{clientId}/customer/{customerId}/wallet. - Loads account details. It loads the virtual accounts for the selected currency through
GET /api/wallet-service/api/v2/client/{clientId}/customer/{customerId}/wallet/{walletHashId}/paymentIds. The same paymentId endpoints create, rename, and add accounts. - Calculates the total balance. It converts each non-USD balance through Nium's exchange-rate API to produce the USD total.
- Runs inline actions. Withdraw Money and Move Funds replace the dashboard with the payout or conversion view in the same iFrame. A back control returns to the wallet and refreshes the balances.
Also note:
- The iFrame applies feature flags. Hiding a section also skips the calls that populate it.
- If the customer has no beneficiary, the withdraw action routes into beneficiary onboarding instead of failing.
- The component shows a loading state during the token exchange and wallet lookup.
- When a currency has transactions that await a Request for Information (RFI) response, its currency card shows an RFI required badge. The badge is visual only, and the component sends no event to your page. Use the RFI component or your RFI webhooks to act on it.
Troubleshooting
- Empty dashboard. Check that the
customerHashIdis correct and that the customer has an active multicurrency wallet. - Total balance missing. The USD total comes from live exchange rates. If a rate is unavailable for a held currency, the total is omitted. It is also hidden when
showTotalBalanceUSDisfalse. - Transaction history not showing.
showTransactionHistoryis opt-in and defaults tofalse. Set it totrue. - Withdraw opens beneficiary onboarding. The customer has no beneficiary. Complete onboarding first, or pass
payout.beneficiaryHashId. - Component not rendering. Check the browser console for
errorevents. Make sure the container element exists before you mount. - Incorrect role. Confirm with your Nium integration contact that you use the role name
mcy-wallet-dashboardfor your environment.
For more help, contact your Nium integration team.
Theming
Pass a NiumTheme object in the theme option to control fonts, colors, input styles, and border radius. The Theme customization reference documents all 15 theme properties, a gating matrix, and 4 example themes.
Next steps
- Download statements: let customers download monthly and custom-range account statements. The same
customerHashIdresolves their statements. - Theme customization: match the component to your brand.