@better-auth/stripe 1.2.6-beta.7 → 1.2.7

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.6-beta.7 build /home/runner/work/better-auth/better-auth/packages/stripe
2
+ > @better-auth/stripe@1.2.7 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: 36.5 kB, chunk size: 36.5 kB, exports: stripe)
8
+ [log] dist/index.cjs (total size: 37 kB, chunk size: 37 kB, exports: stripe)
9
9
 
10
- [log] dist/client.cjs (total size: 160 B, chunk size: 160 B, exports: stripeClient)
10
+ [log] dist/client.cjs (total size: 224 B, chunk size: 224 B, exports: stripeClient)
11
11
 
12
- [log] dist/index.mjs (total size: 36.2 kB, chunk size: 36.2 kB, exports: stripe)
12
+ [log] dist/index.mjs (total size: 36.7 kB, chunk size: 36.7 kB, exports: stripe)
13
13
 
14
- [log] dist/client.mjs (total size: 133 B, chunk size: 133 B, exports: stripeClient)
14
+ [log] dist/client.mjs (total size: 197 B, chunk size: 197 B, exports: stripeClient)
15
15
 
16
- Σ Total dist size (byte size): 198 kB
16
+ Σ Total dist size (byte size): 200 kB
17
17
  [log]
package/dist/client.cjs CHANGED
@@ -3,7 +3,10 @@
3
3
  const stripeClient = (options) => {
4
4
  return {
5
5
  id: "stripe-client",
6
- $InferServerPlugin: {}
6
+ $InferServerPlugin: {},
7
+ pathMethods: {
8
+ "/subscription/restore": "POST"
9
+ }
7
10
  };
8
11
  };
9
12
 
package/dist/client.d.cts CHANGED
@@ -20,6 +20,9 @@ declare const stripeClient: <O extends {
20
20
  stripeClient: any;
21
21
  stripeWebhookSecret: string;
22
22
  }>>;
23
+ pathMethods: {
24
+ "/subscription/restore": "POST";
25
+ };
23
26
  };
24
27
 
25
28
  export { stripeClient };
package/dist/client.d.mts CHANGED
@@ -20,6 +20,9 @@ declare const stripeClient: <O extends {
20
20
  stripeClient: any;
21
21
  stripeWebhookSecret: string;
22
22
  }>>;
23
+ pathMethods: {
24
+ "/subscription/restore": "POST";
25
+ };
23
26
  };
24
27
 
25
28
  export { stripeClient };
package/dist/client.d.ts CHANGED
@@ -20,6 +20,9 @@ declare const stripeClient: <O extends {
20
20
  stripeClient: any;
21
21
  stripeWebhookSecret: string;
22
22
  }>>;
23
+ pathMethods: {
24
+ "/subscription/restore": "POST";
25
+ };
23
26
  };
24
27
 
25
28
  export { stripeClient };
package/dist/client.mjs CHANGED
@@ -1,7 +1,10 @@
1
1
  const stripeClient = (options) => {
2
2
  return {
3
3
  id: "stripe-client",
4
- $InferServerPlugin: {}
4
+ $InferServerPlugin: {},
5
+ pathMethods: {
6
+ "/subscription/restore": "POST"
7
+ }
5
8
  };
6
9
  };
7
10
 
