Unauthorized Error When Upgrading Subscription with Stripe Plugin #825

Closed
opened 2026-03-13 08:05:53 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @x751685875 on GitHub (Mar 11, 2025).

Title: Unauthorized Error When Upgrading Subscription with Stripe Plugin

Description: I'm encountering an UNAUTHORIZED error when attempting to upgrade a subscription using the better-auth Stripe plugin. The referenceId is correctly pointing to my organizations, but the request still fails with a 401 error.

Steps to Reproduce:

  1. Use the following setup in better-auth with the stripe plugin.
  2. Call auth.api.upgradeSubscription with a valid referenceId (organization ID).
  3. Observe that the API request fails with a 401 Unauthorized error.
const subscription = await auth.api.upgradeSubscription({
  headers: await headers(),
  body: {
    plan: "free",
    referenceId: 'cm82z7mjz0006a12t1tr7eoeu',
    seats: 1,
    successUrl: '/websites/213-8a6v',
    cancelUrl: '/websites/213-8a6v',
  },
})

Questions:

  1. Is the referenceId validation in authorizeReference correct?
  2. Are there additional permissions or configurations needed for the upgradeSubscription API?
  3. Could this be an issue with the API expecting a different model name for organizations?

Any guidance or troubleshooting steps would be appreciated!

Current vs. Expected behavior

Expected Behavior:

  • The API call should successfully process the subscription upgrade if the user has the correct permissions.

Actual Behavior:

  • The request fails with the following error:
[Error [APIError]: Unauthorized] {
  status: 'UNAUTHORIZED',
  body: [Object],
  headers: {},
  statusCode: 401,
  digest: '3114361753'
}

Additional Context:

  • The authorizeReference function is implemented as follows:
authorizeReference: async ({ user, referenceId }: { user: User; referenceId: string }) => {
  const colleague = await database.colleagues.findFirst({
    where: {
      organizationId: referenceId,
      userId: user.id,
    },
  })
  return colleague?.role === 'owner'
}
  • The user is an owner in the organization.
  • The schema is configured with:
stripe({
    schema: {
        subscription: {
            modelName: "subscriptions", 
        }
    }
})
...
schema: {
  organization: {
    modelName: 'organizations',
  },
  member: {
    modelName: 'colleagues',
  },
  invitation: {
    modelName: 'invitations',
  },
},

What version of Better Auth are you using?

1.2.3

Provide environment information

-

Which area(s) are affected? (Select all that apply)

Client

Auth config (if applicable)

import { betterAuth } from "better-auth"
export const auth = betterAuth({
  emailAndPassword: {  
    enabled: true
  },
});

Additional context

No response

Originally created by @x751685875 on GitHub (Mar 11, 2025). **Title:** Unauthorized Error When Upgrading Subscription with Stripe Plugin **Description:** I'm encountering an `UNAUTHORIZED` error when attempting to upgrade a subscription using the `better-auth` Stripe plugin. The `referenceId` is correctly pointing to my `organizations`, but the request still fails with a 401 error. **Steps to Reproduce:** 1. Use the following setup in `better-auth` with the `stripe` plugin. 2. Call `auth.api.upgradeSubscription` with a valid `referenceId` (organization ID). 3. Observe that the API request fails with a 401 Unauthorized error. ```js const subscription = await auth.api.upgradeSubscription({ headers: await headers(), body: { plan: "free", referenceId: 'cm82z7mjz0006a12t1tr7eoeu', seats: 1, successUrl: '/websites/213-8a6v', cancelUrl: '/websites/213-8a6v', }, }) ``` **Questions:** 1. Is the `referenceId` validation in `authorizeReference` correct? 2. Are there additional permissions or configurations needed for the `upgradeSubscription` API? 3. Could this be an issue with the API expecting a different model name for `organizations`? Any guidance or troubleshooting steps would be appreciated! ### Current vs. Expected behavior **Expected Behavior:** - The API call should successfully process the subscription upgrade if the user has the correct permissions. **Actual Behavior:** - The request fails with the following error: ``` [Error [APIError]: Unauthorized] { status: 'UNAUTHORIZED', body: [Object], headers: {}, statusCode: 401, digest: '3114361753' } ``` **Additional Context:** - The `authorizeReference` function is implemented as follows: ```ts authorizeReference: async ({ user, referenceId }: { user: User; referenceId: string }) => { const colleague = await database.colleagues.findFirst({ where: { organizationId: referenceId, userId: user.id, }, }) return colleague?.role === 'owner' } ``` - The user is an `owner` in the organization. - The `schema` is configured with: ```ts stripe({ schema: { subscription: { modelName: "subscriptions", } } }) ... schema: { organization: { modelName: 'organizations', }, member: { modelName: 'colleagues', }, invitation: { modelName: 'invitations', }, }, ``` ### What version of Better Auth are you using? 1.2.3 ### Provide environment information ```bash - ``` ### Which area(s) are affected? (Select all that apply) Client ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" export const auth = betterAuth({ emailAndPassword: { enabled: true }, }); ``` ### Additional context _No response_
GiteaMirror added the bug label 2026-03-13 08:05:53 -05:00
Author
Owner

@yzuyr commented on GitHub (May 21, 2025):

@x751685875 how did you manage to solve it? Currently facing similar issue

@yzuyr commented on GitHub (May 21, 2025): @x751685875 how did you manage to solve it? Currently facing similar issue
Author
Owner

@yzuyr commented on GitHub (May 22, 2025):

Okay, so for me the problem was that I updated the cookie settings to use `partitioned: true'. While it works fine with the rest of Better Auth, it breaks the upgrade subscription flow (I got a separate Hono backend that serves Astro frontend).
https://www.better-auth.com/docs/concepts/cookies#cross-subdomain-cookies

@yzuyr commented on GitHub (May 22, 2025): Okay, so for me the problem was that I updated the cookie settings to use `partitioned: true'. While it works fine with the rest of Better Auth, it breaks the upgrade subscription flow (I got a separate Hono backend that serves Astro frontend). https://www.better-auth.com/docs/concepts/cookies#cross-subdomain-cookies
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#825