@better-auth/stripe 1.5.0-beta.8 → 1.5.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/src/schema.ts DELETED
@@ -1,128 +0,0 @@
1
- import type { BetterAuthPluginDBSchema } from "@better-auth/core/db";
2
- import { mergeSchema } from "better-auth/db";
3
- import type { StripeOptions } from "./types";
4
-
5
- export const subscriptions = {
6
- subscription: {
7
- fields: {
8
- plan: {
9
- type: "string",
10
- required: true,
11
- },
12
- referenceId: {
13
- type: "string",
14
- required: true,
15
- },
16
- stripeCustomerId: {
17
- type: "string",
18
- required: false,
19
- },
20
- stripeSubscriptionId: {
21
- type: "string",
22
- required: false,
23
- },
24
- status: {
25
- type: "string",
26
- defaultValue: "incomplete",
27
- },
28
- periodStart: {
29
- type: "date",
30
- required: false,
31
- },
32
- periodEnd: {
33
- type: "date",
34
- required: false,
35
- },
36
- trialStart: {
37
- type: "date",
38
- required: false,
39
- },
40
- trialEnd: {
41
- type: "date",
42
- required: false,
43
- },
44
- cancelAtPeriodEnd: {
45
- type: "boolean",
46
- required: false,
47
- defaultValue: false,
48
- },
49
- cancelAt: {
50
- type: "date",
51
- required: false,
52
- },
53
- canceledAt: {
54
- type: "date",
55
- required: false,
56
- },
57
- endedAt: {
58
- type: "date",
59
- required: false,
60
- },
61
- seats: {
62
- type: "number",
63
- required: false,
64
- },
65
- },
66
- },
67
- } satisfies BetterAuthPluginDBSchema;
68
-
69
- export const user = {
70
- user: {
71
- fields: {
72
- stripeCustomerId: {
73
- type: "string",
74
- required: false,
75
- },
76
- },
77
- },
78
- } satisfies BetterAuthPluginDBSchema;
79
-
80
- export const organization = {
81
- organization: {
82
- fields: {
83
- stripeCustomerId: {
84
- type: "string",
85
- required: false,
86
- },
87
- },
88
- },
89
- } satisfies BetterAuthPluginDBSchema;
90
-
91
- type GetSchemaResult<O extends StripeOptions> = typeof user &
92
- (O["subscription"] extends { enabled: true } ? typeof subscriptions : {}) &
93
- (O["organization"] extends { enabled: true } ? typeof organization : {});
94
-
95
- export const getSchema = <O extends StripeOptions>(
96
- options: O,
97
- ): GetSchemaResult<O> => {
98
- let baseSchema: BetterAuthPluginDBSchema = {};
99
-
100
- if (options.subscription?.enabled) {
101
- baseSchema = {
102
- ...subscriptions,
103
- ...user,
104
- };
105
- } else {
106
- baseSchema = {
107
- ...user,
108
- };
109
- }
110
-
111
- if (options.organization?.enabled) {
112
- baseSchema = {
113
- ...baseSchema,
114
- ...organization,
115
- };
116
- }
117
-
118
- if (
119
- options.schema &&
120
- !options.subscription?.enabled &&
121
- "subscription" in options.schema
122
- ) {
123
- const { subscription: _subscription, ...restSchema } = options.schema;
124
- return mergeSchema(baseSchema, restSchema) as GetSchemaResult<O>;
125
- }
126
-
127
- return mergeSchema(baseSchema, options.schema) as GetSchemaResult<O>;
128
- };
package/src/types.ts DELETED
@@ -1,449 +0,0 @@
1
- import type {
2
- GenericEndpointContext,
3
- InferOptionSchema,
4
- Session,
5
- User,
6
- } from "better-auth";
7
- import type { Organization } from "better-auth/plugins/organization";
8
- import type Stripe from "stripe";
9
- import type { organization, subscriptions, user } from "./schema";
10
-
11
- export type AuthorizeReferenceAction =
12
- | "upgrade-subscription"
13
- | "list-subscription"
14
- | "cancel-subscription"
15
- | "restore-subscription"
16
- | "billing-portal";
17
-
18
- export type CustomerType = "user" | "organization";
19
-
20
- export type WithStripeCustomerId = {
21
- stripeCustomerId?: string;
22
- };
23
-
24
- // TODO: Types extended by a plugin should be moved into that plugin.
25
- export type WithActiveOrganizationId = {
26
- activeOrganizationId?: string;
27
- };
28
-
29
- export type StripeCtxSession = {
30
- session: Session & WithActiveOrganizationId;
31
- user: User & WithStripeCustomerId;
32
- };
33
-
34
- export type StripePlan = {
35
- /**
36
- * Monthly price id
37
- */
38
- priceId?: string | undefined;
39
- /**
40
- * To use lookup key instead of price id
41
- *
42
- * https://docs.stripe.com/products-prices/
43
- * manage-prices#lookup-keys
44
- */
45
- lookupKey?: string | undefined;
46
- /**
47
- * A yearly discount price id
48
- *
49
- * useful when you want to offer a discount for
50
- * yearly subscription
51
- */
52
- annualDiscountPriceId?: string | undefined;
53
- /**
54
- * To use lookup key instead of price id
55
- *
56
- * https://docs.stripe.com/products-prices/
57
- * manage-prices#lookup-keys
58
- */
59
- annualDiscountLookupKey?: string | undefined;
60
- /**
61
- * Plan name
62
- */
63
- name: string;
64
- /**
65
- * Limits for the plan
66
- *
67
- * useful when you want to define plan-specific metadata.
68
- */
69
- limits?: Record<string, unknown> | undefined;
70
- /**
71
- * Plan group name
72
- *
73
- * useful when you want to group plans or
74
- * when a user can subscribe to multiple plans.
75
- */
76
- group?: string | undefined;
77
- /**
78
- * Free trial days
79
- */
80
- freeTrial?:
81
- | {
82
- /**
83
- * Number of days
84
- */
85
- days: number;
86
- /**
87
- * A function that will be called when the trial
88
- * starts.
89
- *
90
- * @param subscription
91
- * @returns
92
- */
93
- onTrialStart?: (subscription: Subscription) => Promise<void>;
94
- /**
95
- * A function that will be called when the trial
96
- * ends
97
- *
98
- * @param subscription - Subscription
99
- * @returns
100
- */
101
- onTrialEnd?: (
102
- data: {
103
- subscription: Subscription;
104
- },
105
- ctx: GenericEndpointContext,
106
- ) => Promise<void>;
107
- /**
108
- * A function that will be called when the trial
109
- * expired.
110
- * @param subscription - Subscription
111
- * @returns
112
- */
113
- onTrialExpired?: (
114
- subscription: Subscription,
115
- ctx: GenericEndpointContext,
116
- ) => Promise<void>;
117
- }
118
- | undefined;
119
- };
120
-
121
- export interface Subscription {
122
- /**
123
- * Database identifier
124
- */
125
- id: string;
126
- /**
127
- * The plan name
128
- */
129
- plan: string;
130
- /**
131
- * Stripe customer id
132
- */
133
- stripeCustomerId?: string | undefined;
134
- /**
135
- * Stripe subscription id
136
- */
137
- stripeSubscriptionId?: string | undefined;
138
- /**
139
- * Trial start date
140
- */
141
- trialStart?: Date | undefined;
142
- /**
143
- * Trial end date
144
- */
145
- trialEnd?: Date | undefined;
146
- /**
147
- * Price Id for the subscription
148
- */
149
- priceId?: string | undefined;
150
- /**
151
- * To what reference id the subscription belongs to
152
- * @example
153
- * - userId for a user
154
- * - workspace id for a saas platform
155
- * - website id for a hosting platform
156
- *
157
- * @default - userId
158
- */
159
- referenceId: string;
160
- /**
161
- * Subscription status
162
- */
163
- status:
164
- | "active"
165
- | "canceled"
166
- | "incomplete"
167
- | "incomplete_expired"
168
- | "past_due"
169
- | "paused"
170
- | "trialing"
171
- | "unpaid";
172
- /**
173
- * The billing cycle start date
174
- */
175
- periodStart?: Date | undefined;
176
- /**
177
- * The billing cycle end date
178
- */
179
- periodEnd?: Date | undefined;
180
- /**
181
- * Whether this subscription will (if status=active)
182
- * or did (if status=canceled) cancel at the end of the current billing period.
183
- */
184
- cancelAtPeriodEnd?: boolean | undefined;
185
- /**
186
- * If the subscription is scheduled to be canceled,
187
- * this is the time at which the cancellation will take effect.
188
- */
189
- cancelAt?: Date | undefined;
190
- /**
191
- * If the subscription has been canceled, this is the time when it was canceled.
192
- *
193
- * Note: If the subscription was canceled with `cancel_at_period_end`,
194
- * this reflects the cancellation request time, not when the subscription actually ends.
195
- */
196
- canceledAt?: Date | undefined;
197
- /**
198
- * If the subscription has ended, the date the subscription ended.
199
- */
200
- endedAt?: Date | undefined;
201
- /**
202
- * A field to group subscriptions so you can have multiple subscriptions
203
- * for one reference id
204
- */
205
- groupId?: string | undefined;
206
- /**
207
- * Number of seats for the subscription (useful for team plans)
208
- */
209
- seats?: number | undefined;
210
- }
211
-
212
- export type SubscriptionOptions = {
213
- /**
214
- * Subscription Configuration
215
- */
216
- /**
217
- * List of plan
218
- */
219
- plans: StripePlan[] | (() => StripePlan[] | Promise<StripePlan[]>);
220
- /**
221
- * Require email verification before a user is allowed to upgrade
222
- * their subscriptions
223
- *
224
- * @default false
225
- */
226
- requireEmailVerification?: boolean | undefined;
227
- /**
228
- * A callback to run after a user has subscribed to a package
229
- * @param event - Stripe Event
230
- * @param subscription - Subscription Data
231
- * @returns
232
- */
233
- onSubscriptionComplete?:
234
- | ((
235
- data: {
236
- event: Stripe.Event;
237
- stripeSubscription: Stripe.Subscription;
238
- subscription: Subscription;
239
- plan: StripePlan;
240
- },
241
- ctx: GenericEndpointContext,
242
- ) => Promise<void>)
243
- | undefined;
244
- /**
245
- * A callback to run after a user is about to cancel their subscription
246
- * @returns
247
- */
248
- onSubscriptionUpdate?:
249
- | ((data: {
250
- event: Stripe.Event;
251
- subscription: Subscription;
252
- }) => Promise<void>)
253
- | undefined;
254
- /**
255
- * A callback to run after a user is about to cancel their subscription
256
- * @returns
257
- */
258
- onSubscriptionCancel?:
259
- | ((data: {
260
- event?: Stripe.Event;
261
- subscription: Subscription;
262
- stripeSubscription: Stripe.Subscription;
263
- cancellationDetails?: Stripe.Subscription.CancellationDetails | null;
264
- }) => Promise<void>)
265
- | undefined;
266
- /**
267
- * A function to check if the reference id is valid
268
- * and belongs to the user
269
- *
270
- * @param data - data containing user, session and referenceId
271
- * @param ctx - the context object
272
- * @returns
273
- */
274
- authorizeReference?:
275
- | ((
276
- data: {
277
- user: User & Record<string, any>;
278
- session: Session & Record<string, any>;
279
- referenceId: string;
280
- action: AuthorizeReferenceAction;
281
- },
282
- ctx: GenericEndpointContext,
283
- ) => Promise<boolean>)
284
- | undefined;
285
- /**
286
- * A callback to run after a user has deleted their subscription
287
- * @returns
288
- */
289
- onSubscriptionDeleted?:
290
- | ((data: {
291
- event: Stripe.Event;
292
- stripeSubscription: Stripe.Subscription;
293
- subscription: Subscription;
294
- }) => Promise<void>)
295
- | undefined;
296
- /**
297
- * A callback to run when a subscription is created
298
- * @returns
299
- */
300
- onSubscriptionCreated?:
301
- | ((data: {
302
- event: Stripe.Event;
303
- stripeSubscription: Stripe.Subscription;
304
- subscription: Subscription;
305
- plan: StripePlan;
306
- }) => Promise<void>)
307
- | undefined;
308
- /**
309
- * parameters for session create params
310
- *
311
- * @param data - data containing user, session and plan
312
- * @param req - the request object
313
- * @param ctx - the context object
314
- */
315
- getCheckoutSessionParams?:
316
- | ((
317
- data: {
318
- user: User & Record<string, any>;
319
- session: Session & Record<string, any>;
320
- plan: StripePlan;
321
- subscription: Subscription;
322
- },
323
- req: GenericEndpointContext["request"],
324
- ctx: GenericEndpointContext,
325
- ) =>
326
- | Promise<{
327
- params?: Stripe.Checkout.SessionCreateParams;
328
- options?: Stripe.RequestOptions;
329
- }>
330
- | {
331
- params?: Stripe.Checkout.SessionCreateParams;
332
- options?: Stripe.RequestOptions;
333
- })
334
- | undefined;
335
- };
336
-
337
- export interface StripeOptions {
338
- /**
339
- * Stripe Client
340
- */
341
- stripeClient: Stripe;
342
- /**
343
- * Stripe Webhook Secret
344
- *
345
- * @description Stripe webhook secret key
346
- */
347
- stripeWebhookSecret: string;
348
- /**
349
- * Enable customer creation when a user signs up
350
- */
351
- createCustomerOnSignUp?: boolean | undefined;
352
- /**
353
- * A callback to run after a customer has been created
354
- * @param customer - Customer Data
355
- * @param stripeCustomer - Stripe Customer Data
356
- * @returns
357
- */
358
- onCustomerCreate?:
359
- | ((
360
- data: {
361
- stripeCustomer: Stripe.Customer;
362
- user: User & WithStripeCustomerId;
363
- },
364
- ctx: GenericEndpointContext,
365
- ) => Promise<void>)
366
- | undefined;
367
- /**
368
- * A custom function to get the customer create
369
- * params
370
- * @param data - data containing user and session
371
- * @returns
372
- */
373
- getCustomerCreateParams?:
374
- | ((
375
- user: User,
376
- ctx: GenericEndpointContext,
377
- ) => Promise<Partial<Stripe.CustomerCreateParams>>)
378
- | undefined;
379
- /**
380
- * Subscriptions
381
- */
382
- subscription?:
383
- | (
384
- | {
385
- enabled: false;
386
- }
387
- | ({
388
- enabled: true;
389
- } & SubscriptionOptions)
390
- )
391
- | undefined;
392
- /**
393
- * Organization Stripe integration
394
- *
395
- * Enable organizations to have their own Stripe customer ID
396
- */
397
- organization?:
398
- | {
399
- /**
400
- * Enable organization Stripe customer
401
- */
402
- enabled: true;
403
- /**
404
- * A custom function to get the customer create params
405
- * for organization customers.
406
- *
407
- * @param organization - the organization
408
- * @param ctx - the context object
409
- * @returns
410
- */
411
- getCustomerCreateParams?:
412
- | ((
413
- organization: Organization,
414
- ctx: GenericEndpointContext,
415
- ) => Promise<Partial<Stripe.CustomerCreateParams>>)
416
- | undefined;
417
- /**
418
- * A callback to run after an organization customer has been created
419
- *
420
- * @param data - data containing stripeCustomer and organization
421
- * @param ctx - the context object
422
- * @returns
423
- */
424
- onCustomerCreate?:
425
- | ((
426
- data: {
427
- stripeCustomer: Stripe.Customer;
428
- organization: Organization & WithStripeCustomerId;
429
- },
430
- ctx: GenericEndpointContext,
431
- ) => Promise<void>)
432
- | undefined;
433
- }
434
- | undefined;
435
- /**
436
- * A callback to run after a stripe event is received
437
- * @param event - Stripe Event
438
- * @returns
439
- */
440
- onEvent?: ((event: Stripe.Event) => Promise<void>) | undefined;
441
- /**
442
- * Schema for the stripe plugin
443
- */
444
- schema?:
445
- | InferOptionSchema<
446
- typeof subscriptions & typeof user & typeof organization
447
- >
448
- | undefined;
449
- }
package/src/utils.ts DELETED
@@ -1,70 +0,0 @@
1
- import type Stripe from "stripe";
2
- import type { StripeOptions, Subscription } from "./types";
3
-
4
- export async function getPlans(
5
- subscriptionOptions: StripeOptions["subscription"],
6
- ) {
7
- if (subscriptionOptions?.enabled) {
8
- return typeof subscriptionOptions.plans === "function"
9
- ? await subscriptionOptions.plans()
10
- : subscriptionOptions.plans;
11
- }
12
- throw new Error("Subscriptions are not enabled in the Stripe options.");
13
- }
14
-
15
- export async function getPlanByPriceInfo(
16
- options: StripeOptions,
17
- priceId: string,
18
- priceLookupKey: string | null,
19
- ) {
20
- return await getPlans(options.subscription).then((res) =>
21
- res?.find(
22
- (plan) =>
23
- plan.priceId === priceId ||
24
- plan.annualDiscountPriceId === priceId ||
25
- (priceLookupKey &&
26
- (plan.lookupKey === priceLookupKey ||
27
- plan.annualDiscountLookupKey === priceLookupKey)),
28
- ),
29
- );
30
- }
31
-
32
- export async function getPlanByName(options: StripeOptions, name: string) {
33
- return await getPlans(options.subscription).then((res) =>
34
- res?.find((plan) => plan.name.toLowerCase() === name.toLowerCase()),
35
- );
36
- }
37
-
38
- /**
39
- * Checks if a subscription is in an available state (active or trialing)
40
- */
41
- export function isActiveOrTrialing(
42
- sub: Subscription | Stripe.Subscription,
43
- ): boolean {
44
- return sub.status === "active" || sub.status === "trialing";
45
- }
46
-
47
- /**
48
- * Check if a subscription is scheduled to be canceled (DB subscription object)
49
- */
50
- export function isPendingCancel(sub: Subscription): boolean {
51
- return !!(sub.cancelAtPeriodEnd || sub.cancelAt);
52
- }
53
-
54
- /**
55
- * Check if a Stripe subscription is scheduled to be canceled (Stripe API response)
56
- */
57
- export function isStripePendingCancel(stripeSub: Stripe.Subscription): boolean {
58
- return !!(stripeSub.cancel_at_period_end || stripeSub.cancel_at);
59
- }
60
-
61
- /**
62
- * Escapes a value for use in Stripe search queries.
63
- * Stripe search query uses double quotes for string values,
64
- * and double quotes within the value need to be escaped with backslash.
65
- *
66
- * @see https://docs.stripe.com/search#search-query-language
67
- */
68
- export function escapeStripeSearchValue(value: string): string {
69
- return value.replace(/"/g, '\\"');
70
- }