We're moving the community! Starting July 7, the current community will be read-only for approx. 2 weeks. You can browse content, but posting will be temporarily unavailable. Learn more

Billing Redirect Not Working On Remix - 401 Error using "billing.request()"

Billing Redirect Not Working On Remix - 401 Error using "billing.request()"

Bluerock
Shopify Partner
1 0 0

I'm using RemixJS, the latest versions of @Shopify/shopify-app-remix

I first noticed this error when the app reviewer declined my app since I didn't have proper "Upgrade/Downgrade" buttons. I was very confused since this works flawlessly on the test store. I even provided a full video of it working, twice.

After debugging logs, I couldn't find ANYTHING.

I have two plans declared on my "shopify.server.ts". under the billing object which are available on "availablePlans". and "isBillingTest()" just checks my .env variable for TEST_BILLING === 'true'

"test: false" in this case right now.

When I click "Subscribe", my code executes here:
 

export const action = async ({ request }: ActionFunctionArgs) => {
  const adminContext = await authenticate.admin(request);
  const { billing, session } = adminContext;

const { hasActivePayment, appSubscriptions } = await billing.check({
    plans: availablePlans,
    isTest: isBillingTest(),
  });


if (!hasActivePayment) {
try { 
await billing.require({
        plans: availablePlans,
        onFailure: async (error) => {
          console.error('Billing require failed:', error);
          console.log('Attempting to redirect to billing page for plan:', plan);
          return billing.request({
            plan: plan.toString() as PlanName,
            isTest: isBillingTest(),
            returnUrl: createReturnUrl(session.shop),
          });
        },
      });    
} catch ( error )  {
   console.log('error billing', error );
}
}

 

and this is the error:

Response {
  size: 0,
  [Symbol(Body internals)]: {
    body: null,
    type: null,
    size: 0,
    boundary: null,
    disturbed: false,
    error: null
  },
  [Symbol(Response internals)]: {
    url: undefined,
    status: 401,
    statusText: 'Unauthorized',
    headers: {
      'x-shopify-api-request-failure-reauthorize-url': 'https://xxxxxx.myshopify.com/admin/charges/123345/21345/RecurringApplicationCharge/confirm_recurring_application_charge?signature=BAh7BzoHaWRsKwg'
    },
    counter: 0,
    highWaterMark: undefined
  }
}

It's very weird. Why am I getting 401 errors? I wonder if this what the reviewer ran into too. 

Although, when I change test: true then I can make successful tests.

Any ideas would be greatly appreciated.

Here is another clue for the Shopify team: On this app, I always had it set to billing test: false. I decided to run a "test payment" (because I'm like "why was the reviewer getting an error? Maybe something on production?), so I changed test: true. Subscription worked. No issues. Webhooks ran.

I then changed it BACK to test: false. I go to subscribe, and I'm expecting it to redirect to the charges URL, but no, 401. This error only started happening AFTER I changed it from the original test: false -> true -> false. 

Now, I don't know what else to do. I'm afraid the reviewer is going to look again and say it failed. This seems to be on the Shopify side I'm assuming. If I manually enter that URL from the response "x-shopify-api-request-failure-reauthorize-url" then it does go to the Approval Page.

Here is the Shopify App Reviewer getting a 401. This is from my server logs. Redacted information.

[shopify-app/INFO] Requesting billing | {shop: 1234.myshopify.com, plan: Starter Plan, isTest: false, returnUrl: https://admin.shopify.com/store/1234/apps/my-app/app/billing}
POST /app/billing?_data=routes%2Fapp.billing 401 - - 735.172 ms

But somehow after this the webhook ran for subscription? How is this possible if they didn't get redirected to an approval page?

app subscription {
  admin_graphql_api_id: 'gid://shopify/AppSubscription/1234',
  name: 'Pro Plan',
  status: 'ACTIVE',
  admin_graphql_api_shop_id: 'gid://shopify/Shop/1234',
  created_at: '2025-07-03T20:35:51+08:00',
  updated_at: '2025-07-03T20:35:57+08:00',
  currency: 'USD',
  capped_amount: null,
  price: '49.00',
  interval: 'every_30_days',
  plan_handle: null
}
POST /webhooks/app/subscriptions_update 200 - - 290.793 ms

 

Replies 0 (0)