Skip to content

Invoice Payment Split Calculator with Tax Deduction #399

Description

@Kingsman-99

Description

Invoices involving multiple recipients often require complex split logic that accounts for jurisdiction-specific tax withholding before each payout is calculated. Currently creators must compute net amounts externally and paste results in. This issue adds an interactive split calculator panel on /invoice/new and /invoice/[id] that takes a gross total, applies configurable tax and fee deduction rates per recipient line, and outputs the resulting net XLM/USDC amounts in real time. The calculator state must be serialised into the invoice payload so the breakdown persists on reload.

Technical Context

Create components/invoice/SplitCalculator.tsx backed by hooks/useSplitCalculator.ts containing pure calculation logic unit-tested independently. The hook should accept an array of RecipientLine objects with { address, sharePercent, taxRatePercent, fixedFeeXLM } and return derived netAmount and effectiveTaxAmount per line. Wire the component into app/invoice/new/page.tsx beneath the recipient list. Persist calculator state inside the invoice JSON schema under a splitMeta key via app/api/invoices/[id]/route.ts. The calculation must re-run reactively on any change to totalAmount, assetCode, or any RecipientLine field. Use zod for schema validation of the splitMeta payload.

Acceptance Criteria

  • Changing the gross total or any recipient's share or tax-rate field recalculates all net amounts within one render cycle with no stale values visible
  • The sum of all recipient sharePercent values is validated to equal 100% and a blocking inline error prevents form submission when the constraint is violated
  • Calculator state (tax rates, fixed fees) round-trips through the API: a saved invoice reloads with identical split metadata
  • Net amounts display in the selected asset (XLM or USDC) with 7-decimal precision matching Stellar's stroop convention
  • Unit tests cover edge cases: single recipient 100%, zero tax rate, recipient removed mid-session, total changed after tax applied
  • All CI checks (npm test, npm run build, ESLint/TypeScript) pass and the branch has no merge conflicts

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions