# Transaction detail screen

> One payment in full: merchant header, the signed amount, a status badge and a category chip that recategorizes, the details as grouped rows, split and receipt actions and Report a problem. The split sheet rolls each person's share as you change the head count.

- Type: Component (screens)
- Access: Pro
- Page: https://goodui.dev/native/components/transaction-detail-screen
- Markdown: https://goodui.dev/native/components/transaction-detail-screen.md
- Registry item: https://goodui.dev/native/r/transaction-detail-screen.json
- Dependencies: react-native-svg
- Keywords: react native transaction details, payment detail screen, banking app transaction, split bill, attach receipt, report a problem payment, recategorize transaction

## When to use

- Opening a payment from a bank, card, wallet or expense app's transaction list.
- Expense tools where people fix the category, attach a receipt or split a bill after paying.

## When not to use

- A list of transactions: use wallet-home-screen or list-row rows.
- A transfer being set up (amount entry, recipient): this screen shows a payment that already happened.
- Order details from a shop: use order-tracking-screen.

## Installation

With the shadcn CLI (needs a components.json in the Expo app), then `npx expo install --fix` so native dependencies match your Expo SDK. The foundation comes along the first time.

```bash
npx shadcn@latest add @goodui-native-pro/transaction-detail-screen
npx expo install --fix
```

Pro: add `"@goodui-native-pro": { "url": "https://goodui.dev/native/r/pro/{name}.json", "headers": { "Authorization": "Bearer ${GOODUI_LICENSE_KEY}" } }` to the `registries` of components.json and put your license key in .env.local.

The component lands in `components/goodui-native/transaction-detail-screen/` and imports the foundation from `components/goodui-native/foundation/` with relative paths; it also installs action-sheet, avatar, badge, banner, bottom-sheet, button, chip, icon-button, list-row, locale, quantity-stepper, rolling-number.

### Setup

- Wrap the app in GestureHandlerRootView and ThemeProvider (the sheets render in its overlay layer).

