Which orders were refunded but still shipped?
By the Analistable team · Updated · 3 min read
Join the refunds export to the shipments export on order ID and compare dates. Orders shipped on or after the refund date were sent for free unless the refund was partial or the parcel was recalled. In the example, O-311 and O-315 shipped a day after being refunded.
Part of our guide: How to answer questions across multiple spreadsheets
The data
| Refund: order | Refunded on | Amount | Shipment: order | Shipped on | Carrier |
|---|---|---|---|---|---|
| O-310 | 2026-09-03 | 45 | O-310 | 2026-09-02 | DPD |
| O-311 | 2026-09-04 | 30 | O-311 | 2026-09-05 | Royal Mail |
| O-315 | 2026-09-06 | 60 | O-312 | 2026-09-05 | DPD |
| O-315 | 2026-09-07 | DPD |
In a spreadsheet
Shipped on =XLOOKUP([@Order], Shipments[Order], Shipments[Shipped on], "")
Flag =IF([@[Shipped on]] = "", "Not shipped",
IF([@[Shipped on]] >= [@[Refunded on]], "Shipped after refund", "Shipped before refund"))In SQL
SELECT r.order_id, r.refunded_on, s.shipped_on,
CASE WHEN s.shipped_on >= r.refunded_on THEN 'shipped after refund'
ELSE 'shipped before refund' END AS flag
FROM refunds r
JOIN shipments s ON s.order_id = r.order_id;| order_id | refunded_on | shipped_on | flag |
|---|---|---|---|
| O-310 | 2026-09-03 | 2026-09-02 | shipped before refund |
| O-311 | 2026-09-04 | 2026-09-05 | shipped after refund |
| O-315 | 2026-09-06 | 2026-09-07 | shipped after refund |
O-310 shipped before the refund — probably a return, which is normal. O-311 and O-315 shipped after the refund: the warehouse didn't get the cancellation in time.
Follow-up checks
- Compare the refund amount with the order total: a partial refund (for a missing item) followed by shipping can be legitimate.
- Group the after-refund cases by warehouse or carrier cut-off time to find where cancellations get lost.
- Use timestamps rather than dates if you have them — a same-day refund and shipment needs the time to tell which came first.
Ask it in Analistable: “Which refunded orders shipped on or after the refund date, and what were they worth?”
Putting a value on it
Sum the order value (or cost of goods) for the “shipped after refund” rows each month. In the example that's 30 + 60 = 90 in refunds on goods that still went out. Over a year, the total usually justifies fixing the cancellation hand-off, for example an automatic hold on refunded orders in the warehouse system.
Excel 2019 and Google Sheets
Shipped on =IFERROR(INDEX(Shipments!B:B, MATCH(A2, Shipments!A:A, 0)), "")=FILTER(Refunds!A2:B, IFERROR(VLOOKUP(Refunds!A2:A, Shipments!A2:B, 2, FALSE), 0) >= Refunds!B2:B)The INDEX/MATCH version works in any Excel version, on Windows or Mac. The Google Sheets formula lists refunded orders whose ship date is on or after the refund date; refunds with no shipment become 0 and drop out. Both assume the dates are real dates — text dates compare alphabetically, which only works for the ISO format.
Same-day cases need timestamps
| Order | Refunded at | Shipped at | Verdict |
|---|---|---|---|
| O-320 | 2026-09-08 09:15 | 2026-09-08 16:40 | Shipped after refund |
| O-321 | 2026-09-08 17:05 | 2026-09-08 11:30 | Shipped before refund |
On dates alone both rows match the “on or after” rule. With times, only O-320 is a real miss: the refund was issued in the morning and the parcel still left in the afternoon. O-321 was probably refunded after the customer complained about a parcel already on its way.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| No matches at all | Order IDs formatted differently (#1001 vs 1001) | Strip prefixes and convert to the same type |
| One refund matched to several shipments | Split shipments under the same order | Use the earliest or latest ship date per order |
| Many “after refund” returns | Return labels exported as shipments | Filter shipments to outbound only |
Make it a weekly check
- Export refunds and shipments for the same date range, with a few days' overlap at each end so late shipments are caught.
- Keep a running list of flagged orders with the outcome (recalled, customer kept goods, re-charged) — the recovery rate shows whether chasing is worth it.
- For the money side of refunds, see reconciling Shopify orders with Stripe payouts.
Frequently asked questions
- How do I find refunded orders that shipped?
- Join refunds to shipments on order ID and flag rows where the ship date is on or after the refund date.
- What if refunds and shipments are in different systems?
- Export both with the order ID, make sure the IDs use the same format, and join on it.
- Are all of these losses?
- Not always — partial refunds and recalled parcels are legitimate. Check the amount and status before chasing.
- Do I need timestamps?
- Only for same-day cases. Dates are enough for most orders, but a refund and shipment on the same day need times to tell which came first.
- Can I check this before goods leave?
- Yes: run the join on refunds against orders still awaiting dispatch, and hold any match.
- What about split shipments?
- Use the latest ship date per order, or flag each parcel separately.