# Credit notes and refunds

> Every negative document is a distinct object with its own numbering, stored with positive amounts, and reconciled separately by the finance team. Merging them into a signed invoice column destroys the audit path.

Source: https://lopifi.com/apis/credit-notes
Part of: Lopifi — US GAAP books on autopilot, reviewed by a CPA (https://lopifi.com)

---

**What object reduces an invoice, and what returns the cash?** Never render a credit note as a negative invoice. Amounts are stored positive everywhere; direction lives in the document type.

## Divergences between Xero, QuickBooks Online and NetSuite

### Refunds are a third object, not a mode of the credit note

Reducing a receivable and returning cash are separate events with separate documents in all three systems, and QuickBooks needs two objects (VendorCredit plus Deposit) to express a vendor refund at all. A UI that treats 'credit' and 'refund' as one action will produce the wrong pair of records.

**Handling:** Model the credit and the cash movement as two linked records, and make the UI ask which one the user means before it writes anything.

### Sign flipping is a one-place decision

All three store positive amounts and encode direction in the type. If normalisation flips signs for display or for aggregation, doing it in two places produces a double negation that reads as a plausible number and survives review.

**Handling:** Flip once, at the boundary between the canonical model and the presentation layer, and test the round trip. The ledger table renders debit and credit as two columns, never one signed column.

## Canonical shape

```ts
/* Credit notes reuse LedgerDocument with a distinct type. The amounts stay
   positive; the type carries the direction; the statement layer decides sign. */
type CreditNote = LedgerDocument & {
  type: "sales_credit" | "purchase_credit";
  remaining: Money;              // unallocated portion
  allocations: Allocation[];     // documents this credit has been applied to
  refund?: { paymentId: string; amount: Money };
};
```
