# Payments and allocation

> Xero stores one payment record per invoice. QuickBooks and NetSuite write one payment with many allocation lines. Going from the second shape to the first turns one user action into N payment records, and a Xero batch write can fail item by item.

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

---

**How is a payment tied to the documents it settles?** Model a payment as one record with N allocations. Xero simply produces one-line payments — and a Xero write must check each allocation, because the items can fail individually.

## Divergences between Xero, QuickBooks Online and NetSuite

### One user action, N payment records, per-item failure

Settling five invoices with one bank receipt is one payment with five allocations on QBO and NetSuite, and five Payment records on Xero. Xero accepts them in one call — PUT /Payments takes an array, and BatchPayments settles many invoices at once — but with summarizeErrors=false each item succeeds or fails on its own. Three of five succeed and the ledger holds a half-applied receipt that reconciles to nothing.

**Handling:** Write Xero payments through a job with a stable idempotency key, and check the result of every allocation in the response. The payment is not 'recorded' until every allocation succeeds; show a partial state honestly when it does not.

### Unapplied cash is a separate object in Xero and most integrations skip it

Xero splits it into Overpayment (the customer paid too much against an invoice) and Prepayment (they paid before an invoice existed), each with its own endpoint. Neither appears in /Invoices. An AR figure built from invoice balances alone disagrees with Xero's own aging report by exactly the unapplied amount.

**Handling:** Fetch both endpoints, model them as documents with no lines, and give unapplied cash its own row in the aging table. Tie to the ledger's aging report and surface any variance.

### AP payments are a different entity in QuickBooks

Payment settles invoices; BillPayment settles bills. They have different shapes, different fields and different endpoints. A single 'payments' sync that reads only Payment silently omits every supplier payment.

**Handling:** The adapter exposes one payments read that fans out to both entities and tags each with its direction.

## Canonical shape

```ts
type Allocation = {
  documentId: string;         // the invoice or bill being settled
  amount: Money;
  /** Xero writes one record per allocation, so the source ref is per-line, not per-payment. */
  source: SourceRef;
};

type Payment = {
  id: string;
  direction: "receipt" | "disbursement";
  partyId?: string;
  date: string;
  bankAccountId: string;
  method?: string;
  total: Money;
  allocations: Allocation[];
  /** Cash that has landed and settles nothing yet. Its own row in aging. */
  unapplied: Money;
  batchId?: string;
  source: SourceRef;
};
```
