@intlayer/backend 3.2.2 → 3.3.3
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/cjs/controllers/stripe.controller.cjs +110 -5
- package/dist/cjs/controllers/stripe.controller.cjs.map +1 -1
- package/dist/cjs/index.cjs +9 -2
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/middlewares/request.middleware.cjs +0 -4
- package/dist/cjs/middlewares/request.middleware.cjs.map +1 -1
- package/dist/cjs/routes/stripe.routes.cjs +8 -2
- package/dist/cjs/routes/stripe.routes.cjs.map +1 -1
- package/dist/cjs/schemas/plans.schema.cjs +27 -5
- package/dist/cjs/schemas/plans.schema.cjs.map +1 -1
- package/dist/cjs/services/organization.service.cjs +5 -27
- package/dist/cjs/services/organization.service.cjs.map +1 -1
- package/dist/cjs/services/subscription.service.cjs +110 -116
- package/dist/cjs/services/subscription.service.cjs.map +1 -1
- package/dist/cjs/types/plan.types.cjs.map +1 -1
- package/dist/cjs/utils/errors/errorCodes.cjs +107 -3
- package/dist/cjs/utils/errors/errorCodes.cjs.map +1 -1
- package/dist/cjs/utils/plan.cjs +3 -3
- package/dist/cjs/utils/plan.cjs.map +1 -1
- package/dist/cjs/webhooks/stripe.webhook.cjs +102 -89
- package/dist/cjs/webhooks/stripe.webhook.cjs.map +1 -1
- package/dist/esm/controllers/stripe.controller.mjs +99 -5
- package/dist/esm/controllers/stripe.controller.mjs.map +1 -1
- package/dist/esm/index.mjs +10 -3
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/middlewares/request.middleware.mjs +0 -4
- package/dist/esm/middlewares/request.middleware.mjs.map +1 -1
- package/dist/esm/routes/stripe.routes.mjs +12 -3
- package/dist/esm/routes/stripe.routes.mjs.map +1 -1
- package/dist/esm/schemas/plans.schema.mjs +27 -5
- package/dist/esm/schemas/plans.schema.mjs.map +1 -1
- package/dist/esm/services/organization.service.mjs +5 -25
- package/dist/esm/services/organization.service.mjs.map +1 -1
- package/dist/esm/services/subscription.service.mjs +101 -120
- package/dist/esm/services/subscription.service.mjs.map +1 -1
- package/dist/esm/utils/errors/errorCodes.mjs +107 -3
- package/dist/esm/utils/errors/errorCodes.mjs.map +1 -1
- package/dist/esm/utils/plan.mjs +3 -3
- package/dist/esm/utils/plan.mjs.map +1 -1
- package/dist/esm/webhooks/stripe.webhook.mjs +103 -90
- package/dist/esm/webhooks/stripe.webhook.mjs.map +1 -1
- package/dist/types/controllers/stripe.controller.d.ts +14 -0
- package/dist/types/controllers/stripe.controller.d.ts.map +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/routes/stripe.routes.d.ts +6 -1
- package/dist/types/routes/stripe.routes.d.ts.map +1 -1
- package/dist/types/schemas/plans.schema.d.ts.map +1 -1
- package/dist/types/services/organization.service.d.ts +1 -8
- package/dist/types/services/organization.service.d.ts.map +1 -1
- package/dist/types/services/subscription.service.d.ts +5 -21
- package/dist/types/services/subscription.service.d.ts.map +1 -1
- package/dist/types/types/plan.types.d.ts +2 -1
- package/dist/types/types/plan.types.d.ts.map +1 -1
- package/dist/types/utils/errors/errorCodes.d.ts +104 -0
- package/dist/types/utils/errors/errorCodes.d.ts.map +1 -1
- package/dist/types/webhooks/stripe.webhook.d.ts +7 -2
- package/dist/types/webhooks/stripe.webhook.d.ts.map +1 -1
- package/package.json +10 -10
|
@@ -1,177 +1,158 @@
|
|
|
1
1
|
import { logger } from './../logger/index.mjs';
|
|
2
2
|
import { GenericError } from './../utils/errors/index.mjs';
|
|
3
3
|
import { retrievePlanInformation } from './../utils/plan.mjs';
|
|
4
|
-
import
|
|
5
|
-
import { Stripe } from "stripe";
|
|
4
|
+
import Stripe from "stripe";
|
|
6
5
|
import { sendEmail } from './email.service.mjs';
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const addSubscription = async (priceId, customerId, email, locale = Locales.ENGLISH) => {
|
|
13
|
-
let user = await getUserByEmail(email);
|
|
14
|
-
const organization = await getOrganizationByCustomerId(customerId);
|
|
15
|
-
if (!organization) {
|
|
16
|
-
throw new GenericError("ORGANIZATION_NOT_FOUND", {
|
|
17
|
-
customerId
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
if (!user) {
|
|
21
|
-
user = await createUser({
|
|
22
|
-
email
|
|
23
|
-
});
|
|
24
|
-
}
|
|
6
|
+
import { getOrganizationById, updatePlan } from './organization.service.mjs';
|
|
7
|
+
import { getUserById } from './user.service.mjs';
|
|
8
|
+
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
|
|
9
|
+
const addOrUpdateSubscription = async (subscriptionId, priceId, customerId, userId, organization, status) => {
|
|
10
|
+
const user = await getUserById(userId);
|
|
25
11
|
if (!user) {
|
|
26
12
|
throw new GenericError("USER_NOT_FOUND", {
|
|
27
|
-
|
|
13
|
+
userId
|
|
28
14
|
});
|
|
29
15
|
}
|
|
30
16
|
if (user.customerId !== customerId) {
|
|
31
17
|
user.customerId = customerId;
|
|
32
18
|
await user.save();
|
|
33
19
|
}
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
status: "ACTIVE"
|
|
44
|
-
});
|
|
45
|
-
if (!editedOrganization2) {
|
|
46
|
-
throw new GenericError("ORGANIZATION_UPDATE_FAILED", {
|
|
47
|
-
organizationId: organization._id
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
logger.info(
|
|
51
|
-
`Updated plan for organization ${organization._id} - ${planType.type} - ${planType.period}`
|
|
20
|
+
const planInfo = retrievePlanInformation(priceId);
|
|
21
|
+
const subscriptions = await stripe.subscriptions.list({
|
|
22
|
+
customer: customerId,
|
|
23
|
+
status: "active",
|
|
24
|
+
limit: 1
|
|
25
|
+
});
|
|
26
|
+
if (subscriptions.data.length >= 1) {
|
|
27
|
+
const otherSubscriptionArray = subscriptions.data.filter(
|
|
28
|
+
(subscription) => subscription.id !== subscriptionId
|
|
52
29
|
);
|
|
53
|
-
|
|
30
|
+
for (const subscription of otherSubscriptionArray) {
|
|
31
|
+
await stripe.subscriptions.cancel(subscription.id);
|
|
32
|
+
}
|
|
54
33
|
}
|
|
55
|
-
const
|
|
34
|
+
const updatedOrganization = await updatePlan(organization, {
|
|
56
35
|
creatorId: user._id,
|
|
57
36
|
priceId,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
37
|
+
customerId,
|
|
38
|
+
subscriptionId,
|
|
39
|
+
type: planInfo.type,
|
|
40
|
+
period: planInfo.period,
|
|
41
|
+
status
|
|
61
42
|
});
|
|
62
|
-
if (!
|
|
43
|
+
if (!updatedOrganization) {
|
|
63
44
|
throw new GenericError("ORGANIZATION_UPDATE_FAILED", {
|
|
64
45
|
organizationId: organization._id
|
|
65
46
|
});
|
|
66
47
|
}
|
|
67
|
-
const { type } = retrievePlanInformation(priceId);
|
|
68
|
-
await sendEmail({
|
|
69
|
-
type: "subscriptionPaymentSuccess",
|
|
70
|
-
to: user.email,
|
|
71
|
-
username: user.name,
|
|
72
|
-
planName: type,
|
|
73
|
-
subscriptionStartDate: (/* @__PURE__ */ new Date()).toLocaleDateString(),
|
|
74
|
-
email,
|
|
75
|
-
manageSubscriptionLink: `${process.env.CLIENT_URL}/dashboard`,
|
|
76
|
-
locale
|
|
77
|
-
});
|
|
78
48
|
logger.info(
|
|
79
|
-
`
|
|
49
|
+
`Plan updated for organization ${organization._id} - ${planInfo.type} - ${planInfo.period}`
|
|
80
50
|
);
|
|
81
|
-
return
|
|
82
|
-
};
|
|
83
|
-
const getActiveSubscriptions = async (customerId) => {
|
|
84
|
-
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
|
|
85
|
-
const subscriptions = await stripe.subscriptions.list({
|
|
86
|
-
customer: customerId,
|
|
87
|
-
status: "active"
|
|
88
|
-
});
|
|
89
|
-
return subscriptions.data;
|
|
51
|
+
return updatedOrganization.plan;
|
|
90
52
|
};
|
|
91
|
-
const cancelSubscription = async (
|
|
92
|
-
const
|
|
93
|
-
const organization = await getOrganizationByCustomerId(customerId);
|
|
53
|
+
const cancelSubscription = async (subscriptionId, organizationId) => {
|
|
54
|
+
const organization = await getOrganizationById(organizationId);
|
|
94
55
|
if (!organization) {
|
|
95
56
|
throw new GenericError("ORGANIZATION_NOT_FOUND", {
|
|
96
|
-
|
|
57
|
+
subscriptionId
|
|
97
58
|
});
|
|
98
59
|
}
|
|
60
|
+
if (!subscriptionId) {
|
|
61
|
+
throw new GenericError("NO_SUBSCRIPTION_ID_PROVIDED");
|
|
62
|
+
}
|
|
99
63
|
if (!organization.plan) {
|
|
100
64
|
throw new GenericError("ORGANIZATION_PLAN_NOT_FOUND", {
|
|
101
|
-
|
|
65
|
+
subscriptionId,
|
|
66
|
+
organizationId: organization._id
|
|
102
67
|
});
|
|
103
68
|
}
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
69
|
+
const updatedOrganization = await updatePlan(organization, {
|
|
70
|
+
status: "canceled"
|
|
71
|
+
});
|
|
72
|
+
if (!updatedOrganization) {
|
|
73
|
+
throw new GenericError("ORGANIZATION_UPDATE_FAILED", {
|
|
74
|
+
organizationId: organization._id
|
|
75
|
+
});
|
|
107
76
|
}
|
|
108
77
|
logger.info(
|
|
109
|
-
`Cancelled plan for organization ${
|
|
78
|
+
`Cancelled plan for organization ${updatedOrganization._id} - ${updatedOrganization.plan.type} - ${updatedOrganization.plan.period}`
|
|
110
79
|
);
|
|
111
|
-
return
|
|
80
|
+
return updatedOrganization.plan;
|
|
112
81
|
};
|
|
113
|
-
const changeSubscriptionStatus = async (
|
|
114
|
-
const organization = await
|
|
82
|
+
const changeSubscriptionStatus = async (subscriptionId, status, userId, organizationId) => {
|
|
83
|
+
const organization = await getOrganizationById(organizationId);
|
|
115
84
|
if (!organization) {
|
|
116
85
|
throw new GenericError("ORGANIZATION_NOT_FOUND", {
|
|
117
|
-
|
|
86
|
+
userId,
|
|
87
|
+
subscriptionId
|
|
118
88
|
});
|
|
119
89
|
}
|
|
120
90
|
if (!organization.plan) {
|
|
121
91
|
throw new GenericError("ORGANIZATION_PLAN_NOT_FOUND", {
|
|
122
|
-
|
|
92
|
+
userId,
|
|
93
|
+
subscriptionId,
|
|
94
|
+
organizationId: organization._id
|
|
123
95
|
});
|
|
124
96
|
}
|
|
125
|
-
const
|
|
126
|
-
status
|
|
97
|
+
const updatedOrganization = await updatePlan(organization, {
|
|
98
|
+
status,
|
|
99
|
+
subscriptionId
|
|
127
100
|
});
|
|
128
|
-
if (!
|
|
101
|
+
if (!updatedOrganization) {
|
|
129
102
|
throw new GenericError("ORGANIZATION_UPDATE_FAILED", {
|
|
130
103
|
organizationId: organization._id
|
|
131
104
|
});
|
|
132
105
|
}
|
|
133
|
-
const user = await getUserById(
|
|
106
|
+
const user = await getUserById(userId);
|
|
107
|
+
if (!user) {
|
|
108
|
+
throw new GenericError("USER_NOT_FOUND", {
|
|
109
|
+
userId,
|
|
110
|
+
subscriptionId
|
|
111
|
+
});
|
|
112
|
+
}
|
|
134
113
|
logger.info(
|
|
135
|
-
`Updated plan for organization ${organization._id} -
|
|
114
|
+
`Updated plan status for organization ${organization._id} - Status: ${status}`
|
|
136
115
|
);
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
116
|
+
const emailData = {
|
|
117
|
+
to: user.email,
|
|
118
|
+
username: user.name,
|
|
119
|
+
email: user.email,
|
|
120
|
+
planName: organization.plan.type,
|
|
121
|
+
date: (/* @__PURE__ */ new Date()).toLocaleDateString(),
|
|
122
|
+
link: `${process.env.CLIENT_URL}/dashboard`
|
|
123
|
+
};
|
|
124
|
+
switch (status) {
|
|
125
|
+
case "active":
|
|
126
|
+
await sendEmail({
|
|
127
|
+
...emailData,
|
|
128
|
+
type: "subscriptionPaymentSuccess",
|
|
129
|
+
subscriptionStartDate: emailData.date,
|
|
130
|
+
manageSubscriptionLink: emailData.link
|
|
131
|
+
});
|
|
132
|
+
break;
|
|
133
|
+
case "canceled":
|
|
134
|
+
await sendEmail({
|
|
135
|
+
...emailData,
|
|
136
|
+
type: "subscriptionPaymentCancellation",
|
|
137
|
+
cancellationDate: emailData.date,
|
|
138
|
+
reactivateLink: emailData.link
|
|
139
|
+
});
|
|
140
|
+
break;
|
|
141
|
+
case "incomplete":
|
|
142
|
+
await sendEmail({
|
|
143
|
+
...emailData,
|
|
144
|
+
type: "subscriptionPaymentError",
|
|
145
|
+
errorDate: emailData.date,
|
|
146
|
+
retryPaymentLink: emailData.link
|
|
147
|
+
});
|
|
148
|
+
break;
|
|
149
|
+
default:
|
|
150
|
+
logger.warn(`Unhandled subscription status: ${status}`);
|
|
170
151
|
}
|
|
171
|
-
return
|
|
152
|
+
return updatedOrganization.plan;
|
|
172
153
|
};
|
|
173
154
|
export {
|
|
174
|
-
|
|
155
|
+
addOrUpdateSubscription,
|
|
175
156
|
cancelSubscription,
|
|
176
157
|
changeSubscriptionStatus
|
|
177
158
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/services/subscription.service.ts"],"sourcesContent":["import { logger } from '@logger';\nimport { GenericError } from '@utils/errors';\nimport { retrievePlanInformation } from '@utils/plan';\nimport { Locales } from 'intlayer';\nimport { Stripe } from 'stripe';\nimport { sendEmail } from './email.service';\nimport {\n getOrganizationByCustomerId,\n updatePlan,\n} from './organization.service';\nimport { getUserByEmail, createUser, getUserById } from './user.service';\nimport { Plan } from '@/types/plan.types';\n\n/**\n * Adds a subscription to an organization.\n * @param priceId - The ID of the price to add.\n * @param customerId - The ID of the customer to add.\n * @param email - The email of the user to add.\n * @param locale - The locale of the user to add.\n * @returns The added plan.\n */\nexport const addSubscription = async (\n priceId: string,\n customerId: string,\n email: string,\n locale: Locales = Locales.ENGLISH\n): Promise<Plan | null> => {\n let user = await getUserByEmail(email);\n const organization = await getOrganizationByCustomerId(customerId);\n\n if (!organization) {\n throw new GenericError('ORGANIZATION_NOT_FOUND', {\n customerId,\n });\n }\n\n if (!user) {\n user = await createUser({\n email,\n });\n }\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', {\n email,\n });\n }\n\n if (user.customerId !== customerId) {\n user.customerId = customerId as string;\n await user.save();\n }\n const planType = retrievePlanInformation(priceId!);\n\n if (organization.plan) {\n // Cancel the current plan\n await cancelSubscription(organization.plan.customerId!);\n\n const editedOrganization = await updatePlan(organization, {\n ...organization.plan,\n creatorId: user._id,\n priceId: priceId!,\n type: planType.type,\n period: planType.period,\n status: 'ACTIVE',\n });\n\n if (!editedOrganization) {\n throw new GenericError('ORGANIZATION_UPDATE_FAILED', {\n organizationId: organization._id,\n });\n }\n\n logger.info(\n `Updated plan for organization ${organization._id} - ${planType.type} - ${planType.period}`\n );\n\n return editedOrganization.plan;\n }\n\n const editedOrganization = await updatePlan(organization, {\n creatorId: user._id,\n priceId: priceId!,\n type: planType.type,\n period: planType.period,\n status: 'ACTIVE',\n });\n\n if (!editedOrganization) {\n throw new GenericError('ORGANIZATION_UPDATE_FAILED', {\n organizationId: organization._id,\n });\n }\n\n const { type } = retrievePlanInformation(priceId!);\n\n await sendEmail({\n type: 'subscriptionPaymentSuccess',\n to: user.email,\n username: user.name,\n planName: type,\n subscriptionStartDate: new Date().toLocaleDateString(),\n email,\n manageSubscriptionLink: `${process.env.CLIENT_URL}/dashboard`!,\n locale,\n });\n\n logger.info(\n `Created plan for organization ${organization._id} - ${planType.type} - ${planType.period}`\n );\n\n return editedOrganization.plan;\n};\n\n/* Function to retrieve active subscriptions for a customer\n * Returns an array of Stripe.Subscription objects\n */\nconst getActiveSubscriptions = async (\n customerId: string\n): Promise<Stripe.Subscription[]> => {\n const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);\n\n const subscriptions = await stripe.subscriptions.list({\n customer: customerId,\n status: 'active',\n });\n return subscriptions.data;\n};\n\nexport const cancelSubscription = async (customerId: string) => {\n const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);\n const organization = await getOrganizationByCustomerId(customerId);\n\n if (!organization) {\n throw new GenericError('ORGANIZATION_NOT_FOUND', {\n customerId,\n });\n }\n\n if (!organization.plan) {\n throw new GenericError('ORGANIZATION_PLAN_NOT_FOUND', {\n customerId,\n });\n }\n\n // Retrieve and cancel existing subscriptions\n const activeSubscriptions = await getActiveSubscriptions(customerId);\n for (const sub of activeSubscriptions) {\n await stripe.subscriptions.cancel(sub.id);\n }\n\n logger.info(\n `Cancelled plan for organization ${organization._id} - ${organization.plan.type} - ${organization.plan.period}`\n );\n\n return organization.plan;\n};\n\n/**\n * Changes the subscription status of an organization.\n *\n * @param customerId - The ID of the customer to change the subscription status for.\n * @param status - The new status of the subscription.\n * @param locale - The locale of the user to change the subscription status for.\n * @returns The updated plan.\n */\nexport const changeSubscriptionStatus = async (\n customerId: string,\n status: Plan['status'],\n locale: Locales = Locales.ENGLISH\n) => {\n const organization = await getOrganizationByCustomerId(customerId);\n\n if (!organization) {\n throw new GenericError('ORGANIZATION_NOT_FOUND', {\n customerId,\n });\n }\n\n if (!organization.plan) {\n throw new GenericError('ORGANIZATION_PLAN_NOT_FOUND', {\n customerId,\n });\n }\n\n const editedOrganization = await updatePlan(organization, {\n status,\n });\n\n if (!editedOrganization) {\n throw new GenericError('ORGANIZATION_UPDATE_FAILED', {\n organizationId: organization._id,\n });\n }\n\n const user = await getUserById(organization.plan.creatorId!);\n\n logger.info(\n `Updated plan for organization ${organization._id} - ${organization.plan.type} - ${organization.plan.period} - ${status}`\n );\n\n if (status === 'ACTIVE') {\n await sendEmail({\n type: 'subscriptionPaymentSuccess',\n to: user!.email,\n username: user!.name,\n email: user!.email,\n planName: organization.plan.type,\n subscriptionStartDate: new Date().toLocaleDateString(),\n manageSubscriptionLink: `${process.env.CLIENT_URL}/dashboard`!,\n locale,\n });\n } else if (status === 'CANCELLED') {\n await sendEmail({\n type: 'subscriptionPaymentCancellation',\n to: user!.email,\n username: user!.name,\n email: user!.email,\n planName: organization.plan.type,\n cancellationDate: new Date().toLocaleDateString(),\n reactivateLink: `${process.env.CLIENT_URL}/dashboard`!,\n locale,\n });\n } else if (status === 'ERROR') {\n await sendEmail({\n type: 'subscriptionPaymentError',\n to: user!.email,\n username: user!.name,\n email: user!.email,\n planName: organization.plan.type,\n errorDate: new Date().toLocaleDateString(),\n retryPaymentLink: `${process.env.CLIENT_URL}/dashboard`!,\n locale,\n });\n }\n\n return editedOrganization.plan;\n};\n"],"mappings":"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","names":["editedOrganization"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/services/subscription.service.ts"],"sourcesContent":["import { logger } from '@logger';\nimport { GenericError } from '@utils/errors';\nimport { retrievePlanInformation } from '@utils/plan';\nimport Stripe from 'stripe';\nimport { sendEmail } from './email.service';\nimport { getOrganizationById, updatePlan } from './organization.service';\nimport { getUserById } from './user.service';\nimport type { Organization } from '@/types/organization.types';\nimport type { Plan } from '@/types/plan.types';\n\nconst stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);\n\nexport const addOrUpdateSubscription = async (\n subscriptionId: string,\n priceId: string,\n customerId: string,\n userId: string,\n organization: Organization,\n status: Plan['status']\n): Promise<Plan | null> => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', {\n userId,\n });\n }\n\n if (user.customerId !== customerId) {\n user.customerId = customerId;\n await user.save();\n }\n\n const planInfo = retrievePlanInformation(priceId);\n\n const subscriptions = await stripe.subscriptions.list({\n customer: customerId,\n status: 'active',\n limit: 1,\n });\n\n if (subscriptions.data.length >= 1) {\n // Active subscription exists; update it to the new plan\n const otherSubscriptionArray = subscriptions.data.filter(\n (subscription) => subscription.id !== subscriptionId\n );\n\n for (const subscription of otherSubscriptionArray) {\n await stripe.subscriptions.cancel(subscription.id);\n }\n }\n\n const updatedOrganization = await updatePlan(organization, {\n creatorId: user._id,\n priceId,\n customerId,\n subscriptionId,\n type: planInfo.type,\n period: planInfo.period,\n status,\n });\n\n if (!updatedOrganization) {\n throw new GenericError('ORGANIZATION_UPDATE_FAILED', {\n organizationId: organization._id,\n });\n }\n\n logger.info(\n `Plan updated for organization ${organization._id} - ${planInfo.type} - ${planInfo.period}`\n );\n\n return updatedOrganization.plan;\n};\n\nexport const cancelSubscription = async (\n subscriptionId: string | Organization['_id'],\n organizationId: Organization['_id'] | string\n): Promise<Plan | null> => {\n const organization = await getOrganizationById(organizationId);\n\n if (!organization) {\n throw new GenericError('ORGANIZATION_NOT_FOUND', {\n subscriptionId,\n });\n }\n\n if (!subscriptionId) {\n throw new GenericError('NO_SUBSCRIPTION_ID_PROVIDED');\n }\n\n if (!organization.plan) {\n throw new GenericError('ORGANIZATION_PLAN_NOT_FOUND', {\n subscriptionId,\n organizationId: organization._id,\n });\n }\n\n const updatedOrganization = await updatePlan(organization, {\n status: 'canceled',\n });\n\n if (!updatedOrganization) {\n throw new GenericError('ORGANIZATION_UPDATE_FAILED', {\n organizationId: organization._id,\n });\n }\n\n logger.info(\n `Cancelled plan for organization ${updatedOrganization._id} - ${updatedOrganization.plan.type} - ${updatedOrganization.plan.period}`\n );\n\n return updatedOrganization.plan;\n};\n\nexport const changeSubscriptionStatus = async (\n subscriptionId: string,\n status: Plan['status'],\n userId: string,\n organizationId: string\n): Promise<Plan | null> => {\n const organization = await getOrganizationById(organizationId);\n\n if (!organization) {\n throw new GenericError('ORGANIZATION_NOT_FOUND', {\n userId,\n subscriptionId,\n });\n }\n\n if (!organization.plan) {\n throw new GenericError('ORGANIZATION_PLAN_NOT_FOUND', {\n userId,\n subscriptionId,\n organizationId: organization._id,\n });\n }\n\n const updatedOrganization = await updatePlan(organization, {\n status,\n subscriptionId,\n });\n\n if (!updatedOrganization) {\n throw new GenericError('ORGANIZATION_UPDATE_FAILED', {\n organizationId: organization._id,\n });\n }\n\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', {\n userId,\n subscriptionId,\n });\n }\n\n logger.info(\n `Updated plan status for organization ${organization._id} - Status: ${status}`\n );\n\n const emailData = {\n to: user.email,\n username: user.name,\n email: user.email,\n planName: organization.plan.type,\n date: new Date().toLocaleDateString(),\n link: `${process.env.CLIENT_URL}/dashboard`,\n };\n\n switch (status) {\n case 'active':\n await sendEmail({\n ...emailData,\n type: 'subscriptionPaymentSuccess',\n subscriptionStartDate: emailData.date,\n manageSubscriptionLink: emailData.link,\n });\n break;\n case 'canceled':\n await sendEmail({\n ...emailData,\n type: 'subscriptionPaymentCancellation',\n cancellationDate: emailData.date,\n reactivateLink: emailData.link,\n });\n break;\n case 'incomplete':\n await sendEmail({\n ...emailData,\n type: 'subscriptionPaymentError',\n errorDate: emailData.date,\n retryPaymentLink: emailData.link,\n });\n break;\n default:\n logger.warn(`Unhandled subscription status: ${status}`);\n }\n\n return updatedOrganization.plan;\n};\n"],"mappings":"AAAA,SAAS,cAAc;AACvB,SAAS,oBAAoB;AAC7B,SAAS,+BAA+B;AACxC,OAAO,YAAY;AACnB,SAAS,iBAAiB;AAC1B,SAAS,qBAAqB,kBAAkB;AAChD,SAAS,mBAAmB;AAI5B,MAAM,SAAS,IAAI,OAAO,QAAQ,IAAI,iBAAkB;AAEjD,MAAM,0BAA0B,OACrC,gBACA,SACA,YACA,QACA,cACA,WACyB;AACzB,QAAM,OAAO,MAAM,YAAY,MAAM;AAErC,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,aAAa,kBAAkB;AAAA,MACvC;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,KAAK,eAAe,YAAY;AAClC,SAAK,aAAa;AAClB,UAAM,KAAK,KAAK;AAAA,EAClB;AAEA,QAAM,WAAW,wBAAwB,OAAO;AAEhD,QAAM,gBAAgB,MAAM,OAAO,cAAc,KAAK;AAAA,IACpD,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,OAAO;AAAA,EACT,CAAC;AAED,MAAI,cAAc,KAAK,UAAU,GAAG;AAElC,UAAM,yBAAyB,cAAc,KAAK;AAAA,MAChD,CAAC,iBAAiB,aAAa,OAAO;AAAA,IACxC;AAEA,eAAW,gBAAgB,wBAAwB;AACjD,YAAM,OAAO,cAAc,OAAO,aAAa,EAAE;AAAA,IACnD;AAAA,EACF;AAEA,QAAM,sBAAsB,MAAM,WAAW,cAAc;AAAA,IACzD,WAAW,KAAK;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM,SAAS;AAAA,IACf,QAAQ,SAAS;AAAA,IACjB;AAAA,EACF,CAAC;AAED,MAAI,CAAC,qBAAqB;AACxB,UAAM,IAAI,aAAa,8BAA8B;AAAA,MACnD,gBAAgB,aAAa;AAAA,IAC/B,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,iCAAiC,aAAa,GAAG,MAAM,SAAS,IAAI,MAAM,SAAS,MAAM;AAAA,EAC3F;AAEA,SAAO,oBAAoB;AAC7B;AAEO,MAAM,qBAAqB,OAChC,gBACA,mBACyB;AACzB,QAAM,eAAe,MAAM,oBAAoB,cAAc;AAE7D,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI,aAAa,0BAA0B;AAAA,MAC/C;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,CAAC,gBAAgB;AACnB,UAAM,IAAI,aAAa,6BAA6B;AAAA,EACtD;AAEA,MAAI,CAAC,aAAa,MAAM;AACtB,UAAM,IAAI,aAAa,+BAA+B;AAAA,MACpD;AAAA,MACA,gBAAgB,aAAa;AAAA,IAC/B,CAAC;AAAA,EACH;AAEA,QAAM,sBAAsB,MAAM,WAAW,cAAc;AAAA,IACzD,QAAQ;AAAA,EACV,CAAC;AAED,MAAI,CAAC,qBAAqB;AACxB,UAAM,IAAI,aAAa,8BAA8B;AAAA,MACnD,gBAAgB,aAAa;AAAA,IAC/B,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,mCAAmC,oBAAoB,GAAG,MAAM,oBAAoB,KAAK,IAAI,MAAM,oBAAoB,KAAK,MAAM;AAAA,EACpI;AAEA,SAAO,oBAAoB;AAC7B;AAEO,MAAM,2BAA2B,OACtC,gBACA,QACA,QACA,mBACyB;AACzB,QAAM,eAAe,MAAM,oBAAoB,cAAc;AAE7D,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI,aAAa,0BAA0B;AAAA,MAC/C;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,CAAC,aAAa,MAAM;AACtB,UAAM,IAAI,aAAa,+BAA+B;AAAA,MACpD;AAAA,MACA;AAAA,MACA,gBAAgB,aAAa;AAAA,IAC/B,CAAC;AAAA,EACH;AAEA,QAAM,sBAAsB,MAAM,WAAW,cAAc;AAAA,IACzD;AAAA,IACA;AAAA,EACF,CAAC;AAED,MAAI,CAAC,qBAAqB;AACxB,UAAM,IAAI,aAAa,8BAA8B;AAAA,MACnD,gBAAgB,aAAa;AAAA,IAC/B,CAAC;AAAA,EACH;AAEA,QAAM,OAAO,MAAM,YAAY,MAAM;AAErC,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,aAAa,kBAAkB;AAAA,MACvC;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,wCAAwC,aAAa,GAAG,cAAc,MAAM;AAAA,EAC9E;AAEA,QAAM,YAAY;AAAA,IAChB,IAAI,KAAK;AAAA,IACT,UAAU,KAAK;AAAA,IACf,OAAO,KAAK;AAAA,IACZ,UAAU,aAAa,KAAK;AAAA,IAC5B,OAAM,oBAAI,KAAK,GAAE,mBAAmB;AAAA,IACpC,MAAM,GAAG,QAAQ,IAAI,UAAU;AAAA,EACjC;AAEA,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,YAAM,UAAU;AAAA,QACd,GAAG;AAAA,QACH,MAAM;AAAA,QACN,uBAAuB,UAAU;AAAA,QACjC,wBAAwB,UAAU;AAAA,MACpC,CAAC;AACD;AAAA,IACF,KAAK;AACH,YAAM,UAAU;AAAA,QACd,GAAG;AAAA,QACH,MAAM;AAAA,QACN,kBAAkB,UAAU;AAAA,QAC5B,gBAAgB,UAAU;AAAA,MAC5B,CAAC;AACD;AAAA,IACF,KAAK;AACH,YAAM,UAAU;AAAA,QACd,GAAG;AAAA,QACH,MAAM;AAAA,QACN,WAAW,UAAU;AAAA,QACrB,kBAAkB,UAAU;AAAA,MAC9B,CAAC;AACD;AAAA,IACF;AACE,aAAO,KAAK,kCAAkC,MAAM,EAAE;AAAA,EAC1D;AAEA,SAAO,oBAAoB;AAC7B;","names":[]}
|
|
@@ -234,6 +234,32 @@ const errorData = {
|
|
|
234
234
|
},
|
|
235
235
|
statusCode: HttpStatusCodes.NOT_FOUND_404
|
|
236
236
|
},
|
|
237
|
+
USER_NOT_ORGANIZATION_MEMBER: {
|
|
238
|
+
title: {
|
|
239
|
+
en: "User Not Organization Member",
|
|
240
|
+
fr: "Utilisateur non membre de l'organisation",
|
|
241
|
+
es: "Usuario no miembro de la organizaci\xF3n"
|
|
242
|
+
},
|
|
243
|
+
message: {
|
|
244
|
+
en: "The user is not a member of the organization.",
|
|
245
|
+
fr: "L'utilisateur n'est pas membre de l'organisation.",
|
|
246
|
+
es: "El usuario no es miembro de la organizaci\xF3n."
|
|
247
|
+
},
|
|
248
|
+
statusCode: HttpStatusCodes.FORBIDDEN_403
|
|
249
|
+
},
|
|
250
|
+
USER_NOT_ORGANIZATION_ADMIN: {
|
|
251
|
+
title: {
|
|
252
|
+
en: "User Not Organization Admin",
|
|
253
|
+
fr: "Utilisateur non administrateur de l'organisation",
|
|
254
|
+
es: "Usuario no administrador de la organizaci\xF3n"
|
|
255
|
+
},
|
|
256
|
+
message: {
|
|
257
|
+
en: "The user is not an admin of the organization.",
|
|
258
|
+
fr: "L'utilisateur n'est pas administrateur de l'organisation.",
|
|
259
|
+
es: "El usuario no es administrador de la organizaci\xF3n."
|
|
260
|
+
},
|
|
261
|
+
statusCode: HttpStatusCodes.FORBIDDEN_403
|
|
262
|
+
},
|
|
237
263
|
JWT_TOKEN_CREATION_FAILED_USER: {
|
|
238
264
|
title: {
|
|
239
265
|
en: "JWT Token Creation Failed",
|
|
@@ -293,9 +319,9 @@ const errorData = {
|
|
|
293
319
|
es: "Organizaci\xF3n no encontrada"
|
|
294
320
|
},
|
|
295
321
|
message: {
|
|
296
|
-
en: "Organization not found
|
|
297
|
-
fr: "Organisation non trouv\xE9e
|
|
298
|
-
es: "Organizaci\xF3n no encontrada
|
|
322
|
+
en: "Organization not found.",
|
|
323
|
+
fr: "Organisation non trouv\xE9e.",
|
|
324
|
+
es: "Organizaci\xF3n no encontrada."
|
|
299
325
|
},
|
|
300
326
|
statusCode: HttpStatusCodes.NOT_FOUND_404
|
|
301
327
|
},
|
|
@@ -1117,6 +1143,84 @@ const errorData = {
|
|
|
1117
1143
|
es: "La URL de devoluci\xF3n no es v\xE1lida."
|
|
1118
1144
|
},
|
|
1119
1145
|
statusCode: HttpStatusCodes.BAD_REQUEST_400
|
|
1146
|
+
},
|
|
1147
|
+
STRIPE_SUBSCRIPTION_NO_CUSTOMER: {
|
|
1148
|
+
title: {
|
|
1149
|
+
en: "No customer found",
|
|
1150
|
+
fr: "Aucun client trouv\xE9",
|
|
1151
|
+
es: "No se encontr\xF3 el cliente"
|
|
1152
|
+
},
|
|
1153
|
+
message: {
|
|
1154
|
+
en: "No customer found for the provided subscription.",
|
|
1155
|
+
fr: "Aucun client n'a \xE9t\xE9 trouv\xE9 pour l'abonnement fourni.",
|
|
1156
|
+
es: "No se encontr\xF3 ning\xFAn cliente para el suscripci\xF3n proporcionada."
|
|
1157
|
+
},
|
|
1158
|
+
statusCode: HttpStatusCodes.INTERNAL_SERVER_ERROR_500
|
|
1159
|
+
},
|
|
1160
|
+
NO_SUBSCRIPTION_ID_PROVIDED: {
|
|
1161
|
+
title: {
|
|
1162
|
+
en: "No subscription ID provided",
|
|
1163
|
+
fr: "Aucun ID d'abonnement fourni",
|
|
1164
|
+
es: "No se proporcion\xF3 ning\xFAn ID de suscripci\xF3n"
|
|
1165
|
+
},
|
|
1166
|
+
message: {
|
|
1167
|
+
en: "No subscription ID provided.",
|
|
1168
|
+
fr: "Aucun ID d'abonnement n'a \xE9t\xE9 fourni.",
|
|
1169
|
+
es: "No se proporcion\xF3 ning\xFAn ID de suscripci\xF3n."
|
|
1170
|
+
},
|
|
1171
|
+
statusCode: HttpStatusCodes.BAD_REQUEST_400
|
|
1172
|
+
},
|
|
1173
|
+
CANNOT_CANCEL_SUBSCRIPTION: {
|
|
1174
|
+
title: {
|
|
1175
|
+
en: "Cannot cancel subscription",
|
|
1176
|
+
fr: "Impossible d'annuler l'abonnement",
|
|
1177
|
+
es: "No se puede cancelar la suscripci\xF3n"
|
|
1178
|
+
},
|
|
1179
|
+
message: {
|
|
1180
|
+
en: "Cannot cancel subscription.",
|
|
1181
|
+
fr: "Impossible d'annuler l'abonnement.",
|
|
1182
|
+
es: "No se puede cancelar la suscripci\xF3n."
|
|
1183
|
+
},
|
|
1184
|
+
statusCode: HttpStatusCodes.INTERNAL_SERVER_ERROR_500
|
|
1185
|
+
},
|
|
1186
|
+
ALREADY_SUBSCRIBED: {
|
|
1187
|
+
title: {
|
|
1188
|
+
en: "Already Subscribed",
|
|
1189
|
+
fr: "D\xE9j\xE0 abonn\xE9",
|
|
1190
|
+
es: "Ya suscrito"
|
|
1191
|
+
},
|
|
1192
|
+
message: {
|
|
1193
|
+
en: "You are already subscribed to this plan.",
|
|
1194
|
+
fr: "Vous \xEAtes d\xE9j\xE0 abonn\xE9 \xE0 ce plan.",
|
|
1195
|
+
es: "Ya est\xE1s suscrito a este plan."
|
|
1196
|
+
},
|
|
1197
|
+
statusCode: HttpStatusCodes.BAD_REQUEST_400
|
|
1198
|
+
},
|
|
1199
|
+
SESSION_CREATION_FAILED: {
|
|
1200
|
+
title: {
|
|
1201
|
+
en: "Session Creation Failed",
|
|
1202
|
+
fr: "\xC9chec de la cr\xE9ation de la session",
|
|
1203
|
+
es: "Error al crear la sesi\xF3n"
|
|
1204
|
+
},
|
|
1205
|
+
message: {
|
|
1206
|
+
en: "Failed to create the specified session.",
|
|
1207
|
+
fr: "La cr\xE9ation de la session a \xE9chou\xE9.",
|
|
1208
|
+
es: "No se pudo crear la sesi\xF3n especificada."
|
|
1209
|
+
},
|
|
1210
|
+
statusCode: HttpStatusCodes.INTERNAL_SERVER_ERROR_500
|
|
1211
|
+
},
|
|
1212
|
+
SETUP_INTENT_CREATION_FAILED: {
|
|
1213
|
+
title: {
|
|
1214
|
+
en: "Setup Intent Creation Failed",
|
|
1215
|
+
fr: "\xC9chec de la cr\xE9ation de l'intention de configuration",
|
|
1216
|
+
es: "Error al crear la intenci\xF3n de configuraci\xF3n"
|
|
1217
|
+
},
|
|
1218
|
+
message: {
|
|
1219
|
+
en: "Failed to create the setup intent.",
|
|
1220
|
+
fr: "\xC9chec de la cr\xE9ation de l'intention de configuration.",
|
|
1221
|
+
es: "Error al crear la intenci\xF3n de configuraci\xF3n."
|
|
1222
|
+
},
|
|
1223
|
+
statusCode: HttpStatusCodes.INTERNAL_SERVER_ERROR_500
|
|
1120
1224
|
}
|
|
1121
1225
|
};
|
|
1122
1226
|
export {
|