Navigating Shopify Payments Payouts: GraphQL Gaps and REST Workarounds
Hey everyone! As a Shopify migration expert and someone who loves digging into the nitty-gritty of how things work (or sometimes don't!), I wanted to share some really valuable insights from a recent community discussion. It touched on a specific, tricky issue with Shopify Payments payouts when using the GraphQL API, especially for stores with complex business structures.
Our friend @twendt kicked off a super important thread, highlighting a head-scratcher: the GraphQL API's
shopifyPaymentsAccount.payouts connection was returning fewer payouts than the good old REST API. Specifically, GraphQL showed 20 payouts with hasNextPage: false, while REST happily delivered all 32. Even trying to query the missing payouts directly by ID in GraphQL came up empty. But here's the kicker: the underlying balance transactions for those missing payouts were still visible!
The Mystery of the Missing Payouts: An Archived Entity Story
This kind of discrepancy is exactly the sort of thing that keeps developers up at night, and the community quickly rallied to help uncover the root cause. The crucial clue, as @HamidEjaz and @cuongnm_trooix pointed out, seemed to be tied to a specific cutoff date around 2026-06-15, which coincided with the merchant's move to a new business entity structure. The original business entity had been marked as
"archived": true.
It turns out, the GraphQL API's
businessEntities { shopifyPaymentsAccount { payouts } } query is designed to scope payouts to a specific business entity. The REST API, on the other hand, isn't entity-scoped in the same way, which is why it continued to return all 32 historical payouts without issue. This was a lightbulb moment: the missing payouts weren't truly gone; they were just hidden behind an archived entity that GraphQL wasn't surfacing in the usual way.
Why Direct Queries to Archived Accounts Fell Short
Initially, there was a thought that perhaps you could just query the archived entity's
shopifyPaymentsAccount directly by its id. However, @twendt confirmed that this didn't yield the missing payouts either. As @cuongnm_trooix wisely observed, when you query the businessEntities response, the archived entity's shopifyPaymentsAccount actually comes back as null. This strongly suggested that there wasn't a separate, queryable account object for archived entities in GraphQL.
Here's a snippet @twendt shared, showing the archived entity's
shopifyPaymentsAccount as null:
{
"data": {
"businessEntities": [
{
"id": "gid://shopify/BusinessEntity/",
"primary": true,
"legalEntityId": "",
"displayName": " – Entität",
"archived": false,
"shopifyPaymentsAccount": {
"payouts": {
"nodes": [
{
// oldest payout
},
{
// more payouts
}
],
"pageInfo": {
"hasNextPage": false,
}
}
}
},
{
"id": "gid://shopify/BusinessEntity/",
"primary": false,
"legalEntityId": null,
"displayName": " - entity",
"archived": true,
"shopifyPaymentsAccount": null
}
]
}
}
This really solidifies the idea that it's a limitation in how GraphQL handles archived business entities and their associated payment data.
Your Action Plan: Workarounds and Best Practices
So, what can you do if you're facing a similar situation? Here's the consolidated wisdom from the community discussion:
1. Lean on the REST API for Historical Data
For now, the REST API remains the most reliable source for a complete, authoritative historical record of your Shopify Payments payouts, especially if they span across business entity changes. Since REST isn't scoped by entity in the same way GraphQL is, it will give you all the payouts for your merchant account.
You can access it like this (using the example version from the thread):
admin/api/2026-07/shopify_payments/payouts.json
2. Reconstruct Missing Payouts from Balance Transactions (GraphQL Workaround)
This is where things get a bit clever! While the payouts themselves might not be directly queryable for archived entities via GraphQL, the individual balance transactions associated with them are. @HamidEjaz suggested a brilliant workaround:
-
Query Balance Transactions: You can still fetch balance transactions for orders that belong to the archived
.merchantBusinessEntity -
Identify Associated Payouts: Each
node has anbalanceTransactions
field. This means the link to the payout still exists, even if the payout object itself isn't directly exposed.associatedPayout { id status } -
Group and Reconstruct: You can group these transactions by their
to effectively rebuild the missing payouts, including their amounts and dates. It's not ideal to reconstruct, but it gives you the data you need for reporting or reconciliation.associatedPayout.id
3. Report to Shopify
This is crucial! As @Steve_TopNewYork and @HamidEjaz both emphasized, this behavior seems like an intentional limitation or an issue with the payouts connection for archived entities in GraphQL. Shopify's API team needs to be aware of this gap. If you encounter this, gather your
x-request-ids (like the ones @twendt provided: fd49c452-5552-4633-a0be-3628d4118689-1783602464 for REST and 2b416458-3e58-4b34-9635-4980eb82857d-1783605076 for GraphQL) and reach out to Shopify Support or the API team. The more data points they have, the better they can understand and potentially address this.
Here's the GraphQL query @twendt was using:
query businessEntities {
businessEntities {
primary
shopifyPaymentsAccount {
payouts(first: 50, sortKey: ISSUED_AT) {
nodes { id issuedAt transactionType status net { amount } }
pageInfo { hasNextPage endCursor }
}
}
}
}
And another query used for direct payout ID retrieval:
query GetPayoutById {
shopifyPaymentsAccount {
payouts(first: 250, query: "id:158560223567") {
nodes {
id
issuedAt,
legacyResourceId
}
}
}
}
This discussion really highlights that while GraphQL is incredibly powerful and flexible, there can still be nuances, especially with historical data and evolving platform structures like business entities. For now, if you're dealing with a merchant who's transitioned business entities and you need their full payout history, combining the REST API for older data and potentially reconstructing missing payouts from balance transactions via GraphQL seems to be the most robust approach. And, of course, letting Shopify know about these edge cases helps them improve the API for all of us!