Skip to content
WingoUI
ComponentsTemplatesDocsPricingAI agentsBlogChangelogContact
Components
Buttons & Actions
ButtonButton GroupCopy ButtonDelete ButtonTheme ToggleToggleToggle Group
Inputs
Avatar UploadCalendarCheckboxColor PickerComboboxCountry SelectCron PickerCurrency InputDate PickerDate Range PickerDate Time PickerDuration PickerEmail InputEmoji PickerFile UploadFilter BuilderInputInput GroupListboxMasked InputMention InputMonth PickerMulti SelectNumber InputOTP InputPassword InputPhone InputRadio GroupRatingSearch InputSegmented ControlSelectSignature PadSliderSwitchTag InputTextareaTime PickerTimezone SelectTree Select
Forms
Address InputBooking WidgetCSV ImportFieldForm WizardInline EditInvoice line itemsRich Text EditorSchema Builder
Navigation
Back To TopBounce SidebarBreadcrumbCommand MenuGlobal SearchGooey NavHook SidebarNav MenuNav TabsPaginationProximity SidebarScroll ProgressSidebarStepsTable Of ContentsTabsTopbarUser MenuWorkspace Switcher
Overlays
Alert DialogContext MenuDialogDrawerDropdown MenuFamily DrawerHover CardPopoverShare DialogSheetShortcuts DialogTooltipTour
Feedback
AlertBannerCookie ConsentEmoji ReactionEmpty StateNotification BellNotification CenterProgressRoute ProgressSetup ChecklistSkeletonSpinnerToast
Data Display
Approval FlowAvatarBadgeCalendar ViewCode BlockComment ThreadContact cardCountdownDescription ListDiff ViewerFile ListFile managerFolderGanttJSON ViewerKbdLog ViewerMarkdownPresenceSchedulerTagTimelineTree View
Tables & Lists
Audit LogData TableDeal PipelineEditable GridKanbanListMembers tablePermissions MatrixTableTask ListVirtual List
Charts & Stats
Animated CounterArea chartBar chartDonut chartFunnel chartGaugeGitHub ActivityHeatmap calendarLeaderboardLine chartRadar chartRadial barSparklineStat CardTrackerTrend badge
Layout
AccordionApp ShellCardCollapsibleDetail LayoutEntity HeaderPage HeaderScroll AreaSeparatorSettings LayoutSplit ViewToolbar
Media
Audio PlayerCarouselCSV ViewerDOCX EditorDOCX ViewerExcel ViewerFile SystemImage compareImage CropperImage GalleryImage LightboxLocation MapPDF ViewerPowerPoint ViewerQR CodeStep PlayerVideo Player
AI Kit
Agent Status CardChat MessageChat ThreadChat WidgetConversation ListFluid OrbGrid RevealMatrix OrbModel PickerPrompt InputReasoning IndicatorRule BuilderSuggestion ChipsTool Call TimelineUsage MeterVoice InputWorkflow Canvas
Text & Effects
Background PatternGravity LettersMarqueeTerminalText AnimateText Rotate
Mobile
Action SheetBottom Tab BarFABHaptic ButtonHero HeaderInstall PromptLarge Title HeaderNotification BannerOnboarding CarouselPicker WheelPull To RefreshSlide To ConfirmSticky CTA BarSwipe DeckSwipeable Tabs
Commerce
Cart drawerCategory pickerCheckout stepsCoupon inputFavorite buttonFilter panelListing cardListing gridOrder trackerPricePrice rangePricing tableProduct galleryQuantity stepperReviewsSeller card
Marketing Sections
App Download SectionBlog Cards SectionCTA SectionFAQ SectionFeature GridFeature ShowcaseHero SectionIntegrations SectionLogo CloudMarketing FooterMarketing HeaderMarketing SectionNewsletter SectionPricing SectionStats SectionSteps SectionTeam SectionTestimonials SectionTimeline SectionVideo Section
Blocks
Admin Dashboard PageAdmin ShellAI Chat PageAPI Keys PageAutomation Builder PageCheckout PageCRM Contact PageCRM Pipeline PageError PagesInbox PageInvoice PageKPI DashboardListing Detail PageLogin PageMarketplace Home PageMarketplace Search PageMarketplace ShellMobile App HomeOnboarding FlowOrder History PagePost Listing WizardPricing PageProfile PageRegister PageSettings PageUsers Admin Page
Templates
About PageAcademy PageAccessibility PageAffiliate PageAgency PageAI Product PageAppointment Booking PageBlog PageBlog Post PageBug Bounty PageCareers PageChangelog PageCommunity PageCompare PageContact PageCustomer Story PageCustomers PageDemo Booking PageDevelopers PageDocs Home PageDownload PageEnterprise PageEvents PageExperts PageFAQ PageFeature PageGlossary PageHelp Article PageHelp Center PageHome Services PageImpact PageIntegration Detail PageIntegrations PageJob Detail PageLanding PageLaunch PageLegal PageManifesto PagePortfolio PagePress PageProduct Tour PagePromo PageReal Estate PageReferral PageResearch Report PageRestaurant PageRoadmap PageROI Calculator PageSecurity PageSolutions PageStartups PageStatus PageStorefront PageSwitch PageTemplate Gallery PageTravel PageWaitlist PageYear in Review Page
Hooks & Utilities
AI ChatChart kitCommerceDate utilsFile exportFile typesFiltersForm validationHapticsInvoicingMotion presetsNavigationNumber formatRelative timeRomanian locationsSpreadsheetText matchTonesUIProvideruseClipboarduseConsentuseControllableStateuseCooldownuseDebounceuseKeyboardInsetuseLocaleuseLongPressuseMediaControlsuseMediaQueryuseOverflowItemsusePersistedStateuseScrollEdgesuseScrollStateuseSelectionuseShortcutuseStickToBottom
GalleryTheme

