diff --git a/packages/stripe/src/routes.ts b/packages/stripe/src/routes.ts index fcc2a23198..57c9cb20c4 100644 --- a/packages/stripe/src/routes.ts +++ b/packages/stripe/src/routes.ts @@ -861,6 +861,7 @@ export const upgradeSubscription = (options: StripeOptions) => { { items: newPhaseItems, start_date: currentPhase.end_date, + billing_cycle_anchor: "phase_start", proration_behavior: "none", }, ], diff --git a/packages/stripe/test/subscription.test.ts b/packages/stripe/test/subscription.test.ts index 6642313ac7..6ef07971c2 100644 --- a/packages/stripe/test/subscription.test.ts +++ b/packages/stripe/test/subscription.test.ts @@ -2551,7 +2551,10 @@ describe("stripe subscription", () => { expect(stripeMock.checkout.sessions.create).not.toHaveBeenCalled(); }); - test("should schedule plan change at period end when scheduleAtPeriodEnd is true", async ({ + /** + * @see https://github.com/better-auth/better-auth/issues/11336 + */ + test("should reset the billing cycle anchor for a scheduled plan change", async ({ stripeMock, memory, stripeOptions, @@ -2638,11 +2641,13 @@ describe("stripe subscription", () => { expect.objectContaining({ metadata: { source: "@better-auth/stripe" }, end_behavior: "release", - phases: expect.arrayContaining([ + phases: [ + expect.anything(), expect.objectContaining({ + billing_cycle_anchor: "phase_start", proration_behavior: "none", }), - ]), + ], }), ); expect(stripeMock.billingPortal.sessions.create).not.toHaveBeenCalled();