Files
cfw-autumn/apps/docs/mintlify/react/hooks/useCustomer.mdx
2026-02-16 12:09:51 +00:00

508 lines
13 KiB
Plaintext

---
title: "useCustomer"
description: "Access a customer's state and use it to display information in your React app"
---
import SWRConfigParam from '/snippets/swr-config-param.mdx';
import LearnHooksTip from '/snippets/learn-hooks-tip.mdx';
The `useCustomer` hook provides access to customer data and related operations. You can use it from your frontend to retrieve customer information, manage loading states, and create entities.
<LearnHooksTip />
## Parameters
<ParamField body="expand" type="CustomerExpandOption[]">
Array of additional data to include in the customer response. Options include
`invoices`, `rewards`, `trials_used`, `entities`, `referrals`, `payment_method`.
</ParamField>
<ParamField body="errorOnNotFound" type="boolean">
Whether to throw an error if the customer is not found. Defaults to `false`.
</ParamField>
<SWRConfigParam />
## Returns
### `customer`
The customer object containing all customer data.
```jsx
import { useCustomer } from "autumn-js/react";
export default function CustomerProfile() {
const { customer } = useCustomer({ expand: ["invoices"] });
return (
<div>
<h2>Customer Profile</h2>
<p>Name: {customer?.name}</p>
<p>Email: {customer?.email}</p>
<p>Balance: {customer?.features.chat_messages?.balance}</p>
</div>
);
}
```
### `checkout()`
Opens a checkout URL for the user to make a payment.
If the payment method already exists, purchase confirmation data will be returned.
If a `dialog` is passed in, a payment confirmation dialog ([`CheckoutDialog`](/react/components/checkout-dialog)) will be opened.
```jsx
import { useCustomer } from "autumn-js/react";
import CheckoutDialog from "@/components/autumn/checkout-dialog";
// or import { CheckoutDialog } from "autumn-js/react";
export default function PurchaseButton() {
const { checkout } = useCustomer();
return (
<button
onClick={async () => {
await checkout({
productId: "pro",
dialog: CheckoutDialog,
});
}}
>
Upgrade to Pro
</button>
);
}
```
**Parameters**
<ParamField body="productId" type="string" required>
The ID of the product being enabled.
</ParamField>
<ParamField body="dialog" type="(data: any) => JSX.Element | React.ReactNode">
A dialog that pops up to confirm the purchase (eg, for upgrades/downgrades).
See the [\<CheckoutDialog />](/react/components/checkout-dialog) page.
</ParamField>
<ParamField body="entityId" type="string">
The ID of the entity (eg, user seat) to attach the product to.
</ParamField>
<ParamField body="options" type="AttachFeatureOptions[]">
Array of feature options to configure for the attachment. Each option contains
`featureId` (string) and `quantity` (number).
</ParamField>
<ParamField body="productIds" type="string[]">
Array of additional product IDs to attach simultaneously.
</ParamField>
<ParamField body="freeTrial" type="boolean">
Whether to disable free trials for this product. Only applicable if the
product has a free trial.
</ParamField>
<ParamField body="successUrl" type="string">
URL to redirect to after successful attachment/checkout.
</ParamField>
<ParamField body="metadata" type="Record<string, string>">
Additional metadata to pass onto Stripe.
</ParamField>
<ParamField body="checkoutSessionParams" type="object">
Pass in Stripe checkout session fields and they will be forwarded on.
</ParamField>
<ParamField body="forceCheckout" type="boolean">
Whether to force the checkout flow even if the payment method already exists.
Not available for upgrades/downgrades.
</ParamField>
<ParamField body="openInNewTab" type="boolean" default="false">
Whether to open the checkout URL in a new tab.
</ParamField>
### `attach()`
Enables a product for a customer and handles a payment. Typically used after the `checkout` function.
If the payment method is not on file, this function will also return a Checkout URL.
```jsx
import { useCustomer } from "autumn-js/react";
export default function ConfirmationButton() {
const { attach } = useCustomer();
return (
<div>
Click to confirm your upgrade. Your card will be charged.
<button
onClick={async () => {
await attach({
productId: "ultra",
});
}}
>
Confirm Purchase
</button>
</div>
);
}
```
**Parameters**
<ParamField body="productId" type="string" required>
The ID of the product to attach.
</ParamField>
<ParamField body="entityId" type="string">
The ID of the entity (eg, user seat) to attach the product to.
</ParamField>
<ParamField body="options" type="AttachFeatureOptions[]">
Array of feature options to configure for the attachment. Each option contains
`featureId` (string) and `quantity` (number).
</ParamField>
<ParamField body="productIds" type="string[]">
Array of additional product IDs to attach simultaneously.
</ParamField>
<ParamField body="freeTrial" type="boolean">
Whether to disable free trials for this product. Only applicable if the
product has a free trial.
</ParamField>
<ParamField body="successUrl" type="string">
URL to redirect to after successful attachment/checkout.
</ParamField>
<ParamField body="metadata" type="Record<string, string>">
Additional metadata to pass onto Stripe.
</ParamField>
<ParamField body="forceCheckout" type="boolean">
Whether to force the checkout flow even if the payment method already exists.
Not available for upgrades/downgrades.
</ParamField>
<ParamField body="openInNewTab" type="boolean" default="false">
Whether to open the checkout URL in a new tab.
</ParamField>
### `check()`
Check if a user has access to a specific feature or product.
<Note>
This will be read from the local `customer` state object, so no API call to
Autumn is made. This should be combined with a backend `check` call for
security.
</Note>
```jsx
import { useCustomer } from "autumn-js/react";
export default function FeatureGate({ children }) {
const { check } = useCustomer();
return (
<button
onClick={async () => {
const { data, error } = await check({
featureId: "chat-messages",
requiredBalance: 7,
});
}}
>
Send 7 Messages
</button>
);
}
```
**Parameters**
<ParamField body="featureId" type="string">
The ID of the feature to check access for.
</ParamField>
<ParamField body="productId" type="string">
The ID of the product to check access for.
</ParamField>
<ParamField body="dialog" type="(data: any) => JSX.Element | React.ReactNode">
A dialog that pops up to act as a paywall (eg, when a feature runs out). See
the [\<PaywallDialog />](/react/components/paywall-dialog) page.
</ParamField>
<ParamField body="entityId" type="string">
The ID of the entity (customer/user) to check access for.
</ParamField>
<ParamField body="requiredBalance" type="number">
The required balance/usage amount to check against.
</ParamField>
<ParamField body="sendEvent" type="boolean">
Whether to send an event when checking access.
</ParamField>
<ParamField body="withPreview" type="boolean">
Return preview data to display to the user. Using this with a `featureID` will
return paywall data, and using it with a `productId` will return
upgrade/downgrade data.
</ParamField>
### `track()`
Track usage events for features or analytics.
<Warning>
Tracking usage client-side is not recommended, as a user in theory could stop
script execution and mess with your tracking data.
</Warning>
```jsx
import { useCustomer } from "autumn-js/react";
export default function ApiCallButton() {
const { track } = useCustomer();
const handleApiCall = async () => {
// Make your API call
await makeApiCall();
// Track the usage
await track({
featureId: "api-calls",
value: 1,
idempotencyKey: `api-call-${Date.now()}`,
});
};
return <button onClick={handleApiCall}>Make API Call</button>;
}
```
**Parameters**
<ParamField body="featureId" type="string">
The ID of the feature to track usage for.
</ParamField>
<ParamField body="eventName" type="string">
Custom event name for tracking.
</ParamField>
<ParamField body="entityId" type="string">
The ID of the entity (customer/user) to track usage for.
</ParamField>
<ParamField body="value" type="number">
The value/quantity to track (e.g., number of API calls, storage used).
</ParamField>
<ParamField body="idempotencyKey" type="string">
Unique key to prevent duplicate tracking events.
</ParamField>
### `openBillingPortal()`
Open the billing portal for customers to manage their subscriptions, payment methods, and billing information.
```jsx
import { useCustomer } from "autumn-js/react";
export default function BillingSettings() {
const { openBillingPortal } = useCustomer();
return (
<button
onClick={async () => {
await openBillingPortal({
returnUrl: "https://useautumn.com/settings/billing",
});
}}
>
Manage Billing
</button>
);
}
```
**Parameters**
<ParamField body="returnUrl" type="string">
URL to redirect to when the customer exits the billing portal.
</ParamField>
### `setupPayment()`
Setup a payment method for a customer.
```jsx
import { useCustomer } from "autumn-js/react";
export default function SetupPayment() {
const { setupPayment } = useCustomer();
}
```
**Parameters**
<ParamField body="successUrl" type="string">
Optional URL to redirect to after successful setup. If not provided, the default return URL will be used.
</ParamField>
<ParamField body="checkoutSessionParams" type="object">
Optional parameters to pass to the Checkout session. Accepts an object with string keys and any values.
</ParamField>
<ParamField body="openInNewTab" type="boolean">
If true, will open the payment session in a new tab. Defaults to false.
</ParamField>
### `cancel()`
Cancel a product or subscription for a user/entity.
```jsx
import { useCustomer } from "autumn-js/react";
export default function CancelSubscription() {
const { cancel } = useCustomer();
return (
<button
onClick={async () => {
await cancel({ productId: "pro" });
}}
>
Cancel Subscription
</button>
);
}
```
**Parameters**
<ParamField body="productId" type="string" required>
The ID of the product to cancel.
</ParamField>
<ParamField body="cancelImmediately" type="boolean">
Whether to cancel the product immediately. If false, the product will be
cancelled at the end of the billing cycle.
</ParamField>
<ParamField body="entityId" type="string">
The ID of the entity (customer/user) to cancel the product for.
</ParamField>
### `refetch()`
Function to manually refetch the `customer` data, eg when updating a customer's usage or balance to display.
```jsx
import { useCustomer } from "autumn-js/react";
export default function CustomerWithRefresh() {
const { customer, refetch } = useCustomer();
const { track } = useCustomer();
const sendMessage = async () => {
await track({ featureId: "chat_messages" });
await refetch();
};
return <button onClick={sendMessage}>Send Message</button>;
}
```
### `createEntity()`
Function to create one or more [entities](/documentation/customers/feature-entities) for the customer.
```jsx
import { useCustomer } from "autumn-js/react";
export default function CreateUserSeat() {
const { createEntity } = useCustomer();
const handleCreateSeat = async () => {
const { data, error } = await createEntity({
id: "user_abc",
name: "John Doe",
featureId: "seats",
});
console.log("Created entity:", data);
};
}
return <button onClick={handleCreateSeat}>Create User Seat</button>;
```
**Parameters**
<ParamField body="id" type="string" required>
The ID of the entity to create.
</ParamField>
<ParamField body="name" type="string">
Display name for the entity.
</ParamField>
<ParamField body="featureId" type="string">
The feature ID for the entity being created. Must be a `continuous_use`
feature.
</ParamField>
### `isLoading`
Boolean indicating whether the customer data is currently being fetched.
```jsx
import { useCustomer } from "autumn-js/react";
export default function CustomerLoader() {
const { customer, isLoading } = useCustomer();
if (isLoading) {
return <div>Loading customer data...</div>;
}
return <div>Welcome, {customer?.name}!</div>;
}
```
### `error`
Any error that occurred while fetching customer data.
```jsx
import { useCustomer } from "autumn-js/react";
export default function CustomerWithError() {
const { customer, error, isLoading } = useCustomer();
if (error) {
return <div>Error loading customer: {error.message}</div>;
}
if (isLoading) {
return <div>Loading...</div>;
}
return <div>Customer: {customer?.name}</div>;
}
```