Counterparts
Manages an organization's customers or vendors: a searchable list with money columns, a details sheet, and create, edit and delete flows, including addresses and a vendor's ACH payment method.
Part ofFinOps
Manages an organization's customers or vendors: a searchable list with money columns, a details sheet, and create, edit and delete flows, including addresses and a vendor's ACH payment method.
Quick Start
import { CounterpartsWidget } from '@tesouro/embedded-components-react';
export function CustomersPage() {
return (
<CounterpartsWidget
counterpartType="customer"
baseUrl="https://api.tesouro.com"
widgetToken="wt_..."
organizationId="org_..."
/>
);
}Pass counterpartType="vendor" for vendors. Data loads once widgetToken and organizationId resolve.
Behaviour
- Permissions come from the widget token's scopes; there are no permission props. Without
counterpart:read,counterpart:read:orgorcounterpart:read:ownthe widget shows an access-restricted state and loads no data. - Create, edit (including address and payment method) and delete actions appear only with
counterpart:create,counterpart:updateorcounterpart:deleterespectively, orcounterpart:write:org. The:ownvariants don't enable them. - Customers show Billed amount, Received amount and Amount due; vendors show Billed amount, Total paid to date and Balance due.
- The list filters by search and by type (individuals or companies). Applied filters show as removable chips with a "Clear all" action.
- The list and open details refresh after every change; you don't need to refetch.
- Addresses are US only: country is fixed to the United States with a US state picker.
- Contact and VAT details can't be managed in this widget.
Props
Widget props
Each label prop is merged over the English defaults, so pass only the strings you want to change.
See the exported label types listed under TypeScript for every key.
| Prop | Type | Default | Description |
|---|---|---|---|
counterpartType | 'customer' | 'vendor' | Required | Selects the customer or vendor surface. |
pageSizeOptions | number[] | [10, 25, 50, 100] | Page-size choices shown by the table. The list opens at the first one. |
onViewAllDocumentsEvent |
| undefined | Shows a "View all" action by the details sheet's recent bills/invoices and passes the counterpart's id and name. Hidden when omitted. |
onCreateDocumentEvent |
| undefined | Runs the details sheet's "Send a payment" (vendor) or "Issue an invoice" (customer) button. Hidden when omitted; you check the scopes it needs. |
Label overrides
| Prop | Type | Default | Description |
|---|---|---|---|
screenLabelsLabels | Partial<CounterpartsScreenLabels> | English labels | Table, search/filter, empty, error and access-restricted copy. |
formLabelsLabels |
| English labels | Create/edit form copy. |
detailsLabelsLabels |
| English labels | Details sheet copy. |
bankAccountLabelsLabels |
| English labels | Vendor payment-method form copy. |
addressLabelsLabels |
| English labels | Address form copy. |
deleteLabelsLabels |
| English labels | Delete-dialog copy. |
messageLabelsLabels | Partial<CounterpartMessageLabels> | English labels | Validation, API failure and delete-prompt messages. |
Examples
Link the details sheet to your documents
<CounterpartsWidget
counterpartType="vendor"
onViewAllDocuments={({ id }) => router.push(`/bills?vendor=${id}`)}
onCreateDocument={({ id }) => router.push(`/bills/new?vendor=${id}`)}
/>Custom labels
<CounterpartsWidget
counterpartType="customer"
screenLabels={{ createButton: 'Add client' }}
detailsLabels={{ customerSubtitleLabel: 'Client' }}
messageLabels={{ genericError: 'We could not save this client.' }}
/>TypeScript
import type {
CounterpartsWidgetProps,
CounterpartMode,
CounterpartActionTarget,
CounterpartsScreenLabels,
CounterpartFormSheetLabels,
CounterpartDetailsSheetLabels,
BankAccountFormSheetLabels,
AddressFormSheetLabels,
ConfirmDeleteDialogLabels,
CounterpartMessageLabels,
} from '@tesouro/embedded-components-react';