package/dist/index.cjs CHANGED
@@ -36,7 +36,7 @@ async function onCheckoutSessionCompleted(ctx, options, event) {
36
36
  const priceId = subscription.items.data[0]?.price.id;
37
37
  const plan = await getPlanByPriceId(options, priceId);
38
38
  if (plan) {
39
- const referenceId = checkoutSession?.metadata?.referenceId;
39
+ const referenceId = checkoutSession?.client_reference_id || checkoutSession?.metadata?.referenceId;
40
40
  const subscriptionId = checkoutSession?.metadata?.subscriptionId;
41
41
  const seats = subscription.items.data[0].quantity;
42
42
  if (referenceId && subscriptionId) {
@@ -306,6 +306,14 @@ const stripe = (options) => {
306
306
  throw new api.APIError("UNAUTHORIZED");
307
307
  }
308
308
  const referenceId = ctx.body?.referenceId || ctx.query?.referenceId || session.user.id;
309
+ if (ctx.body?.referenceId && !options.subscription?.authorizeReference) {
310
+ betterAuth.logger.error(
311
+ `Passing referenceId into a subscription action isn't allowed if subscription.authorizeReference isn't defined in your stripe plugin config.`
312
+ );
313
+ throw new api.APIError("BAD_REQUEST", {
314
+ message: "Reference id is not allowed. Read server logs for more details."
315
+ });
316
+ }
309
317
  const isAuthorized = ctx.body?.referenceId ? await options.subscription?.authorizeReference?.({
310
318
  user: session.user,
311
319
  session: session.session,
@@ -809,9 +817,12 @@ const stripe = (options) => {
809
817
  });
810
818
  }
811
819
  const activeSubscription = await client.subscriptions.list({
812
- customer: subscription.stripeCustomerId,
813
- status: "active"
814
- }).then((res) => res.data[0]);
820
+ customer: subscription.stripeCustomerId
821
+ }).then(
822
+ (res) => res.data.filter(
823
+ (sub) => sub.status === "active" || sub.status === "trialing"
824
+ )[0]
825
+ );
815
826
  if (!activeSubscription) {
816
827
  throw ctx.error("BAD_REQUEST", {
817
828
  message: STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND
package/dist/index.mjs CHANGED
@@ -34,7 +34,7 @@ async function onCheckoutSessionCompleted(ctx, options, event) {
34
34
  const priceId = subscription.items.data[0]?.price.id;
35
35
  const plan = await getPlanByPriceId(options, priceId);
36
36
  if (plan) {
37
- const referenceId = checkoutSession?.metadata?.referenceId;
37
+ const referenceId = checkoutSession?.client_reference_id || checkoutSession?.metadata?.referenceId;
38
38
  const subscriptionId = checkoutSession?.metadata?.subscriptionId;
39
39
  const seats = subscription.items.data[0].quantity;
40
40
  if (referenceId && subscriptionId) {
@@ -304,6 +304,14 @@ const stripe = (options) => {
304
304
  throw new APIError("UNAUTHORIZED");
305
305
  }
306
306
  const referenceId = ctx.body?.referenceId || ctx.query?.referenceId || session.user.id;
307
+ if (ctx.body?.referenceId && !options.subscription?.authorizeReference) {
308
+ logger.error(
309
+ `Passing referenceId into a subscription action isn't allowed if subscription.authorizeReference isn't defined in your stripe plugin config.`
310
+ );
311
+ throw new APIError("BAD_REQUEST", {
312
+ message: "Reference id is not allowed. Read server logs for more details."
313
+ });
314
+ }
307
315
  const isAuthorized = ctx.body?.referenceId ? await options.subscription?.authorizeReference?.({
308
316
  user: session.user,
309
317
  session: session.session,
@@ -807,9 +815,12 @@ const stripe = (options) => {
807
815
  });
808
816
  }
809
817
  const activeSubscription = await client.subscriptions.list({
810
- customer: subscription.stripeCustomerId,
811
- status: "active"
812
- }).then((res) => res.data[0]);
818
+ customer: subscription.stripeCustomerId
819
+ }).then(
820
+ (res) => res.data.filter(
821
+ (sub) => sub.status === "active" || sub.status === "trialing"
822
+ )[0]
823
+ );
813
824
  if (!activeSubscription) {
814
825
  throw ctx.error("BAD_REQUEST", {
815
826
  message: STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND
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.6-beta.7",
4
+ "version": "1.2.7",
5
5
  "main": "dist/index.cjs",
6
6
  "license": "MIT",
7
7
  "keywords": [
@@ -35,14 +35,14 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "zod": "^3.24.1",
38
- "better-auth": "^1.2.6-beta.7"
38
+ "better-auth": "^1.2.7"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@types/better-sqlite3": "^7.6.12",
42
42
  "better-sqlite3": "^11.6.0",
43
43
  "vitest": "^1.6.0",
44
44
  "stripe": "^17.7.0",
45
- "better-call": "^1.0.7"
45
+ "better-call": "^1.0.8"
46
46
  },
47
47
  "scripts": {
48
48
  "test": "vitest",
package/src/client.ts CHANGED
@@ -27,5 +27,8 @@ export const stripeClient = <
27
27
  }
28
28
  >
29
29
  >,
30
+ pathMethods: {
31
+ "/subscription/restore": "POST",
32
+ },
30
33
  } satisfies BetterAuthClientPlugin;
31
34
  };
package/src/hooks.ts CHANGED
@@ -20,7 +20,9 @@ export async function onCheckoutSessionCompleted(
20
20
  const priceId = subscription.items.data[0]?.price.id;
21
21
  const plan = await getPlanByPriceId(options, priceId as string);
22
22
  if (plan) {
23
- const referenceId = checkoutSession?.metadata?.referenceId;
23
+ const referenceId =
24
+ checkoutSession?.client_reference_id ||
25
+ checkoutSession?.metadata?.referenceId;
24
26
  const subscriptionId = checkoutSession?.metadata?.subscriptionId;
25
27
  const seats = subscription.items.data[0].quantity;
26
28
  if (referenceId && subscriptionId) {
package/src/index.ts CHANGED
@@ -66,6 +66,16 @@ export const stripe = <O extends StripeOptions>(options: O) => {
66
66
  }
67
67
  const referenceId =
68
68
  ctx.body?.referenceId || ctx.query?.referenceId || session.user.id;
69
+
70
+ if (ctx.body?.referenceId && !options.subscription?.authorizeReference) {
71
+ logger.error(
72
+ `Passing referenceId into a subscription action isn't allowed if subscription.authorizeReference isn't defined in your stripe plugin config.`,
73
+ );
74
+ throw new APIError("BAD_REQUEST", {
75
+ message:
76
+ "Reference id is not allowed. Read server logs for more details.",
77
+ });
78
+ }
69
79
  const isAuthorized = ctx.body?.referenceId
70
80
  ? await options.subscription?.authorizeReference?.({
71
81
  user: session.user,
@@ -671,9 +681,13 @@ export const stripe = <O extends StripeOptions>(options: O) => {
671
681
  const activeSubscription = await client.subscriptions
672
682
  .list({
673
683
  customer: subscription.stripeCustomerId,
674
- status: "active",
675
684
  })
676
- .then((res) => res.data[0]);
685
+ .then(
686
+ (res) =>
687
+ res.data.filter(
688
+ (sub) => sub.status === "active" || sub.status === "trialing",
689
+ )[0],
690
+ );
677
691
  if (!activeSubscription) {
678
692
  throw ctx.error("BAD_REQUEST", {
679
693
  message: STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND,
@@ -244,19 +244,15 @@ describe("stripe", async () => {
244
244
  });
245
245
 
246
246
  it("should handle subscription webhook events", async () => {
247
- const testSubscriptionId = "sub_123456";
248
- const testReferenceId = "user_123";
249
- await ctx.adapter.create({
247
+ const { id: testReferenceId } = await ctx.adapter.create({
250
248
  model: "user",
251
249
  data: {
252
- id: testReferenceId,
253
250
  email: "test@email.com",
254
251
  },
255
252
  });
256
- await ctx.adapter.create({
253
+ const { id: testSubscriptionId } = await ctx.adapter.create({
257
254
  model: "subscription",
258
255
  data: {
259
- id: testSubscriptionId,
260
256
  referenceId: testReferenceId,
261
257
  stripeCustomerId: "cus_mock123",
262
258
  status: "active",
@@ -354,22 +350,19 @@ describe("stripe", async () => {
354
350
  });
355
351
  });
356
352
 
353
+ const { id: userId } = await ctx.adapter.create({
354
+ model: "user",
355
+ data: {
356
+ email: "delete-test@email.com",
357
+ },
358
+ });
359
+
357
360
  it("should handle subscription deletion webhook", async () => {
358
- const userId = "test_user";
359
361
  const subId = "test_sub_delete";
360
362
 
361
- await ctx.adapter.create({
362
- model: "user",
363
- data: {
364
- id: userId,
365
- email: "delete-test@email.com",
366
- },
367
- });
368
-
369
363
  await ctx.adapter.create({
370
364
  model: "subscription",
371
365
  data: {
372
- id: subId,
373
366
  referenceId: userId,
374
367
  stripeCustomerId: "cus_delete_test",
375
368
  status: "active",
@@ -502,7 +495,6 @@ describe("stripe", async () => {
502
495
  };
503
496
 
504
497
  const mockSubscription = {
505
- id: "sub_123",
506
498
  status: "active",
507
499
  items: {
508
500
  data: [{ price: { id: process.env.STRIPE_PRICE_ID_1 } }],
@@ -533,11 +525,10 @@ describe("stripe", async () => {
533
525
  plugins: [stripe(eventTestOptions)],
534
526
  });
535
527
 
536
- await ctx.adapter.create({
528
+ const { id: testSubscriptionId } = await ctx.adapter.create({
537
529
  model: "subscription",
538
530
  data: {
539
- id: "sub_123",
540
- referenceId: "user_123",
531
+ referenceId: userId,
541
532
  stripeCustomerId: "cus_123",
542
533
  stripeSubscriptionId: "sub_123",
543
534
  status: "incomplete",
@@ -571,7 +562,7 @@ describe("stripe", async () => {
571
562
  type: "customer.subscription.updated",
572
563
  data: {
573
564
  object: {
574
- id: "sub_123",
565
+ id: testSubscriptionId,
575
566
  customer: "cus_123",
576
567
  status: "active",
577
568
  items: {
@@ -609,7 +600,7 @@ describe("stripe", async () => {
609
600
  type: "customer.subscription.updated",
610
601
  data: {
611
602
  object: {
612
- id: "sub_123",
603
+ id: testSubscriptionId,
613
604
  customer: "cus_123",
614
605
  status: "active",
615
606
  cancel_at_period_end: true,
@@ -645,7 +636,7 @@ describe("stripe", async () => {
645
636
  type: "customer.subscription.updated",
646
637
  data: {
647
638
  object: {
648
- id: "sub_123",
639
+ id: testSubscriptionId,
649
640
  customer: "cus_123",
650
641
  status: "active",
651
642
  cancel_at_period_end: true,
@@ -680,12 +671,12 @@ describe("stripe", async () => {
680
671
  type: "customer.subscription.deleted",
681
672
  data: {
682
673
  object: {
683
- id: "sub_123",
674
+ id: testSubscriptionId,
684
675
  customer: "cus_123",
685
676
  status: "canceled",
686
677
  metadata: {
687
- referenceId: "user_123",
688
- subscriptionId: "sub_123",
678
+ referenceId: userId,
679
+ subscriptionId: testSubscriptionId,
689
680
  },
690
681
  },
691
682
  },