Skip to main content
This guide covers the complete cardholder flow. First, check for an existing card. If none exists, use useSignUpForCard with SignUpForCardView to onboard the cardholder. Then, render CardSummaryView to display and manage the card. These APIs are exported from @privy-io/react-auth/cards and must be used within PrivyProvider. Before continuing, complete the cards setup and configure embedded wallets for your app.

Install and import the SDK

Card prebuilt components require @privy-io/react-auth version 3.40.0 or later.
Install the React SDK:
Import usePrivy from the main entrypoint. Import the card hooks and components from the /cards entrypoint.

Get the funding wallet

The signUp method takes the Privy wallet ID, not the wallet address. Read it from the authenticated user’s linkedAccounts. The following helper returns the ID of an embedded EVM wallet:
For a Solana-funded card, select an embedded wallet with chainType === 'solana' instead.

Add the card flow

Use isOpen to mount the container for SignUpForCardView. Connect the container’s close action to close. The view renders the onboarding steps using the options passed to signUp. The promise returns the new card ID after signup completes and rejects if the flow does not complete. This sandbox example uses Tempo Moderato and PathUSD. The SDK supplies built-in stablecoin and Bridge spend-approval targets for supported sandbox networks.
The example checks for an open card before starting signup. A failed list request stops the flow. The cardholder can use the same button to retry. The example checks the newest 20 cards. Apps with more records should use the pagination helper below before starting signup. Replace the aside with the modal or side panel that fits the app. Keep SignUpForCardView mounted while isOpen is true. CardSummaryView uses cardId to load the card, balance, activity, and statements. It also handles card-detail reveal, wallet provisioning, freezing, replacement, and cancellation.

Find the user’s existing cards

The signup promise only returns a card ID during the current page session. To support returning users, use useGetCardsForUser to fetch the authenticated user’s cards. getCardsForUser returns one page for a single environment, ordered newest first. Results include canceled cards. The default page size is 5 and the maximum is 20; pass each next_cursor back as cursor until it returns null.
Call the helper after the user authenticates. Keep the full result if your app lists card history, or select the newest open card to pass to CardSummaryView:

Handle card states

The list response can include these card states:
  • active: The card is open and can spend. Pass it to CardSummaryView.
  • inactive: The card is frozen but remains open. Pass it to CardSummaryView to allow unfreezing.
  • canceled: The card is permanently closed. Keep it for history, but do not select it for management.
  • replaced: A newer card replaced this closed card. Select the newer active or inactive card instead.
Cards are ordered newest first. Select the first active or inactive card for the funding wallet.
Do not treat a failed getCardsForUser request as an empty list. Show the error and retry the request. Offer signup only after a successful request returns no open cards.

Configure production spend approval

Sandbox uses built-in targets for Ethereum Sepolia, OP Sepolia, Polygon Amoy, Base Sepolia, Arbitrum Sepolia, Avalanche Fuji, Tempo Moderato, and Solana devnet. Production requires the spend-approval target for the mainnet chain behind the app’s Bridge integration. Pass the target that a Privy account manager provides. Do not guess or hardcode another integration’s spender or merchant ID: the card can be issued but cannot spend if its wallet approves the wrong target.
Pass the stablecoin contract and Bridge spender for the card’s chain:
The environment option determines which configured card ledger the flow uses. Sandbox does not accept a caller-supplied spendApproval; production requires one.

API reference

useGetCardsForUser

useGetCardsForUser() returns a getCardsForUser method for the authenticated user:
getCardsForUser(options) returns a page with the user’s cards in data and the next page cursor in next_cursor.

useSignUpForCard

useSignUpForCard() returns the signUp and close methods and the isOpen state:
signUp(options) returns Promise<{id: string}>. Only one card signup can be active at a time; starting another before the first finishes rejects with an error. isOpen is true while signup is in progress. Use it to control the container that mounts SignUpForCardView. Call close() when the user dismisses that container. Closing before a card exists rejects the pending signUp promise. DevSpendApprovalTarget is a union of the EVM and Solana target shapes:
For EVM chains, spenderAddress identifies the Bridge contract approved to spend the stablecoin. For Solana, programId and merchantId identify the Bridge delegate.

SignUpForCardView

SignUpForCardView takes no props. Mount one instance within PrivyProvider while isOpen is true. The hook controls its options and completion state. The view handles disclosures, bank and provider terms, KYC, card creation, and the wallet spend approval.

CardSummaryView

Always pass the same environment used to create the card. Cards are scoped by app, user, and environment, so the other environment cannot load the card.