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

# Customer

> Read the current customer and their entitlements, and run core account + billing actions.

import LearnHooksTip from '/snippets/learn-hooks-tip.mdx';

`useCustomer` is the root data hook for the customer portal. It loads the customer record and their full entitlement map in one place, exposes a synchronous cache-based `check()` for gating UI, and bundles the self-service write actions: update the account, start a hosted payment-method setup, or pay an invoice.

<LearnHooksTip />

Every hook returns `isLoading: boolean` and `error: Error | null` — see [Introduction](/react/introduction). The sections below list each hook's specific returns.

## useCustomer

Loads the customer and their entitlements in a single fetch, and returns the core account + billing actions on top of them. Takes no arguments; the customer comes from `<UnitPayProvider>` context.

**Returns**

* `customer` — `Customer | null` — the customer record, or `null` while loading. Identity, locale, structured billing address, tax fields, `defaultPaymentMethodId`, `status`, `metadata`, timestamps. Edit it with `update()` below.
* `entitlements` — `Record<featureSlug, EntitlementValue>` — every feature the customer has access to, keyed by slug. This is the single fetch that powers [entitlement gates and the typed `use*Entitlement` hooks](/react/entitlements-and-gates) — one HTTP call serves the whole tree. Each value is discriminated by `type` (`boolean` / `metered` / `credit` / `config` / `enum`).
* `check(featureSlug, options?)` — synchronous, cache-based access check (see below).
* `update(input)` — patch the customer record (see below).
* `setupPayment(options?)` — start a hosted payment-method setup. See [Payment methods](/react/payment-methods).
* `payInvoice(invoiceId, options?)` — mint a hosted invoice-payment link. See [Invoices](/react/invoices).
* `isUpdating` — `boolean` — `true` while an `update()` mutation is in flight.

```tsx theme={null}
import { useCustomer } from '@unitpay/react';

export default function AccountName() {
  const { customer, isLoading, error } = useCustomer();
  if (isLoading) return <div>Loading…</div>;
  if (error) return <div>Couldn’t load your account.</div>;
  return <div>{customer?.name}</div>;
}
```

### `check(featureSlug, options?)`

Synchronous, cache-based access check. Reads the already-loaded `entitlements` map and returns `{ allowed, deniedReason }` — no network call. Use it to gate UI affordances inline. For metered and credit features, pass `{ requiredBalance }` to require more than the default of 1 unit/credit.

`deniedReason` is one of `not_loaded`, `no_entitlement`, `usage_exceeded`, or `credit_exhausted`.

**Parameters**

<ParamField body="featureSlug" type="string" required>
  The feature's stable slug.
</ParamField>

<ParamField body="options.requiredBalance" type="number">
  For metered/credit features, the amount the customer must have available for `allowed` to be `true`. Defaults to `1`.
</ParamField>

<Note>
  `check()` reads the local entitlement cache for instant UI decisions. Pair it with a server-side check (or `useMeteredEntitlement({ requestedUsage })`) before granting access to anything that must be secure.
</Note>

```tsx theme={null}
import { useCustomer } from '@unitpay/react';

export default function ExportButton() {
  const { check } = useCustomer();
  const { allowed, deniedReason } = check('csv-export-ftr');
  return (
    <button disabled={!allowed}>
      {allowed ? 'Export CSV' : `Unavailable (${deniedReason})`}
    </button>
  );
}
```

### `update(input)`

Patch the customer record (the portal's Account Settings tab). Returns the updated `Customer` and seeds it into the cache, so the UI reflects the new values without a refetch. Server-side validation applies — an invalid email throws via the SDK error model. Track the in-flight state with `isUpdating`.

**Parameters**

<ParamField body="input" type="UpdateCustomerInput" required>
  Partial customer fields to patch. Supports identity (`name`, `email`, `phone`, `billingEmail`, `invoiceEmails`, `invoiceRemindersEnabled`, `legalName`, `taxId`, `registrationNumber`, `domain`), locale (`language`, `timezone`, `country`), the structured billing address (`addressLine1`/`addressLine2`/`addressCity`/`addressRegion`/`addressPostalCode`/`addressCountry` — pass `null` to clear an address field), and `metadata`.
</ParamField>

```tsx theme={null}
import { useCustomer } from '@unitpay/react';
import { useState } from 'react';

export default function BillingEmailForm() {
  const { customer, update, isUpdating } = useCustomer();
  const [email, setEmail] = useState(customer?.billingEmail ?? '');

  return (
    <form
      onSubmit={async (e) => {
        e.preventDefault();
        await update({ billingEmail: email });
      }}
    >
      <input value={email} onChange={(e) => setEmail(e.target.value)} />
      <button disabled={isUpdating}>{isUpdating ? 'Saving…' : 'Save'}</button>
    </form>
  );
}
```

### `setupPayment(options?)` and `payInvoice(invoiceId, options?)`

Convenience actions for the two hosted flows the account page needs:

* **`setupPayment(options?)`** mints a hosted payment-method-update link and, by default, redirects the browser to it. Pass `{ redirect: false }` to receive `{ token, hostedUrl }` without navigating. For the full card-capture surface (inline `<PaymentForm>`, replace, detach), see [Payment methods](/react/payment-methods).
* **`payInvoice(invoiceId, options?)`** mints a hosted invoice-payment link for the given invoice and redirects to it; `{ redirect: false }` returns `{ token, hostedUrl }` without navigating. For inline invoice payment and settlement handling, see [`usePayInvoice`](/react/invoices).

```tsx theme={null}
import { useCustomer } from '@unitpay/react';

export default function AccountActions({ invoiceId }: { invoiceId: string }) {
  const { setupPayment, payInvoice } = useCustomer();
  return (
    <>
      <button onClick={() => setupPayment()}>Add a card</button>
      <button onClick={() => payInvoice(invoiceId)}>Pay now</button>
    </>
  );
}
```

## See also

<CardGroup cols={2}>
  <Card title="Entitlements & gates" icon="shield-halved" href="/react/entitlements-and-gates">
    Typed entitlement hooks and declarative gate components — all served from the `useCustomer` cache.
  </Card>

  <Card title="Subscriptions" icon="repeat" href="/react/subscriptions">
    List, read, create, and change the customer's subscriptions.
  </Card>

  <Card title="Invoices" icon="file-invoice" href="/react/invoices">
    List invoices, preview renewals, and collect payment.
  </Card>

  <Card title="Payment methods" icon="credit-card" href="/react/payment-methods">
    Capture, list, replace, and detach payment methods.
  </Card>
</CardGroup>
