Skip to main content

useSetupIntent

Overview

useSetupIntent is a comprehensive React hook for managing Stripe SetupIntents, which are used to save payment methods for future use. The module exports a family of hooks covering different use cases: the main useSetupIntent query hook, useCreateSetupIntent for on-demand creation, useSetupIntentCache for cache management, useGetSetupIntent for retrieving existing intents, useCreateSetupIntentWithCustomParams for custom creation flows, and useSetupIntentManager that combines all functionality.

Source: template/hooks/use-setup-intent.ts

Hooks Overview

HookPurpose
useSetupIntentMain hook -- creates and caches a SetupIntent via query
useCreateSetupIntentOn-demand SetupIntent creation via mutation
useSetupIntentCacheCache management utilities
useGetSetupIntentRetrieve an existing SetupIntent by ID
useCreateSetupIntentWithCustomParamsCreate with customer name and default flag
useSetupIntentManagerCombined hook merging query, mutation, and cache

useSetupIntent (Main Hook)

Signature

function useSetupIntent(options?: UseSetupIntentOptions): UseSetupIntentReturn

Parameters

PropertyTypeDefaultDescription
enabledbooleantrueWhether to enable the automatic SetupIntent creation query.
paramsCreateSetupIntentParamsundefinedParameters for creating the SetupIntent.
onSuccess(data: SetupIntentResponse) => voidundefinedCallback fired on successful creation.
onError(error: SetupIntentError) => voidundefinedCallback fired on creation failure.
suppressSuccessToastbooleanfalseWhether to suppress the default success toast notification.

CreateSetupIntentParams

interface CreateSetupIntentParams {
customer_id?: string;
payment_method_types?: string[];
usage?: 'off_session' | 'on_session';
metadata?: Record<string, string>;
customer_name?: string;
set_as_default?: boolean;
}

Return Values

PropertyTypeDescription
dataSetupIntentResponse | undefinedThe raw SetupIntent data.
setupIntentSetupIntentResponse | undefinedMemoized alias for data.
clientSecretstring | undefinedThe client secret for Stripe Elements.
isLoadingbooleantrue while the initial creation is in progress.
isFetchingbooleantrue while any fetch (initial or refetch) is in progress.
isErrorbooleantrue if creation failed.
isSuccessbooleantrue if creation succeeded.
isReadybooleantrue when the SetupIntent is created, has a client secret, and its status is 'requires_payment_method'.
isStalebooleantrue if the cached data is considered stale.
errorSetupIntentError | undefinedThe error from the creation attempt.
refetch() => voidManually refetch (re-create) the SetupIntent.
invalidateCache() => voidMark the cache as stale and trigger refetch.
clearCache() => voidRemove the SetupIntent from cache entirely.
prefetch(params?: CreateSetupIntentParams) => Promise<void>Prefetch a SetupIntent with optional parameters.
setData(data: SetupIntentResponse | null) => voidManually set the cached SetupIntent data.

useCreateSetupIntent

On-demand SetupIntent creation using a mutation.

Signature

function useCreateSetupIntent(options?: UseCreateSetupIntentOptions): {
createSetupIntent: (params?: CreateSetupIntentParams) => void;
createSetupIntentAsync: (params?: CreateSetupIntentParams) => Promise<SetupIntentResponse>;
isCreating: boolean;
isError: boolean;
error: SetupIntentError | null;
reset: () => void;
}

useSetupIntentCache

Cache management utilities for SetupIntents.

Signature

function useSetupIntentCache(): {
invalidateAll: () => void;
clearAll: () => void;
getFromCache: (params?: CreateSetupIntentParams) => SetupIntentResponse | undefined;
setInCache: (data: SetupIntentResponse | null, params?: CreateSetupIntentParams) => void;
isCached: (params?: CreateSetupIntentParams) => boolean;
prefetchSetupIntent: (params?: CreateSetupIntentParams) => Promise<void>;
}

useGetSetupIntent

Retrieve an existing SetupIntent by its ID.

Signature

function useGetSetupIntent(
setupIntentId: string,
options?: { enabled?: boolean }
): UseQueryResult<SetupIntentResponse, SetupIntentError>

