@better-auth/stripe 1.3.0-beta.8 → 1.3.0
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.
- package/.turbo/turbo-build.log +4 -4
- package/dist/client.d.cts +1 -1
- package/dist/client.d.mts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/index.cjs +184 -69
- package/dist/index.d.cts +75 -105
- package/dist/index.d.mts +75 -105
- package/dist/index.d.ts +75 -105
- package/dist/index.mjs +162 -61
- package/package.json +3 -3
- package/src/hooks.ts +11 -8
- package/src/index.ts +197 -53
- package/src/stripe.test.ts +27 -0
- package/src/types.ts +15 -10
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
|
|
2
|
-
> @better-auth/stripe@1.3.0
|
|
2
|
+
> @better-auth/stripe@1.3.0 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:
|
|
8
|
+
[log] dist/index.cjs (total size: 42.3 kB, chunk size: 42.3 kB, exports: stripe)
|
|
9
9
|
|
|
10
10
|
[log] dist/client.cjs (total size: 224 B, chunk size: 224 B, exports: stripeClient)
|
|
11
11
|
|
|
12
|
-
[log] dist/index.mjs (total size:
|
|
12
|
+
[log] dist/index.mjs (total size: 41.6 kB, chunk size: 41.6 kB, exports: stripe)
|
|
13
13
|
|
|
14
14
|
[log] dist/client.mjs (total size: 197 B, chunk size: 197 B, exports: stripeClient)
|
|
15
15
|
|
|
16
|
-
Σ Total dist size (byte size):
|
|
16
|
+
Σ Total dist size (byte size): 206 kB
|
|
17
17
|
[log]
|
package/dist/client.d.cts
CHANGED
package/dist/client.d.mts
CHANGED
package/dist/client.d.ts
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -2,11 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
const betterAuth = require('better-auth');
|
|
4
4
|
const plugins = require('better-auth/plugins');
|
|
5
|
-
const
|
|
5
|
+
const z = require('zod/v4');
|
|
6
6
|
const api = require('better-auth/api');
|
|
7
|
-
const crypto = require('better-auth/crypto');
|
|
8
7
|
const db = require('better-auth/db');
|
|
9
8
|
|
|
9
|
+
function _interopNamespaceCompat(e) {
|
|
10
|
+
if (e && typeof e === 'object' && 'default' in e) return e;
|
|
11
|
+
const n = Object.create(null);
|
|
12
|
+
if (e) {
|
|
13
|
+
for (const k in e) {
|
|
14
|
+
n[k] = e[k];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
n.default = e;
|
|
18
|
+
return n;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const z__namespace = /*#__PURE__*/_interopNamespaceCompat(z);
|
|
22
|
+
|
|
10
23
|
async function getPlans(options) {
|
|
11
24
|
return typeof options?.subscription?.plans === "function" ? await options.subscription?.plans() : options.subscription?.plans;
|
|
12
25
|
}
|
|
@@ -81,12 +94,15 @@ async function onCheckoutSessionCompleted(ctx, options, event) {
|
|
|
81
94
|
]
|
|
82
95
|
});
|
|
83
96
|
}
|
|
84
|
-
await options.subscription?.onSubscriptionComplete?.(
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
97
|
+
await options.subscription?.onSubscriptionComplete?.(
|
|
98
|
+
{
|
|
99
|
+
event,
|
|
100
|
+
subscription: dbSubscription,
|
|
101
|
+
stripeSubscription: subscription,
|
|
102
|
+
plan
|
|
103
|
+
},
|
|
104
|
+
ctx
|
|
105
|
+
);
|
|
90
106
|
return;
|
|
91
107
|
}
|
|
92
108
|
}
|
|
@@ -170,10 +186,10 @@ async function onSubscriptionUpdated(ctx, options, event) {
|
|
|
170
186
|
});
|
|
171
187
|
if (plan) {
|
|
172
188
|
if (subscriptionUpdated.status === "active" && subscription.status === "trialing" && plan.freeTrial?.onTrialEnd) {
|
|
173
|
-
await plan.freeTrial.onTrialEnd({ subscription }, ctx
|
|
189
|
+
await plan.freeTrial.onTrialEnd({ subscription }, ctx);
|
|
174
190
|
}
|
|
175
191
|
if (subscriptionUpdated.status === "incomplete_expired" && subscription.status === "trialing" && plan.freeTrial?.onTrialExpired) {
|
|
176
|
-
await plan.freeTrial.onTrialExpired(subscription, ctx
|
|
192
|
+
await plan.freeTrial.onTrialExpired(subscription, ctx);
|
|
177
193
|
}
|
|
178
194
|
}
|
|
179
195
|
} catch (error) {
|
|
@@ -331,12 +347,15 @@ const stripe = (options) => {
|
|
|
331
347
|
message: "Reference id is not allowed. Read server logs for more details."
|
|
332
348
|
});
|
|
333
349
|
}
|
|
334
|
-
const isAuthorized = ctx.body?.referenceId ? await options.subscription?.authorizeReference?.(
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
350
|
+
const isAuthorized = ctx.body?.referenceId ? await options.subscription?.authorizeReference?.(
|
|
351
|
+
{
|
|
352
|
+
user: session.user,
|
|
353
|
+
session: session.session,
|
|
354
|
+
referenceId,
|
|
355
|
+
action
|
|
356
|
+
},
|
|
357
|
+
ctx
|
|
358
|
+
) : true;
|
|
340
359
|
if (!isAuthorized) {
|
|
341
360
|
throw new api.APIError("UNAUTHORIZED", {
|
|
342
361
|
message: "Unauthorized"
|
|
@@ -344,70 +363,89 @@ const stripe = (options) => {
|
|
|
344
363
|
}
|
|
345
364
|
});
|
|
346
365
|
const subscriptionEndpoints = {
|
|
366
|
+
/**
|
|
367
|
+
* ### Endpoint
|
|
368
|
+
*
|
|
369
|
+
* POST `/subscription/upgrade`
|
|
370
|
+
*
|
|
371
|
+
* ### API Methods
|
|
372
|
+
*
|
|
373
|
+
* **server:**
|
|
374
|
+
* `auth.api.upgradeSubscription`
|
|
375
|
+
*
|
|
376
|
+
* **client:**
|
|
377
|
+
* `authClient.subscription.upgrade`
|
|
378
|
+
*
|
|
379
|
+
* @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/stripe#api-method-subscription-upgrade)
|
|
380
|
+
*/
|
|
347
381
|
upgradeSubscription: plugins.createAuthEndpoint(
|
|
348
382
|
"/subscription/upgrade",
|
|
349
383
|
{
|
|
350
384
|
method: "POST",
|
|
351
|
-
body:
|
|
385
|
+
body: z__namespace.object({
|
|
352
386
|
/**
|
|
353
387
|
* The name of the plan to subscribe
|
|
354
388
|
*/
|
|
355
|
-
plan:
|
|
356
|
-
description:
|
|
389
|
+
plan: z__namespace.string().meta({
|
|
390
|
+
description: 'The name of the plan to upgrade to. Eg: "pro"'
|
|
357
391
|
}),
|
|
358
392
|
/**
|
|
359
393
|
* If annual plan should be applied.
|
|
360
394
|
*/
|
|
361
|
-
annual:
|
|
362
|
-
description: "Whether to upgrade to an annual plan"
|
|
395
|
+
annual: z__namespace.boolean().meta({
|
|
396
|
+
description: "Whether to upgrade to an annual plan. Eg: true"
|
|
363
397
|
}).optional(),
|
|
364
398
|
/**
|
|
365
399
|
* Reference id of the subscription to upgrade
|
|
366
400
|
* This is used to identify the subscription to upgrade
|
|
367
401
|
* If not provided, the user's id will be used
|
|
368
402
|
*/
|
|
369
|
-
referenceId:
|
|
370
|
-
description:
|
|
403
|
+
referenceId: z__namespace.string().meta({
|
|
404
|
+
description: 'Reference id of the subscription to upgrade. Eg: "123"'
|
|
371
405
|
}).optional(),
|
|
372
406
|
/**
|
|
373
407
|
* This is to allow a specific subscription to be upgrade.
|
|
374
408
|
* If subscription id is provided, and subscription isn't found,
|
|
375
409
|
* it'll throw an error.
|
|
376
410
|
*/
|
|
377
|
-
subscriptionId:
|
|
378
|
-
description:
|
|
411
|
+
subscriptionId: z__namespace.string().meta({
|
|
412
|
+
description: 'The id of the subscription to upgrade. Eg: "sub_123"'
|
|
379
413
|
}).optional(),
|
|
380
414
|
/**
|
|
381
415
|
* Any additional data you want to store in your database
|
|
382
416
|
* subscriptions
|
|
383
417
|
*/
|
|
384
|
-
metadata:
|
|
418
|
+
metadata: z__namespace.record(z__namespace.string(), z__namespace.any()).optional(),
|
|
385
419
|
/**
|
|
386
420
|
* If a subscription
|
|
387
421
|
*/
|
|
388
|
-
seats:
|
|
389
|
-
description: "Number of seats to upgrade to (if applicable)"
|
|
422
|
+
seats: z__namespace.number().meta({
|
|
423
|
+
description: "Number of seats to upgrade to (if applicable). Eg: 1"
|
|
390
424
|
}).optional(),
|
|
391
425
|
/**
|
|
392
426
|
* Success URL to redirect back after successful subscription
|
|
393
427
|
*/
|
|
394
|
-
successUrl:
|
|
395
|
-
description:
|
|
428
|
+
successUrl: z__namespace.string().meta({
|
|
429
|
+
description: 'Callback URL to redirect back after successful subscription. Eg: "https://example.com/success"'
|
|
396
430
|
}).default("/"),
|
|
397
431
|
/**
|
|
398
432
|
* Cancel URL
|
|
399
433
|
*/
|
|
400
|
-
cancelUrl:
|
|
401
|
-
description:
|
|
434
|
+
cancelUrl: z__namespace.string().meta({
|
|
435
|
+
description: 'Callback URL to redirect back after successful subscription. Eg: "https://example.com/success"'
|
|
402
436
|
}).default("/"),
|
|
403
437
|
/**
|
|
404
438
|
* Return URL
|
|
405
439
|
*/
|
|
406
|
-
returnUrl:
|
|
440
|
+
returnUrl: z__namespace.string().meta({
|
|
441
|
+
description: 'Return URL to redirect back after successful subscription. Eg: "https://example.com/success"'
|
|
442
|
+
}).optional(),
|
|
407
443
|
/**
|
|
408
444
|
* Disable Redirect
|
|
409
445
|
*/
|
|
410
|
-
disableRedirect:
|
|
446
|
+
disableRedirect: z__namespace.boolean().meta({
|
|
447
|
+
description: "Disable redirect after successful subscription. Eg: true"
|
|
448
|
+
}).default(false)
|
|
411
449
|
}),
|
|
412
450
|
use: [
|
|
413
451
|
api.sessionMiddleware,
|
|
@@ -454,19 +492,21 @@ const stripe = (options) => {
|
|
|
454
492
|
let customerId = subscriptionToUpdate?.stripeCustomerId || user.stripeCustomerId;
|
|
455
493
|
if (!customerId) {
|
|
456
494
|
try {
|
|
457
|
-
const
|
|
458
|
-
|
|
495
|
+
const existingCustomers = await client.customers.list({
|
|
496
|
+
email: user.email,
|
|
497
|
+
limit: 1
|
|
498
|
+
});
|
|
499
|
+
let stripeCustomer = existingCustomers.data[0];
|
|
500
|
+
if (!stripeCustomer) {
|
|
501
|
+
stripeCustomer = await client.customers.create({
|
|
459
502
|
email: user.email,
|
|
460
503
|
name: user.name,
|
|
461
504
|
metadata: {
|
|
462
505
|
...ctx.body.metadata,
|
|
463
506
|
userId: user.id
|
|
464
507
|
}
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
idempotencyKey: crypto.generateRandomString(32, "a-z", "0-9")
|
|
468
|
-
}
|
|
469
|
-
);
|
|
508
|
+
});
|
|
509
|
+
}
|
|
470
510
|
await ctx.context.adapter.update({
|
|
471
511
|
model: "user",
|
|
472
512
|
update: {
|
|
@@ -542,17 +582,45 @@ const stripe = (options) => {
|
|
|
542
582
|
}
|
|
543
583
|
let subscription = existingSubscription;
|
|
544
584
|
if (!subscription) {
|
|
545
|
-
const
|
|
546
|
-
|
|
547
|
-
|
|
585
|
+
const incompleteSubscription = subscriptions.find(
|
|
586
|
+
(sub) => sub.status === "incomplete"
|
|
587
|
+
);
|
|
588
|
+
if (incompleteSubscription) {
|
|
589
|
+
await ctx.context.adapter.update({
|
|
590
|
+
model: "subscription",
|
|
591
|
+
update: {
|
|
592
|
+
...incompleteSubscription,
|
|
593
|
+
plan: plan.name.toLowerCase(),
|
|
594
|
+
seats: ctx.body.seats || 1,
|
|
595
|
+
stripeCustomerId: customerId,
|
|
596
|
+
status: "active"
|
|
597
|
+
},
|
|
598
|
+
where: [
|
|
599
|
+
{
|
|
600
|
+
field: "id",
|
|
601
|
+
value: incompleteSubscription.id
|
|
602
|
+
}
|
|
603
|
+
]
|
|
604
|
+
});
|
|
605
|
+
subscription = {
|
|
606
|
+
...incompleteSubscription,
|
|
548
607
|
plan: plan.name.toLowerCase(),
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
608
|
+
seats: ctx.body.seats || 1,
|
|
609
|
+
stripeCustomerId: customerId
|
|
610
|
+
};
|
|
611
|
+
} else {
|
|
612
|
+
const newSubscription = await ctx.context.adapter.create({
|
|
613
|
+
model: "subscription",
|
|
614
|
+
data: {
|
|
615
|
+
plan: plan.name.toLowerCase(),
|
|
616
|
+
stripeCustomerId: customerId,
|
|
617
|
+
status: "incomplete",
|
|
618
|
+
referenceId,
|
|
619
|
+
seats: ctx.body.seats || 1
|
|
620
|
+
}
|
|
621
|
+
});
|
|
622
|
+
subscription = newSubscription;
|
|
623
|
+
}
|
|
556
624
|
}
|
|
557
625
|
if (!subscription) {
|
|
558
626
|
ctx.context.logger.error("Subscription ID not found");
|
|
@@ -565,7 +633,9 @@ const stripe = (options) => {
|
|
|
565
633
|
plan,
|
|
566
634
|
subscription
|
|
567
635
|
},
|
|
568
|
-
ctx.request
|
|
636
|
+
ctx.request,
|
|
637
|
+
//@ts-expect-error
|
|
638
|
+
ctx
|
|
569
639
|
);
|
|
570
640
|
const freeTrail = plan.freeTrial ? {
|
|
571
641
|
trial_period_days: plan.freeTrial.days
|
|
@@ -642,7 +712,7 @@ const stripe = (options) => {
|
|
|
642
712
|
"/subscription/cancel/callback",
|
|
643
713
|
{
|
|
644
714
|
method: "GET",
|
|
645
|
-
query:
|
|
715
|
+
query: z__namespace.record(z__namespace.string(), z__namespace.any()).optional(),
|
|
646
716
|
use: [api.originCheck((ctx) => ctx.query.callbackURL)]
|
|
647
717
|
},
|
|
648
718
|
async (ctx) => {
|
|
@@ -709,14 +779,35 @@ const stripe = (options) => {
|
|
|
709
779
|
throw ctx.redirect(getUrl(ctx, callbackURL));
|
|
710
780
|
}
|
|
711
781
|
),
|
|
782
|
+
/**
|
|
783
|
+
* ### Endpoint
|
|
784
|
+
*
|
|
785
|
+
* POST `/subscription/cancel`
|
|
786
|
+
*
|
|
787
|
+
* ### API Methods
|
|
788
|
+
*
|
|
789
|
+
* **server:**
|
|
790
|
+
* `auth.api.cancelSubscription`
|
|
791
|
+
*
|
|
792
|
+
* **client:**
|
|
793
|
+
* `authClient.subscription.cancel`
|
|
794
|
+
*
|
|
795
|
+
* @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/stripe#api-method-subscription-cancel)
|
|
796
|
+
*/
|
|
712
797
|
cancelSubscription: plugins.createAuthEndpoint(
|
|
713
798
|
"/subscription/cancel",
|
|
714
799
|
{
|
|
715
800
|
method: "POST",
|
|
716
|
-
body:
|
|
717
|
-
referenceId:
|
|
718
|
-
|
|
719
|
-
|
|
801
|
+
body: z__namespace.object({
|
|
802
|
+
referenceId: z__namespace.string().meta({
|
|
803
|
+
description: "Reference id of the subscription to cancel. Eg: '123'"
|
|
804
|
+
}).optional(),
|
|
805
|
+
subscriptionId: z__namespace.string().meta({
|
|
806
|
+
description: "The id of the subscription to cancel. Eg: 'sub_123'"
|
|
807
|
+
}).optional(),
|
|
808
|
+
returnUrl: z__namespace.string().meta({
|
|
809
|
+
description: "Return URL to redirect back after successful subscription. Eg: 'https://example.com/success'"
|
|
810
|
+
})
|
|
720
811
|
}),
|
|
721
812
|
use: [
|
|
722
813
|
api.sessionMiddleware,
|
|
@@ -822,9 +913,13 @@ const stripe = (options) => {
|
|
|
822
913
|
"/subscription/restore",
|
|
823
914
|
{
|
|
824
915
|
method: "POST",
|
|
825
|
-
body:
|
|
826
|
-
referenceId:
|
|
827
|
-
|
|
916
|
+
body: z__namespace.object({
|
|
917
|
+
referenceId: z__namespace.string().meta({
|
|
918
|
+
description: "Reference id of the subscription to restore. Eg: '123'"
|
|
919
|
+
}).optional(),
|
|
920
|
+
subscriptionId: z__namespace.string().meta({
|
|
921
|
+
description: "The id of the subscription to restore. Eg: 'sub_123'"
|
|
922
|
+
}).optional()
|
|
828
923
|
}),
|
|
829
924
|
use: [api.sessionMiddleware, referenceMiddleware("restore-subscription")]
|
|
830
925
|
},
|
|
@@ -907,13 +1002,30 @@ const stripe = (options) => {
|
|
|
907
1002
|
}
|
|
908
1003
|
}
|
|
909
1004
|
),
|
|
1005
|
+
/**
|
|
1006
|
+
* ### Endpoint
|
|
1007
|
+
*
|
|
1008
|
+
* GET `/subscription/list`
|
|
1009
|
+
*
|
|
1010
|
+
* ### API Methods
|
|
1011
|
+
*
|
|
1012
|
+
* **server:**
|
|
1013
|
+
* `auth.api.listActiveSubscriptions`
|
|
1014
|
+
*
|
|
1015
|
+
* **client:**
|
|
1016
|
+
* `authClient.subscription.list`
|
|
1017
|
+
*
|
|
1018
|
+
* @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/stripe#api-method-subscription-list)
|
|
1019
|
+
*/
|
|
910
1020
|
listActiveSubscriptions: plugins.createAuthEndpoint(
|
|
911
1021
|
"/subscription/list",
|
|
912
1022
|
{
|
|
913
1023
|
method: "GET",
|
|
914
|
-
query:
|
|
915
|
-
|
|
916
|
-
referenceId:
|
|
1024
|
+
query: z__namespace.optional(
|
|
1025
|
+
z__namespace.object({
|
|
1026
|
+
referenceId: z__namespace.string().meta({
|
|
1027
|
+
description: "Reference id of the subscription to list. Eg: '123'"
|
|
1028
|
+
}).optional()
|
|
917
1029
|
})
|
|
918
1030
|
),
|
|
919
1031
|
use: [api.sessionMiddleware, referenceMiddleware("list-subscription")]
|
|
@@ -954,7 +1066,7 @@ const stripe = (options) => {
|
|
|
954
1066
|
"/subscription/success",
|
|
955
1067
|
{
|
|
956
1068
|
method: "GET",
|
|
957
|
-
query:
|
|
1069
|
+
query: z__namespace.record(z__namespace.string(), z__namespace.any()).optional(),
|
|
958
1070
|
use: [api.originCheck((ctx) => ctx.query.callbackURL)]
|
|
959
1071
|
},
|
|
960
1072
|
async (ctx) => {
|
|
@@ -1136,11 +1248,14 @@ const stripe = (options) => {
|
|
|
1136
1248
|
if (!customer) {
|
|
1137
1249
|
betterAuth.logger.error("#BETTER_AUTH: Failed to create customer");
|
|
1138
1250
|
} else {
|
|
1139
|
-
await options.onCustomerCreate?.(
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1251
|
+
await options.onCustomerCreate?.(
|
|
1252
|
+
{
|
|
1253
|
+
customer,
|
|
1254
|
+
stripeCustomer,
|
|
1255
|
+
user
|
|
1256
|
+
},
|
|
1257
|
+
ctx2
|
|
1258
|
+
);
|
|
1144
1259
|
}
|
|
1145
1260
|
}
|
|
1146
1261
|
}
|