[GH-ISSUE #2269] Incorrect date fields usage in subscription update at @better-auth/stripe plugin #9122

Closed
opened 2026-04-13 04:28:26 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @ariburaco on GitHub (Apr 13, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/2269

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

There's a bug in the @better-auth/stripe package related to how it handles subscription period dates. The package incorrectly uses subscription.current_period_start and subscription.current_period_end when it should be using subscription.items.data[0].current_period_start and subscription.items.data[0].current_period_end.

Current vs. Expected behavior

Description

There's a bug in the @better-auth/stripe package related to how it handles subscription period dates. The package incorrectly uses subscription.current_period_start and subscription.current_period_end when it should be using subscription.items.data[0].current_period_start and subscription.items.data[0].current_period_end.

Details

The issue occurs in the subscription update logic where the package attempts to set the periodStart and periodEnd fields:

// Current problematic code in @better-auth/stripe
await ctx.context.adapter.update({
  model: "subscription",
  update: {
    // ...other fields
    periodEnd: new Date(
      stripeSubscription.current_period_end * 1000,
    ),
    periodStart: new Date(
      stripeSubscription.current_period_start * 1000,
    ),
    // ...rest of code
  },
});

This causes issues because:

  1. In some cases, these fields might not exist directly on the subscription object
  2. The correct data is available in the subscription items array

What version of Better Auth are you using?

1.2.7

Provide environment information

- Package version: @better-auth/stripe@1.2.7
- Stripe API version: Latest (18.0.0)
- Node.js version: 18.x

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

Backend

Auth config (if applicable)

import { betterAuth } from "better-auth"
export const auth = betterAuth({
  emailAndPassword: {  
    enabled: true
  },
 // with official stripe plugin.. 
});

Additional context

Correct Implementation

We've implemented the correct approach in our custom hook:

const subscriptionItem = subscription.items.data[0]!;

// ...

const periodStart = subscriptionItem.current_period_start
  ? new Date(subscriptionItem.current_period_start * 1000)
  : null;
const periodEnd = subscriptionItem.current_period_end
  ? new Date(subscriptionItem.current_period_end * 1000)
  : null;

Proposed Fix

The package should be updated to use the subscription item's period data instead:

// The fix should look something like this:
const subscriptionItem = stripeSubscription.items.data[0];
const periodStart = subscriptionItem?.current_period_start 
  ? new Date(subscriptionItem.current_period_start * 1000)
  : new Date(stripeSubscription.start_date * 1000); // fallback

const periodEnd = subscriptionItem?.current_period_end 
  ? new Date(subscriptionItem.current_period_start * 1000)
  : new Date(stripeSubscription.start_date * 1000); // fallback maybe? but most of time will be null or not exist

await ctx.context.adapter.update({
  model: "subscription",
  update: {
    // ...other fields
    periodEnd,
    periodStart,
    // ...rest of code
  },
});

Current Workaround

We've implemented a workaround by patching the package and rebuilding it during the post-install process using a custom script.

Additional Context

We've noticed this issue specifically when processing subscription updates. The incorrect date handling leads to errors in creating or updating subscription records in the database.

Originally created by @ariburaco on GitHub (Apr 13, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/2269 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce There's a bug in the @better-auth/stripe package related to how it handles subscription period dates. The package incorrectly uses subscription.current_period_start and subscription.current_period_end when it should be using subscription.items.data[0].current_period_start and subscription.items.data[0].current_period_end. ### Current vs. Expected behavior ## Description There's a bug in the `@better-auth/stripe` package related to how it handles subscription period dates. The package incorrectly uses `subscription.current_period_start` and `subscription.current_period_end` when it should be using `subscription.items.data[0].current_period_start` and `subscription.items.data[0].current_period_end`. ## Details The issue occurs in the subscription update logic where the package attempts to set the `periodStart` and `periodEnd` fields: ```typescript // Current problematic code in @better-auth/stripe await ctx.context.adapter.update({ model: "subscription", update: { // ...other fields periodEnd: new Date( stripeSubscription.current_period_end * 1000, ), periodStart: new Date( stripeSubscription.current_period_start * 1000, ), // ...rest of code }, }); ``` This causes issues because: 1. In some cases, these fields might not exist directly on the subscription object 2. The correct data is available in the subscription items array ### What version of Better Auth are you using? 1.2.7 ### Provide environment information ```bash - Package version: @better-auth/stripe@1.2.7 - Stripe API version: Latest (18.0.0) - Node.js version: 18.x ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" export const auth = betterAuth({ emailAndPassword: { enabled: true }, // with official stripe plugin.. }); ``` ### Additional context ## Correct Implementation We've implemented the correct approach in our custom hook: ```typescript const subscriptionItem = subscription.items.data[0]!; // ... const periodStart = subscriptionItem.current_period_start ? new Date(subscriptionItem.current_period_start * 1000) : null; const periodEnd = subscriptionItem.current_period_end ? new Date(subscriptionItem.current_period_end * 1000) : null; ``` ## Proposed Fix The package should be updated to use the subscription item's period data instead: ```typescript // The fix should look something like this: const subscriptionItem = stripeSubscription.items.data[0]; const periodStart = subscriptionItem?.current_period_start ? new Date(subscriptionItem.current_period_start * 1000) : new Date(stripeSubscription.start_date * 1000); // fallback const periodEnd = subscriptionItem?.current_period_end ? new Date(subscriptionItem.current_period_start * 1000) : new Date(stripeSubscription.start_date * 1000); // fallback maybe? but most of time will be null or not exist await ctx.context.adapter.update({ model: "subscription", update: { // ...other fields periodEnd, periodStart, // ...rest of code }, }); ``` ## Current Workaround We've implemented a workaround by patching the package and rebuilding it during the post-install process using a custom script. ## Additional Context We've noticed this issue specifically when processing subscription updates. The incorrect date handling leads to errors in creating or updating subscription records in the database.
GiteaMirror added the locked label 2026-04-13 04:28:26 -05:00
Author
Owner

@ariburaco commented on GitHub (Apr 13, 2025):

I think #2173 is a suitable solution for this issue!

<!-- gh-comment-id:2800166566 --> @ariburaco commented on GitHub (Apr 13, 2025): I think #2173 is a suitable solution for this issue!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#9122