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:

  1. Query Balance Transactions: You can still fetch balance transactions for orders that belong to the archived

    merchantBusinessEntity
    .

  2. Identify Associated Payouts: Each

    balanceTransactions
    node has an
    associatedPayout { id status }
    field. This means the link to the payout still exists, even if the payout object itself isn't directly exposed.

  3. Group and Reconstruct: You can group these transactions by their

    associatedPayout.id
    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.

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-id
s (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!

Share:

Use cases

Explore use cases

Agencies, store owners, enterprise — find the migration path that fits.

Explore use cases