useCreateSetupIntentWithCustomParams

Create a SetupIntent with customer_name and optional set_as_default flag.

Signature

function useCreateSetupIntentWithCustomParams(options?: {
onSuccess?: (data: { client_secret: string }) => void;
onError?: (error: SetupIntentError) => void;
}): {
createSetupIntent: (params: { customer_name: string; set_as_default?: boolean }) => void;
createSetupIntentAsync: (params: { customer_name: string; set_as_default?: boolean }) => Promise<{ client_secret: string }>;
isCreating: boolean;
isError: boolean;
error: SetupIntentError | null;
reset: () => void;
}

useSetupIntentManager

Combined hook that merges query, mutation, and cache functionality.

Signature

function useSetupIntentManager(params?: CreateSetupIntentParams): {
// All properties from useSetupIntent
// Plus: createSetupIntent, createSetupIntentAsync, isCreating, createError, resetCreate
// Plus: all properties from useSetupIntentCache
}

Type Definitions

SetupIntentData

interface SetupIntentData {
id: string;
client_secret: string;
status: 'requires_payment_method' | 'requires_confirmation' | 'processing' | 'succeeded' | 'canceled';
usage: 'off_session' | 'on_session';
customer?: string;
payment_method?: string;
created: number;
metadata?: Record<string, string>;
}

SetupIntentError

interface SetupIntentError extends Error {
status?: number;
code?: string;
}

Implementation Details

  • Query Key: ['setup-intent'] (exported as SETUP_INTENT_QUERY_KEY). When params are provided, the key becomes ['setup-intent', params].
  • Stale Time: 5 minutes
  • Garbage Collection Time: 30 minutes
  • Max Retries: 3
  • Retry Logic: Auth errors (401, 403) are never retried. Client errors (4xx) are only retried for rate limiting (429) and timeouts (408). No-data responses (204) are not retried. Server errors (5xx) and network errors are retried.
  • Toast Notifications: Success toast ("Payment setup ready") displayed by default (suppressible). Error toasts display user-friendly messages based on status code.
  • API Endpoints:
    • POST /api/stripe/setup-intent -- Create a new SetupIntent
    • GET /api/stripe/setup-intent/{id} -- Retrieve an existing SetupIntent

Usage Examples

Basic Payment Method Setup

import { useSetupIntent } from '@/hooks/use-setup-intent';
import { Elements, PaymentElement } from '@stripe/react-stripe-js';

function PaymentMethodForm() {
const { clientSecret, isReady, isLoading, error } = useSetupIntent({
suppressSuccessToast: true
});

if (isLoading) return <Spinner />;
if (error) return <ErrorMessage message={error.message} />;
if (!isReady || !clientSecret) return <p>Initializing...</p>;

return (
<Elements stripe={stripePromise} options={{ clientSecret }}>
<PaymentElement />
<SubmitButton />
</Elements>
);
}

On-Demand Creation

import { useCreateSetupIntent } from '@/hooks/use-setup-intent';

function AddPaymentMethodButton() {
const { createSetupIntentAsync, isCreating } = useCreateSetupIntent({
onSuccess: (data) => {
// Navigate to payment form with the client secret
router.push(`/payment/setup?secret=${data.client_secret}`);
}
});

return (
<button
onClick={() => createSetupIntentAsync({ usage: 'off_session' })}
disabled={isCreating}
>
{isCreating ? 'Setting up...' : 'Add Payment Method'}
</button>
);
}

Using the Manager Hook

import { useSetupIntentManager } from '@/hooks/use-setup-intent';

function PaymentSetupManager() {
const {
clientSecret,
isReady,
isLoading,
createSetupIntent,
isCreating,
isCached,
clearAll
} = useSetupIntentManager();

return (
<div>
<p>Status: {isLoading ? 'Loading' : isReady ? 'Ready' : 'Not ready'}</p>
<p>Cached: {isCached() ? 'Yes' : 'No'}</p>
<button onClick={() => createSetupIntent()} disabled={isCreating}>
Create New
</button>
<button onClick={clearAll}>Clear Cache</button>
</div>
);
}