> ## Documentation Index
> Fetch the complete documentation index at: https://docs.drpn.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Reconcile returns and exchanges

> Check that Shopify refunds, returns, and exchanges made it into HotWax.

Returns are where two systems drift apart most quietly. A refund lands in Shopify, the return is booked in HotWax a little later, and drafts, cancellations, and in-transit items all look like gaps if you compare naively. Darpan's returns and exchange checks are built to report only the gaps that are real, and to say what they left out.

There are two checks:

* **Returns**: every Shopify refund or return in the window has a matching HotWax return, and the other way round.
* **Exchanges**: every closed Shopify exchange in the window was imported into HotWax as an exchange order. This runs inside an orders run.

## Before you start

Confirm:

* A Shopify connection with **Returns** enabled, and a token that can read returns. See [Set up Shopify](/guides/setup-shopify).
* A HotWax connection with **Refunded returns** or **Returns** enabled for returns, and **Orders** for exchanges. See [Set up HotWax](/guides/setup-hotwax).

## Set up a returns run

Create the run as in [Set up a reconciliation run](/guides/setup-reconciliation-run), with both sides as **API** sources:

| Side | Source | Primary ID |
| - | - | - |
| Shopify | **Shopify returns** | **Refund or return ID** (`refundOrReturnId`) |
| HotWax | **HotWax refunded returns** or **HotWax returns** | **Refund or return ID** (`externalId`) |

**Shopify returns** emits one record per refund or return event, keyed by the Shopify refund ID or return ID. HotWax books each return under the same ID as its `externalId`, so the two sides match one-to-one. On the HotWax side the key card offers **Shopify return ID** and **Refund or return ID**.

### Choose the HotWax returns source

| Source | Transport | Sees |
| - | - | - |
| **HotWax refunded returns** | REST | Refunded returns only. A pending return reads as missing in HotWax. |
| **HotWax returns** | GraphQL | Refunded and pending returns. Slower: one live 6-hour window took 258 s against 17 s on REST. Needs the HotWax GraphQL upgrade. |

The two carry the same fields, so moving a run from one to the other is a source switch.

### Leave in-progress returns out

A Shopify return that has not finished usually has no HotWax return yet. On the Shopify side, add an exclusion on **Return status** with the value `IN_PROGRESS`. This is Shopify's own order return status, so it describes the whole order: excluding `IN_PROGRESS` drops an in-progress order's refund rows as well as its return. See [Leave records out with exclusions](/guides/author-rules#leave-records-out-with-exclusions).

<Note>
  Before 2.0.0 this exclusion used a **Return workflow status** field with `REQUESTED` and `OPEN`. That field is withdrawn, and a rule saved on it matches nothing. Re-add the rule on **Return status** with `IN_PROGRESS`.
</Note>

## What a returns run does not report

Several kinds of one-sided record are expected, not gaps. Darpan removes them before the result is written and says how many it removed.

| Rule | Why it is not reported |
| - | - |
| Sync grace | An event younger than the grace period may still be syncing into HotWax. It is held as pending, not missing. |
| Before the window | Shopify is read a little before the window start so late HotWax returns can still match. A Shopify event dated before the window is never reported missing in HotWax. |
| Whole-order cancellation | A refund on a cancelled order is booked in HotWax as a cancellation, not a return. |
| Superseded return draft | Shopify keeps every draft return; HotWax books one return per settled outcome. A draft on an order that already has a HotWax return is not a gap. |
| Cancelled-item refund | A refund for lines that were never shipped is booked as an item cancellation, not a return. |

Records still reported missing in HotWax are then checked one by one with a point lookup, by both `externalId` and `shopifyReturnId`. Records found that way are dropped. See [Verification passes](/guides/review-results#verification-passes).

<Note>
  A rule only removes a record when the record's own data proves it. Where the evidence is incomplete, the record stays reported.
</Note>

## Exchanges

An exchange in Shopify becomes a separate exchange order in HotWax, carrying the same Shopify order ID as the original. Order extracts from HotWax leave exchange orders out by default, so they do not show up as extra orders in an orders run.

When an orders run compares Shopify orders with the HotWax **Orders** endpoint, Darpan also runs an exchange presence check:

1. It lists the Shopify exchanges created in the run window.
2. It matches them against the exchange orders HotWax returned in the extract.
3. For any left over, it asks HotWax directly by order ID.
4. Only exchanges HotWax confirms it does not have are reported, as missing from HotWax.

| Exchange state | Result |
| - | - |
| Found in HotWax | Matched. |
| Return not yet closed | In transit. Counted in the run note, not reported. |
| Less than 3 hours old | Pending. Not reported. |
| Return cancelled | Ignored. |
| Closed, older than 3 hours, absent from HotWax | Reported as missing from HotWax. |

Each run looks up at most 200 exchanges in HotWax. Any beyond that are deferred to a later run rather than reported, and the run note says how many.

## Reading the result

The run note on a returns or exchange run lists what each rule removed, and how many exchanges were matched, pending, or in transit. A count that moved between runs can be traced to these numbers rather than guessed at.

When a record is reported:

* Missing from HotWax: the refund, return, or exchange was not imported. Check the HotWax import for that order.
* Missing from Shopify: HotWax holds a return that Shopify does not list in the window. Check the return's dates first; a return near the window edge may belong to the next window.

## Next step

Schedule the run in [Set up an automation](/guides/setup-automation). Scheduled runs apply the same checks as a manual run.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.