> ## Documentation Index
> Fetch the complete documentation index at: https://docs.whop.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SendElement

> Sends money from an account to a recipient — a user, another business, or a public claim link anyone can redeem. Renders its own recipient search (team + other businesses the account can reach, or a live search once the viewer types) resolved from the account id with no credentials beyond the account's own token. Needs an `accessToken` scoped to `payout:withdraw_funds`; recipient search additionally needs `company:authorized_user:read` and `member:basic:read`, and claim links need `airdrop_link:manage` — a host without one of those scopes should turn off the matching prop rather than leave a row that will 403.

<Info>**Upcoming** — generated from the latest merged element source; documents unreleased development. Use the channel picker at the top of the sidebar for the docs of a published release.</Info>

*In development — not yet part of a stable release.*

Belongs to the [`Wallet`](/elements/upcoming/wallet/overview) group. Render `<SendElement />` inside it (React), or call `wallet.create('send', { … })` on the handle (vanilla) — consumer props and `on<Event>` callbacks both go in the create options / JSX props.

<Note>This element can be mounted **inline** (`create`) or opened as a **modal** overlay (`createOverlay`).</Note>

## Preview

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

<div data-whop-demo-shell style={{ position: "relative", minHeight: "320px", transition: "min-height 200ms ease" }}>
  <div data-whop-demo-skeleton style={{ position: "absolute", inset: "0", borderRadius: "12px", background: "rgba(140, 140, 140, 0.12)", pointerEvents: "none", transition: "opacity 200ms ease" }} />

  <div data-whop-demo-native="element:wallet/send" data-whop-elements-version="" style={{ position: "relative" }} />
</div>

## Usage

<div data-whop-usage="wallet/send">
  <CodeGroup>
    ```tsx React theme={null}
    import { WhopElements, Wallet, SendElement } from "@whop/elements-react";
    import { loadWhop } from "@whop/elements";

    function Example() {
      return (
        <WhopElements elements={loadWhop()}>
          <Wallet /* options */>
            <SendElement onStepChanged={(payload) => console.log("stepChanged", payload)} onSendCompleted={(payload) => console.log("sendCompleted", payload)} onLinkCreated={(payload) => console.log("linkCreated", payload)} onDone={(payload) => console.log("done", payload)} />
          </Wallet>
        </WhopElements>
      );
    }
    ```

    ```html Vanilla theme={null}
    <script src="https://js.whop.cloud/elements/amber/elements.js" data-whop-elements></script>
    <script type="module">
      const wallet = window.WhopElements().wallet.create({ /* options */ });
      wallet.create('send', {
        onStepChanged: (payload) => console.log("stepChanged", payload),
        onSendCompleted: (payload) => console.log("sendCompleted", payload),
        onLinkCreated: (payload) => console.log("linkCreated", payload),
        onDone: (payload) => console.log("done", payload)
      }).mount('#wallet-send');
    </script>
    ```
  </CodeGroup>
</div>

## Props

<ResponseField name="accessToken" type="string">
  A scoped token for the privileged read/write — needs `payout:withdraw_funds` (plus `company:authorized_user:read` and `member:basic:read` for recipient search, `airdrop_link:manage` for claim links). Omitted, the read carries the viewer's own session, which only answers same-origin.
</ResponseField>

<ResponseField name="canSearchRecipients" type="boolean">
  Off, only the team/other-business list shows — no search box. For a host that knows the viewer lacks `member:basic:read`. Defaults to `true`.
</ResponseField>

<ResponseField name="canCreateLink" type="boolean">
  Off, the "Send via link" row is hidden. For a host that knows the viewer lacks `airdrop_link:manage`. Defaults to `true`.
</ResponseField>

<ResponseField name="initialRecipient" type="SendRecipient | null">
  Skip the picker and open straight onto this recipient's amount screen — for a "pay this person" action row. No back button is shown in that case, matching there being no picker behind it. Defaults to `null`.
</ResponseField>

<ResponseField name="initialCurrency" type="string">
  Preselect a currency in the amount screen's picker. Falls back to `currency`, then USD. Defaults to `""`.
</ResponseField>

### Direct mode only

*These props exist only on the in-process (direct-mode) component — the hosted embed never carries them, and the element renders without them.*

<ResponseField name="elevationHandler" type="direct mode only">
  Called when a transfer needs step-up verification — resolve it once the viewer completes that, and the send retries automatically. Direct-mode only; a host that omits it just sees the transfer fail on a step-up challenge.
</ResponseField>

## Events

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

### `onStepChanged`

The visible screen changed.

**Signature:** `((payload: { step: "enter_amount" | "select_recipient" | "create_link" | "link_success" | "success"; }) => void)`

### `onSendCompleted`

A transfer succeeded. Refresh anything on your side reading the account's balance or activity.

**Signature:** `((payload: { recipient: SendRecipient; amount: number; currency: string; }) => void)`

### `onLinkCreated`

A claim link was created. Refresh anything on your side reading the account's balance.

**Signature:** `((payload: { claimUrl: string; amount: number; redeemableCount: number; }) => void)`

### `onDone`

The viewer clicked "Done" on a success screen — 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).

### `refresh`

Re-fetch the account's balances and recipient list. Call it after anything on your side changes what it can offer.

**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<SendElementProps>) => 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.

| Class               | Targets                                      |
| ------------------- | -------------------------------------------- |
| `.whop-SendSurface` | The send element root — one screen at a time |

```ts theme={null}
const wallet = whop.wallet.create({
  appearance: {
    classes: {
      'whop-SendSurface': { borderRadius: '8px', fontWeight: '600' }
    }
  }
});

// restyle live at any point — the same shape through update()
wallet.update({
  appearance: { classes: { 'whop-SendSurface': { fontWeight: '700' } } }
});
```

In React, pass the same object as the `appearance` prop on `<Wallet>`; `appearance` also applies globally at `WhopElements({ appearance })`.
