A visitor arrives from Perplexity on 3 March, buys a $400 annual plan the same afternoon, and asks for a refund on 20 March. Your report for the first week of March has already gone out, and it said Perplexity earned $400. Where should the refund go?
There are two defensible answers. You can reach back and reduce 3 March, so the order nets to zero where it happened. Or you can book the refund on 20 March, the day it happened, and leave 3 March alone. They produce different charts, and only one of them keeps last week's report true. This post argues for the second, then covers the two rules that go with it: order counts stay gross, and a cancelled subscription takes nothing back.
Backdating rewrites history you already reported
Backdating is the intuitive choice, because it makes each order's own line tidy: $400 in, $400 out, net zero on 3 March. The cost appears the moment anyone compares two reports. The weekly summary sent on 10 March said $400. The same range rerun on 25 March says $0. Nothing about the first week changed, yet its numbers did, and nobody can tell from the chart when the correction arrived.
Once refunds can reach backwards, no closed period is ever closed. A number is only final after the longest refund window you offer, which for an annual plan can be months. Anything you forecast, budget or celebrate from it is quietly provisional.
Booking the refund on its own day keeps every past day fixed. The first week of March shows $400 from Perplexity forever. The week of 20 March shows a $400 refund, attributed to Perplexity, and if nothing else sold that day, the day is negative. That matches how payment processors already think about it: Shopify's sales reports define returns as a negative number on the date the return was processed.
Where a refund lands, and what that does to your reports
Both approaches give the same net total over a range that contains the sale and the refund. They differ on every range that contains only one of them.
| Question | Backdate to the order day | Book on the refund day |
|---|---|---|
| Does last month's total change later? | Yes, whenever a refund arrives | Never |
| Can a single day go negative? | No | Yes, when refunds exceed sales |
| Where does the refund appear on a chart? | Nowhere; the sale shrinks | On the day it happened, as its own figure |
| Net revenue by assistant over the full range | Correct | Correct |
| Revenue for a range with the sale but not the refund | Already net of a refund that had not happened yet | Gross, as it was at the time |
| Agrees with the processor's own daily report | Often not | Yes |
The refund has to find the right assistant
Deciding the date is half the job. The other half is making sure the refund reduces the right thing.
A tempting design keeps refunds in their own table and subtracts the total at the end. The site total comes out right. Every breakdown does not: revenue by assistant, by landing page and by country still shows the original $400, because the refunds table never knew which assistant sold the plan. The one number people check is correct and every number they drill into is overstated.
Traceten avoids that by writing the refund as a mirror of the original revenue record. It points at the same visit and carries the same assistant and source as the sale, with the opposite sign and the refund's own timestamp. Every report that sums revenue, however it is broken down, nets it out without knowing refunds exist. If the sale was split across several touches, the refund is split across them in the same proportions, with any rounding remainder placed on the last share so the parts add up exactly.
Two details keep partial and foreign-currency refunds honest. A partial refund is sized by the ratio of the refunded amount to the original order in the order's own currency. And it is converted at the original order's exchange rate, not today's, so refunding a euro order in full lands on exactly zero rather than a few cents either side. The currency side of that is its own post: convert at the order's date, not today's.
Counts stay gross
Revenue is net. The count of orders is not.
If a refund also removed an order from the count, your conversion rate for March would fall on 20 March for a reason that has nothing to do with the visitors you sent. Worse, it would fall retroactively for whatever range contained the sale. So Traceten counts orders from sales only and reports the refunded amount beside revenue. You can see both facts, and neither one bends the other.
Two numbers, not one adjusted number
"12 orders, $4,800, of which $400 refunded" answers every question a finance review asks. "11 orders, $4,400" answers one of them and hides the rest.
A cancellation takes nothing back
A subscription cancellation feels like it should reduce revenue. It should not.
Cancelling stops future charges. Stripe's documentation describes it plainly: by default a cancellation takes effect immediately and invoices are no longer generated, and refunding anything is a separate decision. The customer who paid for four months and then cancelled still paid for four months. If a merchant also refunds the last payment, that refund arrives as a refund and is handled as one.
So in Traceten a subscription cancellation retracts nothing. Each renewal already arrived as its own payment, and each one stays where it landed. Retracting on cancellation would put your numbers at odds with the merchant's own processor dashboard, which is the one comparison every attribution tool eventually faces.
There is one exception, and it follows the same logic. A cancelled Shopify order is the order itself being voided rather than a subscription ending, so Traceten takes back whatever is still outstanding on it. If that order had already been partly refunded, its refunds own the retraction instead, so the part the merchant kept is not taken twice.
The unglamorous part: order and retries
Two properties of webhooks make refunds harder than they look.
They arrive in any order. A refund can reach you before the sale it refunds, and a merchant can connect a store after a refund has already happened. Traceten records such a refund and holds it until the sale lands, then applies it.
They arrive more than once. Payment providers retry deliveries, and some report each refund on its own while others report the running total refunded so far. Traceten records each refund once by its own identifier, and caps any retraction at what is still outstanding on the order. A redelivered refund, or a running total restated, cannot subtract twice. And a refund in a different currency from its order is held back rather than applied at a ratio that would be wrong.
None of this shows on a chart. It is the reason the chart can be trusted when a finance team puts it next to the processor's own report.
Frequently asked
01Should a refund reduce revenue on the order date or the refund date?
02Do refunds reduce the number of conversions?
03Does cancelling a subscription reduce attributed revenue?
04How is a refund attributed to the right AI assistant?
Sources and further reading
- 01Sales reports: Returns and sales reversals, Shopify Help Center
- 02Refund and cancel payments, Stripe Docs
- 03Cancel subscriptions, Stripe Docs

