Skip to main content
Belongs to the Wallet group. Render <DepositElement /> inside it (React), or call wallet.create('deposit', { … }) on the handle (vanilla) — consumer props and on<Event> callbacks both go in the create options / JSX props.
This element can be mounted inline (create) or opened as a modal overlay (createOverlay).

Preview

A live, interactive demo of this element with sample data:

Usage

Props

string
Prefill the amount and make it read-only — for flows that already know what is owed. An amount at or below zero, or above 9,999,999, is ignored. Defaults to "".
boolean
Offer the crypto rail when the account has a deposit address. Defaults to true.
boolean
Offer the bank-transfer rail when the account has wire instructions. Defaults to true.
DepositSavedCard[]
Cards you already hold for this payer, rendered as funding rows. Choosing one emits cardDepositRequested with the amount — the element never charges a card. Defaults to [].
boolean
Add an “Add card” row that emits addCardRequested so you can open your own card-collection flow. Defaults to false.
boolean
Offer a “Platform balance” row that emits platformBalanceSelected immediately, with no amount step. Defaults to false.
DepositCardFee | null
Processing fees to preview under the amount when a card row is selected. percentageFee is in percentage POINTS (2.9 is 2.9%); fixedFee and radarFee are major units (0.3 is $0.30). Defaults to null.
string
Preselect a rail by id (bank, crypto, platform_balance, or a saved card id). Continue stays disabled while that rail is not yet offered, rather than funding through another one. Defaults to "".
boolean
Emit bankSelected and stay on the amount screen instead of showing the wire fields — for hosts that run their own step (a verification, an onboarding) first. Because that host owns the rail, the row is then offered even before the account has instructions to show. Defaults to false.
boolean
Show an “I have deposited my funds” button on the crypto screen that emits depositConfirmed, so you can start watching for the transfer. Defaults to false.
"amount" | "crypto" | "bank"
Open straight onto a rail instead of the picker. crypto and bank need no amount; their back button emits dismissed because there is no picker behind them. Defaults to "amount".

Events

Pass a callback in the create options (or React prop) to receive these.

onDepositInitiated

The payer confirmed an amount and a rail. Fires for every rail, before any instructions render — the analytics/funnel hook. Signature: ((payload: { method: "crypto" | "bank" | "card" | "platform_balance"; amount: number; currency: string; paymentMethodId?: string | undefined; }) => void)

onCardDepositRequested

A saved card was chosen. Charge it on your side, then call showStep({ step: "amount" }) to return the element to the picker. Signature: ((payload: { amount: number; currency: string; paymentMethodId: string; }) => void)

onAddCardRequested

The “Add card” row was picked — open your card-collection flow. Signature: ((payload: Record<string, never>) => void)

onBankSelected

The bank rail was chosen while deferBankToHost is set — run your step, then show the fields yourself or call showStep({ step: "bank" }). Signature: ((payload: Record<string, never>) => void)

onPlatformBalanceSelected

The platform-balance row was picked. It carries no amount — your own screen collects that. Signature: ((payload: Record<string, never>) => void)

onDepositConfirmed

The payer said they sent the crypto. since is a unix-seconds floor to start matching incoming transfers from (it looks slightly back in time, so a transfer sent moments before the click still matches). Signature: ((payload: { network: string; token: string; networkLabel: string; since: number; }) => void)

onStepChanged

The visible screen changed. Signature: ((payload: { step: "amount" | "crypto" | "bank"; }) => void)

onDismissed

The payer backed out of a rail the element was opened directly onto — close the surface holding it. Signature: ((payload: Record<string, never>) => void)

onLoaderStart

Fired the moment the element’s own loading skeleton has painted inside its frame — the earliest point a consumer-managed loading state can hand off without ever exposing a blank. Always precedes onReady; most consumers only need onReady. Signature: (() => void)

onReady

Fired once the element has booted and painted its first complete frame. Signature: (() => void)

onError

Fired when the element fails to load or crashes; the element shows its own error fallback. message is human-readable; framework refusals also carry code (e.g. HOST_SOURCE_FAILED, with sourceKey naming the failed hostState key) so hosts can switch on codes, never message text. Signature: ((e: { message: string; code?: string | undefined; sourceKey?: string | undefined; }) => void)

Methods

Call these on the element handle — the return of create (vanilla) or the component ref (React).

showStep

Move the element to a screen. { step: "amount" } is how you hand control back after settling a card or platform-balance deposit on your side. Signature: (input: { step: "amount" | "crypto" | "bank"; }) => Promise<void>

refresh

Re-resolve the account’s funding rails. Call it after anything on your side changes what the account can offer — finishing bank onboarding, for instance — so the new rail appears without waiting for the cache to expire. Signature: () => Promise<void>

mount

Place the element on the page: appends its container to target (a CSS selector or an element) and starts loading. Nothing renders until this is called. React consumers never call it — the component mounts itself. Signature: (target: string | HTMLElement) => void

destroy

Remove the element from the page and release its frame and subscriptions. Safe to call more than once. React consumers never call it — unmounting the component does it. Signature: () => void

update

Change this element’s consumer props after mount — it re-renders with the merged props. React consumers never call it — updating the JSX props does the same. Signature: (options: Partial<DepositElementProps>) => void

Styling

Each part below is a stable class name — safe to depend on. Restyle a part by mapping its class to a style declaration object under appearance.classes (properties camelCase or kebab-case, values as strings with units — the same shape as React’s style prop). The element renders in its own frame, so page stylesheets can’t reach it: these declarations are sanitized against a safe-property allowlist and injected inside the frame for you.
In React, pass the same object as the appearance prop on <Wallet>; appearance also applies globally at WhopElements({ appearance }).