Good afternoon,
I am beginning to think that it may be impossible to deterministically tell whether a Transaction (of the “refund” kind) is actually part of a Refund using the GraphQL API.
For context: in certain payment scenarios (using a gift card and a credit card, with the gift card part of the payment being refunded during the 3DS credit card check), a new Transaction
is created (with kind
set to refund
) but without a corresponding Refund
object.
Now, here is the root of the issue: for Transaction
objects (with kind
set to refund
), their corresponding Refund
may be created later (we see this fairly often) - i.e. the Refund
s createdAt
is a later timestamp than the createdAt
of the Transaction
it contains. In practice this is just a matter of a few seconds.
So if we consider a Transaction
object (with kind
set to refund
), how can we tell whether it actually “belongs” to a Refund
? Querying for an order’s refunds won’t help us, because the Refund
may not have been created just yet.
Has anyone come across this issue? Maybe (I hope) I am missing a simple solution?
Thank you!
Hey @Piotr_Wojcicki, this is interesting. Have you queried the order agreements to see what data is returned there? That should give a more complete financial view of the order timeline.
Does the above work for you @Piotr_Wojcicki?
hello @KyleG-Shopify , thanks for getting back to me. I’m afraid querying order agreements is not going to help, because they don’t contain any information about individual transactions.
Interesting, what about tenderTransactions?
A TenderTransaction represents a transaction with financial impact on a shop’s balance sheet. A tender transaction always represents actual money movement between a buyer and a shop. TenderTransactions can be used instead of OrderTransactions for reconciling a shop’s cash flow. A TenderTransaction is immutable once created.
thanks @KyleG-Shopify - I had a look at the TenderTransaction
but that won’t help either I’m afraid, because it does not offer any relationship to the Refund
- which is what we’re trying to establish: if we consider a specific OrderTransaction
of kind
equal to refund
, how can we deterministically tell whether it belongs to a Refund
, considering that its Refund
may be created after the OrderTransaction
has been created? 
Thanks. I was able to replicate this myself refunding an order that had partial gift card payment. I’m looking further to see if this is expected or not.
Hey Piotr,
Could you share a little more context on your use case for these endpoints? We may be able to offer some suggestions around managing these instances where there’s a delay in the refund showing.
For example. which APIs are you using and how are you processing these (webhooks, polling, etc.)? Can your system can work with a short delay rather than needing everything linked instantly or is there a business case for needing details immediately?
hi @KyleG-Shopify , our use case is that, depending on whether a Shopify transaction “belongs” to a Refund
or not, we need to create slightly different data in our backend.
We assumed (as we found out incorrectly), that we could determine this (for any given Transaction
) by querying the Shopify API (fetch the Order
, iterate over its Refunds
and their respective Transactions
trying to find a match).
Could there be any other way to work this out?
The most reliable approach would be implementing a delayed polling strategy where you wait 5-10 seconds before checking transaction-to-refund relationships, or using refunds/create
webhooks to detect when Refund objects are created and then match them retroactively to existing transactions.
Your approach sounds correct in principle, but the timing creates a temporary gap where the relationship doesn’t exist yet. The refund OrderTransaction
objects are created immediately for financial tracking, while the Refund
objects are only created after confirming the transaction was successful. This typically happens within a few seconds, so your iteration logic should work, just not instantly.
thanks @KyleG-Shopify , over the last few days we tried a few things and in the end also decided that a “delayed polling strategy” is probably the best course of action here. Looking at the data in, it a 5-10 second delay would indeed cover all such cases we have seen so far where the Transaction precedes its Refund.
1 Like