# Payment methods

> Three checkout pieces — saved-card picker, add-card form with a flipping live preview and a method selector with animated fees — built for the moment money moves.

- Collection: Examples
- Tier: pro
- Docs: https://geturui.com/docs/payment-methods
- Install: `npx shadcn@latest add @geturui-pro/payment-methods`
- Dependencies: motion, lucide-react

## Variants

### Saved cards

Card picker with a radio dot that springs between rows, a default-card switch, expiry warnings and a pay button that resolves to a check.

Install: `npx shadcn@latest add @geturui-pro/payment-methods-saved-cards`

```tsx
import { SavedCardsPicker } from "@/components/examples/payment-methods/saved-cards";

export function Pay() {
  return <SavedCardsPicker cards={cards} defaultCardId="c1" amount="$48.00" onPay={async (id) => await charge(id)} onAddCard={openAddCard} />;
}
```

| Prop | Type | Default | Description |
|---|---|---|---|
| cards | `SavedCard[]` | — | { id, brand, last4, expiry, expiresSoon?, expired? } per card. |
| defaultSelectedId / defaultCardId | `string` | — | Initially selected card and the account default. |
| amount | `string` | "$48.00" | Formatted amount on the pay button. |
| onPay | `(cardId: string) => Promise<void> | void` | — | Awaited before the button shows complete. |
| onDefaultChange / onAddCard | `(id: string) => void / () => void` | — | Default switch and Add card handlers. |
| className | `string` | — | Extra classes on the root element. |

### Add card

Card form with a live preview that types along, detects the brand and flips to its back while the security code is focused.

Install: `npx shadcn@latest add @geturui-pro/payment-methods-add-card`

```tsx
import { AddCardForm } from "@/components/examples/payment-methods/add-card";

export function NewCard() {
  return <AddCardForm onSubmit={async (card) => await provider.tokenize(card)} />;
}
```

| Prop | Type | Default | Description |
|---|---|---|---|
| defaultName | `string` | "" | Pre-filled cardholder name. |
| today | `string` | "2026-10-02" | Date used to reject expired cards; pass the real date. |
| submitLabel | `string` | "Save card" | Button label. |
| onSubmit | `(card: NewCard) => Promise<void> | void` | — | Receives raw details; tokenize with your provider, never store them. |
| className | `string` | — | Extra classes on the root element. |

### Method selector

Card, device wallet or bank transfer: the chosen row expands with details and the fee and total count to new values.

Install: `npx shadcn@latest add @geturui-pro/payment-methods-wallet-selector`

```tsx
import { PaymentMethodSelector } from "@/components/examples/payment-methods/wallet-selector";

export function Method() {
  return <PaymentMethodSelector subtotal={1240} onContinue={(id, total) => next(id, total)} />;
}
```

| Prop | Type | Default | Description |
|---|---|---|---|
| methods | `PayMethod[]` | — | { id, label, detail, note, feePercent, feeFlat?, feeCap?, icon?, badge? } per method. |
| subtotal | `number` | 1240 | Order subtotal in major units. |
| currency | `string` | "USD" | ISO currency for formatting. |
| defaultMethodId | `string` | "card" | Initially selected method. |
| onContinue | `(methodId: string, total: number) => void` | — | Called by the continue button. |
| className | `string` | — | Extra classes on the root element. |

## Accessibility

- Method lists are radiogroups with roving focus and arrow keys; expired cards are announced and skipped.
- Form fields have labels, autocomplete hints and errors linked with aria-describedby; the decorative card preview is hidden.
- Animated totals keep a static screen-reader value, and the card flip becomes a crossfade with reduced motion.

## Source

Pro item — send `Authorization: Bearer <registry token>` to include the source.
