# Receipt

> What was paid, by whom, when, and how, with the status after the title. A declined payment puts its fixes where it is said.

- Name: `receipt`
- Status: beta
- Categories: data, display
- File: the install writes `receipt.tsx` to your `ui` alias, `@/components/ui` by default.
- Other registry items: `@arbokui/button`, `@arbokui/person`, `@arbokui/status-text`. The install adds them.
- Gallery: https://arbokui.com/components/receipt
- Registry item: https://arbokui.com/r/receipt.json

## Install

1. Add the registry to `components.json`. Do this first, once:

   ```bash
   npx shadcn@latest registry add "@arbokui=https://arbokui.com/r/{name}.json"
   ```

   The command writes this entry. You can also add it by hand:

   ```json
   {
     "registries": {
       "@arbokui": "https://arbokui.com/r/{name}.json"
     }
   }
   ```

   Without this step, the shadcn CLI looks up `@arbokui` in a public list that Arbokui does not control.

2. Add the theme once per app. It replaces your color tokens with ones checked for contrast:

   ```bash
   npx shadcn@latest add @arbokui/theme
   ```

3. Add the component:

   ```bash
   npx shadcn@latest add @arbokui/receipt
   ```

## Use it for

- A payment's record, inside a Card or a Sheet. It draws no box of its own.
- status follows the title as colored text: Paid in success, Processing in brand, Refunded in neutral, Declined in danger.
- A declined payment: onRetry puts a retry icon right beside Declined, note says why in plain words, and onChangeCard adds Try another card under it.
- A refund's note can say where the money went, like "£15 back to Visa ending 4242 on Wed 30 Sep".
- A discount is a negative amount. It shows a true minus, like −£20, and screen readers hear "minus £20".
- Amounts show pence only when some amount has them, so the column lines up.

## Avoid it for

- A badge or a box for the status. The status is colored words after the title.
- A list of payments. Use DataTable or ListRow, and open a Receipt from a row.

## Props

- `title`: `string`. Required. What was paid for, like "October subscription".
- `status`: `"paid" | "pending" | "refunded" | "declined"`. Shown as Paid, Processing, Refunded, or Declined.
- `note`: `string`. One line under the title, in ink.
- `lines`: `{ label: string; amount: number; meta?: string }[]`. What the total is made of. A negative amount is a discount.
- `total`: `number`. Default the sum of the lines.
- `currency`: `string`. Default `"£"`. The money sign.
- `by`: `{ person: string; photo?: string }`. Who paid, drawn by Person with their photo.
- `when`: `string`. Like "Tue 29 Sep, 18:04".
- `method`: `string`. Like "Visa ending 4242".
- `reference`: `string`. The payment's reference.
- `onRetry`: `() => void | Promise<unknown>`. Declined: a retry icon beside Declined. Return a promise and it waits, and a failure turns it into Retry.
- `retryLabel`: `string`. Default `"Try again"`. Names the retry icon, in its tooltip.
- `onChangeCard`: `() => void`. Declined: a quiet text button with a card icon, under the note.
- `changeCardLabel`: `string`. Default `"Try another card"`. Its words.
- `className`: `string`. Extra classes on the root. Later classes win.

## Accessibility

- The status is words, so it never leans on color alone.
- The retry icon is a real button named by retryLabel, in its tooltip too. Try another card is a real button with words.
- A discount is read as "minus £20", and the true minus sign shows.
- The payer, the time, the method, and the reference are a description list, so each is read with its label.

## Examples

### Paid

```tsx
<Receipt
  title="October subscription"
  status="paid"
  lines={[{ label: "Team plan", meta: "1 to 31 Oct", amount: 15 }]}
  by={{ person: "Kate Clarke" }}
  when="Tue 29 Sep, 18:04"
  method="Visa ending 4242"
  reference="INV-0042"
/>
```

### Declined

```tsx
<Receipt
  title="October subscription"
  status="declined"
  note="Your bank turned it down. No money was taken."
  onRetry={() => retry()}
  onChangeCard={() => openCards()}
  lines={[{ label: "Team plan", amount: 15 }]}
/>
```
