You can first define the scope of your orders by specifying a time range.
Traverse through these orders and, based on the events property of each order, check if it contains any return or refund events. Alternatively, you can directly retrieve and use the refunds or returns data associated with the order. However, when it comes to the time of status changes, the action or message fields in the events property should suffice.
Thanks for the suggestion! I tested the Order events API and can see return-related events like:
“created return #1027-R1”
“Return #1027-R1 was closed.”
However, these are natural language messages in the message field. To extract the Return ID and status changes, I would need to parse these strings using regex patterns.
My questions:
Is parsing the message field the recommended approach?
Is there a more structured way to get Return status change history (e.g., a field that directly links to the Return object or provides the status transition.
I see that action is a String type rather than an ENUM. Can I assume that the same action will always return the same string value? (e.g., will “retrun_created” always be represented as the same string?)
I’m planning to map these action strings to ENUMs in my system for easier handling. I’d like to confirm that the action values are consistent before implementing this.
Using the events query on orders is a solid approach for backfilling. The action strings are effectively stable and you can treat them like enums in your system.
Shopify doesnt document them as a formal enum but in practice values like “return_created” or “return_closed” stay consistent. Just make sure your mapping handles unknown actions gracefully in case they add new ones, maybe log them and default to a generic handler rather than throwing errors.
One pattern that works well is running a periodic reconciliation job that queries recent orders and compares their event history against what your system has recorded from webhooks. This way you catch anything that slipped through whether due to endpoint downtime, network issues, or whatever else. Its extra code but webhooks are inherently “at least once” or sometimes “at most once” depending on failure modes, so you really need that safety net.
If you find yourself building a lot of reconciliation logic to work around webhook gaps, its worth knowing there are tools like Stacksync that sync data directly in real time rather than depending on webhook delivery. Removes the whole “did I miss an event” problem entirely since your database just stays in sync. Anyway hope the events approach works well for your use case!