---
name: Payment done
system: lime
kind: component
import: "import {PaymentDone} from '@/components/lime/ui/payment-done'"
install: "npx shadcn@latest add https://design.how/r/lime/payment-done.json"
registryDependencies: [amount, button, card, icon, status, theme, use-focus-when-replaced, utils]
version: 1
last-updated: 2026-10-19
human: https://design.how/systems/lime/components/payment-done
---

# Payment done

Confirms a payment the person sent: to whom, how much, its status, and Undo for a short time.

## Use when
- Right after the person sends, pays or moves money themselves, on the screen they sent it from.
- A payment that can be pulled back for a few seconds before it leaves.

## Don't use when
- What the assistant did on its own. Use [Action receipt](/systems/lime/components/action-receipt.md).
- The assistant asking before it pays. Use [Approval request](/systems/lime/components/approval-request.md).
- A small action that needs no amount, such as saving a nickname. Use [Toast](/systems/lime/components/toast.md).

## Minimal example
```tsx
<PaymentDone to="Maya Chen" amount={-45} detail="From Checking, arrives today"
  leading={<Avatar name="Maya Chen"/>} state={state} undoPending={undoing} onUndo={undo}/>
```

## Rules
Ordered by priority. MUST and NEVER break the system if skipped. SHOULD is style.

1. payment-done-signed-amount MUST Pass amount signed, negative for money out, the same number that left the account. Because a positive 45 prints and reads without the minus, so it looks like money in.
   - Correct: `amount={-45}`
   - Wrong: `amount={45}`
2. payment-done-state-follows MUST Drive state from the payment: sending until the bank confirms, then sent; undone only after the money is back. Because the live footer announces Sent at once, and the person trusts money that may not have left.
   - Correct: `<PaymentDone state={confirmed ? 'sent' : 'sending'} .../>`
   - Wrong: `<PaymentDone state="sent" .../> // set before the bank replies`
3. payment-done-undo-honest MUST Set undoFor to the real time the payment can still be stopped; 0 when it cannot. Because undoFor defaults to 30, so a payment that cannot be stopped still offers Undo.
   - Correct: `<PaymentDone undoFor={0} .../> // card payments leave at once`
4. payment-done-undo-pending MUST Set undoPending while the undo runs, so Undo shows its spinner and the clock stops. Because otherwise the clock runs out mid-undo and the button vanishes with no outcome.
   - Correct: `<PaymentDone undoPending={undoing} onUndo={undo} .../>`
5. payment-done-name-recipient SHOULD Put the name in to and how it went in detail: the account it left and when it arrives.
   - Correct: `to="Maya Chen" detail="From Checking, arrives today"`
   - Wrong: `to="Payment sent to Maya Chen"`
6. payment-done-one-per-screen SHOULD Show one per screen, at the top of what the person sees after sending.
7. payment-done-no-toast NEVER Also show a toast for the same payment; the card is the confirmation. Because the toast brings a second Undo on its own clock and announces the payment twice.
   - Correct: `<PaymentDone to="Maya Chen" amount={-45} onUndo={undo}/>`
   - Wrong: `toast.show({title: 'Sent $45.00 to Maya Chen', action: {label: 'Undo', onClick: undo}})`

## API
| Prop | Type | Default | Note |
|-|-|-|-|
| `to` | `string` | `required` | Who the money went to. |
| `amount` | `number` | `required` | Signed. Negative is money out. |
| `currency` | `string` | `'USD'` | An ISO 4217 code. |
| `leading` | `ReactNode` |  | An Avatar or ListIcon. |
| `detail` | `string` |  | One line under the name. Truncates. |
| `state` | `'sending' \| 'sent' \| 'undone'` | `'sent'` | The Status word, and whether Undo shows. |
| `undoFor` | `number` | `30` | Seconds Undo stays after sent. 0 leaves it out. |
| `undoPending, onUndo` | `boolean, () => void` |  | Undo is running; the Undo press. |
| `labels` | `{sending?, sent?, undone?, undo?}` | `English words` | The status words and the Undo label. |
Other props pass through to the root element.

## Variants and states
- state: sending, sent, undone
- states: sending, sent, undo pending, undone, undo expired

## Accessibility
- [ ] The card is a group named Payment to and the name; the amount is read as words.
- [ ] The footer is a polite live region, so Sending, Sent and Undone are read out as they change.
- [ ] Undo is described as available for the set seconds; the ticking clock is hidden from screen readers.
- [ ] When Undo leaves while focused (pressed or expired), focus moves to the status, never to the page top.
- [ ] Undone strikes through the amount and says Undone; the line is never the only signal.

## Edge cases
- Long name -> The name and detail truncate; the amount never shrinks.
- Undo runs out -> Undo goes away and the status stays; the footer keeps its height.
- Undo fails -> Keep state sent and say why on the screen; the payment went through.
- Money in -> A positive amount shows without a sign; use it for a request that was paid.
- Right to left -> The row mirrors; the amount keeps left-to-right digits.
- Reduced motion -> The Sending spinner keeps turning; nothing else moves.

## Tokens
--surface, --radius-panel, --fg, --fg-2, --fg-3, --text-xl, --control-md, --success, --fg-disabled, --accent-line

## Related
- [Action receipt](/systems/lime/components/action-receipt.md): A message listing what the assistant just did, one line per action, with Undo.
- [Toast](/systems/lime/components/toast.md): A short note after an action, such as Moved $50 to savings, with an optional Undo.
- [Status](/systems/lime/components/status.md): The state of a payment as a dot and a word.
- [Amount](/systems/lime/components/amount.md): A money amount with its sign, currency and tabular figures.
