Why do my sales numbers look wrong every month once returns start coming in?
Refunds and returns post on different dates than the original sale, which makes month-to-month sales comparisons look wrong even when nothing is actually broken.
What's going on
A merchant runs their monthly sales report, sees a number that doesn't match what landed in the bank account, and assumes something is broken. Usually the culprit is returns: a sale gets counted as gross revenue the day the order is placed, but the refund that reverses part or all of it gets counted on a different date, sometimes weeks later, sometimes in the next reporting month entirely. The two events never lived in the same report period to begin with, so any report that only shows one month at a time will look off by design.
This gets more confusing because Shopify treats a return, the physical process of a customer sending an item back, as a separate thing from a refund, the actual money movement. A return can be fully approved and the inventory restocked without a refund ever being issued, for example if the merchant is arranging an exchange or store credit instead. That means sales and finance reports, which move on refund transactions, won't reflect a return until the refund step actually happens, even though the return itself already happened.
None of this is a defect in Shopify's accounting; gross sales, discounts, returns, and net sales are all defined and computed consistently. The distortion merchants report is almost always a timing mismatch between order date and refund date, or a definitional mismatch between Total sales on the dashboard and Net sales in the Finance summary, which are not the same figure.
Why it happens
Shopify records the sale at order time and the refund at refund time. If a customer buys in one period and returns in the next, both events are correct individually, but they never reconcile within a single month's report unless you look at both months together.
On top of that, Shopify's returns workflow deliberately decouples the physical return process, request, approval, transit, and receipt, from the financial refund. That's useful operationally, since it lets a merchant approve a return and get inventory back on the shelf before deciding how to settle the money, but it means returns and refunds are not interchangeable terms in Shopify's data model, and conflating them is what makes the numbers feel unpredictable.
5 ways to fix it
Check Net sales in the Finance summary, not Total sales on the dashboard
Go to Analytics and pull the Finance summary or a Sales report broken into Gross sales, Discounts, Returns, Net sales, and Taxes. Net sales already has returns and discounts subtracted out, so if you've been eyeballing the Total sales figure on the home dashboard instead, you're comparing against a number that was never meant to reconcile with your payouts. It's also worth checking the Returns section under Orders: a return's status (requested, approved, in transit, received) is tracked separately from the refund itself, so an approved return with no completed refund yet won't show up as a deduction in your sales reports until the money actually moves.
Reconcile by refund date, not by the order's original date
The most common cause of a distorted-looking report is comparing a month's sales, which are booked on the order date, against that same month's refunds, which are booked on whatever date the refund transaction posts. An order placed in December and refunded in January reduces January's net sales, not December's, so December looks artificially strong and January looks artificially weak even though nothing is wrong. Pull the sales report and a refunds export for the same window and match line items by order number instead of assuming a report's calendar month tells the whole story.
Export orders and refunds if you need to audit the detail yourself
For a real reconciliation, go beyond the dashboard: export your orders and refunds and cross-reference them line by line. Shopify's Admin API exposes refund and return detail at the order level, and on plans that include it, ShopifyQL Notebooks let you query that same data directly, which is far more reliable than trying to back into the discrepancy from summary dashboards alone.
Treat return-rate analysis and revenue-accuracy analysis as two separate questions
Returns can distort more than your top-line total; they can also make the wrong products look like bestsellers if you're only glancing at gross sales by item. Use the return reason captured when a return is created (damaged, wrong size, changed mind, and so on) to understand which products are coming back and why, and keep that analysis separate from the finance reconciliation. Is my revenue number accurate and why are these particular items being returned are two different questions, and mixing them makes both harder to answer.
Give each month a fixed close date before you call the numbers final
Much of the frustration here comes from checking sales mid-month and then being surprised when refunds processed later change the picture. Treat any given month's numbers as provisional until a set number of days after month-end has passed, long enough to cover your typical return window, and only pull your final net sales figure after that window closes. That alone removes most of the perceived randomness without any new tooling.
Bottom line
There's no bug here. Shopify's reports are doing what they're designed to do, but gross sales post on the order date while returns and refunds post on the transaction date, so the two events can land in different reporting periods unless you deliberately reconcile them. For most stores, the free native fix, the Finance summary plus an orders and refunds export matched by order number, is enough. Larger catalogs or stores with high return rates sometimes end up building a lightweight spreadsheet or BI reconciliation on top of Shopify's exports, but that's a process fix, not something that requires a paid app.
Browse the rest of the problem library, run a free storefront scan to catch issues like this automatically, or email us and we'll work out a custom solution for it.