@better-auth/stripe 1.2.2-beta.2 → 1.2.2-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,17 +1,17 @@
1
1
 
2
- > @better-auth/stripe@1.2.2-beta.2 build /home/runner/work/better-auth/better-auth/packages/stripe
2
+ > @better-auth/stripe@1.2.2-beta.4 build /home/runner/work/better-auth/better-auth/packages/stripe
3
3
  > unbuild
4
4
 
5
5
  [info] Automatically detected entries: src/index, src/client [esm] [cjs] [dts]
6
6
  [info] Building stripe
7
7
  [success] Build succeeded for stripe
8
- [log] dist/index.cjs (total size: 30.4 kB, chunk size: 30.4 kB, exports: stripe)
8
+ [log] dist/index.cjs (total size: 29.9 kB, chunk size: 29.9 kB, exports: stripe)
9
9
 
10
10
  [log] dist/client.cjs (total size: 160 B, chunk size: 160 B, exports: stripeClient)
11
11
 
12
- [log] dist/index.mjs (total size: 30.2 kB, chunk size: 30.2 kB, exports: stripe)
12
+ [log] dist/index.mjs (total size: 29.7 kB, chunk size: 29.7 kB, exports: stripe)
13
13
 
14
14
  [log] dist/client.mjs (total size: 133 B, chunk size: 133 B, exports: stripeClient)
15
15
 
16
- Σ Total dist size (byte size): 171 kB
16
+ Σ Total dist size (byte size): 170 kB
17
17
  [log]
