A free reconciliation spreadsheet template for Shopify and Stripe payouts (and how to actually use it)
A store doing real volume eventually asks the question one r/ecommerce poster put plainly: "For brands doing decent volume, is this mostly handled in Excel manually? Or are there tools people rely on?" The honest answer is that a spreadsheet handles it fine for a long time — if it is built right. The best community answer to that thread says exactly what to do and stops just short of how: most brands "create one clean master sheet that pulls Shopify payouts and gateway fees weekly and reconcile against bank deposits line by line. The no cost fix is discipline and a clear process owner." Correct. But nobody ever hands over the sheet. So here it is — and the one structural decision that separates a master sheet that ties out from one that quietly lies to you.
Is there a reconciliation spreadsheet template I can just use?
Yes — the one above — and for most stores a sheet is the right tool well past the point people assume they have outgrown it. The reason home-built versions fail is almost never the formulas. It is that they reconcile the wrong two things: total sales against the bank deposit. Those two numbers will never be equal, and no amount of XLOOKUP fixes that, because they are not supposed to be equal. The template is built around the number that sits between them — the payout — and that single change is what makes it tie.
Everything below explains how to use it: why sales and the deposit diverge, the structure that resolves it, the six steps to build it from your own exports, and how to read the only column that needs your attention.
Why your sales never equal the bank deposit
A bookkeeper in r/Bookkeeping described the exact trap the master sheet has to avoid: "I keep running into situations where the bank deposit from Stripe/Shopify/PayPal is lower than the sales showing in QuickBooks, and then I have to dig through fees, refunds, chargebacks, and timing differences to figure out what happened." The most useful reply named the cause without dressing it up: "the mismatch is usually because QBO records the gross sale amount but your bank gets the net deposit after processing fees. if you're recording both and trying to match them 1:1 they'll never line up."
That is the whole problem in two sentences. A single payout is not one sale — it is a batch. The processor takes a window of transactions, subtracts its processing fees, refunds you issued, and any chargebacks or dispute fees, and wires you the net. Refunds you process come out of the next available payout, not the one the sale was in, so the timing never lines up cleanly either. Stripe works the same way: a single deposit bundles many charges with fees already deducted, settling a day or two after the sale. So the deposit is smaller than the sales it represents, it covers a different set of orders than any single day, and it arrives late. Three reasons it cannot match — and all three are normal. We cover the mechanics of the gap in more depth in why Shopify deposits never match your sales; here we just build the sheet that absorbs it.
The structure that makes the master sheet work
Stop trying to match sales to the bank in one jump. Insert the payout statement as a middle ledger and reconcile in two hops: orders roll up to a payout on gross amounts, and the payout ties to the bank on the net. The payout is the pivot both sides agree on — every order belongs to exactly one payout, and every payout is exactly one bank deposit.
The two-hop model
-----------------
Hop 1 Orders in the payout window --> Payout statement (match on GROSS)
Hop 2 Payout statement --> Bank deposit (match on NET)
Expected net = Gross sales - Refunds - Processing fees - Adjustments
Difference = Bank deposit - Expected net
Difference == 0 -> matched, ignore it
Difference != 0 -> exception, the only rows you workThe master sheet is one row per payout. The columns are nothing more than the line items the processor already nets out, plus the two it computes for you:
| Column | Where it comes from | What it is for |
|---|---|---|
| Payout ID | Payout / settlement report | The primary ID for the whole row — the key both hops join on |
| Payout date (bank) | Bank statement | When the deposit actually landed, not when the sale closed |
| Gross sales | Orders in that payout | The top of the funnel — what the orders totalled before anything was taken out |
| Refunds | Payout report | Refunds settled in this payout (often from earlier sales) |
| Processing fees | Payout report | The processor's cut for this batch |
| Adjustments | Payout report | Chargebacks, dispute fees, reserves, corrections |
| Expected net | Formula | Gross − Refunds − Fees − Adjustments — what the deposit should be |
| Bank deposit | Bank statement | What actually hit the account |
| Difference | Formula | Bank − Expected net — your exception flag |
| Status / Notes | You | Matched, or what you found when it was not |
How to build it from your own exports, in six steps
The procedure assumes a Shopify or Stripe payout export and your bank transactions. It is the same shape for any processor — only the column names change.
- Export two files: the payout (settlement) report for the period, and your bank transactions. Most payout reports already break out gross, fees, refunds, and adjustments per payout — if so, hop 1 is done for you.
- Clean the exports before anything else. A leading apostrophe, a region's comma-as-decimal, or a payout ID that Excel autoconverted to a number will silently break every match downstream — these are the CSV gotchas that quietly wreck a reconciliation. Import via Power Query and set column types explicitly rather than double-clicking the CSV.
- Make one row per payout in the master sheet. Paste the payout report's gross, refunds, fees, and adjustments into their columns, keyed on Payout ID.
- If your report does not pre-total gross sales, roll the orders up yourself with SUMIFS — sum each order's amount where its payout ID matches the row. One formula, filled down.
- Add the two computed columns: Expected net = Gross − Refunds − Fees − Adjustments, and Difference = Bank deposit − Expected net. Pull the Bank deposit in from the bank file on Payout ID, or match it by amount and date if the bank line has no ID.
- Filter Difference to everything that is not zero. That short list is your entire job for the period. Tag each one in Notes, fix the source, and re-pull. A clean run is every row at zero.
The two formulas are the only mechanics worth writing down. Gross roll-up and the difference, in Excel terms:
Hop 1 — roll orders up to the payout (only if the report does not):
Gross sales for a payout:
=SUMIFS(Orders[Amount], Orders[PayoutID], [@PayoutID])
The two computed columns:
Expected net = [@[Gross sales]] - [@Refunds] - [@[Processing fees]] - [@Adjustments]
Difference = [@[Bank deposit]] - [@[Expected net]]
Pull the bank deposit in by Payout ID (if the bank line carries it):
=XLOOKUP([@PayoutID], Bank[Reference], Bank[Amount], "NO BANK LINE")SUMIFS does the gross roll-up; Power Query does the cleaning and, once you are comfortable, the whole import so next month is a refresh instead of a rebuild. The XLOOKUP that pulls the bank deposit is the same join used in any two-file reconciliation, and if a payout has no matching bank line at all, that is a set-difference you want surfaced, not hidden — which is why the formula returns "NO BANK LINE" instead of an error.
Reading the difference column: what each exception means
A non-zero difference is not a mistake in your sheet — it is the sheet doing its job. It means the deposit and what you expected disagree, and the gap itself usually tells you why. The common cases, and where to look:
| What the difference looks like | Most likely cause | Where to fix it |
|---|---|---|
| Deposit short by a round-ish amount | A chargeback or dispute fee deducted but not yet booked in your Adjustments column | Open the payout statement and find the deduction; add it to Adjustments |
| Deposit short by a small percentage | Processing fees under-counted, or a fee tier you missed | Re-pull fees from the payout report; do not estimate them |
| Expected net higher than the deposit, refund-sized | A refund settled in this payout from an earlier sale | Normal timing — record the refund in the payout it settled in, not the original |
| Payout has no bank line at all | Timing — the deposit lands in the next period; or it is in transit | Carry it open and match it next run; do not force it |
| Difference is tiny and never the same twice | Rounding or an FX conversion on a cross-currency payout | Expected on multi-currency payouts; set a small tolerance, do not chase pennies |
| Two payouts, same amount, one unexplained | A duplicate or a miskeyed payout ID | A near-duplicate the ID hides — verify the IDs are distinct |
The discipline is the one the original thread named — "discipline and a clear process owner" — made concrete: every period, you work the difference column to zero and keep the sheet. Worked the same way each month, it doubles as your month-end tie-out and the evidence an auditor asks for: a payout-by-payout trail from cash back to the orders, with every exception named and resolved rather than plugged.
When the spreadsheet starts to creak
Be honest about the ceiling. The master sheet holds up while you have one or two processors, a clean payout ID on every line, and one person who owns the weekly run. It starts to strain when partial payments and bundled deposits stop lining up to a single key — the point where XLOOKUP quietly gives up — when a third and fourth channel arrive each with their own export format, or when someone other than the owner has to trust the number without re-deriving it by hand. A workbook saves the answer; it does not save the reasoning, and once other people depend on that reasoning it has to live somewhere more repeatable.
None of that is a reason to skip the sheet. It is the right first tool, it teaches you exactly where your money goes, and the manual method underneath it is the same method any tool automates. Build the sheet, run it for a few months, and you will know precisely what a dedicated reconciliation system would have to do to earn its place — because you will have done it by hand first.
Frequently asked questions
Is there a free reconciliation spreadsheet template I can download?
Yes. This page links a no-macro CSV master sheet with one row per payout: gross sales, refunds, processing fees, adjustments, an expected-net column, the bank deposit, and a difference column that flags exceptions. Open it in Excel or Google Sheets, delete the example rows, and paste your own payouts. There is nothing to buy and no signup.
Why does my Shopify or Stripe deposit never match my sales total?
Because a payout is a batch, not a single sale. The processor bundles many orders, subtracts its processing fees, your refunds, and any chargebacks, and deposits the net — and it lands a day or two after the sale. So the deposit is smaller than the sales it represents, covers a different set of orders than any one day, and arrives late. All three are normal. You reconcile by matching at the payout level, not by forcing sales to equal the deposit.
Should I reconcile every order or just the payouts?
Reconcile the payouts. You might have thousands of orders but only a few dozen payouts in a period. The orders only need to roll up correctly to their payout total; the payout is what you tie to the bank deposit. Matching at the payout level turns a multi-hour job into a short one and is the single biggest reason a master sheet ties out quickly.
What does a non-zero difference in the sheet mean?
It means the actual deposit and your expected net disagree, and that is the sheet working as intended. The size and direction usually point at the cause: a deposit short by a round amount is often an unbooked chargeback; a small-percentage gap is usually undercounted fees; a refund-sized gap is normally a refund settling from an earlier sale. Work only the non-zero rows, fix the source, and re-pull until every difference is zero.
When should I move off the spreadsheet to a dedicated tool?
When the structure stops fitting: multiple processors and channels with different export formats, partial payments and bundled deposits that no longer map to a single key, or other people who need to trust the number without re-deriving it. A spreadsheet saves the answer but not the reasoning, and once a team depends on that reasoning it needs to live somewhere more repeatable and auditable than a cell formula.