@better-auth/stripe 1.7.20 → 1.7.22
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.d.mts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { l as StripePlan, n as stripe } from "./index-
|
|
2
|
-
//#region src/error-codes.d.ts
|
|
1
|
+
import { l as StripePlan, n as stripe } from "./index-CEnreyM7.mjs";
|
|
3
2
|
export declare const STRIPE_ERROR_CODES: {
|
|
4
3
|
UNAUTHORIZED: import("better-auth").RawError<"UNAUTHORIZED">;
|
|
5
4
|
INVALID_REQUEST_BODY: import("better-auth").RawError<"INVALID_REQUEST_BODY">;
|
|
@@ -25,8 +24,6 @@ export declare const STRIPE_ERROR_CODES: {
|
|
|
25
24
|
ORGANIZATION_HAS_ACTIVE_SUBSCRIPTION: import("better-auth").RawError<"ORGANIZATION_HAS_ACTIVE_SUBSCRIPTION">;
|
|
26
25
|
ORGANIZATION_REFERENCE_ID_REQUIRED: import("better-auth").RawError<"ORGANIZATION_REFERENCE_ID_REQUIRED">;
|
|
27
26
|
};
|
|
28
|
-
//#endregion
|
|
29
|
-
//#region src/client.d.ts
|
|
30
27
|
export declare const stripeClient: <O extends {
|
|
31
28
|
subscription: boolean;
|
|
32
29
|
}>(options?: O | undefined) => {
|
|
@@ -72,5 +69,4 @@ export declare const stripeClient: <O extends {
|
|
|
72
69
|
ORGANIZATION_HAS_ACTIVE_SUBSCRIPTION: import("better-auth").RawError<"ORGANIZATION_HAS_ACTIVE_SUBSCRIPTION">;
|
|
73
70
|
ORGANIZATION_REFERENCE_ID_REQUIRED: import("better-auth").RawError<"ORGANIZATION_REFERENCE_ID_REQUIRED">;
|
|
74
71
|
};
|
|
75
|
-
};
|
|
76
|
-
//#endregion
|
|
72
|
+
};
|
package/dist/client.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as STRIPE_ERROR_CODES, t as PACKAGE_VERSION } from "./version-
|
|
2
|
-
|
|
1
|
+
import { n as STRIPE_ERROR_CODES, t as PACKAGE_VERSION } from "./version-DsuYpwKS.mjs";
|
|
2
|
+
// src/client.ts
|
|
3
3
|
const stripeClient = (options) => {
|
|
4
4
|
return {
|
|
5
5
|
id: "stripe-client",
|
|
@@ -12,5 +12,4 @@ const stripeClient = (options) => {
|
|
|
12
12
|
$ERROR_CODES: STRIPE_ERROR_CODES
|
|
13
13
|
};
|
|
14
14
|
};
|
|
15
|
-
//#endregion
|
|
16
15
|
export { STRIPE_ERROR_CODES, stripeClient };
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { GenericEndpointContext, InferOptionSchema, Session, User } from "better-auth";
|
|
2
2
|
import { Organization } from "better-auth/plugins/organization";
|
|
3
3
|
import Stripe from "stripe";
|
|
4
|
-
//#region src/schema.d.ts
|
|
5
4
|
declare const subscriptions: {
|
|
6
5
|
subscription: {
|
|
7
6
|
fields: {
|
|
@@ -100,8 +99,6 @@ declare const organization: {
|
|
|
100
99
|
};
|
|
101
100
|
};
|
|
102
101
|
};
|
|
103
|
-
//#endregion
|
|
104
|
-
//#region src/types.d.ts
|
|
105
102
|
type AuthorizeReferenceAction = "upgrade-subscription" | "list-subscription" | "cancel-subscription" | "restore-subscription" | "billing-portal";
|
|
106
103
|
type CustomerType = "user" | "organization";
|
|
107
104
|
type WithStripeCustomerId = {
|
|
@@ -498,8 +495,6 @@ interface StripeOptions {
|
|
|
498
495
|
*/
|
|
499
496
|
schema?: InferOptionSchema<typeof subscriptions & typeof user & typeof organization> | undefined;
|
|
500
497
|
}
|
|
501
|
-
//#endregion
|
|
502
|
-
//#region src/index.d.ts
|
|
503
498
|
declare module "@better-auth/core" {
|
|
504
499
|
interface BetterAuthPluginRegistry<AuthOptions, Options> {
|
|
505
500
|
stripe: {
|
|
@@ -1089,5 +1084,4 @@ declare const stripe: <O extends StripeOptions>(options: O) => {
|
|
|
1089
1084
|
};
|
|
1090
1085
|
};
|
|
1091
1086
|
type StripePlugin<O extends StripeOptions> = ReturnType<typeof stripe<O>>;
|
|
1092
|
-
//#endregion
|
|
1093
1087
|
export { CheckoutSessionLocale as a, StripeOptions as c, SubscriptionOptions as d, WithActiveOrganizationId as f, CheckoutSessionLineItem as i, StripePlan as l, stripe as n, CustomerType as o, WithStripeCustomerId as p, AuthorizeReferenceAction as r, StripeCtxSession as s, StripePlugin as t, Subscription as u };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as CheckoutSessionLocale, c as StripeOptions, d as SubscriptionOptions, f as WithActiveOrganizationId, i as CheckoutSessionLineItem, l as StripePlan, n as stripe, o as CustomerType, p as WithStripeCustomerId, r as AuthorizeReferenceAction, s as StripeCtxSession, t as StripePlugin, u as Subscription } from "./index-
|
|
1
|
+
import { a as CheckoutSessionLocale, c as StripeOptions, d as SubscriptionOptions, f as WithActiveOrganizationId, i as CheckoutSessionLineItem, l as StripePlan, n as stripe, o as CustomerType, p as WithStripeCustomerId, r as AuthorizeReferenceAction, s as StripeCtxSession, t as StripePlugin, u as Subscription } from "./index-CEnreyM7.mjs";
|
|
2
2
|
export { type AuthorizeReferenceAction, type CheckoutSessionLineItem, type CheckoutSessionLocale, type CustomerType, type StripeCtxSession, type StripeOptions, type StripePlan, StripePlugin, type Subscription, type SubscriptionOptions, type WithActiveOrganizationId, type WithStripeCustomerId, stripe };
|
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
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-DsuYpwKS.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";
|
|
9
|
-
|
|
8
|
+
// src/metadata.ts
|
|
10
9
|
const UNSAFE_METADATA_KEYS = /* @__PURE__ */ new Set([
|
|
11
10
|
"__proto__",
|
|
12
11
|
"constructor",
|
|
@@ -74,8 +73,7 @@ const subscriptionMetadata = {
|
|
|
74
73
|
};
|
|
75
74
|
}
|
|
76
75
|
};
|
|
77
|
-
|
|
78
|
-
//#region src/utils.ts
|
|
76
|
+
// src/utils.ts
|
|
79
77
|
async function getPlans(subscriptionOptions) {
|
|
80
78
|
if (subscriptionOptions?.enabled) return typeof subscriptionOptions.plans === "function" ? await subscriptionOptions.plans() : subscriptionOptions.plans;
|
|
81
79
|
throw new Error("Subscriptions are not enabled in the Stripe options.");
|
|
@@ -145,8 +143,7 @@ async function resolvePlanItem(options, items) {
|
|
|
145
143
|
plan: void 0
|
|
146
144
|
} : void 0;
|
|
147
145
|
}
|
|
148
|
-
|
|
149
|
-
//#region src/hooks.ts
|
|
146
|
+
// src/hooks.ts
|
|
150
147
|
/**
|
|
151
148
|
* Find organization or user by stripeCustomerId.
|
|
152
149
|
* @internal
|
|
@@ -385,7 +382,14 @@ async function onSubscriptionUpdated(ctx, options, event) {
|
|
|
385
382
|
return;
|
|
386
383
|
}
|
|
387
384
|
subscription = activeSub;
|
|
388
|
-
} else
|
|
385
|
+
} else {
|
|
386
|
+
const [onlySub] = subs;
|
|
387
|
+
if (!onlySub) {
|
|
388
|
+
ctx.context.logger.warn(`Stripe webhook warning: No subscription found for customerId: ${customerId}`);
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
subscription = onlySub;
|
|
392
|
+
}
|
|
389
393
|
}
|
|
390
394
|
const seats = plan ? resolveQuantity(stripeSubscriptionUpdated.items.data, subscriptionItem, plan.seatPriceId) : subscriptionItem.quantity;
|
|
391
395
|
const trial = stripeSubscriptionUpdated.trial_start && stripeSubscriptionUpdated.trial_end ? {
|
|
@@ -489,31 +493,30 @@ async function onSubscriptionDeleted(ctx, options, event) {
|
|
|
489
493
|
ctx.context.logger.error(`Stripe webhook failed. Error: ${error}`);
|
|
490
494
|
}
|
|
491
495
|
}
|
|
492
|
-
|
|
493
|
-
//#region src/middleware.ts
|
|
496
|
+
// src/middleware.ts
|
|
494
497
|
const stripeSessionMiddleware = createAuthMiddleware({ use: [sessionMiddleware] }, async (ctx) => {
|
|
495
498
|
return { session: ctx.context.session };
|
|
496
499
|
});
|
|
497
500
|
const referenceMiddleware = (options, action) => createAuthMiddleware(async (ctx) => {
|
|
498
501
|
const subscriptionOptions = options.subscription;
|
|
499
502
|
const ctxSession = ctx.context.session;
|
|
500
|
-
if (!ctxSession) throw APIError
|
|
503
|
+
if (!ctxSession) throw APIError.from("UNAUTHORIZED", STRIPE_ERROR_CODES.UNAUTHORIZED);
|
|
501
504
|
const customerType = ctx.body?.customerType || ctx.query?.customerType;
|
|
502
505
|
const explicitReferenceId = ctx.body?.referenceId || ctx.query?.referenceId;
|
|
503
506
|
if (customerType === "organization") {
|
|
504
|
-
if (!options.organization?.enabled) throw APIError
|
|
507
|
+
if (!options.organization?.enabled) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.ORGANIZATION_SUBSCRIPTION_NOT_ENABLED);
|
|
505
508
|
if (!subscriptionOptions.authorizeReference) {
|
|
506
509
|
ctx.context.logger.error(`Organization subscriptions require authorizeReference to be defined in your stripe plugin config.`);
|
|
507
|
-
throw APIError
|
|
510
|
+
throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.AUTHORIZE_REFERENCE_REQUIRED);
|
|
508
511
|
}
|
|
509
512
|
const referenceId = explicitReferenceId || ctxSession.session.activeOrganizationId;
|
|
510
|
-
if (!referenceId) throw APIError
|
|
513
|
+
if (!referenceId) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.ORGANIZATION_REFERENCE_ID_REQUIRED);
|
|
511
514
|
if (!await subscriptionOptions.authorizeReference({
|
|
512
515
|
user: ctxSession.user,
|
|
513
516
|
session: ctxSession.session,
|
|
514
517
|
referenceId,
|
|
515
518
|
action
|
|
516
|
-
}, ctx)) throw APIError
|
|
519
|
+
}, ctx)) throw APIError.from("UNAUTHORIZED", STRIPE_ERROR_CODES.UNAUTHORIZED);
|
|
517
520
|
return {
|
|
518
521
|
referenceId,
|
|
519
522
|
customerType
|
|
@@ -526,21 +529,20 @@ const referenceMiddleware = (options, action) => createAuthMiddleware(async (ctx
|
|
|
526
529
|
};
|
|
527
530
|
if (!subscriptionOptions.authorizeReference) {
|
|
528
531
|
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
|
|
532
|
+
throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.REFERENCE_ID_NOT_ALLOWED);
|
|
530
533
|
}
|
|
531
534
|
if (!await subscriptionOptions.authorizeReference({
|
|
532
535
|
user: ctxSession.user,
|
|
533
536
|
session: ctxSession.session,
|
|
534
537
|
referenceId,
|
|
535
538
|
action
|
|
536
|
-
}, ctx)) throw APIError
|
|
539
|
+
}, ctx)) throw APIError.from("UNAUTHORIZED", STRIPE_ERROR_CODES.UNAUTHORIZED);
|
|
537
540
|
return {
|
|
538
541
|
referenceId,
|
|
539
542
|
customerType: "user"
|
|
540
543
|
};
|
|
541
544
|
});
|
|
542
|
-
|
|
543
|
-
//#region src/routes.ts
|
|
545
|
+
// src/routes.ts
|
|
544
546
|
/**
|
|
545
547
|
* Resolves a Stripe price object, either from a lookup key or by retrieving
|
|
546
548
|
* by ID. Used to inspect `recurring.usage_type` for metered billing.
|
|
@@ -690,9 +692,9 @@ const upgradeSubscription = (options) => {
|
|
|
690
692
|
const { user, session } = ctx.context.session;
|
|
691
693
|
const customerType = ctx.context.customerType;
|
|
692
694
|
const referenceId = ctx.context.referenceId;
|
|
693
|
-
if (!user.emailVerified && subscriptionOptions.requireEmailVerification) throw APIError
|
|
695
|
+
if (!user.emailVerified && subscriptionOptions.requireEmailVerification) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.EMAIL_VERIFICATION_REQUIRED);
|
|
694
696
|
const plan = await getPlanByName(options, ctx.body.plan);
|
|
695
|
-
if (!plan) throw APIError
|
|
697
|
+
if (!plan) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_PLAN_NOT_FOUND);
|
|
696
698
|
const subscriptionToUpdate = ctx.body.subscriptionId ? await ctx.context.adapter.findOne({
|
|
697
699
|
model: "subscription",
|
|
698
700
|
where: [{
|
|
@@ -700,8 +702,8 @@ const upgradeSubscription = (options) => {
|
|
|
700
702
|
value: ctx.body.subscriptionId
|
|
701
703
|
}]
|
|
702
704
|
}) : null;
|
|
703
|
-
if (ctx.body.subscriptionId && !subscriptionToUpdate) throw APIError
|
|
704
|
-
if (ctx.body.subscriptionId && subscriptionToUpdate && subscriptionToUpdate.referenceId !== referenceId) throw APIError
|
|
705
|
+
if (ctx.body.subscriptionId && !subscriptionToUpdate) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND);
|
|
706
|
+
if (ctx.body.subscriptionId && subscriptionToUpdate && subscriptionToUpdate.referenceId !== referenceId) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND);
|
|
705
707
|
let customerId;
|
|
706
708
|
if (customerType === "organization") {
|
|
707
709
|
customerId = subscriptionToUpdate?.stripeCustomerId;
|
|
@@ -713,7 +715,7 @@ const upgradeSubscription = (options) => {
|
|
|
713
715
|
value: referenceId
|
|
714
716
|
}]
|
|
715
717
|
});
|
|
716
|
-
if (!org) throw APIError
|
|
718
|
+
if (!org) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.ORGANIZATION_NOT_FOUND);
|
|
717
719
|
customerId = org.stripeCustomerId;
|
|
718
720
|
if (!customerId) try {
|
|
719
721
|
let stripeCustomer;
|
|
@@ -759,7 +761,7 @@ const upgradeSubscription = (options) => {
|
|
|
759
761
|
customerId = stripeCustomer.id;
|
|
760
762
|
} catch (e) {
|
|
761
763
|
ctx.context.logger.error(e);
|
|
762
|
-
throw APIError
|
|
764
|
+
throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.UNABLE_TO_CREATE_CUSTOMER);
|
|
763
765
|
}
|
|
764
766
|
}
|
|
765
767
|
} else {
|
|
@@ -804,7 +806,7 @@ const upgradeSubscription = (options) => {
|
|
|
804
806
|
customerId = stripeCustomer.id;
|
|
805
807
|
} catch (e) {
|
|
806
808
|
ctx.context.logger.error(e);
|
|
807
|
-
throw APIError
|
|
809
|
+
throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.UNABLE_TO_CREATE_CUSTOMER);
|
|
808
810
|
}
|
|
809
811
|
}
|
|
810
812
|
const subscriptions = subscriptionToUpdate ? [subscriptionToUpdate] : await ctx.context.adapter.findMany({
|
|
@@ -843,7 +845,7 @@ const upgradeSubscription = (options) => {
|
|
|
843
845
|
const isSamePriceId = stripeSubscriptionPriceId === priceIdToUse;
|
|
844
846
|
const isSubscriptionStillValid = !activeOrTrialingSubscription?.periodEnd || activeOrTrialingSubscription.periodEnd > /* @__PURE__ */ new Date();
|
|
845
847
|
const isSeatOnlyPlan = isAutoManagedSeats && plan.seatPriceId === plan.priceId;
|
|
846
|
-
if (activeOrTrialingSubscription?.status === "active" && isSamePlan && isSameSeats && isSamePriceId && isSubscriptionStillValid) throw APIError
|
|
848
|
+
if (activeOrTrialingSubscription?.status === "active" && isSamePlan && isSameSeats && isSamePriceId && isSubscriptionStillValid) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.ALREADY_SUBSCRIBED_PLAN);
|
|
847
849
|
if (activeSubscription && customerId) {
|
|
848
850
|
let dbSubscription = await ctx.context.adapter.findOne({
|
|
849
851
|
model: "subscription",
|
|
@@ -866,7 +868,7 @@ const upgradeSubscription = (options) => {
|
|
|
866
868
|
});
|
|
867
869
|
dbSubscription = activeOrTrialingSubscription;
|
|
868
870
|
}
|
|
869
|
-
if (!planItem) throw APIError
|
|
871
|
+
if (!planItem) throw APIError.from("NOT_FOUND", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND);
|
|
870
872
|
if (activeSubscription.schedule) {
|
|
871
873
|
const { data: existingSchedules } = await client.subscriptionSchedules.list({ customer: customerId });
|
|
872
874
|
const existingSchedule = existingSchedules.find((s) => (typeof s.subscription === "string" ? s.subscription : s.subscription?.id) === activeSubscription.id && s.status === "active");
|
|
@@ -1090,7 +1092,7 @@ const upgradeSubscription = (options) => {
|
|
|
1090
1092
|
});
|
|
1091
1093
|
if (!subscription) {
|
|
1092
1094
|
ctx.context.logger.error("Subscription ID not found");
|
|
1093
|
-
throw APIError
|
|
1095
|
+
throw APIError.from("NOT_FOUND", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND);
|
|
1094
1096
|
}
|
|
1095
1097
|
const params = await subscriptionOptions.getCheckoutSessionParams?.({
|
|
1096
1098
|
user,
|
|
@@ -1220,8 +1222,8 @@ const cancelSubscription = (options) => {
|
|
|
1220
1222
|
}]
|
|
1221
1223
|
}).then((subs) => subs.find((sub) => isActiveOrTrialing(sub)));
|
|
1222
1224
|
if (ctx.body.subscriptionId && subscription && subscription.referenceId !== referenceId) subscription = void 0;
|
|
1223
|
-
if (!subscription || !subscription.stripeCustomerId) throw APIError
|
|
1224
|
-
if (!subscription.stripeSubscriptionId) throw APIError
|
|
1225
|
+
if (!subscription || !subscription.stripeCustomerId) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND);
|
|
1226
|
+
if (!subscription.stripeSubscriptionId) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND);
|
|
1225
1227
|
const activeSubscription = await retrieveStripeSubscription(client, ctx, subscription.stripeSubscriptionId);
|
|
1226
1228
|
if (!activeSubscription || !isActiveOrTrialing(activeSubscription)) {
|
|
1227
1229
|
await ctx.context.adapter.delete({
|
|
@@ -1231,7 +1233,7 @@ const cancelSubscription = (options) => {
|
|
|
1231
1233
|
value: subscription.id
|
|
1232
1234
|
}]
|
|
1233
1235
|
});
|
|
1234
|
-
throw APIError
|
|
1236
|
+
throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND);
|
|
1235
1237
|
}
|
|
1236
1238
|
const { url } = await client.billingPortal.sessions.create({
|
|
1237
1239
|
customer: subscription.stripeCustomerId,
|
|
@@ -1306,13 +1308,13 @@ const restoreSubscription = (options) => {
|
|
|
1306
1308
|
}]
|
|
1307
1309
|
}).then((subs) => subs.find((sub) => isActiveOrTrialing(sub)));
|
|
1308
1310
|
if (ctx.body.subscriptionId && subscription && subscription.referenceId !== referenceId) subscription = void 0;
|
|
1309
|
-
if (!subscription || !subscription.stripeCustomerId) throw APIError
|
|
1310
|
-
if (!isActiveOrTrialing(subscription)) throw APIError
|
|
1311
|
+
if (!subscription || !subscription.stripeCustomerId) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND);
|
|
1312
|
+
if (!isActiveOrTrialing(subscription)) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_ACTIVE);
|
|
1311
1313
|
const hasPendingCancel = isPendingCancel(subscription);
|
|
1312
1314
|
const { stripeScheduleId } = subscription;
|
|
1313
|
-
if (!hasPendingCancel && !stripeScheduleId) throw APIError
|
|
1315
|
+
if (!hasPendingCancel && !stripeScheduleId) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_PENDING_CHANGE);
|
|
1314
1316
|
if (stripeScheduleId) {
|
|
1315
|
-
if (!subscription.stripeSubscriptionId) throw APIError
|
|
1317
|
+
if (!subscription.stripeSubscriptionId) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND);
|
|
1316
1318
|
if ((await client.subscriptionSchedules.retrieve(stripeScheduleId).catch((e) => {
|
|
1317
1319
|
throw ctx.error("BAD_REQUEST", {
|
|
1318
1320
|
message: e.message,
|
|
@@ -1338,9 +1340,9 @@ const restoreSubscription = (options) => {
|
|
|
1338
1340
|
const releasedSub = await client.subscriptions.retrieve(subscription.stripeSubscriptionId);
|
|
1339
1341
|
return ctx.json(releasedSub);
|
|
1340
1342
|
}
|
|
1341
|
-
if (!subscription.stripeSubscriptionId) throw APIError
|
|
1343
|
+
if (!subscription.stripeSubscriptionId) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND);
|
|
1342
1344
|
const activeSubscription = await retrieveStripeSubscription(client, ctx, subscription.stripeSubscriptionId);
|
|
1343
|
-
if (!activeSubscription || !isActiveOrTrialing(activeSubscription)) throw APIError
|
|
1345
|
+
if (!activeSubscription || !isActiveOrTrialing(activeSubscription)) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND);
|
|
1344
1346
|
const updateParams = {};
|
|
1345
1347
|
if (activeSubscription.cancel_at) updateParams.cancel_at = "";
|
|
1346
1348
|
else if (activeSubscription.cancel_at_period_end) updateParams.cancel_at_period_end = false;
|
|
@@ -1575,7 +1577,7 @@ const createBillingPortal = (options) => {
|
|
|
1575
1577
|
}]
|
|
1576
1578
|
}).then((subs) => subs.find((sub) => isActiveOrTrialing(sub))))?.stripeCustomerId;
|
|
1577
1579
|
}
|
|
1578
|
-
if (!customerId) throw APIError
|
|
1580
|
+
if (!customerId) throw APIError.from("NOT_FOUND", STRIPE_ERROR_CODES.CUSTOMER_NOT_FOUND);
|
|
1579
1581
|
try {
|
|
1580
1582
|
const { url } = await client.billingPortal.sessions.create({
|
|
1581
1583
|
locale: ctx.body.locale,
|
|
@@ -1588,7 +1590,7 @@ const createBillingPortal = (options) => {
|
|
|
1588
1590
|
});
|
|
1589
1591
|
} catch (error) {
|
|
1590
1592
|
ctx.context.logger.error("Error creating billing portal session", error);
|
|
1591
|
-
throw APIError
|
|
1593
|
+
throw APIError.from("INTERNAL_SERVER_ERROR", STRIPE_ERROR_CODES.UNABLE_TO_CREATE_BILLING_PORTAL);
|
|
1592
1594
|
}
|
|
1593
1595
|
});
|
|
1594
1596
|
};
|
|
@@ -1603,11 +1605,11 @@ const stripeWebhook = (options) => {
|
|
|
1603
1605
|
cloneRequest: true,
|
|
1604
1606
|
disableBody: true
|
|
1605
1607
|
}, async (ctx) => {
|
|
1606
|
-
if (!ctx.request?.body) throw APIError
|
|
1608
|
+
if (!ctx.request?.body) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.INVALID_REQUEST_BODY);
|
|
1607
1609
|
const sig = ctx.request.headers.get("stripe-signature");
|
|
1608
|
-
if (!sig) throw APIError
|
|
1610
|
+
if (!sig) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.STRIPE_SIGNATURE_NOT_FOUND);
|
|
1609
1611
|
const webhookSecret = options.stripeWebhookSecret;
|
|
1610
|
-
if (!webhookSecret) throw APIError
|
|
1612
|
+
if (!webhookSecret) throw APIError.from("INTERNAL_SERVER_ERROR", STRIPE_ERROR_CODES.STRIPE_WEBHOOK_SECRET_NOT_FOUND);
|
|
1611
1613
|
const payload = await ctx.request.text();
|
|
1612
1614
|
let event;
|
|
1613
1615
|
try {
|
|
@@ -1615,9 +1617,9 @@ const stripeWebhook = (options) => {
|
|
|
1615
1617
|
else event = client.webhooks.constructEvent(payload, sig, webhookSecret);
|
|
1616
1618
|
} catch (err) {
|
|
1617
1619
|
ctx.context.logger.error(`${err.message}`);
|
|
1618
|
-
throw APIError
|
|
1620
|
+
throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.FAILED_TO_CONSTRUCT_STRIPE_EVENT);
|
|
1619
1621
|
}
|
|
1620
|
-
if (!event) throw APIError
|
|
1622
|
+
if (!event) throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.FAILED_TO_CONSTRUCT_STRIPE_EVENT);
|
|
1621
1623
|
try {
|
|
1622
1624
|
switch (event.type) {
|
|
1623
1625
|
case "checkout.session.completed":
|
|
@@ -1640,13 +1642,12 @@ const stripeWebhook = (options) => {
|
|
|
1640
1642
|
}
|
|
1641
1643
|
} catch (e) {
|
|
1642
1644
|
ctx.context.logger.error(`Stripe webhook failed. Error: ${e.message}`);
|
|
1643
|
-
throw APIError
|
|
1645
|
+
throw APIError.from("BAD_REQUEST", STRIPE_ERROR_CODES.STRIPE_WEBHOOK_ERROR);
|
|
1644
1646
|
}
|
|
1645
1647
|
return ctx.json({ success: true });
|
|
1646
1648
|
});
|
|
1647
1649
|
};
|
|
1648
|
-
|
|
1649
|
-
//#region src/schema.ts
|
|
1650
|
+
// src/schema.ts
|
|
1650
1651
|
const subscriptions = { subscription: { fields: {
|
|
1651
1652
|
plan: {
|
|
1652
1653
|
type: "string",
|
|
@@ -1746,8 +1747,7 @@ const getSchema = (options) => {
|
|
|
1746
1747
|
}
|
|
1747
1748
|
return mergeSchema(baseSchema, options.schema);
|
|
1748
1749
|
};
|
|
1749
|
-
|
|
1750
|
-
//#region src/index.ts
|
|
1750
|
+
// src/index.ts
|
|
1751
1751
|
const stripe = (options) => {
|
|
1752
1752
|
const client = options.stripeClient;
|
|
1753
1753
|
const subscriptionEndpoints = {
|
|
@@ -1986,5 +1986,4 @@ const stripe = (options) => {
|
|
|
1986
1986
|
$ERROR_CODES: STRIPE_ERROR_CODES
|
|
1987
1987
|
};
|
|
1988
1988
|
};
|
|
1989
|
-
//#endregion
|
|
1990
1989
|
export { stripe };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineErrorCodes } from "@better-auth/core/utils/error-codes";
|
|
2
|
-
|
|
2
|
+
// src/error-codes.ts
|
|
3
3
|
const STRIPE_ERROR_CODES = defineErrorCodes({
|
|
4
4
|
UNAUTHORIZED: "Unauthorized access",
|
|
5
5
|
INVALID_REQUEST_BODY: "Invalid request body",
|
|
@@ -28,8 +28,6 @@ const STRIPE_ERROR_CODES = defineErrorCodes({
|
|
|
28
28
|
ORGANIZATION_HAS_ACTIVE_SUBSCRIPTION: "Cannot delete organization with active subscription",
|
|
29
29
|
ORGANIZATION_REFERENCE_ID_REQUIRED: "Reference ID is required. Provide referenceId or set activeOrganizationId in session"
|
|
30
30
|
});
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const PACKAGE_VERSION = "1.7.20";
|
|
34
|
-
//#endregion
|
|
31
|
+
// src/version.ts
|
|
32
|
+
const PACKAGE_VERSION = "1.7.22";
|
|
35
33
|
export { STRIPE_ERROR_CODES as n, PACKAGE_VERSION as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-auth/stripe",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.22",
|
|
4
4
|
"description": "Stripe plugin for Better Auth",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -55,17 +55,17 @@
|
|
|
55
55
|
"zod": "^4.5.4"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
+
"@better-auth/core": "1.7.22",
|
|
59
|
+
"better-auth": "1.7.22",
|
|
58
60
|
"better-call": "1.4.5",
|
|
59
61
|
"stripe": "^23.0.0",
|
|
60
|
-
"tsdown": "0.23.1"
|
|
61
|
-
"@better-auth/core": "1.7.20",
|
|
62
|
-
"better-auth": "1.7.20"
|
|
62
|
+
"tsdown": "0.23.1"
|
|
63
63
|
},
|
|
64
64
|
"peerDependencies": {
|
|
65
|
+
"@better-auth/core": "^1.7.22",
|
|
66
|
+
"better-auth": "^1.7.22",
|
|
65
67
|
"better-call": "1.4.5",
|
|
66
|
-
"stripe": "^18 || ^19 || ^20 || ^21 || ^22 || ^23"
|
|
67
|
-
"@better-auth/core": "^1.7.20",
|
|
68
|
-
"better-auth": "^1.7.20"
|
|
68
|
+
"stripe": "^18 || ^19 || ^20 || ^21 || ^22 || ^23"
|
|
69
69
|
},
|
|
70
70
|
"scripts": {
|
|
71
71
|
"build": "tsdown",
|