How Fogo stopped counting refunds as income — and why fixing that naively breaks the number in the other direction.
1. The framing lie
A refund lands in your account: $1,205 back from a cancelled trip. Most finance apps do something quietly wrong with it. Because the deposit is money-in and carries an income-ish flow type, it gets folded into the month's income. Now the app tells you that you "earned" $12,100 in a month you actually earned $9,759 — and every figure built on top of that inherits the error. Your savings rate, in particular: divide the same dollars saved by an inflated income and the percentage moves for a reason that has nothing to do with your behavior.
This is the exact bug Fogo shipped and then hunted down. The tell was a savings rate that read lower than it should have — because the refund had bloated the denominator. The money was real; the label was a lie.
The cleanest way to see why is a register analogy. An income line is a store's revenue report — "what did you earn?", not "what hit the account?" A store that booked customer returns as new sales would post fake growth: the returns inflate revenue while the original sales are still sitting in the same report. Counting a refund as income is precisely that — booking a return as a sale. A refund didn't make you richer. It restored you to the moment before a purchase.
2. The one triage question
Every inflow can be sorted by a single question, and the whole model falls out of it:
Is this new money, or your own money coming back?
- Your own money coming back — refunds, reimbursements. This is un-spending. It should reduce the category you spent in, not appear as income. It never made you wealthier.
- New money from labor or ownership — salary, freelance, dividends, interest. This is income: the baseline you plan against, and the denominator of your savings rate.
- New money that's one-off or odd — cashback, a gift, a tax refund, a signup bonus, an unknowable deposit. This is a windfall: real money that belongs in the month's cash-in, but never in the expected-income baseline and never in the savings-rate denominator.
Two corrections to the obvious first instinct are worth stating, because they're where most apps get it subtly wrong:
Cashback is not income — it's a rebate. Economically, credit-card rewards earned by spending are a retroactive discount on what you bought. The IRS agrees and has for years: rewards earned through spending are treated as a purchase-price adjustment, not taxable income — whereas a bank signup bonus that requires no spending (just opening an account) is income. That distinction — did you have to spend to get it? — is exactly the "new money vs. your own money back" line, drawn by the tax code.
A reimbursement isn't "money with nowhere to go." The $600 your employer paid back for a work trip has spend to net against — not a single purchase, but a pool of trip charges. The honest move is to cancel it against that pool, not to wave it through as salary.
3. The mirror-image lie
Here's the part that makes this genuinely hard, and it's the part worth remembering.
Once you see that refunds shouldn't be income, the tempting fix is one line: stop counting them. Strip refunds out of the income figure and ship it. But that quietly commits the opposite lie.
Savings, in dollars, is roughly money in minus money spent. If you pull a $1,205 refund out of income but the original $1,205 purchase is still sitting in your spending, you've just erased $1,205 of real money from one side of the equation and nowhere else. Your savings now reads $1,205 too low. You traded "refunds inflate my income" for "refunds vanish from my savings." Both are wrong; you've only changed which direction you're wrong in.
Software engineers will recognize the shape. It's the overloaded field — a single figure quietly answering two different questions, where every bug is a reader consuming it for the meaning it didn't encode. "Income received" was doing double duty: it was both the revenue line (what did you earn?) and the cash-in total (how much money arrived?). Those diverge exactly when a refund shows up. The fix is never a cleverer rule on the one figure — it's to split the axis into the two properties it was conflating:
- Honest income (earned + passive) → the revenue line, and the savings-rate denominator.
- Cash-in (honest income + windfall) → the money-that-arrived total, and the numerator of savings dollars.
With the axis split, both statements are true at once: your income line is honest, and no real dollar disappears from your savings. Net a refund against its purchase and it cancels cleanly — out of income, out of spend, savings unchanged. Leave a windfall genuinely unplaceable and it shows on a visible "other inflows" line: counted in the month's cash-in, kept out of the rate. Nothing inflated, nothing vanished.
| Inflow | Bucket | In the income line? | In savings-rate denominator? | In cash-in dollars? |
|---|---|---|---|---|
| Salary, dividends, interest | Income | Yes | Yes | Yes |
| Matched refund | Netting | No — nets against the purchase | No | Cancels (money back on a debit) |
| Cashback, gift, tax refund | Windfall | No | No | Yes |
4. Handle it, but leave the receipt
A model is only honest if the app acts on it, and acting means netting refunds automatically — a budget app that makes you hand-match every return is one nobody uses. But an app that silently rewrites your categories is one nobody trusts.
Fogo's resolution: net the obvious matches automatically — same merchant, exact opposite amount, tight window — and leave a receipt. "Fogo handled — netted 3 refunds, $187 back," with one-tap undo on each. The automation buys the friction-free part; the receipt and the undo buy the trust. The rule that keeps it safe is deliberately strict: Fogo only auto-nets what it can also show you. Anything older or more ambiguous than the receipt window becomes a question, not a silent edit — because an auto-action is only as trustworthy as it is visible. A helpful assistant tidies the desk and leaves a note listing exactly what moved.
The principle
Honesty in a financial number is two-sided. The obvious lie — counting returns as income — has a symmetric twin: excluding real money from everything and understating what you kept. Correcting one without the other just swaps which way you're wrong. The fix is never "remove the bad number." It's to model where every dollar actually belongs — earned, returned, or windfall — so that nothing is double-counted, and nothing quietly disappears.