Skip to main content

Respond to RFIs

Use this component to show a compliance Request for Information (RFI) form in your platform. The form is tied to one payout transaction, or to a customer onboarding RFI. It supports customer mode and agent-on-behalf mode.

An RFI appears after a payout, when Nium's compliance engine flags a transaction for more information. The SDK renders the form in a secure iFrame. Nium's backend decides the questions and required fields, not the SDK.

This component:

  • Binds each transaction RFI form to one transactionId. If the transaction has no open RFI, the hosted form shows an error to the user. Set rfiType: 'customer_onboarding' to open a KYC/KYB onboarding RFI instead.
  • Renders the questions, field types, and validations from Nium's backend schema. The compliance engine generates them at runtime, so you can't preview or mock them offline.
  • Lets users attach files, such as ID scans and invoices, to the response. Uploads go through Nium's backend.
  • Supports agent mode, so a bank operator can complete the form for a customer.

Live preview​

This is the component running against the Nium sandbox with test data. Answer the questions and upload a document to try the RFI form.

Live preview · sandbox

Before you begin​

  • Complete the Quick start to set up PKCE authorization. Use the scope ['rfi-form'] when your server requests the authorization code. The same scope covers transaction and customer onboarding RFIs.
  • For a transaction RFI, have these three values for the flagged transaction: customerHashId, walletHashId, and rfiAuthCode. Store them when you receive the transaction.rfi_required webhook. See The rfiAuthCode field.
  • Make sure the transaction has an open RFI. The SDK can't render a form without a live compliance request. To test in QA, create a transaction that triggers an RFI, or ask your Nium implementation partner for a test systemReferenceNumber.
  • Set customizations.minHeight to 600 or more. After the RFI questions load, the iFrame no longer auto-resizes, so minHeight sets its visible height.
Check the scope string

Use rfi-form, not transaction-history-form. The second one is the scope for a different element, and using it is a common mistake.

Quick example​

After you call init(), create the rfiForm element with all three required fields, mount it, and destroy it when the user closes your RFI panel.

index.html
<div id="rfi-root"></div>
client.ts
const { createElement } = await import('@nium/nium-sdk')

const element = await createElement('rfiForm', {
customerHashId, // required
walletHashId, // required
rfiAuthCode, // required: same value as systemReferenceNumber
customizations: { minHeight: 600 },
})

element.on('ready', () => hideLoadingSpinner())
element.on('error', (e) => console.error(e.error.code, e.error.message))
// No submit or cancel events reach your page. See Events.

element.mount('#rfi-root')

// Your own close control destroys the element and checks completion server-side
closeButton.addEventListener('click', () => {
element.destroy() // an RFI accepts one submission
refreshRfiStatus()
})

Get a fresh authorization code right before each init() call. For a transaction RFI, the SDK checks customerHashId, rfiAuthCode, and walletHashId before it creates the element. If any value is missing or empty, createElement() rejects with MISSING_REQUIRED_OPTION.

The rfiAuthCode field​

rfiAuthCode is one value that has different names in different places.

NameWhere it appears
rfiAuthCodeField name in NiumRfiFormOptions (SDK parameter).
transactionIdField name in Nium API responses and your internal systems.
systemReferenceNumberField name in Nium webhook payloads, for example the transaction.flagged webhook.
authCodeField name in the RFI session that the hosted form creates (internal).

When your webhook handler receives a transaction.rfi_required event, pass the systemReferenceNumber from the payload as rfiAuthCode. Store it with the customerHashId and walletHashId. You need all three to load the form.

app/api/webhooks/nium/route.ts
export async function POST(req: Request) {
const payload = await req.json()

if (payload.event === 'transaction.rfi_required') {
await db.rfiRequests.create({
transactionId: payload.systemReferenceNumber, // save as rfiAuthCode
customerHashId: payload.customerHashId,
walletHashId: payload.walletHashId,
status: 'pending',
})
await notifyCustomer(payload.customerHashId, 'Action required: information needed for your transfer')
}

return Response.json({ ok: true })
}

// Later, when the customer selects "Provide information", load the stored record
// and pass its three values to createElement('rfiForm', ...).

Options​

createElement('rfiForm', options) accepts these options (type NiumRfiFormOptions). For a transaction RFI, three fields are required, and createElement() rejects if any is missing.

