@better-auth/stripe 1.7.19 → 1.7.21
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/dist/client.mjs
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { n as STRIPE_ERROR_CODES, t as PACKAGE_VERSION } from "./version-
|
|
2
|
-
import { APIError
|
|
1
|
+
import { n as STRIPE_ERROR_CODES, t as PACKAGE_VERSION } from "./version-B3YqQsFC.mjs";
|
|
2
|
+
import { APIError } from "@better-auth/core/error";
|
|
3
3
|
import { defu } from "defu";
|
|
4
|
-
import { createAuthEndpoint, createAuthMiddleware } from "@better-auth/core/api";
|
|
5
|
-
import { APIError as APIError$1 } from "@better-auth/core/error";
|
|
4
|
+
import { HIDE_METADATA, createAuthEndpoint, createAuthMiddleware } from "@better-auth/core/api";
|
|
6
5
|
import { getSessionFromCtx, originCheck, sessionMiddleware } from "better-auth/api";
|
|
7
6
|
import * as z from "zod";
|
|
8
7
|
import { mergeSchema } from "better-auth/db";
|
|
@@ -497,23 +496,23 @@ const stripeSessionMiddleware = createAuthMiddleware({ use: [sessionMiddleware]
|
|
|
497
496
|
const referenceMiddleware = (options, action) => createAuthMiddleware(async (ctx) => {
|
|
498
497
|
const subscriptionOptions = options.subscription;
|
|
499
498
|
const ctxSession = ctx.context.session;
|
|
500
|
-
if (!ctxSession) throw APIError
|
|
499
|
+
if (!ctxSession) throw APIError.from("UNAUTHORIZED", STRIPE_ERROR_CODES.UNAUTHORIZED);
|
|
501
500
|
const customerType = ctx.body?.customerType || ctx.query?.customerType;
|
|
502
501
|
const explicitReferenceId = ctx.body?.referenceId || ctx.query?.referenceId;
|
|
503
502
|
if (customerType === "organization") {
|
|
504
|
-
if (!options.organization?.enabled) throw APIError
|
|
503
|
+
if (!options.organization?.enabled) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.ORGANIZATION_SUBSCRIPTION_NOT_ENABLED);
|
|
505
504
|
if (!subscriptionOptions.authorizeReference) {
|
|
506
505
|
ctx.context.logger.error(`Organization subscriptions require authorizeReference to be defined in your stripe plugin config.`);
|
|
507
|
-
throw APIError
|
|
506
|
+
throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.AUTHORIZE_REFERENCE_REQUIRED);
|
|
508
507
|
}
|
|
509
508
|
const referenceId = explicitReferenceId || ctxSession.session.activeOrganizationId;
|
|
510
|
-
if (!referenceId) throw APIError
|
|
509
|
+
if (!referenceId) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.ORGANIZATION_REFERENCE_ID_REQUIRED);
|
|
511
510
|
if (!await subscriptionOptions.authorizeReference({
|
|
512
511
|
user: ctxSession.user,
|
|
513
512
|
session: ctxSession.session,
|
|
514
513
|
referenceId,
|
|
515
514
|
action
|
|
516
|
-
}, ctx)) throw APIError
|
|
515
|
+
}, ctx)) throw APIError.from("UNAUTHORIZED", STRIPE_ERROR_CODES.UNAUTHORIZED);
|
|
517
516
|
return {
|
|
518
517
|
referenceId,
|
|
519
518
|
customerType
|
|
@@ -526,14 +525,14 @@ const referenceMiddleware = (options, action) => createAuthMiddleware(async (ctx
|
|
|
526
525
|
};
|
|
527
526
|
if (!subscriptionOptions.authorizeReference) {
|
|
528
527
|
ctx.context.logger.error(`Passing referenceId into a subscription action isn't allowed if subscription.authorizeReference isn't defined in your stripe plugin config.`);
|
|
529
|
-
throw APIError
|
|
528
|
+
throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.REFERENCE_ID_NOT_ALLOWED);
|
|
530
529
|
}
|
|
531
530
|
if (!await subscriptionOptions.authorizeReference({
|
|
532
531
|
user: ctxSession.user,
|
|
533
532
|
session: ctxSession.session,
|
|
534
533
|
referenceId,
|
|
535
534
|
action
|
|
536
|
-
}, ctx)) throw APIError
|
|
535
|
+
}, ctx)) throw APIError.from("UNAUTHORIZED", STRIPE_ERROR_CODES.UNAUTHORIZED);
|
|
537
536
|
return {
|
|
538
537
|
referenceId,
|
|
539
538
|
customerType: "user"
|
|
@@ -690,9 +689,9 @@ const upgradeSubscription = (options) => {
|
|
|
690
689
|
const { user, session } = ctx.context.session;
|
|
691
690
|
const customerType = ctx.context.customerType;
|
|
692
691
|
const referenceId = ctx.context.referenceId;
|
|
693
|
-
if (!user.emailVerified && subscriptionOptions.requireEmailVerification) throw APIError
|
|
692
|
+
if (!user.emailVerified && subscriptionOptions.requireEmailVerification) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.EMAIL_VERIFICATION_REQUIRED);
|
|
694
693
|
const plan = await getPlanByName(options, ctx.body.plan);
|
|
695
|
-
if (!plan) throw APIError
|
|
694
|
+
if (!plan) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_PLAN_NOT_FOUND);
|
|
696
695
|
const subscriptionToUpdate = ctx.body.subscriptionId ? await ctx.context.adapter.findOne({
|
|
697
696
|
model: "subscription",
|
|
698
697
|
where: [{
|
|
@@ -700,8 +699,8 @@ const upgradeSubscription = (options) => {
|
|
|
700
699
|
value: ctx.body.subscriptionId
|
|
701
700
|
}]
|
|
702
701
|
}) : null;
|
|
703
|
-
if (ctx.body.subscriptionId && !subscriptionToUpdate) throw APIError
|
|
704
|
-
if (ctx.body.subscriptionId && subscriptionToUpdate && subscriptionToUpdate.referenceId !== referenceId) throw APIError
|
|
702
|
+
if (ctx.body.subscriptionId && !subscriptionToUpdate) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND);
|
|
703
|
+
if (ctx.body.subscriptionId && subscriptionToUpdate && subscriptionToUpdate.referenceId !== referenceId) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND);
|
|
705
704
|
let customerId;
|
|
706
705
|
if (customerType === "organization") {
|
|
707
706
|
customerId = subscriptionToUpdate?.stripeCustomerId;
|
|
@@ -713,7 +712,7 @@ const upgradeSubscription = (options) => {
|
|
|
713
712
|
value: referenceId
|
|
714
713
|
}]
|
|
715
714
|
});
|
|
716
|
-
if (!org) throw APIError
|
|
715
|
+
if (!org) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.ORGANIZATION_NOT_FOUND);
|
|
717
716
|
customerId = org.stripeCustomerId;
|
|
718
717
|
if (!customerId) try {
|
|
719
718
|
let stripeCustomer;
|
|
@@ -759,7 +758,7 @@ const upgradeSubscription = (options) => {
|
|
|
759
758
|
customerId = stripeCustomer.id;
|
|
760
759
|
} catch (e) {
|
|
761
760
|
ctx.context.logger.error(e);
|
|
762
|
-
throw APIError
|
|
761
|
+
throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.UNABLE_TO_CREATE_CUSTOMER);
|
|
763
762
|
}
|
|
764
763
|
}
|
|
765
764
|
} else {
|
|
@@ -804,7 +803,7 @@ const upgradeSubscription = (options) => {
|
|
|
804
803
|
customerId = stripeCustomer.id;
|
|
805
804
|
} catch (e) {
|
|
806
805
|
ctx.context.logger.error(e);
|
|
807
|
-
throw APIError
|
|
806
|
+
throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.UNABLE_TO_CREATE_CUSTOMER);
|
|
808
807
|
}
|
|
809
808
|
}
|
|
810
809
|
const subscriptions = subscriptionToUpdate ? [subscriptionToUpdate] : await ctx.context.adapter.findMany({
|
|
@@ -843,7 +842,7 @@ const upgradeSubscription = (options) => {
|
|
|
843
842
|
const isSamePriceId = stripeSubscriptionPriceId === priceIdToUse;
|
|
844
843
|
const isSubscriptionStillValid = !activeOrTrialingSubscription?.periodEnd || activeOrTrialingSubscription.periodEnd > /* @__PURE__ */ new Date();
|
|
845
844
|
const isSeatOnlyPlan = isAutoManagedSeats && plan.seatPriceId === plan.priceId;
|
|
846
|
-
if (activeOrTrialingSubscription?.status === "active" && isSamePlan && isSameSeats && isSamePriceId && isSubscriptionStillValid) throw APIError
|
|
845
|
+
if (activeOrTrialingSubscription?.status === "active" && isSamePlan && isSameSeats && isSamePriceId && isSubscriptionStillValid) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.ALREADY_SUBSCRIBED_PLAN);
|
|
847
846
|
if (activeSubscription && customerId) {
|
|
848
847
|
let dbSubscription = await ctx.context.adapter.findOne({
|
|
849
848
|
model: "subscription",
|
|
@@ -866,7 +865,7 @@ const upgradeSubscription = (options) => {
|
|
|
866
865
|
});
|
|
867
866
|
dbSubscription = activeOrTrialingSubscription;
|
|
868
867
|
}
|
|
869
|
-
if (!planItem) throw APIError
|
|
868
|
+
if (!planItem) throw APIError.from("NOT_FOUND", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND);
|
|
870
869
|
if (activeSubscription.schedule) {
|
|
871
870
|
const { data: existingSchedules } = await client.subscriptionSchedules.list({ customer: customerId });
|
|
872
871
|
const existingSchedule = existingSchedules.find((s) => (typeof s.subscription === "string" ? s.subscription : s.subscription?.id) === activeSubscription.id && s.status === "active");
|
|
@@ -1090,7 +1089,7 @@ const upgradeSubscription = (options) => {
|
|
|
1090
1089
|
});
|
|
1091
1090
|
if (!subscription) {
|
|
1092
1091
|
ctx.context.logger.error("Subscription ID not found");
|
|
1093
|
-
throw APIError
|
|
1092
|
+
throw APIError.from("NOT_FOUND", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND);
|
|
1094
1093
|
}
|
|
1095
1094
|
const params = await subscriptionOptions.getCheckoutSessionParams?.({
|
|
1096
1095
|
user,
|
|
@@ -1220,8 +1219,8 @@ const cancelSubscription = (options) => {
|
|
|
1220
1219
|
}]
|
|
1221
1220
|
}).then((subs) => subs.find((sub) => isActiveOrTrialing(sub)));
|
|
1222
1221
|
if (ctx.body.subscriptionId && subscription && subscription.referenceId !== referenceId) subscription = void 0;
|
|
1223
|
-
if (!subscription || !subscription.stripeCustomerId) throw APIError
|
|
1224
|
-
if (!subscription.stripeSubscriptionId) throw APIError
|
|
1222
|
+
if (!subscription || !subscription.stripeCustomerId) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND);
|
|
1223
|
+
if (!subscription.stripeSubscriptionId) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND);
|
|
1225
1224
|
const activeSubscription = await retrieveStripeSubscription(client, ctx, subscription.stripeSubscriptionId);
|
|
1226
1225
|
if (!activeSubscription || !isActiveOrTrialing(activeSubscription)) {
|
|
1227
1226
|
await ctx.context.adapter.delete({
|
|
@@ -1231,7 +1230,7 @@ const cancelSubscription = (options) => {
|
|
|
1231
1230
|
value: subscription.id
|
|
1232
1231
|
}]
|
|
1233
1232
|
});
|
|
1234
|
-
throw APIError
|
|
1233
|
+
throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND);
|
|
1235
1234
|
}
|
|
1236
1235
|
const { url } = await client.billingPortal.sessions.create({
|
|
1237
1236
|
customer: subscription.stripeCustomerId,
|
|
@@ -1306,13 +1305,13 @@ const restoreSubscription = (options) => {
|
|
|
1306
1305
|
}]
|
|
1307
1306
|
}).then((subs) => subs.find((sub) => isActiveOrTrialing(sub)));
|
|
1308
1307
|
if (ctx.body.subscriptionId && subscription && subscription.referenceId !== referenceId) subscription = void 0;
|
|
1309
|
-
if (!subscription || !subscription.stripeCustomerId) throw APIError
|
|
1310
|
-
if (!isActiveOrTrialing(subscription)) throw APIError
|
|
1308
|
+
if (!subscription || !subscription.stripeCustomerId) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND);
|
|
1309
|
+
if (!isActiveOrTrialing(subscription)) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_ACTIVE);
|
|
1311
1310
|
const hasPendingCancel = isPendingCancel(subscription);
|
|
1312
1311
|
const { stripeScheduleId } = subscription;
|
|
1313
|
-
if (!hasPendingCancel && !stripeScheduleId) throw APIError
|
|
1312
|
+
if (!hasPendingCancel && !stripeScheduleId) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_PENDING_CHANGE);
|
|
1314
1313
|
if (stripeScheduleId) {
|
|
1315
|
-
if (!subscription.stripeSubscriptionId) throw APIError
|
|
1314
|
+
if (!subscription.stripeSubscriptionId) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND);
|
|
1316
1315
|
if ((await client.subscriptionSchedules.retrieve(stripeScheduleId).catch((e) => {
|
|
1317
1316
|
throw ctx.error("BAD_REQUEST", {
|
|
1318
1317
|
message: e.message,
|
|
@@ -1338,9 +1337,9 @@ const restoreSubscription = (options) => {
|
|
|
1338
1337
|
const releasedSub = await client.subscriptions.retrieve(subscription.stripeSubscriptionId);
|
|
1339
1338
|
return ctx.json(releasedSub);
|
|
1340
1339
|
}
|
|
1341
|
-
if (!subscription.stripeSubscriptionId) throw APIError
|
|
1340
|
+
if (!subscription.stripeSubscriptionId) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND);
|
|
1342
1341
|
const activeSubscription = await retrieveStripeSubscription(client, ctx, subscription.stripeSubscriptionId);
|
|
1343
|
-
if (!activeSubscription || !isActiveOrTrialing(activeSubscription)) throw APIError
|
|
1342
|
+
if (!activeSubscription || !isActiveOrTrialing(activeSubscription)) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND);
|
|
1344
1343
|
const updateParams = {};
|
|
1345
1344
|
if (activeSubscription.cancel_at) updateParams.cancel_at = "";
|
|
1346
1345
|
else if (activeSubscription.cancel_at_period_end) updateParams.cancel_at_period_end = false;
|
|
@@ -1575,7 +1574,7 @@ const createBillingPortal = (options) => {
|
|
|
1575
1574
|
}]
|
|
1576
1575
|
}).then((subs) => subs.find((sub) => isActiveOrTrialing(sub))))?.stripeCustomerId;
|
|
1577
1576
|
}
|
|
1578
|
-
if (!customerId) throw APIError
|
|
1577
|
+
if (!customerId) throw APIError.from("NOT_FOUND", STRIPE_ERROR_CODES.CUSTOMER_NOT_FOUND);
|
|
1579
1578
|
try {
|
|
1580
1579
|
const { url } = await client.billingPortal.sessions.create({
|
|
1581
1580
|
locale: ctx.body.locale,
|
|
@@ -1588,7 +1587,7 @@ const createBillingPortal = (options) => {
|
|
|
1588
1587
|
});
|
|
1589
1588
|
} catch (error) {
|
|
1590
1589
|
ctx.context.logger.error("Error creating billing portal session", error);
|
|
1591
|
-
throw APIError
|
|
1590
|
+
throw APIError.from("INTERNAL_SERVER_ERROR", STRIPE_ERROR_CODES.UNABLE_TO_CREATE_BILLING_PORTAL);
|
|
1592
1591
|
}
|
|
1593
1592
|
});
|
|
1594
1593
|
};
|
|
@@ -1603,11 +1602,11 @@ const stripeWebhook = (options) => {
|
|
|
1603
1602
|
cloneRequest: true,
|
|
1604
1603
|
disableBody: true
|
|
1605
1604
|
}, async (ctx) => {
|
|
1606
|
-
if (!ctx.request?.body) throw APIError
|
|
1605
|
+
if (!ctx.request?.body) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.INVALID_REQUEST_BODY);
|
|
1607
1606
|
const sig = ctx.request.headers.get("stripe-signature");
|
|
1608
|
-
if (!sig) throw APIError
|
|
1607
|
+
if (!sig) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.STRIPE_SIGNATURE_NOT_FOUND);
|
|
1609
1608
|
const webhookSecret = options.stripeWebhookSecret;
|
|
1610
|
-
if (!webhookSecret) throw APIError
|
|
1609
|
+
if (!webhookSecret) throw APIError.from("INTERNAL_SERVER_ERROR", STRIPE_ERROR_CODES.STRIPE_WEBHOOK_SECRET_NOT_FOUND);
|
|
1611
1610
|
const payload = await ctx.request.text();
|
|
1612
1611
|
let event;
|
|
1613
1612
|
try {
|
|
@@ -1615,9 +1614,9 @@ const stripeWebhook = (options) => {
|
|
|
1615
1614
|
else event = client.webhooks.constructEvent(payload, sig, webhookSecret);
|
|
1616
1615
|
} catch (err) {
|
|
1617
1616
|
ctx.context.logger.error(`${err.message}`);
|
|
1618
|
-
throw APIError
|
|
1617
|
+
throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.FAILED_TO_CONSTRUCT_STRIPE_EVENT);
|
|
1619
1618
|
}
|
|
1620
|
-
if (!event) throw APIError
|
|
1619
|
+
if (!event) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.FAILED_TO_CONSTRUCT_STRIPE_EVENT);
|
|
1621
1620
|
try {
|
|
1622
1621
|
switch (event.type) {
|
|
1623
1622
|
case "checkout.session.completed":
|
|
@@ -1640,7 +1639,7 @@ const stripeWebhook = (options) => {
|
|
|
1640
1639
|
}
|
|
1641
1640
|
} catch (e) {
|
|
1642
1641
|
ctx.context.logger.error(`Stripe webhook failed. Error: ${e.message}`);
|
|
1643
|
-
throw APIError
|
|
1642
|
+
throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.STRIPE_WEBHOOK_ERROR);
|
|
1644
1643
|
}
|
|
1645
1644
|
return ctx.json({ success: true });
|
|
1646
1645
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-auth/stripe",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.21",
|
|
4
4
|
"description": "Stripe plugin for Better Auth",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -58,14 +58,14 @@
|
|
|
58
58
|
"better-call": "1.4.5",
|
|
59
59
|
"stripe": "^23.0.0",
|
|
60
60
|
"tsdown": "0.23.1",
|
|
61
|
-
"@better-auth/core": "1.7.
|
|
62
|
-
"better-auth": "1.7.
|
|
61
|
+
"@better-auth/core": "1.7.21",
|
|
62
|
+
"better-auth": "1.7.21"
|
|
63
63
|
},
|
|
64
64
|
"peerDependencies": {
|
|
65
65
|
"better-call": "1.4.5",
|
|
66
66
|
"stripe": "^18 || ^19 || ^20 || ^21 || ^22 || ^23",
|
|
67
|
-
"@better-auth/core": "^1.7.
|
|
68
|
-
"better-auth": "^1.7.
|
|
67
|
+
"@better-auth/core": "^1.7.21",
|
|
68
|
+
"better-auth": "^1.7.21"
|
|
69
69
|
},
|
|
70
70
|
"scripts": {
|
|
71
71
|
"build": "tsdown",
|