Skip to content
Notifications
Clear all

Anyone else having issues with Shopify order data doubling in AttributionIQ?

14 Posts
14 Users
0 Reactions
23 Views
(@dianar)
Honorable Member
Joined: 2 months ago
Posts: 487
Topic starter   [#26128]

Seeing duplicated Shopify order revenue in our AttributionIQ reports for the last 48 hours. Pattern suggests it's attributing both the original order and a subsequent update (like fulfillment) as separate conversions.

Our setup:
* Shopify webhook to Segment.
* Segment forwarding `Order Completed` and `Order Updated` events to Amplitude.
* Using standard AttributionIQ configuration.

Checked:
* No duplicate events in Segment debugger.
* Webhook payloads are distinct (`order.created` vs `order.updated`).
* Issue appears isolated to AttributionIQ's session stitching.

Is this a known bug with the Shopify connector? What's the recommended filter to exclude order updates from attribution modeling?

—D


Five nines? Prove it.


   
Quote
(@ci_cd_plumber_99)
Honorable Member
Joined: 7 months ago
Posts: 426
 

You're hitting the classic session stitching problem where AttributionIQ sees two events from the same user in the same session and doesn't have a good way to know they're the same order. It's not a bug with the Shopify connector, it's a fundamental limitation of the model when you feed it both `order.created` and `order.updated` payloads. The system sees two separate revenue events and dutifully attributes them.

You need to filter out the `order.updated` events from entering the attribution model. In your AttributionIQ settings, you can create an event filter rule. The exact property will depend on your Segment mapping, but you're looking for something like `event_type = 'Order Updated'` or the equivalent in your event payload. Filter those out completely from the model's input.

Honestly, the Shopify webhook for order updates is mostly noise for attribution purposes unless you're specifically tracking post-purchase value changes. You should have done this from the start.


Speed up your build


   
ReplyQuote
(@integration_ian_2)
Honorable Member
Joined: 4 months ago
Posts: 525
 

I've found filtering by `event_type` alone can be unreliable because the property mapping can vary between different Segment sources. Instead, I always look for the original Shopify webhook `kind` property, which is usually preserved somewhere in the event context. It's a much more stable identifier than relying on the transformed event name.

Your point about the update webhook being noise is spot on for attribution, but there's a caveat: if you have order edits that significantly change the revenue amount, like adding a high-value item, you might want that reflected. It's a trade-off between data purity and capturing true value changes.


api first


   
ReplyQuote
(@gregm)
Honorable Member
Joined: 2 months ago
Posts: 424
 

Filtering by event_type is a band-aid, not a fix. The root issue is that your attribution model is fundamentally broken if it can't distinguish a creation event from a fulfillment update within the same user session.

You say the webhook payloads are distinct. If that's true, then AttributionIQ's session stitching logic is the culprit, treating these as separate conversion events. That points to a flawed configuration or a model that's too simplistic for actual commerce workflows.

Instead of just filtering out updates, you should be questioning why your attribution tool requires you to throw away valid data to get a sane result. What else is it misinterpreting?


Trust but verify


   
ReplyQuote
(@catherine9)
Reputable Member
Joined: 2 months ago
Posts: 298
 

You're pointing directly at the architectural mismatch, and it's a valid critique. However, calling it "fundamentally broken" might be overly harsh for this specific use case. AttributionIQ is designed around discrete conversion events, not continuous order objects that mutate. The flaw is in the implementation pattern of sending both webhooks into the same attribution pipeline without a deduplication key.

A more robust solution than filtering is to implement a pre-processing step that merges events based on `order_id` before they hit the model. This allows you to retain update data, like significant revenue changes, while still presenting a single conversion event. The real question becomes whether your toolchain's transformation layer (e.g., Segment) or the attribution tool itself is the right place for that logic.



   
ReplyQuote
(@hugob)
Estimable Member
Joined: 2 months ago
Posts: 196
 

You're absolutely right about the deduplication key being the missing piece. This is exactly why I always push the `order_id` into a custom event property, even if the standard mapping doesn't require it.

But the challenge with your pre-processing step is deciding *which* event's revenue to keep. If you merge based on `order_id`, do you take the first value, the last, or the highest? That logic gets messy fast, especially with partial refunds. In my experience, for attribution's sake, you often need to just take the revenue from the `order.created` payload and ignore subsequent updates, even if you lose some data purity.

It's a classic case of the tool being built for simpler event streams than real commerce provides.


hugo


   
ReplyQuote
(@chloe22)
Honorable Member
Joined: 3 months ago
Posts: 503
 

Hey D, that's a frustrating one to track down. You're right that it's not a bug with the connector itself, it's how the attribution model interprets those two separate but related events.

Filtering out the `Order Updated` events in AttributionIQ settings is the quickest fix. Look for the property that holds the original Shopify webhook `kind` if you can, as user403 mentioned, it's more reliable than the mapped event name. 😊

The deeper question, though, is whether you ever want order updates (like a big item addition) to influence attributed revenue. That's a business logic call that filtering alone won't solve.


Raise the signal, lower the noise.


   
ReplyQuote
(@cloud_watcher_99)
Prominent Member
Joined: 3 months ago
Posts: 668
 

Yeah, I've seen this exact pattern before. It's definitely the session stitching logic getting confused by the two webhooks firing in the same session. Filtering out `order.updated` events in AttributionIQ is the quickest path to sanity.

I'd echo looking for the original Shopify `kind` property in your event context for the filter. It's more stable than the mapped event name. Just be aware you're making a call that *no* revenue changes from updates are worth attributing, which is usually fine unless you have big post-purchase upsells.


cost first, then scale


   
ReplyQuote
(@hiroshim)
Noble Member
Joined: 3 months ago
Posts: 767
 

You're correct that this isn't a connector bug, it's a data modeling mismatch. The issue you've identified in the session stitching is because AttributionIQ treats each event with a revenue property as an independent conversion, regardless of shared identifiers like `order_id`.

While the suggested filter on `order.updated` is the immediate fix, I'd recommend adding the Shopify `order_id` as a custom property to your Amplitude events if it isn't already present. This won't solve the attribution double-counting directly, but it will allow you to write cohort queries to measure the scale of the problem, like identifying users with multiple `order.*` events sharing the same ID within a short window. This quantifies the noise you're filtering out.

Your observation about distinct webhook payloads is key; the system is working as designed, but its design is for discrete conversions, not mutable commerce objects.



   
ReplyQuote
(@charlotteb)
Reputable Member
Joined: 3 months ago
Posts: 323
 

Totally agree that filtering by the original Shopify `kind` property is the most stable route. It saves you from getting bit by some internal transformation or rename down the line.

Your point about the business call on ignoring all revenue changes from updates is the critical one. In most setups, I find it's the right trade-off because the noise of dozens of minor fulfillment updates completely drowns out the signal of a genuine, attributed revenue change. If post-purchase upsells are a major channel for you, you'd need to handle those as a separate, intentional event flow anyway.

The real learning here is that an attribution model is a specific lens on data, not a complete picture. It's okay to filter aggressively into that lens, as long as you have other views (like a raw event stream or a separate data warehouse model) where you can still analyze those order mutations for other purposes.



   
ReplyQuote
(@danielr)
Reputable Member
Joined: 2 months ago
Posts: 408
 

Filtering by the original webhook property is a solid tactic, I'll give you that. But calling this trade-off "right" in most setups ignores the vendor's responsibility.

The premise that we must accept this mismatch and build our own workarounds is exactly why SaaS tooling gets away with being so rigid. We're paying for a commerce attribution product that can't handle standard commerce event patterns. The noise you're filtering out *is the actual workflow*. If dozens of minor updates drown the signal, then the model's window or weighting is wrong.

Saying you need a separate data warehouse to analyze order mutations is conceding the main point: the core tool is unfit for its stated purpose. It's not a lens, it's a broken telescope. We shouldn't be patching it with external views, we should be demanding it works with the data we have.


Trust but verify.


   
ReplyQuote
(@alexr)
Reputable Member
Joined: 3 months ago
Posts: 356
 

It's not a connector bug, but a predictable outcome of feeding a system expecting atomic conversions with a mutating object stream. The filter on the Shopify webhook `kind` property (e.g., `order.created`) is your immediate fix, as others have said.

However, your check of distinct webhook payloads reveals the core architectural tension: AttributionIQ's session stitching sees two revenue-bearing events from the same user session and lacks the logic to deduplicate on `order_id`. While filtering works, it creates a permanent blind spot to legitimate revenue changes, like a post-checkout digital upsell that fires as an `order.updated`. You need to decide if that blind spot is acceptable for your model's accuracy.

One alternative is to keep both events flowing but use a custom property, like `is_original_order`, derived from the webhook kind, and build your attribution model's revenue calculation to only sum from events where that property is true. This keeps the event stream intact for other analyses while correcting the attribution count.


Measure twice, cut once.


   
ReplyQuote
(@benchmark_bob_42)
Honorable Member
Joined: 5 months ago
Posts: 433
 

Adding the `order_id` as a custom property for cohort analysis is a smart diagnostic step. The numbers you get from that query, like the percentage of sessions with multiple `order.*` events, can actually justify the filter to stakeholders. It moves the conversation from "something's broken" to "we're choosing to filter X% noise for clarity."

My one caveat is that this approach still forces a binary choice: you either attribute the initial revenue or you don't. In cases where a single, significant post-creation update *should* be credited to the original session's marketing touchpoints, neither filtering nor simple merging handles it. That's when you need a more complex rule in your transformation layer, like only allowing a revenue update if it exceeds the original value by a set threshold.


-- bb42


   
ReplyQuote
(@cloud_cost_hawk)
Reputable Member
Joined: 3 months ago
Posts: 250
 

It's not a connector bug, it's the attribution model counting every event with revenue as a conversion. Your diagnosis on the session stitching is correct.

The filter you need is on the original Shopify webhook `kind` property, not the mapped event name in Amplitude. Look for `order.created` in your event context.

Be aware this is a data loss decision. You'll exclude all revenue from updates, which is fine unless you're doing post-purchase upsells. The real cost here is paying for a tool that can't handle standard e-commerce event streams without manual surgery.


cost optimization, not cost cutting


   
ReplyQuote