OptionTypeDescription
customerHashIdstringRequired. Nium customer ID of the transaction owner. Must match the customer on the flagged transaction.
rfiType'transaction' | 'customer_onboarding'Which RFI to open. Defaults to 'transaction'. 'customer_onboarding' opens a KYC/KYB onboarding RFI and needs only customerHashId. Don't pass rfiAuthCode or walletHashId with it. An invalid value throws INVALID_RFI_TYPE.
rfiAuthCodestringRequired for transaction RFIs. The RT number of the flagged transaction. Same as systemReferenceNumber and transactionId. See The rfiAuthCode field.
walletHashIdstringRequired for transaction RFIs. Nium wallet of the flagged transaction. Available in the webhook payload.
onBehalfbooleantrue for agent or bank operator mode. Requires email. See Agent mode.
emailstringAgent's email address. Required when onBehalf: true. Identifies the operator who completed the form.
themeNiumThemeVisual overrides. Has no effect on this component. See Theming.
customizations{ minHeight?: number }Sets the iFrame's visible height. Pass minHeight: 600 or more so multi-question forms, upload areas, and validation messages aren't truncated. The form scrolls inside the iFrame beyond that height.

Agent mode​

Banks and financial institutions can complete an RFI for their customers. Set onBehalf: true and the agent's email to turn on this mode.

  • Standard mode (default). The end customer completes the RFI. onBehalf is false or omitted. No extra fields are needed.
  • Agent mode. A bank operator completes the form. Nium records the operator's email in the audit trail and shows a modified form that indicates the agent context.
Agent mode
await createElement('rfiForm', {
customerHashId,
walletHashId,
rfiAuthCode,
onBehalf: true,
email: 'agent@yourbank.com', // recorded in the audit trail
customizations: { minHeight: 600 },
})

Events​

Call element.on(eventName, handler) after createElement(), before or after mount(). Each call returns a function that removes that listener. Store it and call it on teardown.

  • ready: The hosted page loaded and connected to the SDK, before the RFI questions appear. The iFrame shows its own loading spinner until then. No payload.
  • error: The SDK or iFrame failed to load, the auth code exchange failed, a parameter is missing, or the RFI session can't be created (SESSION_CREATION_FAILED). Errors inside the RFI form itself, for example no open RFI on the transaction, appear to the user but aren't relayed to your page. Always attach this handler. Payload: { error: { message: string, code: string } }.
No submit, cancel, or resize events

After loading, the iFrame switches to Nium's RFI app on a different origin. The SDK accepts messages only from the hosted-form origin. So submit, cancel, and resize never reach your page, and element.submit() isn't supported. Detect a completed RFI on your server, through the transaction status or a webhook. Give users your own control to close the RFI panel.

Common errors and fixes
Error or symptomCauseFix
createElement() missing required option: rfiAuthCoderfiAuthCode is an empty string or undefined.Check for empty values in your UI before you call createElement().
createElement() missing required option: walletHashIdwalletHashId is an empty string or undefined.Store walletHashId with systemReferenceNumber in your webhook handler.
Form loads but shows no RFI foundThe transaction has no open RFI, or the RFI was already submitted.Check the transaction status through the Nium API. An RFI accepts one submission.
Form is truncated or cut offminHeight isn't set, or the container is too small.Add customizations: { minHeight: 600 } or more. The form scrolls inside the iFrame past that height.
Wrong scope errorYou passed transaction-history-form instead of rfi-form.Check the literal string in your auth call: "scopes": ["rfi-form"].
Auth code expired or invalidThe auth code was already used or is older than its expiresInSecs window, typically 300 seconds.Get a new auth code right before each init() call.

Clean up​

One submission per RFI

An RFI accepts one submission. There's no submit event to hook. Call element.destroy() from your own close control, or when your backend reports the RFI as answered, then show your confirmation. Don't remount the same instance. Don't load a new RFI on a transaction that's already answered.

  • element.destroy(): Removes the iFrame and all listeners permanently. Create a new element to show another form.
  • element.unmount(): Removes the iFrame and keeps the instance. Call mount() to show it again. It's rarely used for RFI because the form accepts one submission.

Theming​

Theming isn't supported

NiumTheme isn't supported on this component. NiumRfiFormOptions accepts the theme option without an error, but it has no visual effect. This component uses a separate compliance rendering layer that doesn't expose theming parameters.

For details, see Theme customization.

Next steps​

LLM-ready documentation:: llms.txt and llms-full.txt
Was this page helpful?