> ## 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.

# TaxIdElement

> Collects a business tax registration: a type select carrying every registration the API accepts — labeled the way buyers know them (EU VAT, AR CUIT, US EIN, …) — and a value input whose placeholder follows the selected type's format. The type preselects from the buyer's country when one is given. Collection only: it emits each committed `{ type, value }` and renders whatever refusal the composer passes back — validity is the API's own answer when the registration is written, so the set of accepted registrations grows without an element release.

<Info>**Upcoming.** These docs cover unreleased development, ahead of any published release. 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 [`Payments`](/elements/upcoming/payments/overview) group. Render `<TaxIdElement />` inside it (React), or call `payments.create('taxId', { … })` on the handle (vanilla). Consumer props and `on<Event>` callbacks both go in the create options / JSX props.

## 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:payments/taxId" data-whop-elements-version="" style={{ position: "relative" }} />
</div>

## Usage

<div data-whop-usage="payments/taxId">
  <CodeGroup>
    ```tsx React theme={null}
    import { WhopElements, Payments, TaxIdElement } from "@whop/elements-react";
    import { loadWhop } from "@whop/elements";

    function Example() {
      return (
        <WhopElements elements={loadWhop()}>
          <Payments /* options */>
            <TaxIdElement onChange={(payload) => console.log("change", payload)} />
          </Payments>
        </WhopElements>
      );
    }
    ```

    ```html Vanilla theme={null}
    <script src="https://js.whop.cloud/elements/amber/elements.js" data-whop-elements></script>
    <script type="module">
      const payments = window.WhopElements().payments.create({ /* options */ });
      payments.create('taxId', { onChange: (payload) => console.log("change", payload) }).mount('#payments-taxId');
    </script>
    ```
  </CodeGroup>
</div>

## Props

<ResponseField name="disabled" type="boolean">
  Disables both fields — e.g. while the composer's write of the last committed registration is in flight. Defaults to `false`.
</ResponseField>

<ResponseField name="country" type="string">
  The buyer's ISO2 country, used to preselect the registration type: a country with exactly one accepted registration preselects it (`AR` → `ar_cuit`), EU countries stay on `eu_vat`, and anything else — including the empty default — falls back to `eu_vat`. A selection the buyer has made always outlives a later country change. Defaults to `""`.
</ResponseField>

<ResponseField name="defaultValue" type="{ type: string; value: string; }">
  Seed registration applied once at mount — a stored `{ type, value }` from a resumed session. A `type` outside the accepted set falls back to the country preselect.
</ResponseField>

<ResponseField name="error" type="string">
  A refusal line rendered under the value input — the server refused the committed registration, and the answer belongs beside where the buyer typed it. Empty (default) renders nothing. Defaults to `""`.
</ResponseField>

## Events

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

### `onChange`

A registration was committed — the value field settled (blur or Enter) with something in it, or the type changed while a value was present. Consecutive identical commits fire once. Never fires with an empty value: clearing a stored registration is a composer concern, not a collection one.

**Signature:** `((payload: { taxId: { type: "ad_nrt" | "ao_tin" | "ar_cuit" | "al_tin" | "am_tin" | "aw_tin" | "au_abn" | "au_arn" | "eu_vat" | "az_tin" | "bs_tin" | "bh_vat" | "bd_bin" | "bb_tin" | "by_tin" | "bj_ifu" | "bo_tin" | "ba_tin" | "br_cnpj" | "br_cpf" | "bg_uic" | "bf_ifu" | "kh_tin" | "cm_niu" | "ca_bn" | "ca_gst_hst" | "ca_pst_bc" | "ca_pst_mb" | "ca_pst_sk" | "ca_qst" | "cv_nif" | "cl_tin" | "cn_tin" | "co_nit" | "cd_nif" | "cr_tin" | "hr_oib" | "do_rcn" | "ec_ruc" | "eg_tin" | "sv_nit" | "et_tin" | "eu_oss_vat" | "ge_vat" | "gh_tin" | "de_stn" | "gb_vat" | "gn_nif" | "hk_br" | "hu_tin" | "is_vat" | "in_gst" | "id_npwp" | "il_vat" | "jp_cn" | "jp_rn" | "jp_trn" | "kz_bin" | "ke_pin" | "kg_tin" | "la_tin" | "li_uid" | "li_vat" | "my_frp" | "my_itn" | "my_sst" | "mr_nif" | "mx_rfc" | "md_vat" | "me_pib" | "ma_vat" | "np_pan" | "nz_gst" | "ng_tin" | "mk_vat" | "no_vat" | "no_voec" | "om_vat" | "pe_ruc" | "ph_tin" | "pl_nip" | "ro_tin" | "ru_inn" | "ru_kpp" | "sa_vat" | "sn_ninea" | "rs_pib" | "sg_gst" | "sg_uen" | "si_tin" | "za_vat" | "kr_brn" | "es_cif" | "ch_uid" | "ch_vat" | "tw_vat" | "tj_tin" | "tz_vat" | "th_vat" | "tr_tin" | "ug_tin" | "ua_vat" | "ae_trn" | "us_ein" | "uy_ruc" | "uz_tin" | "uz_vat" | "ve_rif" | "vn_tin" | "zm_tin" | "zw_tin" | "sr_fin" | "xi_vat"; value: string; }; }) => void)`

### `onLoaderStart`

Fired the moment the element's own loading skeleton has painted inside its frame. This is 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, which is the return of `create` (vanilla) or the component `ref` (React).

### `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, and it re-renders with the merged props. React consumers never call it; updating the JSX props does the same.

**Signature:** `(options: Partial<TaxIdElementProps>) => 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-TaxId`           | The tax registration element root             |
| `.whop-TaxIdError`      | The server refusal line under the value input |
| `.whop-TaxIdInput`      | The registration value input                  |
| `.whop-TaxIdLabel`      | The label above the registration value input  |
| `.whop-TaxIdTypeLabel`  | The label above the registration type select  |
| `.whop-TaxIdTypeSelect` | The registration type select                  |

```ts theme={null}
const payments = whop.payments.create({
  appearance: {
    classes: {
      'whop-TaxId': { borderRadius: '8px', fontWeight: '600' },
      'whop-TaxIdError': { borderRadius: '8px', fontWeight: '600' },
      'whop-TaxIdInput': { borderRadius: '8px', fontWeight: '600' },
      'whop-TaxIdLabel': { borderRadius: '8px', fontWeight: '600' },
      'whop-TaxIdTypeLabel': { borderRadius: '8px', fontWeight: '600' },
      'whop-TaxIdTypeSelect': { borderRadius: '8px', fontWeight: '600' }
    }
  }
});

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

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