Hooks & Utilities

Invoicing

Hooks & Utilities

Invoicing TypeScript helper for React

HapticsMotion presets
Live props
Options
pricesIncludeVat
discountNone
discountType
locale
code
  1. Home
  2. Components
  3. Hooks & Utilities
  4. Invoicing
Pro

Invoicing TypeScript helper for React

v1.0.0·Added in 1.0.0

Invoice math for React billing apps: VAT per rate the way e-Factura checks it, Romanian VAT rates, and CUI, IBAN and CNP validation.

Change the quantities of the invoice lines with − and +: the net per line, the VAT breakdown per rate (21% and 11%), the discounts and the total are one computeInvoiceTotals call. Turn on prices with VAT, set a document discount in percent or as an amount, and see the VAT stay exact per rate. Type any CUI, IBAN or CNP in the checker: it recognises which one it is, validates the control digit, names the bank of a Romanian IBAN and reads the birth date and county from a CNP.

Invoicing is a Pro React helper in the React hooks and utilities category, written in TypeScript for React 19. It installs as source with npx wingo-ui@latest add invoicing, together with Commerce and Number format.

Add to a project

Requirements: React 19, in Next.js (App Router or Pages), Vite or React Router. Installation guide · Next.js setup · Vite setup

npx wingo-ui@latest add invoicing

Invoicing is part of Pro, with 298 more Pro items: $8 a month or $150 once. 14-day refund before you download any Pro item. See plans

Usage

Import computeInvoiceTotals from @/lib/invoicing.

import { computeInvoiceTotals, formatVatRate, isValidCui } from "@/lib/invoicing"
import { formatPrice } from "@/lib/commerce"

const totals = computeInvoiceTotals(
  [
    { id: "l1", quantity: 3, unitPrice: 1250, vatRate: 0.21, discount: 10 },
    { id: "l2", quantity: 12, unitPrice: 64.9, vatRate: 0.11 },
  ],
  { discount: { type: "amount", value: 100 } },
)

totals.vatBreakdown.map((row) => `VAT ${formatVatRate(row.rate, "en-US")}: ${formatPrice(row.vat, { locale: "en-US", currency: "USD" })}`)
formatPrice(totals.total, { locale: "en-US", currency: "USD" }) // "$4,829.10"
isValidCui("RO12345674") // true

API

  • pricesIncludeVatdefault false
    boolean

    options.pricesIncludeVat: false for B2B invoices (unit prices without VAT, VAT added), true for shops and B2C quotes (VAT inside the prices).

  • discountdefault 0
    number

    The demo's document discount, options.discount.value: shared across lines by value after their own discounts, so every VAT rate stays exact.

  • discountTypedefault "amount"
    "percent" | "amount"

    options.discount.type: a percent of the subtotal or a fixed amount (dollars in the demo).

  • localedefault "en-US"
    string

    The demo's formatting locale (formatPrice from commerce, formatVatRate).

  • codedefault "RO12345674"
    string

    The demo's id checker: a CUI (with or without RO), an IBAN or a CNP.

  • computeInvoiceTotals
    (lines: InvoiceLineInput[], options?: InvoiceTotalsOptions) => InvoiceTotals

    Lines are { id, quantity, unitPrice, vatRate? (0.21), discount?, discountType?: "percent" | "amount" }; options { pricesIncludeVat, discount: { type, value }, defaultVatRate, categoryFor, decimals }. Returns lines (gross, discount, net, vat, total each), gross, lineDiscount, documentDiscount, discount, net, vat, total and vatBreakdown (one row per rate: rate, category, net, vat, total, lineCount). VAT is rounded once per rate on its taxable amount (EN 16931 BR-CO-17, what e-Factura validates), so per-line VAT is informative and the totals always add up.