package/dist/index.cjs CHANGED
@@ -314,7 +314,12 @@ const stripe = (options) => {
314
314
  {
315
315
  method: "POST",
316
316
  body: zod.z.object({
317
- plan: zod.z.string(),
317
+ plan: zod.z.string({
318
+ description: "The name of the plan to upgrade to"
319
+ }),
320
+ annual: zod.z.boolean({
321
+ description: "Whether to upgrade to an annual plan"
322
+ }).optional(),
318
323
  referenceId: zod.z.string().optional(),
319
324
  metadata: zod.z.record(zod.z.string(), zod.z.any()).optional(),
320
325
  seats: zod.z.number({
@@ -328,7 +333,6 @@ const stripe = (options) => {
328
333
  description: "callback url to redirect back after successful subscription"
329
334
  }).default("/"),
330
335
  returnUrl: zod.z.string().optional(),
331
- withoutTrial: zod.z.boolean().optional(),
332
336
  disableRedirect: zod.z.boolean().default(false)
333
337
  }),
334
338
  use: [
@@ -405,6 +409,11 @@ const stripe = (options) => {
405
409
  const existingSubscription = subscriptions.find(
406
410
  (sub) => sub.status === "active" || sub.status === "trialing"
407
411
  );
412
+ if (existingSubscription && existingSubscription.status === "active" && existingSubscription.plan === ctx.body.plan) {
413
+ throw new api.APIError("BAD_REQUEST", {
414
+ message: STRIPE_ERROR_CODES.ALREADY_SUBSCRIBED_PLAN
415
+ });
416
+ }
408
417
  if (activeSubscription && customerId) {
409
418
  const { url } = await client.billingPortal.sessions.create({
410
419
  customer: customerId,
@@ -417,35 +426,12 @@ const stripe = (options) => {
417
426
  {
418
427
  id: activeSubscription.items.data[0]?.id,
419
428
  quantity: 1,
420
- price: plan.priceId
429
+ price: ctx.body.annual ? plan.annualDiscountPriceId : plan.priceId
421
430
  }
422
431
  ]
423
432
  }
424
433
  }
425
434
  }).catch(async (e) => {
426
- if (e.message.includes("no changes")) {
427
- const plan2 = await getPlanByPriceId(
428
- options,
429
- activeSubscription.items.data[0]?.plan.id
430
- );
431
- await ctx.context.adapter.update({
432
- model: "subscription",
433
- update: {
434
- status: activeSubscription.status,
435
- seats: activeSubscription.items.data[0]?.quantity,
436
- plan: plan2?.name.toLowerCase()
437
- },
438
- where: [
439
- {
440
- field: "referenceId",
441
- value: referenceId
442
- }
443
- ]
444
- });
445
- throw new api.APIError("BAD_REQUEST", {
446
- message: STRIPE_ERROR_CODES.ALREADY_SUBSCRIBED_PLAN
447
- });
448
- }
449
435
  throw ctx.error("BAD_REQUEST", {
450
436
  message: e.message,
451
437
  code: e.code
@@ -456,11 +442,6 @@ const stripe = (options) => {
456
442
  redirect: true
457
443
  });
458
444
  }
459
- if (existingSubscription && existingSubscription.status === "active" && existingSubscription.plan === ctx.body.plan) {
460
- throw new api.APIError("BAD_REQUEST", {
461
- message: STRIPE_ERROR_CODES.ALREADY_SUBSCRIBED_PLAN
462
- });
463
- }
464
445
  let subscription = existingSubscription;
465
446
  if (!subscription) {
466
447
  const newSubscription = await ctx.context.adapter.create({
@@ -488,39 +469,42 @@ const stripe = (options) => {
488
469
  },
489
470
  ctx.request
490
471
  );
491
- const checkoutSession = await client.checkout.sessions.create({
492
- ...customerId ? {
493
- customer: customerId,
494
- customer_update: {
495
- name: "auto",
496
- address: "auto"
472
+ const checkoutSession = await client.checkout.sessions.create(
473
+ {
474
+ ...customerId ? {
475
+ customer: customerId,
476
+ customer_update: {
477
+ name: "auto",
478
+ address: "auto"
479
+ }
480
+ } : {
481
+ customer_email: session.user.email
482
+ },
483
+ success_url: getUrl(
484
+ ctx,
485
+ `${ctx.context.baseURL}/subscription/success?callbackURL=${encodeURIComponent(
486
+ ctx.body.successUrl
487
+ )}&reference=${encodeURIComponent(referenceId)}`
488
+ ),
489
+ cancel_url: getUrl(ctx, ctx.body.cancelUrl),
490
+ line_items: [
491
+ {
492
+ price: ctx.body.annual ? plan.annualDiscountPriceId : plan.priceId,
493
+ quantity: ctx.body.seats || 1
494
+ }
495
+ ],
496
+ mode: "subscription",
497
+ client_reference_id: referenceId,
498
+ ...params?.params,
499
+ metadata: {
500
+ userId: user.id,
501
+ subscriptionId: subscription.id,
502
+ referenceId,
503
+ ...params?.params?.metadata
497
504
  }
498
- } : {
499
- customer_email: session.user.email
500
505
  },
501
- success_url: getUrl(
502
- ctx,
503
- `${ctx.context.baseURL}/subscription/success?callbackURL=${encodeURIComponent(
504
- ctx.body.successUrl
505
- )}&reference=${encodeURIComponent(referenceId)}`
506
- ),
507
- cancel_url: getUrl(ctx, ctx.body.cancelUrl),
508
- line_items: [
509
- {
510
- price: plan.priceId,
511
- quantity: ctx.body.seats || 1
512
- }
513
- ],
514
- mode: "subscription",
515
- client_reference_id: referenceId,
516
- ...params,
517
- metadata: {
518
- userId: user.id,
519
- subscriptionId: subscription.id,
520
- referenceId,
521
- ...params?.params?.metadata
522
- }
523
- }).catch(async (e) => {
506
+ params?.options
507
+ ).catch(async (e) => {
524
508
  throw ctx.error("BAD_REQUEST", {
525
509
  message: e.message,
526
510
  code: e.code
package/dist/index.d.cts CHANGED
@@ -335,13 +335,13 @@ declare const stripe: <O extends StripeOptions>(options: O) => {
335
335
  body: {
336
336
  plan: string;
337
337
  metadata?: Record<string, any> | undefined;
338
+ annual?: boolean | undefined;
338
339
  referenceId?: string | undefined;
339
340
  seats?: number | undefined;
340
341
  uiMode?: "embedded" | "hosted" | undefined;
341
342
  successUrl?: string | undefined;
342
343
  cancelUrl?: string | undefined;
343
344
  returnUrl?: string | undefined;
344
- withoutTrial?: boolean | undefined;
345
345
  disableRedirect?: boolean | undefined;
346
346
  };
347
347
  method?: "POST" | undefined;
@@ -511,6 +511,7 @@ declare const stripe: <O extends StripeOptions>(options: O) => {
511
511
  method: "POST";
512
512
  body: z.ZodObject<{
513
513
  plan: z.ZodString;
514
+ annual: z.ZodOptional<z.ZodBoolean>;
514
515
  referenceId: z.ZodOptional<z.ZodString>;
515
516
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
516
517
  seats: z.ZodOptional<z.ZodNumber>;
@@ -518,7 +519,6 @@ declare const stripe: <O extends StripeOptions>(options: O) => {
518
519
  successUrl: z.ZodDefault<z.ZodString>;
519
520
  cancelUrl: z.ZodDefault<z.ZodString>;
520
521
  returnUrl: z.ZodOptional<z.ZodString>;
521
- withoutTrial: z.ZodOptional<z.ZodBoolean>;
522
522
  disableRedirect: z.ZodDefault<z.ZodBoolean>;
523
523
  }, "strip", z.ZodTypeAny, {
524
524
  plan: string;
@@ -527,20 +527,20 @@ declare const stripe: <O extends StripeOptions>(options: O) => {
527
527
  cancelUrl: string;
528
528
  disableRedirect: boolean;
529
529
  metadata?: Record<string, any> | undefined;
530
+ annual?: boolean | undefined;
530
531
  referenceId?: string | undefined;
531
532
  seats?: number | undefined;
532
533
  returnUrl?: string | undefined;
533
- withoutTrial?: boolean | undefined;
534
534
  }, {
535
535
  plan: string;
536
536
  metadata?: Record<string, any> | undefined;
537
+ annual?: boolean | undefined;
537
538
  referenceId?: string | undefined;
538
539
  seats?: number | undefined;
539
540
  uiMode?: "embedded" | "hosted" | undefined;
540
541
  successUrl?: string | undefined;
541
542
  cancelUrl?: string | undefined;
542
543
  returnUrl?: string | undefined;
543
- withoutTrial?: boolean | undefined;
544
544
  disableRedirect?: boolean | undefined;
545
545
  }>;
546
546
  use: (((inputContext: {
package/dist/index.d.mts CHANGED
@@ -335,13 +335,13 @@ declare const stripe: <O extends StripeOptions>(options: O) => {
335
335
  body: {
336
336
  plan: string;
337
337
  metadata?: Record<string, any> | undefined;
338
+ annual?: boolean | undefined;
338
339
  referenceId?: string | undefined;
339
340
  seats?: number | undefined;
340
341
  uiMode?: "embedded" | "hosted" | undefined;
341
342
  successUrl?: string | undefined;
342
343
  cancelUrl?: string | undefined;
343
344
  returnUrl?: string | undefined;
344
- withoutTrial?: boolean | undefined;
345
345
  disableRedirect?: boolean | undefined;
346
346
  };
347
347
  method?: "POST" | undefined;
@@ -511,6 +511,7 @@ declare const stripe: <O extends StripeOptions>(options: O) => {
511
511
  method: "POST";
512
512
  body: z.ZodObject<{
513
513
  plan: z.ZodString;
514
+ annual: z.ZodOptional<z.ZodBoolean>;
514
515
  referenceId: z.ZodOptional<z.ZodString>;
515
516
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
516
517
  seats: z.ZodOptional<z.ZodNumber>;
@@ -518,7 +519,6 @@ declare const stripe: <O extends StripeOptions>(options: O) => {
518
519
  successUrl: z.ZodDefault<z.ZodString>;
519
520
  cancelUrl: z.ZodDefault<z.ZodString>;
520
521
  returnUrl: z.ZodOptional<z.ZodString>;
521
- withoutTrial: z.ZodOptional<z.ZodBoolean>;
522
522
  disableRedirect: z.ZodDefault<z.ZodBoolean>;
523
523
  }, "strip", z.ZodTypeAny, {
524
524
  plan: string;
@@ -527,20 +527,20 @@ declare const stripe: <O extends StripeOptions>(options: O) => {
527
527
  cancelUrl: string;
528
528
  disableRedirect: boolean;
529
529
  metadata?: Record<string, any> | undefined;
530
+ annual?: boolean | undefined;
530
531
  referenceId?: string | undefined;
531
532
  seats?: number | undefined;
532
533
  returnUrl?: string | undefined;
533
- withoutTrial?: boolean | undefined;
534
534
  }, {
535
535
  plan: string;
536
536
  metadata?: Record<string, any> | undefined;
537
+ annual?: boolean | undefined;
537
538
  referenceId?: string | undefined;
538
539
  seats?: number | undefined;
539
540
  uiMode?: "embedded" | "hosted" | undefined;
540
541
  successUrl?: string | undefined;
541
542
  cancelUrl?: string | undefined;
542
543
  returnUrl?: string | undefined;
543
- withoutTrial?: boolean | undefined;
544
544
  disableRedirect?: boolean | undefined;
545
545
  }>;
546
546
  use: (((inputContext: {
package/dist/index.d.ts CHANGED
@@ -335,13 +335,13 @@ declare const stripe: <O extends StripeOptions>(options: O) => {
335
335
  body: {
336
336
  plan: string;
337
337
  metadata?: Record<string, any> | undefined;
338
+ annual?: boolean | undefined;
338
339
  referenceId?: string | undefined;
339
340
  seats?: number | undefined;
340
341
  uiMode?: "embedded" | "hosted" | undefined;
341
342
  successUrl?: string | undefined;
342
343
  cancelUrl?: string | undefined;
343
344
  returnUrl?: string | undefined;
344
- withoutTrial?: boolean | undefined;
345
345
  disableRedirect?: boolean | undefined;
346
346
  };
347
347
  method?: "POST" | undefined;
@@ -511,6 +511,7 @@ declare const stripe: <O extends StripeOptions>(options: O) => {
511
511
  method: "POST";
512
512
  body: z.ZodObject<{
513
513
  plan: z.ZodString;
514
+ annual: z.ZodOptional<z.ZodBoolean>;
514
515
  referenceId: z.ZodOptional<z.ZodString>;
515
516
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
516
517
  seats: z.ZodOptional<z.ZodNumber>;
@@ -518,7 +519,6 @@ declare const stripe: <O extends StripeOptions>(options: O) => {
518
519
  successUrl: z.ZodDefault<z.ZodString>;
519
520
  cancelUrl: z.ZodDefault<z.ZodString>;
520
521
  returnUrl: z.ZodOptional<z.ZodString>;
521
- withoutTrial: z.ZodOptional<z.ZodBoolean>;
522
522
  disableRedirect: z.ZodDefault<z.ZodBoolean>;
523
523
  }, "strip", z.ZodTypeAny, {
524
524
  plan: string;
@@ -527,20 +527,20 @@ declare const stripe: <O extends StripeOptions>(options: O) => {
527
527
  cancelUrl: string;
528
528
  disableRedirect: boolean;
529
529
  metadata?: Record<string, any> | undefined;
530
+ annual?: boolean | undefined;
530
531
  referenceId?: string | undefined;
531
532
  seats?: number | undefined;
532
533
  returnUrl?: string | undefined;
533
- withoutTrial?: boolean | undefined;
534
534
  }, {
535
535
  plan: string;
536
536
  metadata?: Record<string, any> | undefined;
537
+ annual?: boolean | undefined;
537
538
  referenceId?: string | undefined;
538
539
  seats?: number | undefined;
539
540
  uiMode?: "embedded" | "hosted" | undefined;
540
541
  successUrl?: string | undefined;
541
542
  cancelUrl?: string | undefined;
542
543
  returnUrl?: string | undefined;
543
- withoutTrial?: boolean | undefined;
544
544
  disableRedirect?: boolean | undefined;
545
545
  }>;
546
546
  use: (((inputContext: {
package/dist/index.mjs CHANGED
@@ -312,7 +312,12 @@ const stripe = (options) => {
312
312
  {
313
313
  method: "POST",
314
314
  body: z.object({
315
- plan: z.string(),
315
+ plan: z.string({
316
+ description: "The name of the plan to upgrade to"
317
+ }),
318
+ annual: z.boolean({
319
+ description: "Whether to upgrade to an annual plan"
320
+ }).optional(),
316
321
  referenceId: z.string().optional(),
317
322
  metadata: z.record(z.string(), z.any()).optional(),
318
323
  seats: z.number({
@@ -326,7 +331,6 @@ const stripe = (options) => {
326
331
  description: "callback url to redirect back after successful subscription"
327
332
  }).default("/"),
328
333
  returnUrl: z.string().optional(),
329
- withoutTrial: z.boolean().optional(),
330
334
  disableRedirect: z.boolean().default(false)
331
335
  }),
332
336
  use: [
@@ -403,6 +407,11 @@ const stripe = (options) => {
403
407
  const existingSubscription = subscriptions.find(
404
408
  (sub) => sub.status === "active" || sub.status === "trialing"
405
409
  );
410
+ if (existingSubscription && existingSubscription.status === "active" && existingSubscription.plan === ctx.body.plan) {
411
+ throw new APIError("BAD_REQUEST", {
412
+ message: STRIPE_ERROR_CODES.ALREADY_SUBSCRIBED_PLAN
413
+ });
414
+ }
406
415
  if (activeSubscription && customerId) {
407
416
  const { url } = await client.billingPortal.sessions.create({
408
417
  customer: customerId,
@@ -415,35 +424,12 @@ const stripe = (options) => {
415
424
  {
416
425
  id: activeSubscription.items.data[0]?.id,
417
426
  quantity: 1,
418
- price: plan.priceId
427
+ price: ctx.body.annual ? plan.annualDiscountPriceId : plan.priceId
419
428
  }
420
429
  ]
421
430
  }
422
431
  }
423
432
  }).catch(async (e) => {
424
- if (e.message.includes("no changes")) {
425
- const plan2 = await getPlanByPriceId(
426
- options,
427
- activeSubscription.items.data[0]?.plan.id
428
- );
429
- await ctx.context.adapter.update({
430
- model: "subscription",
431
- update: {
432
- status: activeSubscription.status,
433
- seats: activeSubscription.items.data[0]?.quantity,
434
- plan: plan2?.name.toLowerCase()
435
- },
436
- where: [
437
- {
438
- field: "referenceId",
439
- value: referenceId
440
- }
441
- ]
442
- });
443
- throw new APIError("BAD_REQUEST", {
444
- message: STRIPE_ERROR_CODES.ALREADY_SUBSCRIBED_PLAN
445
- });
446
- }
447
433
  throw ctx.error("BAD_REQUEST", {
448
434
  message: e.message,
449
435
  code: e.code
@@ -454,11 +440,6 @@ const stripe = (options) => {
454
440
  redirect: true
455
441
  });
456
442
  }
457
- if (existingSubscription && existingSubscription.status === "active" && existingSubscription.plan === ctx.body.plan) {
458
- throw new APIError("BAD_REQUEST", {
459
- message: STRIPE_ERROR_CODES.ALREADY_SUBSCRIBED_PLAN
460
- });
461
- }
462
443
  let subscription = existingSubscription;
463
444
  if (!subscription) {
464
445
  const newSubscription = await ctx.context.adapter.create({
@@ -486,39 +467,42 @@ const stripe = (options) => {
486
467
  },
487
468
  ctx.request
488
469
  );
489
- const checkoutSession = await client.checkout.sessions.create({
490
- ...customerId ? {
491
- customer: customerId,
492
- customer_update: {
493
- name: "auto",
494
- address: "auto"
470
+ const checkoutSession = await client.checkout.sessions.create(
471
+ {
472
+ ...customerId ? {
473
+ customer: customerId,
474
+ customer_update: {
475
+ name: "auto",
476
+ address: "auto"
477
+ }
478
+ } : {
479
+ customer_email: session.user.email
480
+ },
481
+ success_url: getUrl(
482
+ ctx,
483
+ `${ctx.context.baseURL}/subscription/success?callbackURL=${encodeURIComponent(
484
+ ctx.body.successUrl
485
+ )}&reference=${encodeURIComponent(referenceId)}`
486
+ ),
487
+ cancel_url: getUrl(ctx, ctx.body.cancelUrl),
488
+ line_items: [
489
+ {
490
+ price: ctx.body.annual ? plan.annualDiscountPriceId : plan.priceId,
491
+ quantity: ctx.body.seats || 1
492
+ }
493
+ ],
494
+ mode: "subscription",
495
+ client_reference_id: referenceId,
496
+ ...params?.params,
497
+ metadata: {
498
+ userId: user.id,
499
+ subscriptionId: subscription.id,
500
+ referenceId,
501
+ ...params?.params?.metadata
495
502
  }
496
- } : {
497
- customer_email: session.user.email
498
503
  },
499
- success_url: getUrl(
500
- ctx,
501
- `${ctx.context.baseURL}/subscription/success?callbackURL=${encodeURIComponent(
502
- ctx.body.successUrl
503
- )}&reference=${encodeURIComponent(referenceId)}`
504
- ),
505
- cancel_url: getUrl(ctx, ctx.body.cancelUrl),
506
- line_items: [
507
- {
508
- price: plan.priceId,
509
- quantity: ctx.body.seats || 1
510
- }
511
- ],
512
- mode: "subscription",
513
- client_reference_id: referenceId,
514
- ...params,
515
- metadata: {
516
- userId: user.id,
517
- subscriptionId: subscription.id,
518
- referenceId,
519
- ...params?.params?.metadata
520
- }
521
- }).catch(async (e) => {
504
+ params?.options
505
+ ).catch(async (e) => {
522
506
  throw ctx.error("BAD_REQUEST", {
523
507
  message: e.message,
524
508
  code: e.code
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@better-auth/stripe",
3
3
  "author": "Bereket Engida",
4
- "version": "1.2.2-beta.2",
4
+ "version": "1.2.2-beta.4",
5
5
  "main": "dist/index.cjs",
6
6
  "license": "MIT",
7
7
  "keywords": [
@@ -35,7 +35,7 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "zod": "^3.24.1",
38
- "better-auth": "^1.2.2-beta.2"
38
+ "better-auth": "^1.2.2-beta.4"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@types/better-sqlite3": "^7.6.12",
package/src/index.ts CHANGED
@@ -77,7 +77,14 @@ export const stripe = <O extends StripeOptions>(options: O) => {
77
77
  {
78
78
  method: "POST",
79
79
  body: z.object({
80
- plan: z.string(),
80
+ plan: z.string({
81
+ description: "The name of the plan to upgrade to",
82
+ }),
83
+ annual: z
84
+ .boolean({
85
+ description: "Whether to upgrade to an annual plan",
86
+ })
87
+ .optional(),
81
88
  referenceId: z.string().optional(),
82
89
  metadata: z.record(z.string(), z.any()).optional(),
83
90
  seats: z
@@ -99,7 +106,6 @@ export const stripe = <O extends StripeOptions>(options: O) => {
99
106
  })
100
107
  .default("/"),
101
108
  returnUrl: z.string().optional(),
102
- withoutTrial: z.boolean().optional(),
103
109
  disableRedirect: z.boolean().default(false),
104
110
  }),
105
111
  use: [
@@ -182,9 +188,21 @@ export const stripe = <O extends StripeOptions>(options: O) => {
182
188
  },
183
189
  ],
184
190
  });
191
+
185
192
  const existingSubscription = subscriptions.find(
186
193
  (sub) => sub.status === "active" || sub.status === "trialing",
187
194
  );
195
+
196
+ if (
197
+ existingSubscription &&
198
+ existingSubscription.status === "active" &&
199
+ existingSubscription.plan === ctx.body.plan
200
+ ) {
201
+ throw new APIError("BAD_REQUEST", {
202
+ message: STRIPE_ERROR_CODES.ALREADY_SUBSCRIBED_PLAN,
203
+ });
204
+ }
205
+
188
206
  if (activeSubscription && customerId) {
189
207
  const { url } = await client.billingPortal.sessions
190
208
  .create({
@@ -198,40 +216,15 @@ export const stripe = <O extends StripeOptions>(options: O) => {
198
216
  {
199
217
  id: activeSubscription.items.data[0]?.id as string,
200
218
  quantity: 1,
201
- price: plan.priceId,
219
+ price: ctx.body.annual
220
+ ? plan.annualDiscountPriceId
221
+ : plan.priceId,
202
222
  },
203
223
  ],
204
224
  },
205
225
  },
206
226
  })
207
227
  .catch(async (e) => {
208
- if (e.message.includes("no changes")) {
209
- /**
210
- * If the subscription is already active on stripe, we need to
211
- * update the status to the new status.
212
- */
213
- const plan = await getPlanByPriceId(
214
- options,
215
- activeSubscription.items.data[0]?.plan.id,
216
- );
217
- await ctx.context.adapter.update({
218
- model: "subscription",
219
- update: {
220
- status: activeSubscription.status,
221
- seats: activeSubscription.items.data[0]?.quantity,
222
- plan: plan?.name.toLowerCase(),
223
- },
224
- where: [
225
- {
226
- field: "referenceId",
227
- value: referenceId,
228
- },
229
- ],
230
- });
231
- throw new APIError("BAD_REQUEST", {
232
- message: STRIPE_ERROR_CODES.ALREADY_SUBSCRIBED_PLAN,
233
- });
234
- }
235
228
  throw ctx.error("BAD_REQUEST", {
236
229
  message: e.message,
237
230
  code: e.code,
@@ -243,15 +236,6 @@ export const stripe = <O extends StripeOptions>(options: O) => {
243
236
  });
244
237
  }
245
238
 
246
- if (
247
- existingSubscription &&
248
- existingSubscription.status === "active" &&
249
- existingSubscription.plan === ctx.body.plan
250
- ) {
251
- throw new APIError("BAD_REQUEST", {
252
- message: STRIPE_ERROR_CODES.ALREADY_SUBSCRIBED_PLAN,
253
- });
254
- }
255
239
  let subscription = existingSubscription;
256
240
  if (!subscription) {
257
241
  const newSubscription = await ctx.context.adapter.create<
@@ -286,43 +270,48 @@ export const stripe = <O extends StripeOptions>(options: O) => {
286
270
  );
287
271
 
288
272
  const checkoutSession = await client.checkout.sessions
289
- .create({
290
- ...(customerId
291
- ? {
292
- customer: customerId,
293
- customer_update: {
294
- name: "auto",
295
- address: "auto",
296
- },
297
- }
298
- : {
299
- customer_email: session.user.email,
300
- }),
301
- success_url: getUrl(
302
- ctx,
303
- `${
304
- ctx.context.baseURL
305
- }/subscription/success?callbackURL=${encodeURIComponent(
306
- ctx.body.successUrl,
307
- )}&reference=${encodeURIComponent(referenceId)}`,
308
- ),
309
- cancel_url: getUrl(ctx, ctx.body.cancelUrl),
310
- line_items: [
311
- {
312
- price: plan.priceId,
313
- quantity: ctx.body.seats || 1,
273
+ .create(
274
+ {
275
+ ...(customerId
276
+ ? {
277
+ customer: customerId,
278
+ customer_update: {
279
+ name: "auto",
280
+ address: "auto",
281
+ },
282
+ }
283
+ : {
284
+ customer_email: session.user.email,
285
+ }),
286
+ success_url: getUrl(
287
+ ctx,
288
+ `${
289
+ ctx.context.baseURL
290
+ }/subscription/success?callbackURL=${encodeURIComponent(
291
+ ctx.body.successUrl,
292
+ )}&reference=${encodeURIComponent(referenceId)}`,
293
+ ),
294
+ cancel_url: getUrl(ctx, ctx.body.cancelUrl),
295
+ line_items: [
296
+ {
297
+ price: ctx.body.annual
298
+ ? plan.annualDiscountPriceId
299
+ : plan.priceId,
300
+ quantity: ctx.body.seats || 1,
301
+ },
302
+ ],
303
+ mode: "subscription",
304
+ client_reference_id: referenceId,
305
+ ...params?.params,
306
+ metadata: {
307
+ userId: user.id,
308
+ subscriptionId: subscription.id,
309
+ referenceId,
310
+ ...params?.params?.metadata,
314
311
  },
315
- ],
316
- mode: "subscription",
317
- client_reference_id: referenceId,
318
- ...params,
319
- metadata: {
320
- userId: user.id,
321
- subscriptionId: subscription.id,
322
- referenceId,
323
- ...params?.params?.metadata,
324
312
  },
325
- })
313
+ params?.options,
314
+ )
326
315
  .catch(async (e) => {
327
316
  throw ctx.error("BAD_REQUEST", {
328
317
  message: e.message,