How to Keep Shopify Exchanges From Skewing Your GA4 and Ad Platform Revenue

|Dan Giura
How to Keep Shopify Exchanges From Skewing Your GA4 and Ad Platform Revenue

TL;DR

In Shopify, an exchange is a return on the original order, with the replacement added as a line item on that same order [1][8]. WeltPixel Conversion Tracking hears about it only if you issue a refund, so the damage follows the balance: even swaps distort item reports, cheaper swaps reach GA4 alone, pricier swaps reach nobody, and refund-and-re-buy counts the sale twice in every ad platform. One GA4 lookup shows which version of the cheaper case your store produces.

Key Takeaways

  • Shopify creates no new order for an exchange made in the admin; the replacement becomes a line item on the original order [1][8].
  • An even swap leaves every total right, and every item report still shows the variant the shopper sent back.
  • A pricier swap's balance is collected on the same order [2] and never reaches any destination.
  • Refunding in full and letting the shopper re-buy puts two purchases in every ad platform for one item kept.
  • Read exchange-heavy months against Shopify's net sales, which subtract sales reversals [5].

Where does a Shopify exchange live in your order data?

The swap stays on the original order. You build the exchange on the order itself: Orders → the order → Return (or More actions → Return), then Add products in the Exchange items section [1]. Shopify's API calls the replacement's lines "The order line items for the exchange" [8]. No second order is created. Creating the return "creates sales records that reverse the sales records for the items being returned" and "creates sales records for any exchange line items" [7], and processing it "Records the return and exchanges in merchant financial reports" [6]. Shopify's sales reports show sales on the day they were made and reversals on the day they were processed [5].

Money moves only when one side owes the other. Equal values make "an even exchange"; cheaper new items mean "You owe the customer money" [1]; pricier ones mean you collect the balance on the order [1][2]. A refund exists only if you issue one: "When exchanging items, you don't need to refund every item unless you owe money to your customer" [2].

WeltPixel Conversion Tracking hears about an order when it's created, when it's paid and when it's refunded. Shopify sends returns through separate webhooks [10], which the app doesn't subscribe to. Each purchase carries the order total at the moment it's sent and is never edited afterwards; GA4's refund event, on Plus, is the only correction the app sends.

Run it on an illustrative $60 jacket order with no tax or shipping, swapped three ways, plus one workaround:

After the swap What Shopify records What the app hears GA4 keeps Ad platforms keep (Plus)
Even: size M for size L, $60 A return and an exchange line item; a sale and a reversal that net to zero Nothing $60, listed as size M $60; items, where sent, as size M
Store owes: a $45 jacket The same, plus a $15 refund if you issue one The refund $60 minus the refund's value (Plus) $60
Shopper owes: a $75 jacket The same, plus $15 collected on the order No new purchase $60 $60
Full refund, then a new $60 order A $60 refund on order 1 and a separate order 2 The refund, then a new order $60 net (Plus) $120

The even swap leaves item reports showing the returned variant

A shopper sends back the size M jacket and keeps the L. Shopify books a $60 sale for the L and a $60 reversal for the M on the processing day [5][6]. Every destination the app sent the order to still holds $60, which is right, and still holds size M. Nothing about the swap is sent afterwards, so GA4's item reports and the product data the ad platforms received never see the L. If a size keeps topping GA4's best sellers and turning up in the returns pile, this is one reason. In a month heavy with size swaps, GA4's variant-level sales lean toward what people order first, and Shopify's sales report, which books the swap itself, is the better read of what they kept.

When the replacement costs less, only GA4 hears about it

Swap the $60 jacket for a $45 one and you owe $15. Shopify adds "The amount that you owe your customer" to the Refund amount field when you issue the refund [2]. That refund is the one part of an exchange the app receives. On Plus it sends GA4 a refund event keyed to the original order, built the way server-side GA4 refund tracking describes. Google Ads, Meta and the other ad platforms keep $60, because the app sends refunds to GA4 only.

