Incorrect PriceId after upgrading subscription from monthly to yearly #1450

Closed
opened 2026-03-13 08:40:48 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @MikeCodeur on GitHub (Jul 1, 2025).

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

When upgrading a subscription from monthly to yearly via Better Auth, the priceId returned by the subscription.list() API call is not updated and remains the one from the monthly version. This prevents correctly determining the billing mode (yearly/monthly) of the subscription.

Steps to Reproduce

  1. Create a monthly subscription

    • Create a new Pro subscription in monthly mode
    • Verify that the priceId corresponds to the monthly price (e.g., price_123_monthly)
  2. Upgrade to yearly

    • Use Better Auth's upgrade function with annual: true
    • Choose the same plan (Pro) but in yearly mode
    • Complete the payment process
  3. Check priceId after upgrade

    • Retrieve the subscription via authClient.subscription.list()
    • Observe that the priceId remains the one from the monthly price
    • The Stripe subscription is correctly yearly but Better Auth keeps the old priceId

Current vs. Expected behavior

Expected Behavior

  • The priceId in Better Auth should be updated with the new yearly priceId
  • The isYearlyPrice(priceId) function should return true for a yearly subscription
  • The interface should correctly display "Yearly" in the summary
  • The monthly/yearly toggle should initialize to the correct value

Actual Behavior

  • The priceId remains the one from the original monthly price
  • isYearlyPrice(priceId) returns false even for a yearly subscription
  • The interface displays "Monthly" instead of "Yearly"
  • The toggle initializes incorrectly

Workaround Implemented

To work around this issue, we have implemented:

  1. Retrieve the real priceId via Stripe

    const realPriceId = await getPriceIdFromSubscriptionIdAction(
      activeSubscription.stripeSubscriptionId
    )
    
  2. Use the real priceId for business logic

    const activeSubscriptionIsYearly = realPriceId ? isYearlyPrice(realPriceId) : false
    

Impact

  • Functionality: Subscription management works correctly with the workaround
  • Performance: An additional Stripe API call is required
  • Maintenance: More complex code to handle data inconsistencies

Labels

  • bug
  • better-auth
  • stripe
  • subscription
  • data-sync

Notes

This bug appears to be related to data synchronization between Stripe and Better Auth during subscription modifications. A permanent solution would require a fix on the Better Auth side to correctly update the priceId during upgrades.

What version of Better Auth are you using?

1.2.12

Provide environment information

-WSL2

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 @MikeCodeur on GitHub (Jul 1, 2025). ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce When upgrading a subscription from monthly to yearly via Better Auth, the `priceId` returned by the `subscription.list()` API call is not updated and remains the one from the monthly version. This prevents correctly determining the billing mode (yearly/monthly) of the subscription. ## Steps to Reproduce 1. **Create a monthly subscription** - Create a new Pro subscription in monthly mode - Verify that the `priceId` corresponds to the monthly price (e.g., `price_123_monthly`) 2. **Upgrade to yearly** - Use Better Auth's `upgrade` function with `annual: true` - Choose the same plan (Pro) but in yearly mode - Complete the payment process 3. **Check priceId after upgrade** - Retrieve the subscription via `authClient.subscription.list()` - Observe that the `priceId` remains the one from the monthly price - The Stripe subscription is correctly yearly but Better Auth keeps the old priceId > ### Current vs. Expected behavior ## Expected Behavior - The `priceId` in Better Auth should be updated with the new yearly priceId - The `isYearlyPrice(priceId)` function should return `true` for a yearly subscription - The interface should correctly display "Yearly" in the summary - The monthly/yearly toggle should initialize to the correct value ## Actual Behavior - The `priceId` remains the one from the original monthly price - `isYearlyPrice(priceId)` returns `false` even for a yearly subscription - The interface displays "Monthly" instead of "Yearly" - The toggle initializes incorrectly ## Workaround Implemented To work around this issue, we have implemented: 1. **Retrieve the real priceId via Stripe** ```typescript const realPriceId = await getPriceIdFromSubscriptionIdAction( activeSubscription.stripeSubscriptionId ) ``` 2. **Use the real priceId for business logic** ```typescript const activeSubscriptionIsYearly = realPriceId ? isYearlyPrice(realPriceId) : false ``` ## Impact - **Functionality**: Subscription management works correctly with the workaround - **Performance**: An additional Stripe API call is required - **Maintenance**: More complex code to handle data inconsistencies ## Labels - `bug` - `better-auth` - `stripe` - `subscription` - `data-sync` ## Notes This bug appears to be related to data synchronization between Stripe and Better Auth during subscription modifications. A permanent solution would require a fix on the Better Auth side to correctly update the `priceId` during upgrades. ### What version of Better Auth are you using? 1.2.12 ### Provide environment information ```bash -WSL2 ``` ### 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:40:48 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Sep 30, 2025):

Hi, @MikeCodeur. I'm Dosu, and I'm helping the better-auth team manage their backlog and am marking this issue as stale.

Issue Summary:

  • You reported that after upgrading a subscription from monthly to yearly, the priceId from subscription.list() does not update and still shows the monthly price.
  • This causes incorrect billing mode detection in your application.
  • You implemented a workaround by fetching the correct priceId directly from Stripe, which adds complexity and extra API calls.
  • The expected behavior is for Better Auth to return the updated priceId reflecting the yearly subscription.
  • No further comments or updates have been made on this issue.

Next Steps:

  • Please let me know if this issue is still relevant with the latest version of better-auth by commenting here to keep the discussion open.
  • Otherwise, I will automatically close this issue in 7 days.

Thank you for your understanding and contribution!

@dosubot[bot] commented on GitHub (Sep 30, 2025): Hi, @MikeCodeur. I'm [Dosu](https://dosu.dev), and I'm helping the better-auth team manage their backlog and am marking this issue as stale. **Issue Summary:** - You reported that after upgrading a subscription from monthly to yearly, the `priceId` from `subscription.list()` does not update and still shows the monthly price. - This causes incorrect billing mode detection in your application. - You implemented a workaround by fetching the correct `priceId` directly from Stripe, which adds complexity and extra API calls. - The expected behavior is for Better Auth to return the updated `priceId` reflecting the yearly subscription. - No further comments or updates have been made on this issue. **Next Steps:** - Please let me know if this issue is still relevant with the latest version of better-auth by commenting here to keep the discussion open. - Otherwise, I will automatically close this issue in 7 days. Thank you for your understanding and contribution!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#1450