Skip to content

Fix precision loss: use atomic units for monetary amounts instead of Number() #166

@coderabbitai

Description

@coderabbitai

Problem

Converting monetary amounts to JavaScript Number can cause silent precision loss, which is unsafe for financial operations.

Current Implementation

In src/app/(dashboard)/s/[id]/_components/subscription-plan-preview.tsx (line ~97):

const recurringPaymentBody = {
  payee: subscriptionPlan.recipient,
  amount: Number(subscriptionPlan.amount),  // ⚠️ Unsafe conversion
  invoiceCurrency: subscriptionPlan.paymentCurrency as PayoutCurrency,
  // ...
};

Suggested Solution

Send atomic units (string or bigint) end-to-end to avoid precision loss:

const recurringPaymentBody = {
  payee: subscriptionPlan.recipient,
  amountAtomic: amount.toString(),  // Send as string
  invoiceCurrency: subscriptionPlan.paymentCurrency as PayoutCurrency,
  // ...
};

Required Changes

  1. Update the recurringPaymentBody to use amountAtomic: string (or bigint)
  2. Update useCreateRecurringPayment hook to accept atomic units
  3. Update API types and backend handlers to accept and validate atomic unit strings
  4. Compute human-readable display values from atomic units when needed

Context

Impact

Priority: High - affects financial calculations and could lead to incorrect payment amounts.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

Status

🎫 Backlog

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions