[Bug] Payment made with managed payment cannot be verified in app

Hi!

In the dev environment, even after payment is successful, “await billing.check();” returns nothing.
But this query returns the active plan (Only in the graphql test page).

query {
  currentAppInstallation {
    activeSubscriptions {
      id
      name
      status
      createdAt
      currentPeriodEnd
    }
  }
}

Also the plan selection page shows the active plan:

In this video managed payment and billing.check works together too: https://www.youtube.com/watch?v=CHhEfifBMWg

A weird detail:
Graphql test page returns the correct result:

But this returns nothing:

    const response = await graphql(
      `
        query {
          currentAppInstallation {
            activeSubscriptions {
              id
              name
              status
              createdAt
              currentPeriodEnd
            }
          }
        }
      `
    );
    const { data } = await response.json();
    console.log("⭐⭐⭐", data);
1 Like

Hey @Anil_Sezer,

Thanks for the details shared here.

I tested this scenario with a managed pricing setup in development and actually couldn’t reproduce the issue you’re experiencing. Both billing.check() and direct GraphQL returned consistent results showing active subscriptions. Here’s the working test code I used if it helps:

export const loader = async ({ request }) => {
  const { billing, admin, session } = await authenticate.admin(request);
  const { hasActivePayment } = await billing.check();

  const response = await admin.graphql(`#graphql
    query {
      currentAppInstallation {
        activeSubscriptions {
          id
          name
          status
          createdAt
          currentPeriodEnd
        }
      }
    }
  `);
  const graph = await response.json();
  const activeSubscriptions =
    graph?.data?.currentAppInstallation?.activeSubscriptions ?? [];

  return json({ hasActivePayment, activeSubscriptions });
};

One thing I noticed with your code and your GraphQL call that might explain the inconsistent behavior. In your app code you’re using await graphql() directly, but it should be await admin.graphql() to use the authenticated client properly.

Let me know if anything above helps unblock you. If not, can you share a little more context on your environment and specific details to help me replicate this?

Hi Kyle!
Thank you.

I also copy pasted your code to make sure no mismatches but I’m still getting the same inconsistent result. Cancelling then subscribing again produces the same problem on my environment.

Before using Managed Payment, I wanted to use billing api to have more control over the whole thing and added packages to my shopify.server.ts. I did several deployments with that data.
Then I removed them for using managed api.
Current block at my shopify.server.ts file is this:

const shopify = shopifyApp({
  apiKey: process.env.SHOPIFY_API_KEY,
  apiSecretKey: process.env.SHOPIFY_API_SECRET || "",
  apiVersion: ApiVersion.January25,
  scopes: process.env.SCOPES?.split(","),
  appUrl: process.env.SHOPIFY_APP_URL || "",
  authPathPrefix: "/auth",
  sessionStorage: new PrismaSessionStorage(prisma),
  distribution: AppDistribution.AppStore,
  future: {
    unstable_newEmbeddedAuthStrategy: true,
    removeRest: true,
  },
  ...(process.env.SHOP_CUSTOM_DOMAIN
    ? { customShopDomains: [process.env.SHOP_CUSTOM_DOMAIN] }
    : {}),
});

As a workaround I used Webhooks to learn about users payment and store that at my DB but that approach introduced its own set of problems in my system.

I also updated api_version = "2025-04" to api_version = "2025-07" but that did not solved it too.

Updating shopify cli, making the mandatory migration and redeploying app also had no effect.

I would be happy to help about this, guide me about it.

Thanks for sharing that Anil.

Can you clarify that this is only returning empty when you have cancelled and then resubscribed?

Is this happening only with test stores or development stores, or do you notice this in production environments as well? The reason I ask is test charges don’t always have the same replacement behaviour as live charges so this could be why it’s returning empty.

Hey @Anil_Sezer, Are you still experiencing this issue, or can I mark this as solved?

Hi! sorry for late reply.
1 - Its always retuning empty, whichever package I choose, cancel or not. I tried every option to have a workaround.

2 - I did not tested at prod.

Issue still persists, I worked around by using webhooks and storing that in my db.

^ Are you fairly confident that these changes were removed completely and aren’t interfering?

When you test on a brand new development store, does the issue persist?

Can you share the steps you are taking to subscribe to your plan? There may be something there that is causing this as well.

To anyone who encounters this or if their proxies refuse to work randomly, create development shops from the new dev panel: https://dev.shopify.com/dashboard/ and try it there.

Thank you for your recommendation Kyle, using a new store fixed the dreaded app theme extension proxy bug and empty subscription bug instantly. Also I think it made results a bit faster?
Maybe Shopify was making some exception handling at the older stores.

What a great experience.

Thanks for sharing that you’ve been able to fix this and sharing what worked with the community!