Parts

  • computeInvoiceLine

    function

    One line on its own (gross, discount, net, VAT and total), for the row of a line editor. Takes the same line and options as computeInvoiceTotals.

  • RO_VAT_RATES

    constant

    Options for a VAT select, each { value, rate, category, label, description }: 21% standard, 11% reduced, and 0% exempt (E), reverse charge (AE) and intra-community supply (K).

  • RO_VAT_RATE

    constant

    Romania's standard VAT rate as a fraction, 0.21, in force since Aug 1, 2025. Re-exported from commerce.

  • RO_REDUCED_VAT_RATE

    constant

    Romania's reduced VAT rate, 0.11, for food, medicines, books and accommodation. Re-exported from commerce.

  • formatVatRate

    function

    A VAT rate as text in the locale: formatVatRate(0.21, "en-US") is "21%" ("21 %" in ro-RO).

  • incrementDocumentNumber

    function

    The next number of an invoice series, keeping its padding and prefix: "2026-0412" becomes "2026-0413", "CRP 099" becomes "CRP 100".

  • parseCui

    function

    Reads a Romanian company code (CUI / CIF) such as "RO 12345674": { digits, vatPayer, valid } with the ANAF control digit checked, or null when it is not 2 to 10 digits.

  • isValidCui

    function

    Whether a CUI's control digit holds: RO12345674 is valid, RO12345678 is not.

  • formatCui

    function

    A CUI written the standard way: "RO12345674" for VAT payers, "12345674" otherwise. Returns the input unchanged when it is not a CUI.

  • isValidIban

    function

    The ISO 13616 mod-97 check with each country's length, for Romanian and other European IBANs.

  • formatIban

    function

    An IBAN in groups of four for display: "RO49 AAAA 1B31 0075 9384 0000".

  • getIbanBank

    function

    The bank of a Romanian IBAN from its four-letter code, e.g. { code: "BTRL", name: "Banca Transilvania" }; null for other countries or unknown codes.

  • RO_BANKS

    constant

    Romanian bank names by IBAN bank code (BTRL, RNCB, BRDE, INGB and more), the table getIbanBank reads.

  • parseCnp

    function

    Reads a Romanian personal numeric code (CNP): { valid, sex, birthDate, countyCode, countyName, anonymous } with the control digit, date and county checked, or null when it is not 13 digits.

  • isValidCnp

    function

    Whether a CNP is valid. "0000000000000", the e-Factura placeholder for a buyer who gave no CNP, counts as valid.

  • VatCategory

    type

    The UBL / EN 16931 VAT category codes an e-Factura line carries: S, Z, E, AE, K, G, O.

  • InvoiceLineInput

    type

    { id, quantity, unitPrice, vatRate?, discount?, discountType? }, one line of an invoice or quote.

  • InvoiceTotals

    type

    What computeInvoiceTotals returns: lines, gross, discounts, net, VAT, total and the VAT breakdown per rate.

Examples

VAT rate options

RO_VAT_RATES for a line's VAT select, with the e-Factura category of each.

Invoice numbering

incrementDocumentNumber keeps the prefix and the zero padding of a series.

CUI and IBAN checks

Control digits, the standard written form and the bank of a Romanian IBAN.

Dependencies

commercenumber-format

Files

  • lib/invoicing.ts

FAQ

Is the Invoicing helper free?

The preview, props and docs are free; copying the source needs a Pro plan. See plans.

How do I install Invoicing?

Run npx wingo-ui@latest add invoicing. It also adds the Wingo UI items it builds on (Commerce and Number format). With shadcn, add the @wingo-ui registry with your API key, then run npx shadcn@latest add @wingo-ui/invoicing.

See also

CommercelibNumber formatlibMasked Input

Used in

CSV ImportInvoice line itemsCRM Contact PageInvoice PageRegister PageForm validationlib

More React hooks and utilities

Motion presetslibNavigationlibRelative timelibRomanian locationslibSpreadsheetlibText matchlib
All 36 React hooks and utilities

Articles using this component

  • React Invoice Template: Line Items, VAT and Print View

    Build it: screens and apps · Oct 16, 2026 · 10 min read

  • E-Factura VAT Calculation in TypeScript and React

    Build it: screens and apps · Oct 9, 2026 · 11 min read

  • IBAN Validation JavaScript: Mod 97, Regex and a React Field

    Component guides · Oct 9, 2026 · 12 min read

  • Romanian CNP Validator in TypeScript, Zod and React

    Component guides · Oct 9, 2026 · 13 min read

PreviousHapticsNext Motion presets
Invoice #2026-0412prices excl. VAT
  • Northwind CRM Business license$1,250.00/month · VAT 21% · -10%
    $3,375.00
    3
  • Setup and training$320.00/hour · VAT 21%
    $1,920.00
    6
  • Carpathian Mountains guide (book)$64.90/pc · VAT 11%
    $778.80
    12
Value before discounts$6,448.80
Discounts-$375.00
Total excl. VAT$6,073.80
VAT 21% on $5,295.00$1,111.95
VAT 11% on $778.80$85.67
Amount due$7,271.42
CUI validRO12345674 · VAT payer