Built-in strings follow `<GooduiLocaleProvider>` (one [language pack](https://goodui.dev/native/r/locale-tr.json) translates the whole kit); the `labels` prop overrides them for one instance.

## Usage

```tsx
// app/transaction/[id].tsx
import { Stack, router, useLocalSearchParams } from "expo-router";
import * as Clipboard from "expo-clipboard";
import { TransactionDetailScreen } from "@/components/goodui-native/transaction-detail-screen/transaction-detail-screen";
import { api, useTransaction } from "@/lib/bank";

export default function TransactionRoute() {
  const { id } = useLocalSearchParams<{ id: string }>();
  const { transaction, hasReceipt } = useTransaction(id);
  return (
    <>
      <Stack.Screen options={{ headerShown: false }} />
      <TransactionDetailScreen
        transaction={transaction} // { merchant, amount: -46.5, currency: "EUR", date, status, category, card, reference }
        onCategoryChange={(category) => api.recategorize(id, category)} // rejects: the chip goes back
        onSplit={(people, share) => api.requestSplit(id, people, share)}
        hasReceipt={hasReceipt}
        onReceiptPress={() => (hasReceipt ? router.push(`/receipt/${id}`) : api.attachReceipt(id))}
        onReport={(reason) => api.openDispute(id, reason.key)} // resolve with the case number
        onCopyReference={(ref) => Clipboard.setStringAsync(ref)}
        onBack={() => router.back()}
      />
    </>
  );
}
```

## Examples

### On its own, with a sample payment

```tsx
<TransactionDetailScreen onBack={() => router.back()} />
```

### Paid abroad, still pending

```tsx
<TransactionDetailScreen
  transaction={{
    id: "tx_19", merchant: "Blue Bottle Coffee", amount: -6.72, currency: "EUR", date: "2026-10-30T08:14:00Z",
    status: "pending", category: "Eating out", card: { name: "Travel", last4: "7731" }, reference: "US44 0021 77",
    original: { amount: 7.25, currency: "USD", rate: 0.9269 },
  }}
/>
```

## API reference

### TransactionDetailScreen

`import { TransactionDetailScreen } from "@/components/goodui-native/transaction-detail-screen/transaction-detail-screen";`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `transaction` | `TransactionDetail` | `defaultTransaction` | – |
| `categories` | `string[]` | `defaultCategories` | Categories offered by the category chip. |
| `onCategoryChange` | `(category: string) => unknown` | – | Called with the new category. Return a promise; the chip goes back if it rejects. |
| `onSplit` | `(people: number, share: number) => unknown` | – | Split sheet: called with the number of people (you included) and each share. Return a promise; the sheet's button shows its states. |
| `hasReceipt` | `boolean` | `false` | Whether a receipt is attached. Switches the button between Attach receipt and View receipt. |
| `onReceiptPress` | `() => unknown` | – | Attach or open the receipt. Return a promise to show a spinner while a photo uploads. |
| `reportReasons` | `TransactionReportReason[]` | `defaultReasons` | Reasons offered by Report a problem. |
| `onReport` | `(reason: TransactionReportReason) => Promise<string \| void> \| void` | – | Called with the reason picked. Return a promise that resolves with a case number (or nothing); a rejection shows an error banner. |
| `onBack` | `() => void` | – | Back button. Hidden when omitted. |
| `onCopyReference` | `(reference: string) => void` | – | Copy the reference, called on a long press of its row. |
| `locale` | `string` | – | BCP 47 locale for amounts and dates. Defaults to the device locale. |
| `style` | `StyleProp<ViewStyle>` | – | Style for the outer container. |
| `testID` | `string` | – | Identifier for end-to-end tests. |

## Accessibility

- 'Transaction' is the header; Back is a labelled icon button.
- The status badge is read by its label (Completed, Pending, Declined, Refunded); a declined amount adds 'not charged' on native.
- The category chip is a button read as '<category>, category. Change' and opens an action sheet; the change is announced, and so is a rollback when onCategoryChange rejects.
- Detail rows are read as one element each on native ('Paid with, Everyday •••• 4242'); the reference row has the hint 'Long press to copy' when onCopyReference is set.
- The split sheet's stepper is adjustable ('People, including you'); the share is plain text that updates with it.
- The report outcome appears in a banner that is announced, not only in a toast.

## Motion

- Split sheet: the stepper's value rolls and each person's share rolls in the direction of the change; the request button gathers into a spinner and opens into 'Requests sent', then the sheet closes and a footer under Details keeps the result.
- Report a problem: the banner slides down and pushes the content, then crossfades from sending to sent or error.
- The category chip and action sheets use their own springs; buttons press on touch down.
- Reduced motion: digits change in place, sheets fade, the banner fades with an instant height change, buttons crossfade their states.

## Haptics

- select on each step of the people stepper, warning at 2 and 12 (QuantityStepper)
- tap on Split, Attach receipt and the split request; success or error when its promise settles (Button)
- tap when a category or report reason is chosen (ActionSheet)
- success or error when an async Banner action settles (Try again)

## Performance

- A static ScrollView; sheets mount only while open, and every animation runs on the UI thread inside the kit components.

## Notes for AI

- Pass transaction.amount signed (negative for spending) with an ISO currency; date is an ISO string or Date. Split is offered only for spending that was not declined.
- onCategoryChange: the chip changes at once; reject to roll it back. onSplit receives the head count including the payer and each share rounded to cents.
- onReport resolves with a case number string (shown in the banner) or nothing; a rejection shows an error banner with Try again.
- hasReceipt switches the receipt button between Attach receipt (shows 'Attached' when the promise resolves) and View receipt; update it from your data after attaching.
- Render it full-bleed with the navigator header hidden (headerShown: false); it handles the safe areas itself.

## Related

- [Wallet home screen](https://goodui.dev/native/components/wallet-home-screen.md): A banking or wallet home: greeting, the balance of the centered card with hide and show, a swipeable card carousel, quick actions, this month's spending as a scrubbable sparkline and recent transactions, all inside pull to refresh. Swiping to another card rolls the balance, morphs the sparkline and swaps the list.
- [List row](https://goodui.dev/native/components/list-row.md): Settings and navigation cells with a token-colored icon tile, title, subtitle and a trailing value, switch, badge, check or chevron, grouped in inset sections with headers and footers. On touch down the highlight floods in, the tile sinks and the chevron leans forward; on release the highlight lingers and fades.
- [Bottom sheet](https://goodui.dev/native/components/bottom-sheet.md): A sheet that rests at detents, follows the finger 1:1, settles with velocity and hands drags off to its scroll view.
- [Action sheet](https://goodui.dev/native/components/action-sheet.md): An iOS-style list of choices that springs up from the bottom edge in grouped cards; it follows the finger to be dragged away, and pulling it up stretches the gap between the cards before they spring back together.
- [Quantity stepper](https://goodui.dev/native/components/quantity-stepper.md): A − value + stepper whose value rolls in the direction of change. Hold a button to repeat with acceleration; the ends push back with a rubber-band bounce and a warning haptic. In a cart the − turns into a trash button at the minimum.
- [Badge](https://goodui.dev/native/components/badge.md): A count, dot or status badge that springs in when it appears, pops when its value changes, caps at 99+ and shrinks away at zero; BadgeAnchor pins it to an icon or avatar.

## Guidance for AI tools

Transaction detail screen: One payment in full: merchant header, the signed amount, a status badge and a category chip that recategorizes, the details as grouped rows, split and receipt actions and Report a problem. The split sheet rolls each person's share as you change the head count. Use only the documented props. Keep accessibility, reduced motion and both color schemes intact when adapting it.

Full library index: https://goodui.dev/native/llms.txt
