[GH-ISSUE #3537] [BUG]: Stripe plugin does not handle lookupKey and annualDiscountLookupKey in onCheckoutSessionCompleted #9636

Closed
opened 2026-04-13 05:13:26 -05:00 by GiteaMirror · 3 comments
Owner

Originally created by @max-om on GitHub (Jul 22, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/3537

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

Create a plan without priceId and pass it to the Stripe Plugin options:

ex:

plans = [
        {
            name: "basic", 
            lookupKey: "basic_monthly",
            annualDiscountLookupKey: "basic_yearly",
        },
]

Then perform a strip checkout.

Current vs. Expected behavior

On successful checkout, the subscription is not updated in the database. The subscription id is still NULL and the status incomplete.

Documentation says:

priceId: string - The Stripe price ID. Required unless using lookupKey.
lookupKey: string - The Stripe price lookup key. Alternative to priceId.
annualDiscountPriceId: string - A price ID for annual billing.
annualDiscountLookupKey: string - The Stripe price lookup key for annual billing. Alternative to annualDiscountPriceId.

So, the understanding is that if lookup keys are provided, then the price id is not mandatory.

Issue in code:

  1. https://github.com/better-auth/better-auth/blob/v1.3.2/packages/stripe/src/hooks.ts#L20-L21
  2. https://github.com/better-auth/better-auth/blob/v1.3.2/packages/stripe/src/utils.ts
const priceId = subscription.items.data[0]?.price.id;
const plan = await getPlanByPriceId(options, priceId as string);
if (plan) {...}

No checks on lookup key hence plan is effectively empty.

What version of Better Auth are you using?

1.3.2

Provide environment information

- MacOS

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

Package

Auth config (if applicable)

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

Additional context

No response

Originally created by @max-om on GitHub (Jul 22, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/3537 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce Create a plan without priceId and pass it to the Stripe Plugin options: ex: ``` plans = [ { name: "basic", lookupKey: "basic_monthly", annualDiscountLookupKey: "basic_yearly", }, ] ``` Then perform a strip checkout. ### Current vs. Expected behavior On successful checkout, the subscription is not updated in the database. The subscription id is still `NULL` and the status `incomplete`. Documentation says: priceId: string - The Stripe price ID. Required unless using lookupKey. lookupKey: string - The Stripe price lookup key. Alternative to priceId. annualDiscountPriceId: string - A price ID for annual billing. annualDiscountLookupKey: string - The Stripe price lookup key for annual billing. Alternative to annualDiscountPriceId. So, the understanding is that if lookup keys are provided, then the price id is not mandatory. Issue in code: 1. https://github.com/better-auth/better-auth/blob/v1.3.2/packages/stripe/src/hooks.ts#L20-L21 2. https://github.com/better-auth/better-auth/blob/v1.3.2/packages/stripe/src/utils.ts ``` const priceId = subscription.items.data[0]?.price.id; const plan = await getPlanByPriceId(options, priceId as string); if (plan) {...} ``` No checks on lookup key hence `plan` is effectively empty. ### What version of Better Auth are you using? 1.3.2 ### Provide environment information ```bash - MacOS ``` ### Which area(s) are affected? (Select all that apply) Package ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" export const auth = betterAuth({ emailAndPassword: { enabled: true }, }); ``` ### Additional context _No response_
GiteaMirror added the lockedbug labels 2026-04-13 05:13:26 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Jul 22, 2025):

You're right—this is a bug. The current Stripe plugin only identifies plans by priceId during checkout session completion, so if you define plans using only lookupKey or annualDiscountLookupKey, the subscription won't be updated in the database as expected. This doesn't match the documented behavior, which says lookupKey should be a valid alternative to priceId.

A recent pull request (#3351) introduces logic to resolve lookupKey to priceId, including a caching mechanism to improve performance. However, this fix is not available in v1.3.2.

Until a release includes this fix, the only reliable workaround is to include priceId (and annualDiscountPriceId, if needed) in your plan definitions. If you can't, you would need to patch your local code to resolve lookupKey to priceId before plan lookup in the affected Stripe plugin files (hooks.ts, utils.ts).

Let me know if you want a code snippet for a temporary patch or more details on how the fix works.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Join Discord Share on X

<!-- gh-comment-id:3101023154 --> @dosubot[bot] commented on GitHub (Jul 22, 2025): <!-- Answer --> You're right—this is a bug. The current Stripe plugin only identifies plans by priceId during checkout session completion, so if you define plans using only lookupKey or annualDiscountLookupKey, the subscription won't be updated in the database as expected. This doesn't match the documented behavior, which says lookupKey should be a valid alternative to priceId. A recent pull request ([#3351](https://github.com/better-auth/better-auth/pull/3351)) introduces logic to resolve lookupKey to priceId, including a caching mechanism to improve performance. However, this fix is not available in v1.3.2. Until a release includes this fix, the only reliable workaround is to include priceId (and annualDiscountPriceId, if needed) in your plan definitions. If you can't, you would need to patch your local code to resolve lookupKey to priceId before plan lookup in the affected Stripe plugin files ([hooks.ts](https://github.com/better-auth/better-auth/blob/v1.3.2/packages/stripe/src/hooks.ts#L20-L21), [utils.ts](https://github.com/better-auth/better-auth/blob/v1.3.2/packages/stripe/src/utils.ts)). Let me know if you want a code snippet for a temporary patch or more details on how the fix works. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/11cd88e7-9934-450c-adb8-d0b908612f42?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/11cd88e7-9934-450c-adb8-d0b908612f42?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/11cd88e7-9934-450c-adb8-d0b908612f42?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/11cd88e7-9934-450c-adb8-d0b908612f42?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/11cd88e7-9934-450c-adb8-d0b908612f42?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/11cd88e7-9934-450c-adb8-d0b908612f42?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/11cd88e7-9934-450c-adb8-d0b908612f42?feedback_type=other)</sup>&nbsp;&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/3537)
Author
Owner

@max-om commented on GitHub (Jul 22, 2025):

This is a quick fix for review: https://github.com/better-auth/better-auth/pull/3539

<!-- gh-comment-id:3101107673 --> @max-om commented on GitHub (Jul 22, 2025): This is a quick fix for review: https://github.com/better-auth/better-auth/pull/3539
Author
Owner

@dosubot[bot] commented on GitHub (Oct 21, 2025):

Hi, @max-om. 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 Better Auth v1.3.2's Stripe plugin lacks support for lookupKey and annualDiscountLookupKey in the onCheckoutSessionCompleted event, causing subscriptions to have NULL IDs.
  • A recent PR (#3351) adds lookupKey resolution and caching but is not included in v1.3.2 yet.
  • Until the fix is released, users must either include priceId in plans or patch the code locally.
  • You submitted a quick fix PR (#3539) addressing this issue, which I am currently reviewing.

Next Steps:

  • Please confirm if this issue is still relevant with the latest version of better-auth, and if so, you can keep the discussion open by commenting here.
  • Otherwise, I will automatically close this issue in 7 days.

Thank you for your understanding and contribution!

<!-- gh-comment-id:3427435460 --> @dosubot[bot] commented on GitHub (Oct 21, 2025): Hi, @max-om. 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 Better Auth v1.3.2's Stripe plugin lacks support for `lookupKey` and `annualDiscountLookupKey` in the `onCheckoutSessionCompleted` event, causing subscriptions to have NULL IDs. - A recent PR (#3351) adds `lookupKey` resolution and caching but is not included in v1.3.2 yet. - Until the fix is released, users must either include `priceId` in plans or patch the code locally. - You submitted a quick fix PR (#3539) addressing this issue, which I am currently reviewing. **Next Steps:** - Please confirm if this issue is still relevant with the latest version of better-auth, and if so, you can keep the discussion open by commenting here. - 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#9636