useSignUpForCard to open card onboarding, useGetCardsForUser to find existing cards, and CardSummaryView to display and manage a card.
Import these APIs from @privy-io/expo/cards. Card signup runs in the PrivyElements modal. CardSummaryView renders inside the app’s own screen.
For an approved Earn-backed card program, follow Spend from vault balances. The same hooks and components handle vault-share approval and available balances.
These APIs are experimental and may change in a minor version. React Native card signup supports
embedded EVM wallets.
Set up the SDK
Complete the cards setup, React Native SDK installation, and Privy UI setup, including the UI dependencies and fonts. Use@privy-io/expo version 0.76.4 or later for signup, card management, and card-detail reveal:
PrivyElements once inside PrivyProvider, alongside the app’s navigation. Use the app ID and mobile client ID from the Privy dashboard.
Add the card flow
The example below checks every page for an existing open card before starting signup. It uses Tempo Moderato and PathUSD in sandbox.PrivyElements when signUp runs. The modal handles disclosures, bank and provider terms, identity verification, card creation, and spend approval. Hosted terms and identity verification open in the in-app browser through expo-web-browser.
The funding walletId is the Privy wallet ID from the user’s linked accounts. getAllUserEmbeddedEthereumWallets(user) returns those accounts, including their IDs.
CardSummaryView fills its parent and scrolls internally. Give it available height, such as a screen with flex: 1. It uses the appearance configured on PrivyElements.
Find returning users’ cards
getCardsForUser returns one page for the authenticated user in the selected environment, ordered newest first. Pass next_cursor as cursor until it is null. The default page size is 5; the maximum is 20.
Select the first active or inactive card for the funding wallet. An inactive card is frozen and can be unfrozen in CardSummaryView. Keep canceled and replaced cards for history.
onReplaced receives the replacement card’s ID. Update the selected ID to display it, as shown above. Otherwise, the view stays on the closed card.
If signup closes before spend approval succeeds, the card can already exist. The example’s Finish card setup action calls signUp again with the same wallet, chain, asset, and environment. Signup reuses the existing card and resumes the approval flow.
Configure production spend approval
Sandbox uses built-in approval targets for Ethereum Sepolia, OP Sepolia, Polygon Amoy, Base Sepolia, Arbitrum Sepolia, Avalanche Fuji, and Tempo Moderato. Tempo Moderato supports PathUSD (pathusd) and OUSD (ousd); the other listed testnets use USDC (usdc).
Production requires the stablecoin contract and Bridge spender for the card program’s funding chain. Obtain these addresses from the Privy account manager. The stablecoin must match asset, and the spender must belong to the app’s card program.
spendApproval object contains stablecoinAddress: string and spenderAddress: string. Sandbox uses its built-in targets and does not accept this option.
API reference
useSignUpForCard
Returns signUp, close, and isOpen. signUp(options) requires PrivyElements to be mounted and returns Promise<{id: string}>.
isOpen is true while signup is in progress. Only one signup can run at a time. close() dismisses the flow and settles its pending promise.
Closing before a card exists rejects the promise. Applications under review or rejected also reject when closed. If a card already exists at the ready or approval-error step, closing resolves with its ID. A returned card ID alone does not guarantee that spend approval succeeded.
An unsupported funding chain, another active signup, or an unmounted PrivyElements causes signUp to reject. Catch rejections to handle cancellation and errors in the app.
useGetCardsForUser
Returns getCardsForUser(options), which resolves to a page with data and next_cursor.
CardSummaryView
Displays the card’s balance, paginated activity, transaction details, and dispute contact. The details screen reveals the card number and CVC and supports freezing, replacement, and cancellation.
Card details render in Stripe Issuing Elements inside a
react-native-webview. The app’s configured Stripe publishable key is loaded through Privy. Keep Stripe and Bridge secret keys in the Privy dashboard.
