This is the most common quiet tax on construction and field-service bookkeeping, and almost nobody writes about it, because the vendors causing it would rather not.
Here's the shape. You hand your foreman a company card. He buys $412.86 of lumber. He photographs the receipt in an app so the cost lands on the right job. Two days later the charge shows up in the QuickBooks bank feed from the card connection. Now there are two records of one purchase, and somebody has to notice that and clean it up — every time, forever.
The same $412.86, twice
Most receipt-capture tools work exactly one way: read the receipt, then create a transaction in QuickBooks — an Expense or a Purchase — coded to a vendor, an account, and ideally a job. Taken alone that's reasonable. It's how you'd build it, and it demos beautifully.
The problem is that it isn't alone. A company card connected to QuickBooks already delivers that purchase. The bank feed isn't an optional convenience; it's how the card account gets reconciled to the statement at month end. So the app's posting is a second copy of a dollar that was always going to arrive.
What that costs, concretely: your bookkeeper opens the card register, sees two $412.86 lumber-yard lines, has to determine which one came from the feed (the one that reconciles) and which one came from the app (the one carrying the job code and the photo), delete one, and manually move the useful parts onto the survivor. At a company doing forty card purchases a week that's forty small judgment calls, each of which can go wrong. And the failure mode when it goes wrong is not a missing number — it's an inflated one. Job cost reads high, gross margin reads low, and the explanation is buried in a register nobody reviews line by line.
Ask your bookkeeper whether this is happening. If she's been quietly absorbing it, she'll know the exact vendors it happens with most.
Why it's hard: the feed is invisible until a human touches it
If the answer is obviously "match it to the bank feed line instead of posting your own," why doesn't everyone do it? Because of a genuinely awkward property of how QuickBooks works.
Downloaded bank-feed items are not transactions yet. They sit in the For Review queue. They are not exposed to the API as something you can read, search, or attach to. They only become a real Purchase — a thing with an id that software can find — once a human accepts or adds them in the banking screen.
That single fact reorders the whole design. The receipt exists at 9:40 on Tuesday morning, in a parking lot, on a phone. The transaction it belongs to may not exist in any form software can see until Thursday, or until the bookkeeper does her weekly pass, or until the 4th of next month. An integration that tries to match at the moment of capture will find nothing and conclude, wrongly, that it needs to post its own copy.
So a correct design has to be comfortable being unfinished. The receipt has to be a first-class thing that exists, holds its photo and its job code and its total, and waits — for days if needed — without either posting or getting lost.
The fix: hold, then match
Four rules, in order:
- A card receipt is held, never posted. When the field worker submits it, it enters an awaiting-match state with everything a human gave it: total, vendor, job, photo, who took it.
- A background pass retries the match on a schedule. Hourly is plenty. Each pass looks for candidate purchases the bookkeeper has since accepted.
- One candidate means attach it automatically. Exactly one plausible line, no ambiguity, no human needed — attach the photo, fill in the job coding, mark the receipt matched.
- Several candidates means ask. The office sees the receipt beside the two or three possible lines and picks. Never guess between them.
And then one more, which matters as much as the other four: keep an explicit post-anyway exit. Sometimes the card was a personal card that isn't connected. Sometimes the charge was refunded and re-run. Sometimes it's a receipt from 2024 nobody will ever find in a feed. The person in the office must be able to say "I've looked; post it as its own purchase" in one click. A matching system with no escape hatch strands receipts, and stranded receipts are how people lose faith in a tool and go back to a shoebox.
If you want to see this against your own QuickBooks file — your card, your vendors, your crew's actual receipts — book a demo and bring one week of card charges.
The matching rules in detail
The rules are where this gets real, because a sloppy match is worse than no match. What we use, and why:
- Exact amount. Not "close," not a tolerance. The total on the receipt must equal the total on the accepted line to the cent. Card totals aren't approximate, and a tolerance is how a $118.40 fuel stop attaches itself to a $118.42 one.
- A date window, not a date. Cards post on their own schedule — a purchase on Friday afternoon can settle Monday. A window of about four days either side catches almost everything. Widen it for old backlog receipts and for ones that have failed several passes, since those are precisely the cases where the dates have drifted.
- Exclude anything already claimed. Once a receipt is attached to a purchase, that purchase is spoken for. Otherwise two $89 fuel receipts from the same week can both grab the same line and the other one waits forever.
- Exclude your own postings. This is the one that bites people. If your system ever posts purchases itself — cash receipts, post-anyway exits, backlog imports — those are in the register too, and a later receipt can match one of them, producing a self-inflicted mess. Stamp every purchase you create with a marker in a private field and skip anything carrying it.
- Exclude cash-account purchases. A card receipt belongs to the card account. If it matches something paid in cash, the match is wrong by construction.
Notice that all five rules are about refusing matches. That's the correct bias. An unmatched receipt sitting visibly in a queue costs somebody thirty seconds. A wrong match puts a photo of the wrong purchase onto a line that reconciles to the bank, which is an error with no natural discovery mechanism at all.
Cash is the opposite case
Cash receipts post immediately, and the reasoning is a one-liner: no bank feed will ever carry a cash purchase. There is nothing to duplicate and nothing to wait for. Holding a cash receipt for matching would just mean it sits in a queue until someone gives up on it.
So payment method isn't a detail on the form — it's the branch that decides the whole path. Which is why the field app should ask card-or-cash in the plainest possible way, as one big two-button choice, right after the total. It's the question that determines whether the receipt waits or goes.
Enriching the line without overwriting her work
When a match lands, you're editing a transaction the bookkeeper already accepted. Two disciplines apply.
Fill blanks; don't replace decisions. If the line has no customer:job, add it. If the class is empty, set it. If the expense account is still the catch-all "Uncategorized" bucket, replace it with the right one. But if she has already chosen an account, leave it alone. She picked it for a reason — often a tax reason you can't see from a receipt photo — and an app that quietly re-accounts her coding is an app she'll disconnect.
Know the API's sharp edge. QuickBooks sparse updates are sparse at the top level, not inside a transaction's line array. If you send a partial update that includes lines, you must resend the whole line array, or you can wipe lines you didn't mean to touch. This is the one place in this entire workflow where a coding mistake damages real accounting data, so it deserves an integration test rather than a hopeful read of the docs.
What to ask any receipt vendor
Whether you're evaluating us or anyone else, three questions settle it:
- "When my foreman snaps a company-card receipt, do you create a transaction in QuickBooks?" If yes, and your card is on the bank feed, you have signed up for duplicates. There's no configuration that fixes it.
- "What happens to a receipt you can't match?" The acceptable answer is "it stays visible in a queue with a count you can see." Anything involving guessing or silence is disqualifying.
- "Can I force a post when I know matching won't work?" Must be yes, and must be one click, by a person, with a record of who did it.
Our answers, for the record: receipts are held and matched, unmatched ones sit in a visible queue on the integrations screen, and post-anyway is an explicit button. The mechanics are on the receipt-capture feature page; the downstream half — how the coded dollar reaches the project's cost report — is in the QuickBooks-to-Autodesk post and on the sync feature page.
And the honest caveat: if your company cards aren't connected to QuickBooks at all — some contractors deliberately key card statements in monthly — none of this applies to you and a plain posting app is fine. Matching solves a problem created by the bank feed. No feed, no problem.
If you do run the feed, the fix is worth chasing down. It's not a big feature. It's the difference between a receipt workflow your bookkeeper defends and one she works around.