# Order summary

> A checkout order-summary card — line items, a promo code field, a total, and a pay-now button.

A shadcn/ui block from the [@quill](https://www.quilldesignsystem.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/quill/order-summary).

- Page, with a live preview: https://shadcn.exchange/r/quill/order-summary
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/quill/order-summary-light-a36a3d911b052447.png
- Registry item: https://www.quilldesignsystem.com/r/order-summary.json
- Categories: commerce
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://www.quilldesignsystem.com/r/order-summary.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- Registry items: `card`, `button`, `input`, `separator`, `https://www.quilldesignsystem.com/r/icon.json`

## Notes from the registry

A checkout order-summary card — line items, a promo code field, a total, and a pay-now button. Do: Recompute the total the instant a promo code applies or a line item changes — never leave a stale total on screen after an update. Don't: Require a page refresh or separate action to see the corrected total. Do: Show an applied promo as its own line item with the discount amount, so the line items and the total add up to the same number. Don't: Let the total drop after a promo applies with no corresponding line item — buyers can't verify what changed. Use invoice when you're showing a record of a completed, already-paid transaction, not a cart pending payment. Use checkout when you need the full payment form (card fields, billing address) alongside the summary, not just the review.

## Files

### `registry/blocks/order-summary.tsx`

```tsx
import {
  Card,
  CardHeader,
  CardTitle,
  CardContent,
  CardFooter,
} from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Separator } from '@/components/ui/separator'
import { Icon } from '@/components/ui/icon'

const lines = [
  { name: 'Pro plan (annual)', qty: 1, price: '$180.00' },
  { name: 'Extra seats × 3', qty: 3, price: '$54.00' },
  { name: 'Priority support', qty: 1, price: '$24.00' },
]

/** A checkout order-summary card — line items, a promo code field, a total, and a pay-now button. */
export function OrderSummary() {
  return (
    <Card className="w-[400px]">
      <CardHeader>
        <CardTitle>Order summary</CardTitle>
      </CardHeader>
      <CardContent className="flex flex-col gap-3">
        {lines.map((l) => (
          <div key={l.name} className="flex items-center justify-between text-sm">
            <span className="text-foreground">{l.name}</span>
            <span className="text-muted-foreground tabular-nums">{l.price}</span>
          </div>
        ))}
        <Separator />
        <div className="flex items-center gap-2">
          <Input placeholder="Promo code" className="flex-1" />
          <Button variant="outline">Apply</Button>
        </div>
        <Separator />
        <div className="flex items-center justify-between">
          <span className="text-sm text-muted-foreground">Total due today</span>
          <span className="text-lg font-medium text-foreground tabular-nums">$258.00</span>
        </div>
      </CardContent>
      <CardFooter>
        <Button className="w-full">
          <Icon name="credit_card" size={16} /> Pay now
        </Button>
      </CardFooter>
    </Card>
  )
}
```
