@faire-auth/stripe 1.0.4 → 1.1.1
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 +29 -22
- package/dist/client.cjs +3 -5
- package/dist/client.d.cts +3 -7
- package/dist/client.d.mts +3 -7
- package/dist/client.mjs +2 -4
- package/dist/{index-6UTHxaqg.d.cts → index-CWz-G_AJ.d.cts} +223 -328
- package/dist/{index-CYV4awaB.d.mts → index-D4yUrDJc.d.mts} +221 -326
- package/dist/index.cjs +192 -124
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +128 -59
- package/package.json +13 -13
- package/tsdown.config.ts +10 -8
- package/.turbo/turbo-test.log +0 -1578
- package/.turbo/turbo-typecheck.log +0 -4
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
// \0rolldown/runtime.js
|
|
2
3
|
var __create = Object.create;
|
|
3
4
|
var __defProp = Object.defineProperty;
|
|
4
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -15,36 +16,31 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
16
|
}
|
|
16
17
|
return to;
|
|
17
18
|
};
|
|
18
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
19
20
|
value: mod,
|
|
20
21
|
enumerable: true
|
|
21
22
|
}) : target, mod));
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
let __faire_auth_core_factory = require("@faire-auth/core/factory");
|
|
25
|
-
let __faire_auth_core_static = require("@faire-auth/core/static");
|
|
23
|
+
let _faire_auth_core_factory = require("@faire-auth/core/factory");
|
|
24
|
+
let _faire_auth_core_static = require("@faire-auth/core/static");
|
|
26
25
|
let faire_auth = require("faire-auth");
|
|
27
26
|
let faire_auth_middleware = require("faire-auth/middleware");
|
|
28
27
|
let faire_auth_plugins = require("faire-auth/plugins");
|
|
29
28
|
require("stripe");
|
|
30
29
|
let zod = require("zod");
|
|
31
|
-
zod = __toESM(zod);
|
|
30
|
+
zod = __toESM(zod, 1);
|
|
32
31
|
let faire_auth_db = require("faire-auth/db");
|
|
33
|
-
|
|
34
|
-
//#region src/utils.ts
|
|
32
|
+
// src/utils.ts
|
|
35
33
|
async function getPlans(subscriptionOptions) {
|
|
36
34
|
if (subscriptionOptions?.enabled) return typeof subscriptionOptions.plans === "function" ? await subscriptionOptions.plans() : subscriptionOptions.plans;
|
|
37
35
|
throw new Error("Subscriptions are not enabled in the Stripe options.");
|
|
38
36
|
}
|
|
39
37
|
async function getPlanByPriceInfo(options, priceId, priceLookupKey) {
|
|
40
|
-
return await getPlans(options.subscription).then((res
|
|
38
|
+
return await getPlans(options.subscription).then((res) => res?.find((plan) => plan.priceId === priceId || plan.annualDiscountPriceId === priceId || priceLookupKey && (plan.lookupKey === priceLookupKey || plan.annualDiscountLookupKey === priceLookupKey)));
|
|
41
39
|
}
|
|
42
40
|
async function getPlanByName(options, name) {
|
|
43
|
-
return await getPlans(options.subscription).then((res
|
|
41
|
+
return await getPlans(options.subscription).then((res) => res?.find((plan) => plan.name.toLowerCase() === name.toLowerCase()));
|
|
44
42
|
}
|
|
45
|
-
|
|
46
|
-
//#endregion
|
|
47
|
-
//#region src/hooks.ts
|
|
43
|
+
// src/hooks.ts
|
|
48
44
|
async function onCheckoutSessionCompleted(ctx, options, event) {
|
|
49
45
|
try {
|
|
50
46
|
const client = options.stripeClient;
|
|
@@ -208,9 +204,7 @@ async function onSubscriptionDeleted(ctx, options, event) {
|
|
|
208
204
|
faire_auth.logger.error(`Stripe webhook failed. Error: ${error}`);
|
|
209
205
|
}
|
|
210
206
|
}
|
|
211
|
-
|
|
212
|
-
//#endregion
|
|
213
|
-
//#region src/schema.ts
|
|
207
|
+
// src/schema.ts
|
|
214
208
|
const subscriptions = { subscription: { fields: {
|
|
215
209
|
plan: {
|
|
216
210
|
type: "string",
|
|
@@ -270,14 +264,12 @@ const getSchema = (options) => {
|
|
|
270
264
|
};
|
|
271
265
|
else baseSchema = { ...user };
|
|
272
266
|
if (options.schema && !options.subscription?.enabled && "subscription" in options.schema) {
|
|
273
|
-
const { subscription
|
|
267
|
+
const { subscription, ...restSchema } = options.schema;
|
|
274
268
|
return (0, faire_auth_db.mergeSchema)(baseSchema, restSchema);
|
|
275
269
|
}
|
|
276
270
|
return (0, faire_auth_db.mergeSchema)(baseSchema, options.schema);
|
|
277
271
|
};
|
|
278
|
-
|
|
279
|
-
//#endregion
|
|
280
|
-
//#region src/index.ts
|
|
272
|
+
// src/index.ts
|
|
281
273
|
const STRIPE_ERROR_CODES = {
|
|
282
274
|
SUBSCRIPTION_NOT_FOUND: "Subscription not found",
|
|
283
275
|
SUBSCRIPTION_PLAN_NOT_FOUND: "Subscription plan not found",
|
|
@@ -304,10 +296,10 @@ const stripe$1 = (options) => {
|
|
|
304
296
|
const client = options.stripeClient;
|
|
305
297
|
const referenceMiddleware = (action) => (0, faire_auth_plugins.createMiddleware)()(async (ctx, next) => {
|
|
306
298
|
const session = ctx.get("session");
|
|
307
|
-
if (!session) return ctx.json({ success:
|
|
299
|
+
if (!session) return ctx.json({ success: _faire_auth_core_static.False }, 401);
|
|
308
300
|
if (!options.subscription?.enabled) {
|
|
309
301
|
faire_auth.logger.error(`Subscription actions are not enabled in your stripe plugin config.`);
|
|
310
|
-
return ctx.json({ success:
|
|
302
|
+
return ctx.json({ success: _faire_auth_core_static.False }, 400);
|
|
311
303
|
}
|
|
312
304
|
let body = {};
|
|
313
305
|
let bodyHasId = false;
|
|
@@ -319,7 +311,7 @@ const stripe$1 = (options) => {
|
|
|
319
311
|
if (bodyHasId && !options.subscription?.authorizeReference) {
|
|
320
312
|
faire_auth.logger.error(`Passing referenceId into a subscription action isn't allowed if subscription.authorizeReference isn't defined in your stripe plugin config.`);
|
|
321
313
|
return ctx.json({
|
|
322
|
-
success:
|
|
314
|
+
success: _faire_auth_core_static.False,
|
|
323
315
|
message: "Reference id is not allowed. Read server logs for more details."
|
|
324
316
|
}, 400);
|
|
325
317
|
}
|
|
@@ -328,11 +320,26 @@ const stripe$1 = (options) => {
|
|
|
328
320
|
session: session.session,
|
|
329
321
|
referenceId: body.referenceId,
|
|
330
322
|
action
|
|
331
|
-
}, ctx) : true)) return ctx.json({ success:
|
|
323
|
+
}, ctx) : true)) return ctx.json({ success: _faire_auth_core_static.False }, 401);
|
|
332
324
|
return await next();
|
|
333
325
|
});
|
|
334
326
|
const subscriptionEndpoints = {
|
|
335
|
-
|
|
327
|
+
/**
|
|
328
|
+
* ### Endpoint
|
|
329
|
+
*
|
|
330
|
+
* POST `/subscription/upgrade`
|
|
331
|
+
*
|
|
332
|
+
* ### API Methods
|
|
333
|
+
*
|
|
334
|
+
* **server:**
|
|
335
|
+
* `auth.api.upgradeSubscription`
|
|
336
|
+
*
|
|
337
|
+
* **client:**
|
|
338
|
+
* `authClient.subscription.upgrade`
|
|
339
|
+
*
|
|
340
|
+
* @see [Read our docs to learn more.](https://faire-auth.com/docs/plugins/stripe#api-method-subscription-upgrade)
|
|
341
|
+
*/
|
|
342
|
+
upgradeSubscription: (0, faire_auth_plugins.createEndpoint)((0, _faire_auth_core_factory.createRoute)({
|
|
336
343
|
operationId: "upgradeSubscription",
|
|
337
344
|
method: "post",
|
|
338
345
|
path: "/subscription/upgrade",
|
|
@@ -344,33 +351,68 @@ const stripe$1 = (options) => {
|
|
|
344
351
|
}),
|
|
345
352
|
referenceMiddleware("upgrade-subscription")
|
|
346
353
|
],
|
|
347
|
-
request: (0,
|
|
354
|
+
request: (0, _faire_auth_core_factory.req)().bdy(zod.object({
|
|
355
|
+
/**
|
|
356
|
+
* The name of the plan to subscribe
|
|
357
|
+
*/
|
|
348
358
|
plan: zod.string().meta({ description: "The name of the plan to upgrade to. Eg: \"pro\"" }),
|
|
359
|
+
/**
|
|
360
|
+
* If annual plan should be applied.
|
|
361
|
+
*/
|
|
349
362
|
annual: zod.boolean().meta({ description: "Whether to upgrade to an annual plan. Eg: true" }).optional(),
|
|
363
|
+
/**
|
|
364
|
+
* Reference id of the subscription to upgrade
|
|
365
|
+
* This is used to identify the subscription to upgrade
|
|
366
|
+
* If not provided, the user's id will be used
|
|
367
|
+
*/
|
|
350
368
|
referenceId: zod.string().meta({ description: "Reference id of the subscription to upgrade. Eg: \"123\"" }).optional(),
|
|
369
|
+
/**
|
|
370
|
+
* This is to allow a specific subscription to be upgrade.
|
|
371
|
+
* If subscription id is provided, and subscription isn't found,
|
|
372
|
+
* it'll throw an error.
|
|
373
|
+
*/
|
|
351
374
|
subscriptionId: zod.string().meta({ description: "The id of the subscription to upgrade. Eg: \"sub_123\"" }).optional(),
|
|
375
|
+
/**
|
|
376
|
+
* Any additional data you want to store in your database
|
|
377
|
+
* subscriptions
|
|
378
|
+
*/
|
|
352
379
|
metadata: zod.record(zod.string(), zod.any()).optional(),
|
|
380
|
+
/**
|
|
381
|
+
* If a subscription
|
|
382
|
+
*/
|
|
353
383
|
seats: zod.number().meta({ description: "Number of seats to upgrade to (if applicable). Eg: 1" }).optional(),
|
|
384
|
+
/**
|
|
385
|
+
* Success URL to redirect back after successful subscription
|
|
386
|
+
*/
|
|
354
387
|
successUrl: zod.string().meta({ description: "Callback URL to redirect back after successful subscription. Eg: \"https://example.com/success\"" }).default("/"),
|
|
388
|
+
/**
|
|
389
|
+
* Cancel URL
|
|
390
|
+
*/
|
|
355
391
|
cancelUrl: zod.string().meta({ description: "If set, checkout shows a back button and customers will be directed here if they cancel payment. Eg: \"https://example.com/pricing\"" }).default("/"),
|
|
392
|
+
/**
|
|
393
|
+
* Return URL
|
|
394
|
+
*/
|
|
356
395
|
returnUrl: zod.string().meta({ description: "URL to take customers to when they click on the billing portal’s link to return to your website. Eg: \"https://example.com/dashboard\"" }).optional(),
|
|
396
|
+
/**
|
|
397
|
+
* Disable Redirect
|
|
398
|
+
*/
|
|
357
399
|
disableRedirect: zod.boolean().meta({ description: "Disable redirect after successful subscription. Eg: true" }).default(false)
|
|
358
400
|
})).bld(),
|
|
359
|
-
responses: (0,
|
|
401
|
+
responses: (0, _faire_auth_core_factory.res)(zod.intersection(_faire_auth_core_factory.redirectUrlSchema, zod.record(zod.string(), zod.any()))).err(400).err(401).err(500).bld()
|
|
360
402
|
}), (authOptions) => async (ctx) => {
|
|
361
403
|
if (!options.subscription?.enabled) {
|
|
362
404
|
faire_auth.logger.error(`Subscription actions are not enabled in your stripe plugin config.`);
|
|
363
|
-
return ctx.json({ success:
|
|
405
|
+
return ctx.json({ success: _faire_auth_core_static.False }, 400);
|
|
364
406
|
}
|
|
365
|
-
const { user
|
|
366
|
-
if (!user
|
|
367
|
-
success:
|
|
407
|
+
const { user, session } = ctx.get("session");
|
|
408
|
+
if (!user.emailVerified && options.subscription?.enabled && options.subscription.requireEmailVerification) return ctx.json({
|
|
409
|
+
success: _faire_auth_core_static.False,
|
|
368
410
|
message: STRIPE_ERROR_CODES.EMAIL_VERIFICATION_REQUIRED
|
|
369
411
|
}, 400);
|
|
370
|
-
const { referenceId = user
|
|
412
|
+
const { referenceId = user.id, plan: requestPlan, subscriptionId, metadata, seats, returnUrl, cancelUrl, disableRedirect, successUrl, annual } = ctx.req.valid("json");
|
|
371
413
|
const plan = await getPlanByName(options, requestPlan);
|
|
372
414
|
if (!plan) return ctx.json({
|
|
373
|
-
success:
|
|
415
|
+
success: _faire_auth_core_static.False,
|
|
374
416
|
message: STRIPE_ERROR_CODES.SUBSCRIPTION_PLAN_NOT_FOUND
|
|
375
417
|
}, 400);
|
|
376
418
|
const subscriptionToUpdate = subscriptionId ? await ctx.get("context").adapter.findOne({
|
|
@@ -392,21 +434,21 @@ const stripe$1 = (options) => {
|
|
|
392
434
|
}]
|
|
393
435
|
}) : null;
|
|
394
436
|
if (subscriptionId && !subscriptionToUpdate) return ctx.json({
|
|
395
|
-
success:
|
|
437
|
+
success: _faire_auth_core_static.False,
|
|
396
438
|
message: STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND
|
|
397
439
|
}, 400);
|
|
398
|
-
let customerId = subscriptionToUpdate?.stripeCustomerId || user
|
|
440
|
+
let customerId = subscriptionToUpdate?.stripeCustomerId || user.stripeCustomerId;
|
|
399
441
|
if (!customerId) try {
|
|
400
442
|
let stripeCustomer = (await client.customers.list({
|
|
401
|
-
email: user
|
|
443
|
+
email: user.email,
|
|
402
444
|
limit: 1
|
|
403
445
|
})).data[0];
|
|
404
446
|
if (!stripeCustomer) stripeCustomer = await client.customers.create({
|
|
405
|
-
email: user
|
|
406
|
-
...user
|
|
447
|
+
email: user.email,
|
|
448
|
+
...user.name && { name: user.name },
|
|
407
449
|
metadata: {
|
|
408
450
|
...metadata,
|
|
409
|
-
userId: user
|
|
451
|
+
userId: user.id
|
|
410
452
|
}
|
|
411
453
|
});
|
|
412
454
|
await ctx.get("context").adapter.update({
|
|
@@ -414,33 +456,33 @@ const stripe$1 = (options) => {
|
|
|
414
456
|
update: { stripeCustomerId: stripeCustomer.id },
|
|
415
457
|
where: [{
|
|
416
458
|
field: "id",
|
|
417
|
-
value: user
|
|
459
|
+
value: user.id
|
|
418
460
|
}]
|
|
419
461
|
});
|
|
420
462
|
customerId = stripeCustomer.id;
|
|
421
463
|
} catch (e) {
|
|
422
464
|
ctx.get("context").logger.error(e);
|
|
423
465
|
return ctx.json({
|
|
424
|
-
success:
|
|
466
|
+
success: _faire_auth_core_static.False,
|
|
425
467
|
message: STRIPE_ERROR_CODES.UNABLE_TO_CREATE_CUSTOMER
|
|
426
468
|
}, 400);
|
|
427
469
|
}
|
|
428
|
-
const activeSubscription = (await client.subscriptions.list({ customer: customerId }).then((res
|
|
429
|
-
const subscriptions
|
|
470
|
+
const activeSubscription = (await client.subscriptions.list({ customer: customerId }).then((res) => res.data.filter((sub) => sub.status === "active" || sub.status === "trialing"))).find((sub) => subscriptionToUpdate?.stripeSubscriptionId || subscriptionId ? sub.id === subscriptionToUpdate?.stripeSubscriptionId || sub.id === subscriptionId : false);
|
|
471
|
+
const subscriptions = subscriptionToUpdate ? [subscriptionToUpdate] : await ctx.get("context").adapter.findMany({
|
|
430
472
|
model: "subscription",
|
|
431
473
|
where: [{
|
|
432
474
|
field: "referenceId",
|
|
433
|
-
value: referenceId || user
|
|
475
|
+
value: referenceId || user.id
|
|
434
476
|
}]
|
|
435
477
|
});
|
|
436
|
-
const activeOrTrialingSubscription = subscriptions
|
|
437
|
-
const incompleteSubscription = subscriptions
|
|
478
|
+
const activeOrTrialingSubscription = subscriptions.find((sub) => sub.status === "active" || sub.status === "trialing");
|
|
479
|
+
const incompleteSubscription = subscriptions.find((sub) => sub.status === "incomplete");
|
|
438
480
|
if (activeOrTrialingSubscription && activeOrTrialingSubscription.status === "active" && activeOrTrialingSubscription.plan === requestPlan && activeOrTrialingSubscription.seats === (seats || 1)) return ctx.json({
|
|
439
|
-
success:
|
|
481
|
+
success: _faire_auth_core_static.False,
|
|
440
482
|
message: STRIPE_ERROR_CODES.ALREADY_SUBSCRIBED_PLAN
|
|
441
483
|
}, 400);
|
|
442
484
|
if (activeSubscription && customerId) {
|
|
443
|
-
const res
|
|
485
|
+
const res = await client.billingPortal.sessions.create({
|
|
444
486
|
customer: customerId,
|
|
445
487
|
return_url: getUrl(authOptions, returnUrl || "/"),
|
|
446
488
|
flow_data: {
|
|
@@ -459,14 +501,14 @@ const stripe$1 = (options) => {
|
|
|
459
501
|
}
|
|
460
502
|
}
|
|
461
503
|
}).catch(async (e) => ctx.json({
|
|
462
|
-
success:
|
|
504
|
+
success: _faire_auth_core_static.False,
|
|
463
505
|
message: e.message,
|
|
464
506
|
code: e.code
|
|
465
507
|
}, 400));
|
|
466
|
-
if (res
|
|
508
|
+
if (res instanceof Response) return res;
|
|
467
509
|
return ctx.json({
|
|
468
|
-
url: res
|
|
469
|
-
redirect:
|
|
510
|
+
url: res.url,
|
|
511
|
+
redirect: _faire_auth_core_static.True
|
|
470
512
|
}, 200);
|
|
471
513
|
}
|
|
472
514
|
let subscription = activeOrTrialingSubscription || incompleteSubscription;
|
|
@@ -494,15 +536,15 @@ const stripe$1 = (options) => {
|
|
|
494
536
|
});
|
|
495
537
|
if (!subscription) {
|
|
496
538
|
ctx.get("context").logger.error("Subscription ID not found");
|
|
497
|
-
return ctx.json({ success:
|
|
539
|
+
return ctx.json({ success: _faire_auth_core_static.False }, 500);
|
|
498
540
|
}
|
|
499
541
|
const params = await options.subscription?.getCheckoutSessionParams?.({
|
|
500
|
-
user
|
|
542
|
+
user,
|
|
501
543
|
session,
|
|
502
544
|
plan,
|
|
503
545
|
subscription
|
|
504
546
|
}, ctx);
|
|
505
|
-
const freeTrial = !subscriptions
|
|
547
|
+
const freeTrial = !subscriptions.some((s) => {
|
|
506
548
|
return !!(s.trialStart || s.trialEnd) || s.status === "trialing";
|
|
507
549
|
}) && plan.freeTrial ? { trial_period_days: plan.freeTrial.days } : void 0;
|
|
508
550
|
let priceIdToUse = void 0;
|
|
@@ -520,7 +562,7 @@ const stripe$1 = (options) => {
|
|
|
520
562
|
name: "auto",
|
|
521
563
|
address: "auto"
|
|
522
564
|
}
|
|
523
|
-
} : { customer_email: user
|
|
565
|
+
} : { customer_email: user.email },
|
|
524
566
|
success_url: getUrl(authOptions, `${ctx.get("context").baseURL}/subscription/success?callbackURL=${encodeURIComponent(successUrl)}&subscriptionId=${encodeURIComponent(subscription.id)}`),
|
|
525
567
|
cancel_url: getUrl(authOptions, cancelUrl),
|
|
526
568
|
line_items: [{
|
|
@@ -532,13 +574,13 @@ const stripe$1 = (options) => {
|
|
|
532
574
|
client_reference_id: referenceId,
|
|
533
575
|
...params?.params,
|
|
534
576
|
metadata: {
|
|
535
|
-
userId: user
|
|
577
|
+
userId: user.id,
|
|
536
578
|
subscriptionId: subscription.id,
|
|
537
579
|
referenceId,
|
|
538
580
|
...params?.params?.metadata
|
|
539
581
|
}
|
|
540
582
|
}, params?.options).catch(async (e) => ctx.json({
|
|
541
|
-
success:
|
|
583
|
+
success: _faire_auth_core_static.False,
|
|
542
584
|
message: e.message,
|
|
543
585
|
code: e.code
|
|
544
586
|
}, 400));
|
|
@@ -548,20 +590,20 @@ const stripe$1 = (options) => {
|
|
|
548
590
|
redirect: !disableRedirect
|
|
549
591
|
}, 200);
|
|
550
592
|
}),
|
|
551
|
-
cancelSubscriptionCallback: (0, faire_auth_plugins.createEndpoint)((0,
|
|
593
|
+
cancelSubscriptionCallback: (0, faire_auth_plugins.createEndpoint)((0, _faire_auth_core_factory.createRoute)({
|
|
552
594
|
operationId: "cancelSubscriptionCallback",
|
|
553
595
|
method: "get",
|
|
554
596
|
path: "/subscription/cancel/callback",
|
|
555
597
|
middleware: [(0, faire_auth_middleware.originCheck)((ctx) => ctx.req.query("callbackURL"))],
|
|
556
|
-
request: (0,
|
|
557
|
-
callbackURL: (0,
|
|
598
|
+
request: (0, _faire_auth_core_factory.req)().qry(zod.object({
|
|
599
|
+
callbackURL: (0, _faire_auth_core_factory.callbackURLSchema)(true),
|
|
558
600
|
subscriptionId: zod.string().optional()
|
|
559
601
|
})).bld(),
|
|
560
|
-
responses: (0,
|
|
602
|
+
responses: (0, _faire_auth_core_factory.res)().rdr().bld()
|
|
561
603
|
}), (authOptions) => async (ctx) => {
|
|
562
604
|
if (!options.subscription?.enabled) {
|
|
563
605
|
faire_auth.logger.error(`Subscription actions are not enabled in your stripe plugin config.`);
|
|
564
|
-
return ctx.json({ success:
|
|
606
|
+
return ctx.json({ success: _faire_auth_core_static.False }, 400);
|
|
565
607
|
}
|
|
566
608
|
const { callbackURL, subscriptionId } = ctx.req.valid("query");
|
|
567
609
|
if (!callbackURL || !subscriptionId) return ctx.redirect(getUrl(authOptions, callbackURL || "/"), 302);
|
|
@@ -604,7 +646,22 @@ const stripe$1 = (options) => {
|
|
|
604
646
|
}
|
|
605
647
|
return ctx.redirect(getUrl(authOptions, callbackURL), 302);
|
|
606
648
|
}),
|
|
607
|
-
|
|
649
|
+
/**
|
|
650
|
+
* ### Endpoint
|
|
651
|
+
*
|
|
652
|
+
* POST `/subscription/cancel`
|
|
653
|
+
*
|
|
654
|
+
* ### API Methods
|
|
655
|
+
*
|
|
656
|
+
* **server:**
|
|
657
|
+
* `auth.api.cancelSubscription`
|
|
658
|
+
*
|
|
659
|
+
* **client:**
|
|
660
|
+
* `authClient.subscription.cancel`
|
|
661
|
+
*
|
|
662
|
+
* @see [Read our docs to learn more.](https://faire-auth.com/docs/plugins/stripe#api-method-subscription-cancel)
|
|
663
|
+
*/
|
|
664
|
+
cancelSubscription: (0, faire_auth_plugins.createEndpoint)((0, _faire_auth_core_factory.createRoute)({
|
|
608
665
|
operationId: "cancelSubscription",
|
|
609
666
|
method: "post",
|
|
610
667
|
path: "/subscription/cancel",
|
|
@@ -613,12 +670,12 @@ const stripe$1 = (options) => {
|
|
|
613
670
|
(0, faire_auth_middleware.originCheck)((ctx) => ctx.req.raw.clone().json().then((v) => v.returnUrl)),
|
|
614
671
|
referenceMiddleware("cancel-subscription")
|
|
615
672
|
],
|
|
616
|
-
request: (0,
|
|
673
|
+
request: (0, _faire_auth_core_factory.req)().bdy(zod.object({
|
|
617
674
|
referenceId: zod.string().meta({ description: "Reference id of the subscription to cancel. Eg: '123'" }).optional(),
|
|
618
675
|
subscriptionId: zod.string().meta({ description: "The id of the subscription to cancel. Eg: 'sub_123'" }).optional(),
|
|
619
676
|
returnUrl: zod.string().meta({ description: "URL to take customers to when they click on the billing portal’s link to return to your website. Eg: \"https://example.com/dashboard\"" })
|
|
620
677
|
})).bld(),
|
|
621
|
-
responses: (0,
|
|
678
|
+
responses: (0, _faire_auth_core_factory.res)(zod.object({
|
|
622
679
|
url: zod.string(),
|
|
623
680
|
redirect: zod.literal(true)
|
|
624
681
|
})).err(400).err(401).bld()
|
|
@@ -639,10 +696,10 @@ const stripe$1 = (options) => {
|
|
|
639
696
|
}]
|
|
640
697
|
}).then((subs) => subs.find((sub) => sub.status === "active" || sub.status === "trialing"));
|
|
641
698
|
if (!subscription || !subscription.stripeCustomerId) return ctx.json({
|
|
642
|
-
success:
|
|
699
|
+
success: _faire_auth_core_static.False,
|
|
643
700
|
message: STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND
|
|
644
701
|
}, 400);
|
|
645
|
-
const activeSubscriptions = await client.subscriptions.list({ customer: subscription.stripeCustomerId }).then((res
|
|
702
|
+
const activeSubscriptions = await client.subscriptions.list({ customer: subscription.stripeCustomerId }).then((res) => res.data.filter((sub) => sub.status === "active" || sub.status === "trialing"));
|
|
646
703
|
if (!activeSubscriptions.length) {
|
|
647
704
|
/**
|
|
648
705
|
* If the subscription is not found, we need to delete the subscription
|
|
@@ -656,16 +713,16 @@ const stripe$1 = (options) => {
|
|
|
656
713
|
}]
|
|
657
714
|
});
|
|
658
715
|
return ctx.json({
|
|
659
|
-
success:
|
|
716
|
+
success: _faire_auth_core_static.False,
|
|
660
717
|
message: STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND
|
|
661
718
|
}, 400);
|
|
662
719
|
}
|
|
663
720
|
const activeSubscription = activeSubscriptions.find((sub) => sub.id === subscription.stripeSubscriptionId);
|
|
664
721
|
if (!activeSubscription) return ctx.json({
|
|
665
|
-
success:
|
|
722
|
+
success: _faire_auth_core_static.False,
|
|
666
723
|
message: STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND
|
|
667
724
|
}, 400);
|
|
668
|
-
const res
|
|
725
|
+
const res = await client.billingPortal.sessions.create({
|
|
669
726
|
customer: subscription.stripeCustomerId,
|
|
670
727
|
return_url: getUrl(authOptions, `${ctx.get("context").baseURL}/subscription/cancel/callback?callbackURL=${encodeURIComponent(returnUrl || "/")}&subscriptionId=${encodeURIComponent(subscription.id)}`),
|
|
671
728
|
flow_data: {
|
|
@@ -688,27 +745,27 @@ const stripe$1 = (options) => {
|
|
|
688
745
|
});
|
|
689
746
|
}
|
|
690
747
|
return ctx.json({
|
|
691
|
-
success:
|
|
748
|
+
success: _faire_auth_core_static.False,
|
|
692
749
|
message: e.message,
|
|
693
750
|
code: e.code
|
|
694
751
|
}, 400);
|
|
695
752
|
});
|
|
696
|
-
if (res
|
|
753
|
+
if (res instanceof Response) return res;
|
|
697
754
|
return ctx.json({
|
|
698
|
-
url: res
|
|
699
|
-
redirect:
|
|
755
|
+
url: res.url,
|
|
756
|
+
redirect: _faire_auth_core_static.True
|
|
700
757
|
}, 200);
|
|
701
758
|
}),
|
|
702
|
-
restoreSubscription: (0, faire_auth_plugins.createEndpoint)((0,
|
|
759
|
+
restoreSubscription: (0, faire_auth_plugins.createEndpoint)((0, _faire_auth_core_factory.createRoute)({
|
|
703
760
|
operationId: "restoreSubscription",
|
|
704
761
|
method: "post",
|
|
705
762
|
path: "/subscription/restore",
|
|
706
763
|
middleware: [(0, faire_auth_middleware.sessionMiddleware)(), referenceMiddleware("restore-subscription")],
|
|
707
|
-
request: (0,
|
|
764
|
+
request: (0, _faire_auth_core_factory.req)().bdy(zod.object({
|
|
708
765
|
referenceId: zod.string().meta({ description: "Reference id of the subscription to restore. Eg: '123'" }).optional(),
|
|
709
766
|
subscriptionId: zod.string().meta({ description: "The id of the subscription to restore. Eg: 'sub_123'" }).optional()
|
|
710
767
|
})).bld(),
|
|
711
|
-
responses: (0,
|
|
768
|
+
responses: (0, _faire_auth_core_factory.res)(zod.looseObject({})).err(400).err(401).bld()
|
|
712
769
|
}), (authOptions) => async (ctx) => {
|
|
713
770
|
const session = ctx.get("session");
|
|
714
771
|
const { referenceId = session.user.id, subscriptionId } = ctx.req.valid("json");
|
|
@@ -726,20 +783,20 @@ const stripe$1 = (options) => {
|
|
|
726
783
|
}]
|
|
727
784
|
}).then((subs) => subs.find((sub) => sub.status === "active" || sub.status === "trialing"));
|
|
728
785
|
if (!subscription || !subscription.stripeCustomerId) return ctx.json({
|
|
729
|
-
success:
|
|
786
|
+
success: _faire_auth_core_static.False,
|
|
730
787
|
message: STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND
|
|
731
788
|
}, 400);
|
|
732
789
|
if (subscription.status != "active" && subscription.status != "trialing") return ctx.json({
|
|
733
|
-
success:
|
|
790
|
+
success: _faire_auth_core_static.False,
|
|
734
791
|
message: STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_ACTIVE
|
|
735
792
|
}, 400);
|
|
736
793
|
if (!subscription.cancelAtPeriodEnd) return ctx.json({
|
|
737
|
-
success:
|
|
794
|
+
success: _faire_auth_core_static.False,
|
|
738
795
|
message: STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_SCHEDULED_FOR_CANCELLATION
|
|
739
796
|
}, 400);
|
|
740
|
-
const activeSubscription = await client.subscriptions.list({ customer: subscription.stripeCustomerId }).then((res
|
|
797
|
+
const activeSubscription = await client.subscriptions.list({ customer: subscription.stripeCustomerId }).then((res) => res.data.filter((sub) => sub.status === "active" || sub.status === "trialing")[0]);
|
|
741
798
|
if (!activeSubscription) return ctx.json({
|
|
742
|
-
success:
|
|
799
|
+
success: _faire_auth_core_static.False,
|
|
743
800
|
message: STRIPE_ERROR_CODES.SUBSCRIPTION_NOT_FOUND
|
|
744
801
|
}, 400);
|
|
745
802
|
try {
|
|
@@ -759,36 +816,51 @@ const stripe$1 = (options) => {
|
|
|
759
816
|
} catch (error) {
|
|
760
817
|
ctx.get("context").logger.error("Error restoring subscription", error);
|
|
761
818
|
return ctx.json({
|
|
762
|
-
success:
|
|
819
|
+
success: _faire_auth_core_static.False,
|
|
763
820
|
message: STRIPE_ERROR_CODES.UNABLE_TO_CREATE_CUSTOMER
|
|
764
821
|
}, 400);
|
|
765
822
|
}
|
|
766
823
|
}),
|
|
767
|
-
|
|
824
|
+
/**
|
|
825
|
+
* ### Endpoint
|
|
826
|
+
*
|
|
827
|
+
* GET `/subscription/list`
|
|
828
|
+
*
|
|
829
|
+
* ### API Methods
|
|
830
|
+
*
|
|
831
|
+
* **server:**
|
|
832
|
+
* `auth.api.listActiveSubscriptions`
|
|
833
|
+
*
|
|
834
|
+
* **client:**
|
|
835
|
+
* `authClient.subscription.list`
|
|
836
|
+
*
|
|
837
|
+
* @see [Read our docs to learn more.](https://faire-auth.com/docs/plugins/stripe#api-method-subscription-list)
|
|
838
|
+
*/
|
|
839
|
+
listActiveSubscriptions: (0, faire_auth_plugins.createEndpoint)((0, _faire_auth_core_factory.createRoute)({
|
|
768
840
|
operationId: "listActiveSubscriptions",
|
|
769
841
|
method: "get",
|
|
770
842
|
path: "/subscription/list",
|
|
771
843
|
middleware: [(0, faire_auth_middleware.sessionMiddleware)(), referenceMiddleware("list-subscription")],
|
|
772
|
-
request: (0,
|
|
773
|
-
responses: (0,
|
|
844
|
+
request: (0, _faire_auth_core_factory.req)().qry(zod.object({ referenceId: zod.string().meta({ description: "Reference id of the subscription to list. Eg: '123'" }).optional() })).bld(),
|
|
845
|
+
responses: (0, _faire_auth_core_factory.res)(zod.array(zod.looseObject({}))).err(400).err(401).bld()
|
|
774
846
|
}), (_authOptions) => async (ctx) => {
|
|
775
847
|
if (!options.subscription?.enabled) {
|
|
776
848
|
faire_auth.logger.error(`Subscription actions are not enabled in your stripe plugin config.`);
|
|
777
|
-
return ctx.json({ success:
|
|
849
|
+
return ctx.json({ success: _faire_auth_core_static.False }, 400);
|
|
778
850
|
}
|
|
779
851
|
const session = ctx.get("session");
|
|
780
852
|
const { referenceId = session.user.id } = ctx.req.valid("query");
|
|
781
|
-
const subscriptions
|
|
853
|
+
const subscriptions = await ctx.get("context").adapter.findMany({
|
|
782
854
|
model: "subscription",
|
|
783
855
|
where: [{
|
|
784
856
|
field: "referenceId",
|
|
785
857
|
value: referenceId
|
|
786
858
|
}]
|
|
787
859
|
});
|
|
788
|
-
if (!subscriptions
|
|
860
|
+
if (!subscriptions.length) return ctx.json([], 200);
|
|
789
861
|
const plans = await getPlans(options.subscription);
|
|
790
862
|
if (!plans) return ctx.json([], 200);
|
|
791
|
-
const subs = subscriptions
|
|
863
|
+
const subs = subscriptions.map((sub) => {
|
|
792
864
|
const plan = plans.find((p) => p.name.toLowerCase() === sub.plan.toLowerCase());
|
|
793
865
|
return {
|
|
794
866
|
...sub,
|
|
@@ -798,16 +870,16 @@ const stripe$1 = (options) => {
|
|
|
798
870
|
}).filter((sub) => sub.status === "active" || sub.status === "trialing");
|
|
799
871
|
return ctx.json(subs, 200);
|
|
800
872
|
}),
|
|
801
|
-
subscriptionSuccess: (0, faire_auth_plugins.createEndpoint)((0,
|
|
873
|
+
subscriptionSuccess: (0, faire_auth_plugins.createEndpoint)((0, _faire_auth_core_factory.createRoute)({
|
|
802
874
|
operationId: "subscriptionSuccess",
|
|
803
875
|
method: "get",
|
|
804
876
|
path: "/subscription/success",
|
|
805
877
|
middleware: [(0, faire_auth_middleware.originCheck)((ctx) => ctx.req.query("callbackURL"))],
|
|
806
|
-
request: (0,
|
|
807
|
-
callbackURL: (0,
|
|
878
|
+
request: (0, _faire_auth_core_factory.req)().qry(zod.object({
|
|
879
|
+
callbackURL: (0, _faire_auth_core_factory.callbackURLSchema)(true),
|
|
808
880
|
subscriptionId: zod.string().optional()
|
|
809
881
|
})).bld(),
|
|
810
|
-
responses: (0,
|
|
882
|
+
responses: (0, _faire_auth_core_factory.res)().rdr().bld()
|
|
811
883
|
}), (authOptions) => async (ctx) => {
|
|
812
884
|
const { callbackURL, subscriptionId } = ctx.req.valid("query");
|
|
813
885
|
if (!callbackURL || !subscriptionId) return ctx.redirect(getUrl(authOptions, callbackURL || "/"), 302);
|
|
@@ -826,7 +898,7 @@ const stripe$1 = (options) => {
|
|
|
826
898
|
const stripeSubscription = await client.subscriptions.list({
|
|
827
899
|
customer: customerId,
|
|
828
900
|
status: "active"
|
|
829
|
-
}).then((res
|
|
901
|
+
}).then((res) => res.data[0]);
|
|
830
902
|
if (stripeSubscription) {
|
|
831
903
|
const firstItem = stripeSubscription.items.data[0];
|
|
832
904
|
if (firstItem) {
|
|
@@ -857,7 +929,7 @@ const stripe$1 = (options) => {
|
|
|
857
929
|
}
|
|
858
930
|
return ctx.redirect(getUrl(authOptions, callbackURL), 302);
|
|
859
931
|
}),
|
|
860
|
-
createBillingPortal: (0, faire_auth_plugins.createEndpoint)((0,
|
|
932
|
+
createBillingPortal: (0, faire_auth_plugins.createEndpoint)((0, _faire_auth_core_factory.createRoute)({
|
|
861
933
|
operationId: "createBillingPortal",
|
|
862
934
|
method: "post",
|
|
863
935
|
path: "/subscription/billing-portal",
|
|
@@ -866,14 +938,14 @@ const stripe$1 = (options) => {
|
|
|
866
938
|
(0, faire_auth_middleware.originCheck)((ctx) => ctx.req.raw.clone().json().then((v) => v.returnUrl)),
|
|
867
939
|
referenceMiddleware("billing-portal")
|
|
868
940
|
],
|
|
869
|
-
request: (0,
|
|
941
|
+
request: (0, _faire_auth_core_factory.req)().bdy(zod.object({
|
|
870
942
|
locale: zod.custom((localization) => {
|
|
871
943
|
return typeof localization === "string";
|
|
872
944
|
}).optional(),
|
|
873
945
|
referenceId: zod.string().optional(),
|
|
874
946
|
returnUrl: zod.string().default("/")
|
|
875
947
|
})).bld(),
|
|
876
|
-
responses: (0,
|
|
948
|
+
responses: (0, _faire_auth_core_factory.res)(zod.object({
|
|
877
949
|
url: zod.string(),
|
|
878
950
|
redirect: zod.literal(true)
|
|
879
951
|
})).err(400).err(401).bld()
|
|
@@ -889,7 +961,7 @@ const stripe$1 = (options) => {
|
|
|
889
961
|
}]
|
|
890
962
|
}).then((subs) => subs.find((sub) => sub.status === "active" || sub.status === "trialing")))?.stripeCustomerId;
|
|
891
963
|
if (!customerId) return ctx.json({
|
|
892
|
-
success:
|
|
964
|
+
success: _faire_auth_core_static.False,
|
|
893
965
|
message: "No Stripe customer found for this user"
|
|
894
966
|
}, 400);
|
|
895
967
|
try {
|
|
@@ -900,12 +972,12 @@ const stripe$1 = (options) => {
|
|
|
900
972
|
});
|
|
901
973
|
return ctx.json({
|
|
902
974
|
url,
|
|
903
|
-
redirect:
|
|
975
|
+
redirect: _faire_auth_core_static.True
|
|
904
976
|
}, 200);
|
|
905
977
|
} catch (error) {
|
|
906
978
|
ctx.get("context").logger.error("Error creating billing portal session", error);
|
|
907
979
|
return ctx.json({
|
|
908
|
-
success:
|
|
980
|
+
success: _faire_auth_core_static.False,
|
|
909
981
|
message: error.message
|
|
910
982
|
}, 400);
|
|
911
983
|
}
|
|
@@ -914,28 +986,28 @@ const stripe$1 = (options) => {
|
|
|
914
986
|
return {
|
|
915
987
|
id: "stripe",
|
|
916
988
|
routes: {
|
|
917
|
-
stripeWebhook: (0, faire_auth_plugins.createEndpoint)((0,
|
|
989
|
+
stripeWebhook: (0, faire_auth_plugins.createEndpoint)((0, _faire_auth_core_factory.createRoute)({
|
|
918
990
|
operationId: "stripeWebhook",
|
|
919
991
|
method: "post",
|
|
920
992
|
path: "/stripe/webhook",
|
|
921
993
|
client: false,
|
|
922
|
-
responses: (0,
|
|
994
|
+
responses: (0, _faire_auth_core_factory.res)(zod.object({ success: zod.literal(true) })).err(400).err(500).bld()
|
|
923
995
|
}), (_authOptions) => async (ctx) => {
|
|
924
|
-
if (!ctx.req.raw?.body) return ctx.json({ success:
|
|
996
|
+
if (!ctx.req.raw?.body) return ctx.json({ success: _faire_auth_core_static.False }, 500);
|
|
925
997
|
const buf = await ctx.req.text();
|
|
926
998
|
const sig = ctx.req.header("stripe-signature");
|
|
927
999
|
const webhookSecret = options.stripeWebhookSecret;
|
|
928
1000
|
let event;
|
|
929
1001
|
try {
|
|
930
1002
|
if (!sig || !webhookSecret) return ctx.json({
|
|
931
|
-
success:
|
|
1003
|
+
success: _faire_auth_core_static.False,
|
|
932
1004
|
message: "Stripe webhook secret not found"
|
|
933
1005
|
}, 400);
|
|
934
1006
|
event = await client.webhooks.constructEventAsync(buf, sig, webhookSecret);
|
|
935
1007
|
} catch (err) {
|
|
936
1008
|
ctx.get("context").logger.error(`${err.message}`);
|
|
937
1009
|
return ctx.json({
|
|
938
|
-
success:
|
|
1010
|
+
success: _faire_auth_core_static.False,
|
|
939
1011
|
message: `Webhook Error: ${err.message}`
|
|
940
1012
|
}, 400);
|
|
941
1013
|
}
|
|
@@ -953,40 +1025,36 @@ const stripe$1 = (options) => {
|
|
|
953
1025
|
await onSubscriptionDeleted(ctx, options, event);
|
|
954
1026
|
await options.onEvent?.(event);
|
|
955
1027
|
break;
|
|
956
|
-
default:
|
|
957
|
-
await options.onEvent?.(event);
|
|
958
|
-
break;
|
|
1028
|
+
default: await options.onEvent?.(event);
|
|
959
1029
|
}
|
|
960
1030
|
} catch (e) {
|
|
961
1031
|
ctx.get("context").logger.error(`Stripe webhook failed. Error: ${e.message}`);
|
|
962
1032
|
return ctx.json({
|
|
963
|
-
success:
|
|
1033
|
+
success: _faire_auth_core_static.False,
|
|
964
1034
|
message: "Webhook error: See server logs for more information."
|
|
965
1035
|
}, 400);
|
|
966
1036
|
}
|
|
967
|
-
return ctx.json({ success:
|
|
1037
|
+
return ctx.json({ success: _faire_auth_core_static.True }, 200);
|
|
968
1038
|
}),
|
|
969
1039
|
...options.subscription?.enabled ? subscriptionEndpoints : {}
|
|
970
1040
|
},
|
|
971
1041
|
init(ctx) {
|
|
972
|
-
return { options: { databaseHooks: { user: { create: { async after(user
|
|
973
|
-
if (ctx
|
|
1042
|
+
return { options: { databaseHooks: { user: { create: { async after(user, ctx) {
|
|
1043
|
+
if (ctx && options.createCustomerOnSignUp) {
|
|
974
1044
|
const stripeCustomer = await client.customers.create({
|
|
975
|
-
email: user
|
|
976
|
-
...user
|
|
977
|
-
metadata: { userId: user
|
|
1045
|
+
email: user.email,
|
|
1046
|
+
...user.name && { name: user.name },
|
|
1047
|
+
metadata: { userId: user.id }
|
|
978
1048
|
});
|
|
979
|
-
if (!await ctx
|
|
1049
|
+
if (!await ctx.get("context").internalAdapter.updateUser(user.id, { stripeCustomerId: stripeCustomer.id })) faire_auth.logger.error("#FAIRE_AUTH: Failed to create customer");
|
|
980
1050
|
else if (options.onCustomerCreate) await options.onCustomerCreate({
|
|
981
1051
|
stripeCustomer,
|
|
982
|
-
user
|
|
983
|
-
}, ctx
|
|
1052
|
+
user
|
|
1053
|
+
}, ctx);
|
|
984
1054
|
}
|
|
985
1055
|
} } } } } };
|
|
986
1056
|
},
|
|
987
1057
|
schema: getSchema(options)
|
|
988
1058
|
};
|
|
989
1059
|
};
|
|
990
|
-
|
|
991
|
-
//#endregion
|
|
992
|
-
exports.stripe = stripe$1;
|
|
1060
|
+
exports.stripe = stripe$1;
|