Staaarter

Billing Bank Transfer

A bank transfer instruction block for invoices paid by wire or ACH. Shows the amount due, a status badge, and a list of bank details (account number, routing/SWIFT, IBAN) each with a one-click copy button, plus a generated reference code and a short numbered list of next steps. Built for B2B billing portals and high-value invoice payments where a card isn't the preferred rail.

By Staaarter Team
Billing
Updated February 9, 2026
Docs
Live preview

Docs

Installation

A real shadcn registry command, not a copy-paste stand-in: it fetches this block plus its badge, button dependencies and any missing npm packages, and installs them straight into your project.

npx shadcn add https://staaarter.com/r/billing-bank-transfer.json

Prefer not to use the CLI? Copy the source from the Code toggle above into src/components/blocks/billing/billing25.tsx instead.

Usage

The file also exports billing25Demo, the exact props behind the preview above. Spread it to get a working section in one line, then replace it with your own data.

import { Billing25, billing25Demo } from "@/components/blocks/billing/billing25";

export default function Page() {
  return <Billing25 {...billing25Demo} />;
}

Props

PropTypeDefaultDescription
headingstring"Pay by bank transfer"Heading in the card header.
descriptionstringnoneOptional one-line note under the heading.
status"awaiting_transfer" | "processing" | "received""awaiting_transfer"Drives the status badge in the header.
amountDuestringnoneAmount shown in the highlighted total row, as a pre-formatted string.
dueDatestringnoneOptional due date shown next to the amount.
referenceCodestringnonePayment reference the customer should include in their transfer memo. Rendered as its own copyable field.
fieldsBankDetailField[]noneBank detail rows (account holder, account number, SWIFT, IBAN, etc), rendered above the reference code.
instructionsstring[]noneOptional numbered list of next steps shown below the details.
classNamestringnoneExtra classes for the outer container.

Types

interface BankDetailField {
  label: string;
  value: string;
  /** Whether this field gets a copy button. Defaults to true. */
  copyable?: boolean;
}

Behavior notes

  • Every field, plus the referenceCode, gets its own copy button by default; clicking it writes that field's value to the clipboard via navigator.clipboard and swaps the button icon to a checkmark for 2 seconds.
  • If the Clipboard API throws (permission denied, unsupported browser), the copy click is a silent no-op and the button stays in its default state so the user can select the text manually instead.
  • Only one field shows the 'copied' state at a time, tracked by the field's label in a single piece of state, not a per-field boolean array.
  • Set copyable: false on any field (for example a static bank name) to hide its copy button while still listing it.
  • The reference code is appended to the rendered field list internally, you don't need to duplicate it inside the fields array.

Frequently asked questions