What GA4 subtracts depends on what the refund lists. The app values a GA4 refund at the subtotal of the line items the refund lists, and at the money refunded only when it lists none. It's the rule gift cards and store credit in Shopify conversion tracking describes, so store credit and the card report the same value. Shopify doesn't document which form an exchange's difference refund takes. It does document that you can "refund line items for less than their calculated amount", with an order adjustment created for the discrepancy [11]. Two outcomes are possible:

  • The refund lists no items. GA4 subtracts $15 and keeps $45, which is what you earned.
  • The refund lists the returned jacket at its $60 subtotal. GA4 subtracts $60, the $45 replacement never arrives as a sale, and GA4 shows nothing left for an order that earned $45.

Whether $15 per exchange is worth a Google Ads restatement is the same test handling refunds and cancellations in ad platform reporting runs for any partial refund.

When the replacement costs more, where does the extra payment go?

It stays on the original order, and none of the app's destinations hears about it. Swap the $60 jacket for a $75 one and the shopper owes $15. You can send an invoice when you process the return, or collect afterwards "by using the payment card on the order page" [2]. Shopify's developer guide puts the exchange items on hold until a balance due is paid [6]. The order total then updates to show any remaining balance [1].

That payment isn't a new order or a refund, and the app sends each order's purchase once. GA4 keeps $60, and so does every ad platform on Plus, while Shopify's net sales record $75. Post-purchase upsell tracking on Shopify hits the same wall for the same reason: money added to an order after its purchase went out never reaches the platforms, on either send setting. Nothing the app sends raises a GA4 or Meta value after the fact.

Refunding and letting the shopper re-buy counts the sale twice

Some stores skip the exchange feature: refund the first order in full, then let the shopper buy the replacement as a new order. It's the one shape that inflates the ad platforms. Order 1 keeps its $60 in Google Ads, Meta and the rest, since they receive no refund, and order 2 arrives as a fresh $60 purchase that each platform attributes by its own rules. One jacket kept, $120 reported.

On Plus, GA4 gets order 1's refund and nets to $60. On the free plan GA4 gets no refund events, so it shows $120 too. If a staff member creates the replacement in the admin, it's an admin order: the free plan skips it, and Plus sends it unless "Exclude Admin/API Orders" is on for that channel, as admin and POS order tracking on Shopify explains.

Do POS and self-serve Shopify exchanges work differently?

Shopify's developer docs put both on one Return record that holds "returns and exchanges data created on both the Shopify admin and POS" [9]. A Shopify POS exchange for a different item needs POS Pro: "If you're on the POS Pro subscription, then you can also exchange a returned item for a new item" [4]. The same page says you "can collect or pay out the difference during the exchange" [4], and since POS v11.5, posted April 27, 2026, returns, refunds and exchanges happen directly in the POS cart [13]. On a POS exchange the return's transactions include "both refunds and captured payments", where an online one includes refunds only [9]. A payout is a refund and a collection is a payment on the order, so a POS swap that stays on the original order lands in one of the same three shapes.

Self-serve returns start as a request from the order status page, which you approve or decline. "When you approve a return, you can add exchange items" [3]. Nothing financial happens until you process it, so a self-serve exchange ends in the same shapes as one you built yourself.

How do you check what one exchange sent GA4?

Use a past exchange where you refunded a difference, on a store with the app's Plus plan and GA4 connected.

  1. In Shopify admin, open the order and note the refund amount and the number at the end of the order page's URL. That number is the transaction ID the app sends GA4 for the purchase and for its refund.
  2. In GA4, go to Explore and open a Free form exploration. Add the Transaction ID dimension and the Refund amount and Purchase revenue metrics, then filter to that transaction ID. GA4 defines Refund amount as "The total amount from refunds given on your website or app" [12].
  3. Compare. A Refund amount equal to the money you refunded means your exchange refunds list no items and GA4 nets correctly. A Refund amount equal to what the returned item cost means they list it, and GA4 under-reports every cheaper exchange by the replacement's price.

No past exchange to read? A fresh test exchange works, but on Plus its refund is a real refund event in your GA4 reports, not a test. The app's Enable Debug Mode setting makes the event visible in GA4 DebugView on Shopify as it arrives.

