This tool lets you backfill historical dues, fees, assessments, payments, and credits against individual units. It's designed for onboarding or reconstructing account history without affecting your General Ledger.
Where to Find It
Admin β Financials β Import Tools β Unit Ledger History
Before You Begin
Import your properties/units first. Addresses in your CSV are matched against existing properties in your system by street address. Any rows with unmatched addresses will be flagged as warnings.
Preview before committing. The tool always runs in preview mode first - you'll see every row classified as ready, warning, or error before anything is written to the database.
Balances are recalculated automatically for each affected unit after the import completes.
CSV Format
Your CSV needs these columns (header names are case-insensitive and accept several common aliases):
Column | Required | Description |
| Yes | Street address that matches a property in your system (e.g. |
| Yes | Transaction date in |
| Yes | One of: |
| Yes | Free-text description (e.g. "2024 Annual Dues") |
| Yes | Always a positive number - the sign is inferred from the type. Payments and credits become negative automatically. |
| No |
|
Header aliases: address, property, street_address, transaction_date, due_date, charge_type, transaction_type, memo, notes, total, and charge_status are all accepted.
The Two Approaches - Pick One Per Unit
This is the most important thing to get right. There are two valid ways to represent historical charges that have been paid, and mixing them will double-count the money and create phantom credit balances.
π Approach A: Import Charges as "Paid" (Recommended for Fully Settled History)
Each row is a self-contained historical record. Set status to paid on every charge row. Do not add separate payment rows.
Example:
unit_address,date,type,description,amount,status
123 Main St,01/15/2024,annual_dues,2024 Annual Dues,400.00,paid
123 Main St,03/31/2024,late_fee,Q1 Late Fee,25.00,paid
What happens behind the scenes: Each charge is created with status paid. No OfflinePayment records are created. The unit's charge history shows each settled charge. The balance is $0.
When to use this approach:
You're backfilling years of history that's already fully settled
Each charge was paid in full with its own transaction
You don't need to track which specific payments covered which specific charges
π Approach B: Import Charges as "Pending" + Separate Payment Rows
Leave charges with status set to pending (or blank β but note the default is paid, so you must explicitly set pending). Then add separate rows with type payment to represent the money that came in.
Example:
unit_address,date,type,description,amount,status
123 Main St,01/15/2024,annual_dues,2024 Annual Dues,400.00,pending
123 Main St,03/31/2024,late_fee,Q1 Late Fee,25.00,pending
123 Main St,04/10/2024,payment,Check #1234,425.00,
What happens behind the scenes: Two charges are created as pending. One OfflinePayment of $425 is created and auto-allocated to the oldest outstanding charges first. Both charges become paid (or partially_paid if the payment doesn't cover them fully). Any remainder becomes a credit on the unit.
When to use this approach:
One payment covers multiple charges
The payment amount differs from the charge total (partial payment, overpayment)
You want to preserve the original payment-to-charge relationships
You need to record overpayments as credits on the unit
βΌοΈ Critical Rule: Do Not Mix Approaches
Do not import a charge as paid AND include a separate payment row that also covers that charge. This double-counts the money:
The charge shows $400 with status
paid(settled)The payment row creates a $400
OfflinePaymenton the accountResult: unit shows a phantom $400 credit balance
If this happens: You'll see a credit on the account that doesn't reflect real money. The fix is to either delete the duplicate payment rows OR change the charges back to pending and let the system re-allocate.
Multiple Payments on the Same Unit
Approach B handles multiple payment rows cleanly. Payments are processed in date order, and each one auto-allocates against the oldest outstanding charges first:
unit_address,date,type,description,amount,status
123 Main St, 01/15/2024, annual_dues,2024 Annual Dues, 400.00, pending
123 Main St, 06/30/2024, special_assessment, Roof Assessment, 200.00, pending
123 Main St, 02/01/2024, payment, Check #1100, 400.00
123 Main St, 07/05/2024, payment, Check #1250, 250.00
Result: The $400 payment pays off the annual dues. The $250 payment covers the $200 assessment and leaves a $50 credit on the account.
Special Transaction Types
prior_balanceβ Use this for opening balances at the start of a fiscal year. Treated as a charge (positive).creditβ Same effect as apaymentrow: reduces balance, auto-allocates to outstanding charges, any remainder becomes a credit on the unit.late_fee,fine,special_assessment,otherβ All treated as regular charges.
How the Preview Works
When you upload your CSV, the system:
Parses every row and normalizes headers
Matches each
unit_addressagainst your existing properties using fuzzy street-address matchingClassifies each row:
Ready β all required fields valid, address matched β will be imported
Warning β address couldn't be matched β row will be skipped
Error β missing/invalid data (bad date, invalid type, zero amount) β row will be skipped
Flags duplicates β rows with the same address, date, type, and amount are flagged but still imported (you may have legitimate duplicates, like two late fees on the same day)
Shows a summary with counts: ready, warnings, errors, total charges, total credits, unique units affected
You then confirm to execute the actual import.
What Happens During Import
Phase 1: Charges are created first (all non-payment/credit rows). Each becomes a
UnitChargewith the status you specified.Phase 2: Payments/Credits are created as
OfflinePaymentrecords and auto-allocated against outstanding charges on the same unit (oldest first).Phase 3: Balance Recalculation β every affected unit's account summary is recomputed.
Multi-Year History
You can include multiple years of transactions in a single CSV. The system sorts and processes everything correctly. There's no year limit.
Verifying the Results
After import, navigate to Community Management β Units β [any affected unit] and check:
Charge History β should show each charge with the correct status
Payment History β should show any payments imported under Approach B (labeled "Imported")
Account Summary β balance should match your expectation
If a balance looks wrong:
Most common cause: mixed Approach A and Approach B for the same unit
Vlge Support team can "Recalculate All Balances" to force a full re-computation across all units if needed
Troubleshooting
Problem | Likely Cause | Fix |
Unit shows phantom credit balance | Mixed Approach A (paid charges) with payment rows for the same period | If this happens, you should contact support so we can reverse that import. For audit purposes, payments typically cannot be deleted at the organization level. |
Address not matched | CSV address doesn't match property address closely enough | Edit the CSV to use the exact street format, or add the property first |
Dates off by one day | Date format ambiguity or timezone issue | Use |
Charges imported but no payment history | Used Approach A (payments embedded as "paid" status) | This is correct behavior - Payment History only shows separate payment rows |
Balance didn't update | Rare - import completed before balance job finished | Contact support to Recalculate All Balances |
Download a Template
On the import page, click Download Template to get a sample CSV with the correct column headers and example rows.
