Skip to main content
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. Every hook returns isLoading: boolean and error: Error | null — see 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
  • customerCustomer | null — the customer record, or null while loading. Identity, locale, structured billing address, tax fields, defaultPaymentMethodId, status, metadata, timestamps. Edit it with update() below.
  • entitlementsRecord<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 — 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.
  • payInvoice(invoiceId, options?) — mint a hosted invoice-payment link. See Invoices.
  • isUpdatingbooleantrue while an update() mutation is in flight.
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
featureSlug
string
required
The feature’s stable slug.
options.requiredBalance
number
For metered/credit features, the amount the customer must have available for allowed to be true. Defaults to 1.
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.
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
input
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.
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.
  • 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.
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

Entitlements & gates

Typed entitlement hooks and declarative gate components — all served from the useCustomer cache.

Subscriptions

List, read, create, and change the customer’s subscriptions.

Invoices

List invoices, preview renewals, and collect payment.

Payment methods

Capture, list, replace, and detach payment methods.