Then read exchange months against Shopify's net sales, which subtract sales reversals, rather than gross sales, which count each replacement as a new sale [5][7]. Reporting one blended ROAS across Shopify, Meta and Google Ads builds its revenue from the same report. Against net sales, the ad platforms run high by every difference you refunded and low by every balance you collected.

FAQ

Does a Shopify exchange create a new order?

Not when you make it from the order in Shopify admin. Shopify adds the replacement as a line item on the original order and records the swap as a return on it [1][8]. A second order appears when you refund the first one and the shopper buys again.

Does WeltPixel Conversion Tracking track Shopify exchanges?

No. An exchange made in the admin creates no new order, and the app never updates a purchase it already sent. The refund you issue on a cheaper exchange reaches GA4, on the Plus plan.

Why does GA4 show less revenue than Shopify after a month of exchanges?

Balances collected on pricier swaps never reach GA4. If your exchange refunds also list the returned item, GA4 subtracts that item's full price on every cheaper swap.

Read one past exchange in GA4 before December

WeltPixel Conversion Tracking sends every purchase at the order total Shopify reports when it's sent, and sends GA4 refund events on Plus ($39/month, no order limit, also sends admin, POS and draft orders) [14]. The free plan covers GA4 only, up to 100 storefront orders a month. Run the GA4 check on one past exchange now, while you can still change how you refund the next one.

Sources

  1. Shopify Help Center, "Creating returns and exchanges", help.shopify.com/en/manual/fulfillment/managing-orders/returns/creating-returns, accessed October 20, 2026
  2. Shopify Help Center, "Processing and managing returns", help.shopify.com/en/manual/fulfillment/managing-orders/returns/processing-returns, accessed October 20, 2026
  3. Shopify Help Center, "Self-serve returns and cancellations", help.shopify.com/en/manual/fulfillment/managing-orders/returns/self-serve-returns, accessed October 20, 2026
  4. Shopify Help Center, "Exchange an order on Shopify POS", help.shopify.com/en/manual/sell-in-person/shopify-pos/order-management/exchange, accessed October 20, 2026
  5. Shopify Help Center, "Sales reports" (gross sales, sales reversals, net sales; adjustments by processing day), help.shopify.com/en/manual/reports-and-analytics/shopify-reports/report-types/default-reports/sales-report, accessed October 20, 2026
  6. Shopify Developer documentation, "Creating and managing exchanges", shopify.dev/docs/apps/build/orders-fulfillment/returns-apps/manage-exchanges, accessed October 20, 2026
  7. Shopify Developer documentation, "Build for return management", shopify.dev/docs/apps/build/orders-fulfillment/returns-apps/build-return-management, accessed October 20, 2026
  8. Shopify Developer documentation, GraphQL Admin API "ExchangeLineItem" object, shopify.dev/docs/api/admin-graphql/latest/objects/ExchangeLineItem, accessed October 20, 2026
  9. Shopify Developer documentation, "Integration with the Return object for exchanges", shopify.dev/docs/apps/build/pos/exchangesv2, accessed October 20, 2026
  10. Shopify Developer documentation, "Apps in returns" (return webhooks), shopify.dev/docs/apps/build/orders-fulfillment/returns-apps, accessed October 20, 2026
  11. Shopify Developer documentation, REST Admin API "Refund" resource, shopify.dev/docs/api/admin-rest/latest/resources/refund, accessed October 20, 2026
  12. Google Analytics Help, "Analytics dimensions and metrics" (Transaction ID, Refund amount, Purchase revenue), support.google.com/analytics/answer/9143382, accessed October 20, 2026
  13. Shopify Changelog, "Returns and exchanges in cart for POS", posted April 27, 2026, changelog.shopify.com/posts/returns-and-exchanges-in-cart-for-pos, accessed October 20, 2026
  14. WeltPixel Conversion Tracking, Shopify App Store listing (free plan; Plus $39/month), apps.shopify.com/weltpixel-conversion-tracking, accessed October 20, 2026

Ready to upgrade your tracking?

Server-side tracking for Magento and Shopify — accurate data, better attribution, full privacy compliance.