sidekick-server-2 0.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/README.md +223 -0
- package/dist/ai/index.d.ts +2 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +2 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/perplexity-ai.d.ts +3 -0
- package/dist/ai/perplexity-ai.d.ts.map +1 -0
- package/dist/ai/perplexity-ai.js +28 -0
- package/dist/ai/perplexity-ai.js.map +1 -0
- package/dist/app-config.d.ts +13 -0
- package/dist/app-config.d.ts.map +1 -0
- package/dist/app-config.js +33 -0
- package/dist/app-config.js.map +1 -0
- package/dist/cors-config.d.ts +9 -0
- package/dist/cors-config.d.ts.map +1 -0
- package/dist/cors-config.js +24 -0
- package/dist/cors-config.js.map +1 -0
- package/dist/db-connection.d.ts +13 -0
- package/dist/db-connection.d.ts.map +1 -0
- package/dist/db-connection.js +22 -0
- package/dist/db-connection.js.map +1 -0
- package/dist/error-handler.d.ts +3 -0
- package/dist/error-handler.d.ts.map +1 -0
- package/dist/error-handler.js +15 -0
- package/dist/error-handler.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +87 -0
- package/dist/index.js.map +1 -0
- package/dist/local-cache.d.ts +14 -0
- package/dist/local-cache.d.ts.map +1 -0
- package/dist/local-cache.js +44 -0
- package/dist/local-cache.js.map +1 -0
- package/dist/r2-buckets/get-signed-url.d.ts +2 -0
- package/dist/r2-buckets/get-signed-url.d.ts.map +1 -0
- package/dist/r2-buckets/get-signed-url.js +22 -0
- package/dist/r2-buckets/get-signed-url.js.map +1 -0
- package/dist/r2-buckets/index.d.ts +3 -0
- package/dist/r2-buckets/index.d.ts.map +1 -0
- package/dist/r2-buckets/index.js +3 -0
- package/dist/r2-buckets/index.js.map +1 -0
- package/dist/r2-buckets/r2-client.d.ts +3 -0
- package/dist/r2-buckets/r2-client.d.ts.map +1 -0
- package/dist/r2-buckets/r2-client.js +18 -0
- package/dist/r2-buckets/r2-client.js.map +1 -0
- package/dist/r2-buckets/upload-r2.d.ts +11 -0
- package/dist/r2-buckets/upload-r2.d.ts.map +1 -0
- package/dist/r2-buckets/upload-r2.js +49 -0
- package/dist/r2-buckets/upload-r2.js.map +1 -0
- package/dist/routes/authentication/check-session.d.ts +4 -0
- package/dist/routes/authentication/check-session.d.ts.map +1 -0
- package/dist/routes/authentication/check-session.js +79 -0
- package/dist/routes/authentication/check-session.js.map +1 -0
- package/dist/routes/authentication/login-router.d.ts +3 -0
- package/dist/routes/authentication/login-router.d.ts.map +1 -0
- package/dist/routes/authentication/login-router.js +83 -0
- package/dist/routes/authentication/login-router.js.map +1 -0
- package/dist/routes/authentication/reset-password.d.ts +3 -0
- package/dist/routes/authentication/reset-password.d.ts.map +1 -0
- package/dist/routes/authentication/reset-password.js +92 -0
- package/dist/routes/authentication/reset-password.js.map +1 -0
- package/dist/routes/authentication/send-otp-router.d.ts +3 -0
- package/dist/routes/authentication/send-otp-router.d.ts.map +1 -0
- package/dist/routes/authentication/send-otp-router.js +89 -0
- package/dist/routes/authentication/send-otp-router.js.map +1 -0
- package/dist/routes/authentication/user-profile.d.ts +3 -0
- package/dist/routes/authentication/user-profile.d.ts.map +1 -0
- package/dist/routes/authentication/user-profile.js +44 -0
- package/dist/routes/authentication/user-profile.js.map +1 -0
- package/dist/routes/authentication/user-registration-router.d.ts +3 -0
- package/dist/routes/authentication/user-registration-router.d.ts.map +1 -0
- package/dist/routes/authentication/user-registration-router.js +120 -0
- package/dist/routes/authentication/user-registration-router.js.map +1 -0
- package/dist/routes/authentication/validator.d.ts +14 -0
- package/dist/routes/authentication/validator.d.ts.map +1 -0
- package/dist/routes/authentication/validator.js +69 -0
- package/dist/routes/authentication/validator.js.map +1 -0
- package/dist/routes/countries/countries-router.d.ts +3 -0
- package/dist/routes/countries/countries-router.d.ts.map +1 -0
- package/dist/routes/countries/countries-router.js +23 -0
- package/dist/routes/countries/countries-router.js.map +1 -0
- package/dist/routes/feature-flags/feature-flags.d.ts +5 -0
- package/dist/routes/feature-flags/feature-flags.d.ts.map +1 -0
- package/dist/routes/feature-flags/feature-flags.js +28 -0
- package/dist/routes/feature-flags/feature-flags.js.map +1 -0
- package/dist/routes/index.d.ts +9 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/index.js +92 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/routes/link-metadata.d.ts +3 -0
- package/dist/routes/link-metadata.d.ts.map +1 -0
- package/dist/routes/link-metadata.js +34 -0
- package/dist/routes/link-metadata.js.map +1 -0
- package/dist/routes/orgs/index.d.ts +2 -0
- package/dist/routes/orgs/index.d.ts.map +1 -0
- package/dist/routes/orgs/index.js +2 -0
- package/dist/routes/orgs/index.js.map +1 -0
- package/dist/routes/orgs/invitation.d.ts +3 -0
- package/dist/routes/orgs/invitation.d.ts.map +1 -0
- package/dist/routes/orgs/invitation.js +103 -0
- package/dist/routes/orgs/invitation.js.map +1 -0
- package/dist/routes/orgs/org-delete.d.ts +3 -0
- package/dist/routes/orgs/org-delete.d.ts.map +1 -0
- package/dist/routes/orgs/org-delete.js +53 -0
- package/dist/routes/orgs/org-delete.js.map +1 -0
- package/dist/routes/orgs/org-get.d.ts +3 -0
- package/dist/routes/orgs/org-get.d.ts.map +1 -0
- package/dist/routes/orgs/org-get.js +45 -0
- package/dist/routes/orgs/org-get.js.map +1 -0
- package/dist/routes/orgs/org-members.d.ts +12 -0
- package/dist/routes/orgs/org-members.d.ts.map +1 -0
- package/dist/routes/orgs/org-members.js +560 -0
- package/dist/routes/orgs/org-members.js.map +1 -0
- package/dist/routes/orgs/org-post.d.ts +3 -0
- package/dist/routes/orgs/org-post.d.ts.map +1 -0
- package/dist/routes/orgs/org-post.js +89 -0
- package/dist/routes/orgs/org-post.js.map +1 -0
- package/dist/routes/orgs/org-put.d.ts +3 -0
- package/dist/routes/orgs/org-put.d.ts.map +1 -0
- package/dist/routes/orgs/org-put.js +87 -0
- package/dist/routes/orgs/org-put.js.map +1 -0
- package/dist/routes/orgs/org-registration-router.d.ts +3 -0
- package/dist/routes/orgs/org-registration-router.d.ts.map +1 -0
- package/dist/routes/orgs/org-registration-router.js +12 -0
- package/dist/routes/orgs/org-registration-router.js.map +1 -0
- package/dist/routes/orgs/org-utils.d.ts +14 -0
- package/dist/routes/orgs/org-utils.d.ts.map +1 -0
- package/dist/routes/orgs/org-utils.js +234 -0
- package/dist/routes/orgs/org-utils.js.map +1 -0
- package/dist/routes/orgs/premium-org-utils.d.ts +3 -0
- package/dist/routes/orgs/premium-org-utils.d.ts.map +1 -0
- package/dist/routes/orgs/premium-org-utils.js +61 -0
- package/dist/routes/orgs/premium-org-utils.js.map +1 -0
- package/dist/routes/paid-plans/billingsdk-config.d.ts +36 -0
- package/dist/routes/paid-plans/billingsdk-config.d.ts.map +1 -0
- package/dist/routes/paid-plans/billingsdk-config.js +2 -0
- package/dist/routes/paid-plans/billingsdk-config.js.map +1 -0
- package/dist/routes/paid-plans/get-subscription-config.d.ts +3 -0
- package/dist/routes/paid-plans/get-subscription-config.d.ts.map +1 -0
- package/dist/routes/paid-plans/get-subscription-config.js +25 -0
- package/dist/routes/paid-plans/get-subscription-config.js.map +1 -0
- package/dist/routes/paid-plans/payment-gateway.d.ts +3 -0
- package/dist/routes/paid-plans/payment-gateway.d.ts.map +1 -0
- package/dist/routes/paid-plans/payment-gateway.js +324 -0
- package/dist/routes/paid-plans/payment-gateway.js.map +1 -0
- package/dist/routes/paid-plans/purchased-plans.d.ts +8 -0
- package/dist/routes/paid-plans/purchased-plans.d.ts.map +1 -0
- package/dist/routes/paid-plans/purchased-plans.js +191 -0
- package/dist/routes/paid-plans/purchased-plans.js.map +1 -0
- package/dist/routes/paid-plans/subscription-utils.d.ts +25 -0
- package/dist/routes/paid-plans/subscription-utils.d.ts.map +1 -0
- package/dist/routes/paid-plans/subscription-utils.js +156 -0
- package/dist/routes/paid-plans/subscription-utils.js.map +1 -0
- package/dist/s3-buckets/get-signed-url.d.ts +2 -0
- package/dist/s3-buckets/get-signed-url.d.ts.map +1 -0
- package/dist/s3-buckets/get-signed-url.js +22 -0
- package/dist/s3-buckets/get-signed-url.js.map +1 -0
- package/dist/s3-buckets/index.d.ts +3 -0
- package/dist/s3-buckets/index.d.ts.map +1 -0
- package/dist/s3-buckets/index.js +3 -0
- package/dist/s3-buckets/index.js.map +1 -0
- package/dist/s3-buckets/s3-client.d.ts +3 -0
- package/dist/s3-buckets/s3-client.d.ts.map +1 -0
- package/dist/s3-buckets/s3-client.js +17 -0
- package/dist/s3-buckets/s3-client.js.map +1 -0
- package/dist/s3-buckets/upload-s3.d.ts +11 -0
- package/dist/s3-buckets/upload-s3.d.ts.map +1 -0
- package/dist/s3-buckets/upload-s3.js +51 -0
- package/dist/s3-buckets/upload-s3.js.map +1 -0
- package/dist/secret.d.ts +4 -0
- package/dist/secret.d.ts.map +1 -0
- package/dist/secret.js +11 -0
- package/dist/secret.js.map +1 -0
- package/dist/socket-config.d.ts +4 -0
- package/dist/socket-config.d.ts.map +1 -0
- package/dist/socket-config.js +23 -0
- package/dist/socket-config.js.map +1 -0
- package/dist/types.d.ts +141 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/common-utils.d.ts +61 -0
- package/dist/utils/common-utils.d.ts.map +1 -0
- package/dist/utils/common-utils.js +99 -0
- package/dist/utils/common-utils.js.map +1 -0
- package/dist/utils/email-helper.d.ts +6 -0
- package/dist/utils/email-helper.d.ts.map +1 -0
- package/dist/utils/email-helper.js +33 -0
- package/dist/utils/email-helper.js.map +1 -0
- package/dist/utils/enums.d.ts +17 -0
- package/dist/utils/enums.d.ts.map +1 -0
- package/dist/utils/enums.js +27 -0
- package/dist/utils/enums.js.map +1 -0
- package/dist/utils/error-logger.d.ts +4 -0
- package/dist/utils/error-logger.d.ts.map +1 -0
- package/dist/utils/error-logger.js +30 -0
- package/dist/utils/error-logger.js.map +1 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/otp-helper.d.ts +5 -0
- package/dist/utils/otp-helper.d.ts.map +1 -0
- package/dist/utils/otp-helper.js +89 -0
- package/dist/utils/otp-helper.js.map +1 -0
- package/dist/utils/response-utils.d.ts +8 -0
- package/dist/utils/response-utils.d.ts.map +1 -0
- package/dist/utils/response-utils.js +37 -0
- package/dist/utils/response-utils.js.map +1 -0
- package/dist/utils/sql-helper.d.ts +27 -0
- package/dist/utils/sql-helper.d.ts.map +1 -0
- package/dist/utils/sql-helper.js +97 -0
- package/dist/utils/sql-helper.js.map +1 -0
- package/dist/utils/type.d.ts +81 -0
- package/dist/utils/type.d.ts.map +1 -0
- package/dist/utils/type.js +2 -0
- package/dist/utils/type.js.map +1 -0
- package/package.json +70 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import logger from '../../utils/error-logger.js';
|
|
3
|
+
import { getResponseObj, sendSuccessResponse, throwErrorInResponseIfErrorIsNotCustom } from '../../utils/response-utils.js';
|
|
4
|
+
import { CURRENCY, CURRENCY_SYMBOL, faqs, freePurchasedPlan, plans } from './subscription-utils.js';
|
|
5
|
+
const getSubscriptionConfigRouter = express.Router();
|
|
6
|
+
getSubscriptionConfigRouter.get('/', (request, response) => {
|
|
7
|
+
try {
|
|
8
|
+
sendSuccessResponse(response, getResponseObj({
|
|
9
|
+
plans,
|
|
10
|
+
freePurchasedPlan,
|
|
11
|
+
CURRENCY_SYMBOL,
|
|
12
|
+
CURRENCY,
|
|
13
|
+
faqs,
|
|
14
|
+
}));
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
logger.error('Error while returning plans:', error);
|
|
18
|
+
throwErrorInResponseIfErrorIsNotCustom(response, error, {
|
|
19
|
+
errorMsg: 'An error occurred while fetching countries.',
|
|
20
|
+
solution: 'Please try again later or contact support if the issue persists.',
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
export default getSubscriptionConfigRouter;
|
|
25
|
+
//# sourceMappingURL=get-subscription-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-subscription-config.js","sourceRoot":"","sources":["../../../src/routes/paid-plans/get-subscription-config.ts"],"names":[],"mappings":"AAAA,OAAO,OAA8B,MAAM,SAAS,CAAC;AACrD,OAAO,MAAM,MAAM,6BAA6B,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,sCAAsC,EAAE,MAAM,+BAA+B,CAAC;AAC5H,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAEpG,MAAM,2BAA2B,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;AAErD,2BAA2B,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,OAAgB,EAAE,QAAkB,EAAE,EAAE;IAC5E,IAAI,CAAC;QACH,mBAAmB,CACjB,QAAQ,EACR,cAAc,CAAC;YACb,KAAK;YACL,iBAAiB;YACjB,eAAe;YACf,QAAQ;YACR,IAAI;SACL,CAAC,CACH,CAAC;IACJ,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;QACpD,sCAAsC,CAAC,QAAQ,EAAE,KAAK,EAAE;YACtD,QAAQ,EAAE,6CAA6C;YACvD,QAAQ,EAAE,kEAAkE;SAC7E,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,eAAe,2BAA2B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payment-gateway.d.ts","sourceRoot":"","sources":["../../../src/routes/paid-plans/payment-gateway.ts"],"names":[],"mappings":"AAYA,QAAA,MAAM,oBAAoB,4CAAmB,CAAC;AA+Z9C,eAAe,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
import express from 'express';
|
|
3
|
+
import Razorpay from 'razorpay';
|
|
4
|
+
import { getSecretValue } from '../../secret.js';
|
|
5
|
+
import { isValidId } from '../../utils/common-utils.js';
|
|
6
|
+
import logger from '../../utils/error-logger.js';
|
|
7
|
+
import { getErrorResponseObj, getResponseObj, sendSuccessResponse, throwErrorInResponseIfErrorIsNotCustom } from '../../utils/response-utils.js';
|
|
8
|
+
import { initializeConnection, insertRecords, updateRecords } from '../../utils/sql-helper.js';
|
|
9
|
+
import { getPurchasedPlans, invalidatePurchasedPlansCacheForUser } from './purchased-plans.js';
|
|
10
|
+
import { CURRENCY, plans } from './subscription-utils.js';
|
|
11
|
+
const paymentGateWayRouter = express.Router();
|
|
12
|
+
let razorpayInstance;
|
|
13
|
+
const getRazorPayInstance = () => {
|
|
14
|
+
if (razorpayInstance)
|
|
15
|
+
return razorpayInstance;
|
|
16
|
+
const key_id = getSecretValue('razorpayKeyId');
|
|
17
|
+
const key_secret = getSecretValue('razorpayKeySecret');
|
|
18
|
+
if (!key_id || !key_secret) {
|
|
19
|
+
throw getErrorResponseObj({
|
|
20
|
+
errorMsg: 'RAZORPAY_KEY_ID or RAZORPAY_KEY_SECRET is not defined.',
|
|
21
|
+
solution: 'Check your .env file or environment configuration and provide valid Razorpay credentials.',
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
razorpayInstance = new Razorpay({
|
|
25
|
+
key_id,
|
|
26
|
+
key_secret,
|
|
27
|
+
});
|
|
28
|
+
return razorpayInstance;
|
|
29
|
+
};
|
|
30
|
+
const validatePaymentRequest = ({ planId, billingPeriod, currency, for_no_users, billing_name, billing_country, billing_address, billing_email, billing_contact_no, }) => {
|
|
31
|
+
const planIndex = plans.findIndex((plan) => plan.id === planId);
|
|
32
|
+
if (planIndex === -1) {
|
|
33
|
+
throw getErrorResponseObj({
|
|
34
|
+
errorMsg: 'Invalid plan selected.',
|
|
35
|
+
solution: 'Please select a valid plan.',
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
if (plans[planIndex].monthlyPrice === '0' || plans[planIndex].yearlyPrice === '0') {
|
|
39
|
+
throw getErrorResponseObj({
|
|
40
|
+
errorMsg: 'There is no need to pay for this plan.',
|
|
41
|
+
solution: 'Please select a valid plan.',
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (billingPeriod !== 'monthly' && billingPeriod !== 'yearly') {
|
|
45
|
+
throw getErrorResponseObj({
|
|
46
|
+
errorMsg: 'Invalid billing period.',
|
|
47
|
+
solution: 'Please provide a valid billing period.',
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
if (!currency || typeof currency !== 'string' || currency.trim() === '') {
|
|
51
|
+
throw getErrorResponseObj({
|
|
52
|
+
errorMsg: 'Invalid currency.',
|
|
53
|
+
solution: 'Please provide a valid currency code.',
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
// if (!for_months || typeof for_months !== 'number' || for_months <= 0) {
|
|
57
|
+
// throw getErrorResponseObj({
|
|
58
|
+
// errorMsg: 'Invalid duration for months.',
|
|
59
|
+
// solution: 'Duration for months must be a positive number.',
|
|
60
|
+
// });
|
|
61
|
+
// }
|
|
62
|
+
if (!for_no_users || typeof for_no_users !== 'number' || for_no_users <= 0) {
|
|
63
|
+
throw getErrorResponseObj({
|
|
64
|
+
errorMsg: 'Invalid number of users.',
|
|
65
|
+
solution: 'Number of users must be a positive number.',
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
if (!billing_name || typeof billing_name !== 'string' || billing_name.trim() === '') {
|
|
69
|
+
throw getErrorResponseObj({
|
|
70
|
+
errorMsg: 'Billing name is required.',
|
|
71
|
+
solution: 'Please provide the billing name.',
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
if (!billing_country || typeof billing_country !== 'string' || billing_country.trim() === '') {
|
|
75
|
+
throw getErrorResponseObj({
|
|
76
|
+
errorMsg: 'Billing country is required.',
|
|
77
|
+
solution: 'Please provide the billing country.',
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
if (!billing_address || typeof billing_address !== 'string' || billing_address.trim() === '') {
|
|
81
|
+
throw getErrorResponseObj({
|
|
82
|
+
errorMsg: 'Billing address is required.',
|
|
83
|
+
solution: 'Please provide the billing address.',
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
87
|
+
if (!billing_email || typeof billing_email !== 'string' || !emailRegex.test(billing_email)) {
|
|
88
|
+
throw getErrorResponseObj({
|
|
89
|
+
errorMsg: 'Invalid billing email.',
|
|
90
|
+
solution: 'Please provide a valid billing email address.',
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
if (!billing_contact_no || typeof billing_contact_no !== 'string' || billing_contact_no.trim() === '') {
|
|
94
|
+
throw getErrorResponseObj({
|
|
95
|
+
errorMsg: 'Billing contact number is required.',
|
|
96
|
+
solution: 'Please provide the billing contact number.',
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const calculateAmount = (billingPeriod, for_no_users, planId, minUserRequired) => {
|
|
101
|
+
const selectedPlanRecord = plans.find((plan) => plan.id === planId);
|
|
102
|
+
if (!selectedPlanRecord) {
|
|
103
|
+
throw getErrorResponseObj({
|
|
104
|
+
errorMsg: 'Invalid plan ID.',
|
|
105
|
+
solution: 'Please provide a valid plan ID.',
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
const minUser = minUserRequired || selectedPlanRecord.minUserRequired;
|
|
109
|
+
const teamSizeForCalculation = for_no_users <= minUser ? minUser : for_no_users;
|
|
110
|
+
const planAmount = billingPeriod === 'yearly' ? selectedPlanRecord.yearlyPrice : selectedPlanRecord.monthlyPrice;
|
|
111
|
+
const amount = teamSizeForCalculation * parseFloat(planAmount);
|
|
112
|
+
return amount;
|
|
113
|
+
};
|
|
114
|
+
paymentGateWayRouter.post('/create-order', async (req, response) => {
|
|
115
|
+
const userId = req.user.id;
|
|
116
|
+
await initializeConnection(async (connection) => {
|
|
117
|
+
try {
|
|
118
|
+
const { planId, billingPeriod, currency, for_no_users, billing_name, billing_country, billing_address, billing_email, billing_contact_no } = req.body;
|
|
119
|
+
// currency = CURRENCY;
|
|
120
|
+
if (!isValidId(userId)) {
|
|
121
|
+
throw getErrorResponseObj({
|
|
122
|
+
errorMsg: 'Invalid logged-in user.',
|
|
123
|
+
solution: 'Please re-login and try again.',
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
validatePaymentRequest({
|
|
127
|
+
planId,
|
|
128
|
+
billingPeriod,
|
|
129
|
+
currency,
|
|
130
|
+
for_no_users,
|
|
131
|
+
billing_name,
|
|
132
|
+
billing_country,
|
|
133
|
+
billing_address,
|
|
134
|
+
billing_email,
|
|
135
|
+
billing_contact_no,
|
|
136
|
+
});
|
|
137
|
+
const amount = calculateAmount(billingPeriod, for_no_users, planId);
|
|
138
|
+
const options = {
|
|
139
|
+
amount: amount * 100,
|
|
140
|
+
currency: currency,
|
|
141
|
+
receipt: `receipt_${Date.now()}`,
|
|
142
|
+
};
|
|
143
|
+
//create razorpay order
|
|
144
|
+
const order = await getRazorPayInstance().orders.create(options);
|
|
145
|
+
//save order in db
|
|
146
|
+
const transactionRec = {
|
|
147
|
+
z_order_id: order.id,
|
|
148
|
+
user_id: userId,
|
|
149
|
+
z_currency: currency,
|
|
150
|
+
amount,
|
|
151
|
+
status: 'idle',
|
|
152
|
+
};
|
|
153
|
+
const transactionRecSqlResponse = await insertRecords('b_transactions', [transactionRec], connection);
|
|
154
|
+
const purchasePlanRec = {
|
|
155
|
+
for_months: billingPeriod === 'yearly' ? 12 : 1,
|
|
156
|
+
for_no_users,
|
|
157
|
+
plan_id: planId,
|
|
158
|
+
user_id: userId,
|
|
159
|
+
y_billing_name: billing_name || '',
|
|
160
|
+
y_billing_country: billing_country || '',
|
|
161
|
+
y_billing_address: billing_address || '',
|
|
162
|
+
y_billing_email: billing_email || '',
|
|
163
|
+
y_billing_contact_no: billing_contact_no || '',
|
|
164
|
+
transaction_id: transactionRecSqlResponse.insertId,
|
|
165
|
+
};
|
|
166
|
+
const sqlResponse = await insertRecords('b_purchased_plans', [purchasePlanRec], connection);
|
|
167
|
+
sendSuccessResponse(response, getResponseObj({
|
|
168
|
+
message: 'Order created successfully.',
|
|
169
|
+
orderId: order.id,
|
|
170
|
+
insertRecordId: sqlResponse.insertId,
|
|
171
|
+
}));
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
logger.error(`Error creating RazorPay order`, error);
|
|
175
|
+
throwErrorInResponseIfErrorIsNotCustom(response, error, {
|
|
176
|
+
errorMsg: error.message || `An error occurred while creating order.`,
|
|
177
|
+
solution: 'Please try again later or contact support if the issue persists.',
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
finally {
|
|
181
|
+
await invalidatePurchasedPlansCacheForUser(userId);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
paymentGateWayRouter.post('/add-more-users-order', async (req, response) => {
|
|
186
|
+
const userId = req.user.id;
|
|
187
|
+
await initializeConnection(async (connection) => {
|
|
188
|
+
try {
|
|
189
|
+
const { purchased_id, for_no_users, currency } = req.body;
|
|
190
|
+
if (!isValidId(purchased_id)) {
|
|
191
|
+
throw getErrorResponseObj({
|
|
192
|
+
errorMsg: 'Invalid purchased plan.',
|
|
193
|
+
solution: 'Please try again later or contact support if the issue persists.',
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
if (for_no_users < 1) {
|
|
197
|
+
throw getErrorResponseObj({
|
|
198
|
+
errorMsg: 'Invalid number of users.',
|
|
199
|
+
solution: 'Please try again later or contact support if the issue persists.',
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
if (currency !== CURRENCY) {
|
|
203
|
+
throw getErrorResponseObj({
|
|
204
|
+
errorMsg: 'Invalid currency.',
|
|
205
|
+
solution: 'Please try again later or contact support if the issue persists.',
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
if (!isValidId(userId)) {
|
|
209
|
+
throw getErrorResponseObj({
|
|
210
|
+
errorMsg: 'Invalid logged-in user.',
|
|
211
|
+
solution: 'Please re-login and try again.',
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
const purchasedPlans = await getPurchasedPlans(userId, connection);
|
|
215
|
+
const purchasedPlan = purchasedPlans.find((plan) => Number(plan.purchased_id) === Number(purchased_id));
|
|
216
|
+
if (!purchasedPlan) {
|
|
217
|
+
throw getErrorResponseObj({
|
|
218
|
+
errorMsg: 'Invalid purchased plan.',
|
|
219
|
+
solution: 'Please try again later or contact support if the issue persists.',
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
const amount = calculateAmount(purchasedPlan.billing_period, Number(for_no_users), purchasedPlan.plan_id, 1);
|
|
223
|
+
const options = {
|
|
224
|
+
amount: amount * 100,
|
|
225
|
+
currency: currency,
|
|
226
|
+
receipt: `receipt_${Date.now()}`,
|
|
227
|
+
};
|
|
228
|
+
//create razorpay order
|
|
229
|
+
const order = await getRazorPayInstance().orders.create(options);
|
|
230
|
+
//save order in db
|
|
231
|
+
const transactionRec = {
|
|
232
|
+
z_order_id: order.id,
|
|
233
|
+
user_id: userId,
|
|
234
|
+
z_currency: currency,
|
|
235
|
+
amount,
|
|
236
|
+
status: 'idle',
|
|
237
|
+
};
|
|
238
|
+
const transactionRecSqlResponse = await insertRecords('b_transactions', [transactionRec], connection);
|
|
239
|
+
const updatedPlanRec = {
|
|
240
|
+
for_no_users,
|
|
241
|
+
user_id: userId,
|
|
242
|
+
transaction_id: transactionRecSqlResponse.insertId,
|
|
243
|
+
purchased_id: Number(purchased_id),
|
|
244
|
+
};
|
|
245
|
+
const sqlResponse = await insertRecords('b_updated_plans', [updatedPlanRec], connection);
|
|
246
|
+
sendSuccessResponse(response, getResponseObj({
|
|
247
|
+
message: 'Add Users order has been created successfully.',
|
|
248
|
+
orderId: order.id,
|
|
249
|
+
insertRecordId: sqlResponse.insertId,
|
|
250
|
+
}));
|
|
251
|
+
}
|
|
252
|
+
catch (error) {
|
|
253
|
+
logger.error(`Error while updating purchased plan for more users`, error);
|
|
254
|
+
throwErrorInResponseIfErrorIsNotCustom(response, error, {
|
|
255
|
+
errorMsg: error.message || `An error occurred while updating purchased plan for more users.`,
|
|
256
|
+
solution: 'Please try again later or contact support if the issue persists.',
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
finally {
|
|
260
|
+
await invalidatePurchasedPlansCacheForUser(userId);
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
paymentGateWayRouter.post('/verify-payment', async (req, res) => {
|
|
265
|
+
const { orderId, razorpayPaymentId, razorpaySignature } = req.body;
|
|
266
|
+
await initializeConnection(async (connection) => {
|
|
267
|
+
try {
|
|
268
|
+
const generatedSignature = crypto
|
|
269
|
+
.createHmac('sha256', getSecretValue('razorpayKeySecret') || '')
|
|
270
|
+
.update(`${orderId}|${razorpayPaymentId}`)
|
|
271
|
+
.digest('hex');
|
|
272
|
+
if (generatedSignature !== razorpaySignature) {
|
|
273
|
+
const updateResponse = await updateRecords('b_transactions', { status: 'failed', z_payment_id: razorpayPaymentId, z_payment_signature: razorpaySignature }, { z_order_id: orderId }, connection);
|
|
274
|
+
throw getErrorResponseObj({
|
|
275
|
+
errorMsg: 'Invalid signature.',
|
|
276
|
+
solution: 'Please try again later or contact support if the issue persists.',
|
|
277
|
+
}, { ...updateResponse });
|
|
278
|
+
}
|
|
279
|
+
const updateResponse = await updateRecords('b_transactions', { status: 'verified', z_payment_id: razorpayPaymentId, z_payment_signature: razorpaySignature }, { z_order_id: orderId }, connection);
|
|
280
|
+
try {
|
|
281
|
+
// Fetch payment details from Razorpay to get the payment method
|
|
282
|
+
const razorpayInstance = getRazorPayInstance();
|
|
283
|
+
const paymentDetails = await razorpayInstance.payments.fetch(razorpayPaymentId);
|
|
284
|
+
const paymentMethod = paymentDetails?.method || 'unknown';
|
|
285
|
+
await updateRecords('b_transactions', { z_payment_method: paymentMethod, status: paymentDetails.captured ? 'paid' : 'failed' }, { z_order_id: orderId }, connection);
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
logger.error(`Error fetching payment details from RazorPay`, error);
|
|
289
|
+
}
|
|
290
|
+
sendSuccessResponse(res, getResponseObj({ message: 'Payment verified successfully.', ...updateResponse, success: true }));
|
|
291
|
+
}
|
|
292
|
+
catch (error) {
|
|
293
|
+
logger.error(`Error creating RazorPay verification`, error);
|
|
294
|
+
throwErrorInResponseIfErrorIsNotCustom(res, error, {
|
|
295
|
+
errorMsg: error.message || `An error occurred while verifying payment.`,
|
|
296
|
+
solution: 'Please try again later or contact support if the issue persists.',
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
paymentGateWayRouter.post('/log-failure', async (req, res) => {
|
|
302
|
+
const { orderId, errorCode, errorDescription, errorReason, paymentId } = req.body;
|
|
303
|
+
await initializeConnection(async (connection) => {
|
|
304
|
+
try {
|
|
305
|
+
const updateResponse = await updateRecords('b_transactions', {
|
|
306
|
+
status: 'failed',
|
|
307
|
+
z_error_code: errorCode || '',
|
|
308
|
+
z_error_description: errorDescription || '',
|
|
309
|
+
z_error_reason: errorReason || '',
|
|
310
|
+
z_payment_id: paymentId || '',
|
|
311
|
+
}, { z_order_id: orderId }, connection);
|
|
312
|
+
sendSuccessResponse(res, getResponseObj({ message: 'Payment error logged successfully.', ...updateResponse, success: true }));
|
|
313
|
+
}
|
|
314
|
+
catch (error) {
|
|
315
|
+
logger.error(`Error logging payment error`, error);
|
|
316
|
+
throwErrorInResponseIfErrorIsNotCustom(res, error, {
|
|
317
|
+
errorMsg: error.message || `An error occurred while logging payment error.`,
|
|
318
|
+
solution: 'Please try again later or contact support if the issue persists.',
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
});
|
|
323
|
+
export default paymentGateWayRouter;
|
|
324
|
+
//# sourceMappingURL=payment-gateway.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payment-gateway.js","sourceRoot":"","sources":["../../../src/routes/paid-plans/payment-gateway.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,MAAM,MAAM,6BAA6B,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,mBAAmB,EAAE,sCAAsC,EAAE,MAAM,+BAA+B,CAAC;AACjJ,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/F,OAAO,EAAE,iBAAiB,EAAE,oCAAoC,EAAE,MAAM,sBAAsB,CAAC;AAC/F,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAE1D,MAAM,oBAAoB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;AAC9C,IAAI,gBAA0B,CAAC;AAE/B,MAAM,mBAAmB,GAAG,GAAG,EAAE;IAC/B,IAAI,gBAAgB;QAAE,OAAO,gBAAgB,CAAC;IAE9C,MAAM,MAAM,GAAG,cAAc,CAAC,eAAe,CAAC,CAAC;IAC/C,MAAM,UAAU,GAAG,cAAc,CAAC,mBAAmB,CAAC,CAAC;IAEvD,IAAI,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QAC3B,MAAM,mBAAmB,CAAC;YACxB,QAAQ,EAAE,wDAAwD;YAClE,QAAQ,EAAE,2FAA2F;SACtG,CAAC,CAAC;IACL,CAAC;IAED,gBAAgB,GAAG,IAAI,QAAQ,CAAC;QAC9B,MAAM;QACN,UAAU;KACX,CAAC,CAAC;IAEH,OAAO,gBAAgB,CAAC;AAC1B,CAAC,CAAC;AAEF,MAAM,sBAAsB,GAAG,CAAC,EAC9B,MAAM,EACN,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,eAAe,EACf,aAAa,EACb,kBAAkB,GAWnB,EAAE,EAAE;IACH,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;IAChE,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;QACrB,MAAM,mBAAmB,CAAC;YACxB,QAAQ,EAAE,wBAAwB;YAClC,QAAQ,EAAE,6BAA6B;SACxC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,YAAY,KAAK,GAAG,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,WAAW,KAAK,GAAG,EAAE,CAAC;QAClF,MAAM,mBAAmB,CAAC;YACxB,QAAQ,EAAE,wCAAwC;YAClD,QAAQ,EAAE,6BAA6B;SACxC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,aAAa,KAAK,SAAS,IAAI,aAAa,KAAK,QAAQ,EAAE,CAAC;QAC9D,MAAM,mBAAmB,CAAC;YACxB,QAAQ,EAAE,yBAAyB;YACnC,QAAQ,EAAE,wCAAwC;SACnD,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACxE,MAAM,mBAAmB,CAAC;YACxB,QAAQ,EAAE,mBAAmB;YAC7B,QAAQ,EAAE,uCAAuC;SAClD,CAAC,CAAC;IACL,CAAC;IAED,0EAA0E;IAC1E,gCAAgC;IAChC,gDAAgD;IAChD,kEAAkE;IAClE,QAAQ;IACR,IAAI;IAEJ,IAAI,CAAC,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;QAC3E,MAAM,mBAAmB,CAAC;YACxB,QAAQ,EAAE,0BAA0B;YACpC,QAAQ,EAAE,4CAA4C;SACvD,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACpF,MAAM,mBAAmB,CAAC;YACxB,QAAQ,EAAE,2BAA2B;YACrC,QAAQ,EAAE,kCAAkC;SAC7C,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,eAAe,IAAI,OAAO,eAAe,KAAK,QAAQ,IAAI,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC7F,MAAM,mBAAmB,CAAC;YACxB,QAAQ,EAAE,8BAA8B;YACxC,QAAQ,EAAE,qCAAqC;SAChD,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,eAAe,IAAI,OAAO,eAAe,KAAK,QAAQ,IAAI,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC7F,MAAM,mBAAmB,CAAC;YACxB,QAAQ,EAAE,8BAA8B;YACxC,QAAQ,EAAE,qCAAqC;SAChD,CAAC,CAAC;IACL,CAAC;IAED,MAAM,UAAU,GAAG,4BAA4B,CAAC;IAChD,IAAI,CAAC,aAAa,IAAI,OAAO,aAAa,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;QAC3F,MAAM,mBAAmB,CAAC;YACxB,QAAQ,EAAE,wBAAwB;YAClC,QAAQ,EAAE,+CAA+C;SAC1D,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,kBAAkB,IAAI,OAAO,kBAAkB,KAAK,QAAQ,IAAI,kBAAkB,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACtG,MAAM,mBAAmB,CAAC;YACxB,QAAQ,EAAE,qCAAqC;YAC/C,QAAQ,EAAE,4CAA4C;SACvD,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,aAAmC,EAAE,YAAoB,EAAE,MAAc,EAAE,eAAwB,EAAE,EAAE;IAC9H,MAAM,kBAAkB,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;IAEpE,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxB,MAAM,mBAAmB,CAAC;YACxB,QAAQ,EAAE,kBAAkB;YAC5B,QAAQ,EAAE,iCAAiC;SAC5C,CAAC,CAAC;IACL,CAAC;IAED,MAAM,OAAO,GAAG,eAAe,IAAI,kBAAkB,CAAC,eAAe,CAAC;IACtE,MAAM,sBAAsB,GAAG,YAAY,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC;IAEhF,MAAM,UAAU,GAAG,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAC,kBAAkB,CAAC,YAAY,CAAC;IACjH,MAAM,MAAM,GAAG,sBAAsB,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IAC/D,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,oBAAoB,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE;IACjE,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;IAE3B,MAAM,oBAAoB,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE;QAC9C,IAAI,CAAC;YACH,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,aAAa,EAAE,kBAAkB,EAAE,GACxI,GAAG,CAAC,IAAI,CAAC;YAEX,uBAAuB;YAEvB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;gBACvB,MAAM,mBAAmB,CAAC;oBACxB,QAAQ,EAAE,yBAAyB;oBACnC,QAAQ,EAAE,gCAAgC;iBAC3C,CAAC,CAAC;YACL,CAAC;YAED,sBAAsB,CAAC;gBACrB,MAAM;gBACN,aAAa;gBACb,QAAQ;gBACR,YAAY;gBACZ,YAAY;gBACZ,eAAe;gBACf,eAAe;gBACf,aAAa;gBACb,kBAAkB;aACnB,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,eAAe,CAAC,aAAa,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;YAEpE,MAAM,OAAO,GAAG;gBACd,MAAM,EAAE,MAAM,GAAG,GAAG;gBACpB,QAAQ,EAAE,QAAQ;gBAClB,OAAO,EAAE,WAAW,IAAI,CAAC,GAAG,EAAE,EAAE;aACjC,CAAC;YAEF,uBAAuB;YACvB,MAAM,KAAK,GAAG,MAAM,mBAAmB,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAEjE,kBAAkB;YAElB,MAAM,cAAc,GAAG;gBACrB,UAAU,EAAE,KAAK,CAAC,EAAE;gBACpB,OAAO,EAAE,MAAM;gBACf,UAAU,EAAE,QAAQ;gBACpB,MAAM;gBACN,MAAM,EAAE,MAAM;aACf,CAAC;YACF,MAAM,yBAAyB,GAAG,MAAM,aAAa,CAAC,gBAAgB,EAAE,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC,CAAC;YAEtG,MAAM,eAAe,GAAG;gBACtB,UAAU,EAAE,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC/C,YAAY;gBACZ,OAAO,EAAE,MAAM;gBACf,OAAO,EAAE,MAAM;gBAEf,cAAc,EAAE,YAAY,IAAI,EAAE;gBAClC,iBAAiB,EAAE,eAAe,IAAI,EAAE;gBACxC,iBAAiB,EAAE,eAAe,IAAI,EAAE;gBACxC,eAAe,EAAE,aAAa,IAAI,EAAE;gBACpC,oBAAoB,EAAE,kBAAkB,IAAI,EAAE;gBAE9C,cAAc,EAAE,yBAAyB,CAAC,QAAQ;aACnD,CAAC;YAEF,MAAM,WAAW,GAAG,MAAM,aAAa,CAAC,mBAAmB,EAAE,CAAC,eAAe,CAAC,EAAE,UAAU,CAAC,CAAC;YAE5F,mBAAmB,CACjB,QAAQ,EACR,cAAc,CAAC;gBACb,OAAO,EAAE,6BAA6B;gBACtC,OAAO,EAAE,KAAK,CAAC,EAAE;gBACjB,cAAc,EAAE,WAAW,CAAC,QAAQ;aACrC,CAAC,CACH,CAAC;QACJ,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;YACrD,sCAAsC,CAAC,QAAQ,EAAE,KAAK,EAAE;gBACtD,QAAQ,EAAE,KAAK,CAAC,OAAO,IAAI,yCAAyC;gBACpE,QAAQ,EAAE,kEAAkE;aAC7E,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,MAAM,oCAAoC,CAAC,MAAM,CAAC,CAAC;QACrD,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,oBAAoB,CAAC,IAAI,CAAC,uBAAuB,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE;IACzE,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;IAE3B,MAAM,oBAAoB,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE;QAC9C,IAAI,CAAC;YACH,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;YAE1D,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC7B,MAAM,mBAAmB,CAAC;oBACxB,QAAQ,EAAE,yBAAyB;oBACnC,QAAQ,EAAE,kEAAkE;iBAC7E,CAAC,CAAC;YACL,CAAC;YAED,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;gBACrB,MAAM,mBAAmB,CAAC;oBACxB,QAAQ,EAAE,0BAA0B;oBACpC,QAAQ,EAAE,kEAAkE;iBAC7E,CAAC,CAAC;YACL,CAAC;YAED,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC1B,MAAM,mBAAmB,CAAC;oBACxB,QAAQ,EAAE,mBAAmB;oBAC7B,QAAQ,EAAE,kEAAkE;iBAC7E,CAAC,CAAC;YACL,CAAC;YAED,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;gBACvB,MAAM,mBAAmB,CAAC;oBACxB,QAAQ,EAAE,yBAAyB;oBACnC,QAAQ,EAAE,gCAAgC;iBAC3C,CAAC,CAAC;YACL,CAAC;YAED,MAAM,cAAc,GAAG,MAAM,iBAAiB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YACnE,MAAM,aAAa,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,IAAuB,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;YAE3H,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,MAAM,mBAAmB,CAAC;oBACxB,QAAQ,EAAE,yBAAyB;oBACnC,QAAQ,EAAE,kEAAkE;iBAC7E,CAAC,CAAC;YACL,CAAC;YAED,MAAM,MAAM,GAAG,eAAe,CAAC,aAAa,CAAC,cAAc,EAAE,MAAM,CAAC,YAAY,CAAC,EAAE,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAE7G,MAAM,OAAO,GAAG;gBACd,MAAM,EAAE,MAAM,GAAG,GAAG;gBACpB,QAAQ,EAAE,QAAQ;gBAClB,OAAO,EAAE,WAAW,IAAI,CAAC,GAAG,EAAE,EAAE;aACjC,CAAC;YACF,uBAAuB;YACvB,MAAM,KAAK,GAAG,MAAM,mBAAmB,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAEjE,kBAAkB;YAClB,MAAM,cAAc,GAAG;gBACrB,UAAU,EAAE,KAAK,CAAC,EAAE;gBACpB,OAAO,EAAE,MAAM;gBACf,UAAU,EAAE,QAAQ;gBACpB,MAAM;gBACN,MAAM,EAAE,MAAM;aACf,CAAC;YACF,MAAM,yBAAyB,GAAG,MAAM,aAAa,CAAC,gBAAgB,EAAE,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC,CAAC;YAEtG,MAAM,cAAc,GAAG;gBACrB,YAAY;gBACZ,OAAO,EAAE,MAAM;gBACf,cAAc,EAAE,yBAAyB,CAAC,QAAQ;gBAClD,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC;aACnC,CAAC;YACF,MAAM,WAAW,GAAG,MAAM,aAAa,CAAC,iBAAiB,EAAE,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC,CAAC;YAEzF,mBAAmB,CACjB,QAAQ,EACR,cAAc,CAAC;gBACb,OAAO,EAAE,gDAAgD;gBACzD,OAAO,EAAE,KAAK,CAAC,EAAE;gBACjB,cAAc,EAAE,WAAW,CAAC,QAAQ;aACrC,CAAC,CACH,CAAC;QACJ,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,MAAM,CAAC,KAAK,CAAC,oDAAoD,EAAE,KAAK,CAAC,CAAC;YAC1E,sCAAsC,CAAC,QAAQ,EAAE,KAAK,EAAE;gBACtD,QAAQ,EAAE,KAAK,CAAC,OAAO,IAAI,iEAAiE;gBAC5F,QAAQ,EAAE,kEAAkE;aAC7E,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,MAAM,oCAAoC,CAAC,MAAM,CAAC,CAAC;QACrD,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,oBAAoB,CAAC,IAAI,CAAC,iBAAiB,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IAC9D,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;IAEnE,MAAM,oBAAoB,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE;QAC9C,IAAI,CAAC;YACH,MAAM,kBAAkB,GAAG,MAAM;iBAC9B,UAAU,CAAC,QAAQ,EAAE,cAAc,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC;iBAC/D,MAAM,CAAC,GAAG,OAAO,IAAI,iBAAiB,EAAE,CAAC;iBACzC,MAAM,CAAC,KAAK,CAAC,CAAC;YAEjB,IAAI,kBAAkB,KAAK,iBAAiB,EAAE,CAAC;gBAC7C,MAAM,cAAc,GAAG,MAAM,aAAa,CACxC,gBAAgB,EAChB,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,EAC7F,EAAE,UAAU,EAAE,OAAO,EAAE,EACvB,UAAU,CACX,CAAC;gBAEF,MAAM,mBAAmB,CACvB;oBACE,QAAQ,EAAE,oBAAoB;oBAC9B,QAAQ,EAAE,kEAAkE;iBAC7E,EACD,EAAE,GAAG,cAAc,EAAE,CACtB,CAAC;YACJ,CAAC;YAED,MAAM,cAAc,GAAG,MAAM,aAAa,CACxC,gBAAgB,EAChB,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,EAC/F,EAAE,UAAU,EAAE,OAAO,EAAE,EACvB,UAAU,CACX,CAAC;YAEF,IAAI,CAAC;gBACH,gEAAgE;gBAChE,MAAM,gBAAgB,GAAG,mBAAmB,EAAE,CAAC;gBAC/C,MAAM,cAAc,GAAG,MAAM,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;gBAChF,MAAM,aAAa,GAAG,cAAc,EAAE,MAAM,IAAI,SAAS,CAAC;gBAC1D,MAAM,aAAa,CACjB,gBAAgB,EAChB,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,EACxF,EAAE,UAAU,EAAE,OAAO,EAAE,EACvB,UAAU,CACX,CAAC;YACJ,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,MAAM,CAAC,KAAK,CAAC,8CAA8C,EAAE,KAAK,CAAC,CAAC;YACtE,CAAC;YAED,mBAAmB,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,OAAO,EAAE,gCAAgC,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC5H,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,MAAM,CAAC,KAAK,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC;YAE5D,sCAAsC,CAAC,GAAG,EAAE,KAAK,EAAE;gBACjD,QAAQ,EAAE,KAAK,CAAC,OAAO,IAAI,4CAA4C;gBACvE,QAAQ,EAAE,kEAAkE;aAC7E,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,oBAAoB,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IAC3D,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;IAElF,MAAM,oBAAoB,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE;QAC9C,IAAI,CAAC;YACH,MAAM,cAAc,GAAG,MAAM,aAAa,CACxC,gBAAgB,EAChB;gBACE,MAAM,EAAE,QAAQ;gBAChB,YAAY,EAAE,SAAS,IAAI,EAAE;gBAC7B,mBAAmB,EAAE,gBAAgB,IAAI,EAAE;gBAC3C,cAAc,EAAE,WAAW,IAAI,EAAE;gBACjC,YAAY,EAAE,SAAS,IAAI,EAAE;aAC9B,EACD,EAAE,UAAU,EAAE,OAAO,EAAE,EACvB,UAAU,CACX,CAAC;YAEF,mBAAmB,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,OAAO,EAAE,oCAAoC,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAChI,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,MAAM,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;YAEnD,sCAAsC,CAAC,GAAG,EAAE,KAAK,EAAE;gBACjD,QAAQ,EAAE,KAAK,CAAC,OAAO,IAAI,gDAAgD;gBAC3E,QAAQ,EAAE,kEAAkE;aAC7E,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,eAAe,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { purchasedPlansInf } from '../../types.js';
|
|
2
|
+
import { freePurchasedPlan } from './subscription-utils.js';
|
|
3
|
+
declare const purchasedPlansRouter: import("express-serve-static-core").Router;
|
|
4
|
+
export declare const invalidatePurchasedPlansCacheForUser: (userId: number) => Promise<void>;
|
|
5
|
+
export declare const getPurchasedPlans: (p_userId: number | string, connection: any) => Promise<any>;
|
|
6
|
+
export declare const getActivePurchasedPlan: (userId: number, connection: any) => Promise<purchasedPlansInf | typeof freePurchasedPlan>;
|
|
7
|
+
export default purchasedPlansRouter;
|
|
8
|
+
//# sourceMappingURL=purchased-plans.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"purchased-plans.d.ts","sourceRoot":"","sources":["../../../src/routes/paid-plans/purchased-plans.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAKnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,QAAA,MAAM,oBAAoB,4CAAmB,CAAC;AAK9C,eAAO,MAAM,oCAAoC,GAAU,QAAQ,MAAM,kBAIxE,CAAC;AAiIF,eAAO,MAAM,iBAAiB,GAAU,UAAU,MAAM,GAAG,MAAM,EAAE,YAAY,GAAG,iBAuCjF,CAAC;AAGF,eAAO,MAAM,sBAAsB,GAAU,QAAQ,MAAM,EAAE,YAAY,GAAG,KAAG,OAAO,CAAC,iBAAiB,GAAG,OAAO,iBAAiB,CAqBlI,CAAC;AAqBF,eAAe,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import { getSingletonCacheInstance } from '../../local-cache.js';
|
|
3
|
+
import { convertServerDateToJS, isValidId } from '../../utils/common-utils.js';
|
|
4
|
+
import logger from '../../utils/error-logger.js';
|
|
5
|
+
import { getErrorResponseObj, getResponseObj, sendSuccessResponse, throwErrorInResponseIfErrorIsNotCustom } from '../../utils/response-utils.js';
|
|
6
|
+
import { executeSql, initializeConnection } from '../../utils/sql-helper.js';
|
|
7
|
+
import { freePurchasedPlan } from './subscription-utils.js';
|
|
8
|
+
const purchasedPlansRouter = express.Router();
|
|
9
|
+
const purchasedPlansCache = await getSingletonCacheInstance('purchased-plans-cache', 100);
|
|
10
|
+
// Map to track in-flight database queries for purchased plans
|
|
11
|
+
const loadingPurchasedPlansFor = new Map();
|
|
12
|
+
export const invalidatePurchasedPlansCacheForUser = async (userId) => {
|
|
13
|
+
const cacheKey = `purchasedPlans_user_${userId}`;
|
|
14
|
+
await purchasedPlansCache.del(cacheKey);
|
|
15
|
+
loadingPurchasedPlansFor.delete(userId);
|
|
16
|
+
};
|
|
17
|
+
const getUpdatedPurchasedPlans = async (p_userId, connection) => {
|
|
18
|
+
try {
|
|
19
|
+
const userId = Number(p_userId);
|
|
20
|
+
if (!isValidId(userId)) {
|
|
21
|
+
throw getErrorResponseObj({
|
|
22
|
+
errorMsg: 'It seems like you are not logged in',
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
const updatedPurchasedPlansSql = `SELECT u.purchased_id, u.updated_at, u.for_no_users, t.status, t.amount,
|
|
26
|
+
t.z_order_id, t.z_payment_id, t.z_payment_at, t.z_currency, t.z_payment_method
|
|
27
|
+
FROM b_updated_plans u INNER JOIN b_transactions t ON u.transaction_id = t.transaction_id
|
|
28
|
+
WHERE u.user_id = ${userId} AND t.status != 'idle' ORDER BY u.updated_plan_id DESC;`;
|
|
29
|
+
const updatedPlansResult = await executeSql(updatedPurchasedPlansSql, connection);
|
|
30
|
+
return updatedPlansResult;
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
logger.error('Error in getUpdatedPurchasedPlans function', error);
|
|
34
|
+
throw getErrorResponseObj({
|
|
35
|
+
errorMsg: 'An error occurred while retrieving updated purchased plans.',
|
|
36
|
+
solution: 'Please try again later or contact support if the issue persists.',
|
|
37
|
+
}, error);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
const attachUpdatedPurchasedPlansToPurchasedPlans = async (purchasedPlans, userId, connection) => {
|
|
41
|
+
const updatedPurchasedPlans = await getUpdatedPurchasedPlans(userId, connection);
|
|
42
|
+
if (!updatedPurchasedPlans || updatedPurchasedPlans.length === 0)
|
|
43
|
+
return purchasedPlans;
|
|
44
|
+
updatedPurchasedPlans.sort((a, b) => {
|
|
45
|
+
const dateA = new Date(a.updated_at).getTime();
|
|
46
|
+
const dateB = new Date(b.updated_at).getTime();
|
|
47
|
+
return dateA - dateB;
|
|
48
|
+
});
|
|
49
|
+
updatedPurchasedPlans.forEach((updatedPlan) => {
|
|
50
|
+
// if (updatedPlan.status !== 'paid') return;
|
|
51
|
+
const planIndex = purchasedPlans.findIndex((p) => p.purchased_id === updatedPlan.purchased_id);
|
|
52
|
+
if (planIndex < 0) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const record = purchasedPlans[planIndex];
|
|
56
|
+
if (updatedPlan.status === 'paid') {
|
|
57
|
+
record.for_no_users = Number(updatedPlan.for_no_users) + Number(record.for_no_users);
|
|
58
|
+
}
|
|
59
|
+
record.updatedRecords = record.updatedRecords || [];
|
|
60
|
+
record.updatedRecords.push(updatedPlan);
|
|
61
|
+
purchasedPlans[planIndex] = record;
|
|
62
|
+
});
|
|
63
|
+
return purchasedPlans;
|
|
64
|
+
};
|
|
65
|
+
const processPurchasedPlansData = (purchasedPlans) => {
|
|
66
|
+
// Sort plans by purchased_at to ensure proper chronological chaining
|
|
67
|
+
purchasedPlans.sort((a, b) => {
|
|
68
|
+
const dateA = new Date(a.purchased_at).getTime();
|
|
69
|
+
const dateB = new Date(b.purchased_at).getTime();
|
|
70
|
+
return dateA - dateB;
|
|
71
|
+
});
|
|
72
|
+
// Chain plans together: each plan starts when the previous one ends
|
|
73
|
+
// BUT only if the previous plan hasn't expired yet
|
|
74
|
+
let previousEndDate = null;
|
|
75
|
+
purchasedPlans.forEach((plan) => {
|
|
76
|
+
if (plan.status !== 'paid')
|
|
77
|
+
return;
|
|
78
|
+
const purchasedAt = convertServerDateToJS(plan.purchased_at);
|
|
79
|
+
if (previousEndDate === null) {
|
|
80
|
+
// First plan: starts at purchased_at
|
|
81
|
+
plan.startAt = purchasedAt;
|
|
82
|
+
}
|
|
83
|
+
else if (previousEndDate > purchasedAt) {
|
|
84
|
+
// Previous plan is still active/future: chain this plan to start when previous ends
|
|
85
|
+
plan.startAt = new Date(previousEndDate);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// Previous plan has already ended: start fresh from purchased_at
|
|
89
|
+
plan.startAt = purchasedAt;
|
|
90
|
+
}
|
|
91
|
+
// Calculate end date: startAt + for_months
|
|
92
|
+
plan.endAt = new Date(plan.startAt);
|
|
93
|
+
plan.endAt.setMonth(plan.endAt.getMonth() + plan.for_months);
|
|
94
|
+
// Update previousEndDate for the next iteration
|
|
95
|
+
previousEndDate = plan.endAt;
|
|
96
|
+
});
|
|
97
|
+
return purchasedPlans;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Fetches purchased plans from database and caches the result.
|
|
101
|
+
*/
|
|
102
|
+
const fetchAndCachePurchasedPlans = async (userId, connection) => {
|
|
103
|
+
try {
|
|
104
|
+
const purchasedPlanSql = `SELECT p.plan_id, p.purchased_id, p.purchased_at, p.for_months, p.for_no_users, p.for_no_users as old_purchased_for_no_users,
|
|
105
|
+
t.status, t.amount, t.z_order_id, t.z_payment_id, t.z_payment_at, t.z_currency, t.z_payment_method,
|
|
106
|
+
p.y_billing_name, p.y_billing_country, p.y_billing_address, p.y_billing_email, p.y_billing_contact_no
|
|
107
|
+
FROM b_purchased_plans p INNER JOIN b_transactions t ON p.transaction_id = t.transaction_id
|
|
108
|
+
WHERE p.user_id = ${userId} AND t.status != 'idle' ORDER BY p.purchased_id DESC;`;
|
|
109
|
+
const purchasedPlans = await executeSql(purchasedPlanSql, connection);
|
|
110
|
+
const processedPlans = processPurchasedPlansData(purchasedPlans);
|
|
111
|
+
const updatedPurchasedPlans = await attachUpdatedPurchasedPlansToPurchasedPlans(processedPlans, userId, connection);
|
|
112
|
+
const cacheKey = `purchasedPlans_user_${userId}`;
|
|
113
|
+
await purchasedPlansCache.set(cacheKey, updatedPurchasedPlans || []);
|
|
114
|
+
return updatedPurchasedPlans;
|
|
115
|
+
}
|
|
116
|
+
finally {
|
|
117
|
+
// Clean up the promise from the map once completed
|
|
118
|
+
loadingPurchasedPlansFor.delete(userId);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
export const getPurchasedPlans = async (p_userId, connection) => {
|
|
122
|
+
try {
|
|
123
|
+
const userId = Number(p_userId);
|
|
124
|
+
if (!isValidId(userId)) {
|
|
125
|
+
throw getErrorResponseObj({
|
|
126
|
+
errorMsg: 'It seems like you are not logged in',
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
const cacheKey = `purchasedPlans_user_${userId}`;
|
|
130
|
+
// Check cache first
|
|
131
|
+
const cachedPurchasedPlans = await purchasedPlansCache.get(cacheKey);
|
|
132
|
+
if (cachedPurchasedPlans) {
|
|
133
|
+
return cachedPurchasedPlans;
|
|
134
|
+
}
|
|
135
|
+
// Check if there's already a query in progress for this user
|
|
136
|
+
let plansPromise = loadingPurchasedPlansFor.get(userId);
|
|
137
|
+
if (!plansPromise) {
|
|
138
|
+
// No query in progress, create a new one
|
|
139
|
+
plansPromise = fetchAndCachePurchasedPlans(userId, connection);
|
|
140
|
+
loadingPurchasedPlansFor.set(userId, plansPromise);
|
|
141
|
+
}
|
|
142
|
+
// Wait for the query to complete (either new or existing)
|
|
143
|
+
return await plansPromise;
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
logger.error('Error in getPurchasedPlans function', error);
|
|
147
|
+
throw getErrorResponseObj({
|
|
148
|
+
errorMsg: 'An error occurred while retrieving purchased plans.',
|
|
149
|
+
solution: 'Please try again later or contact support if the issue persists.',
|
|
150
|
+
}, error);
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
// Retrieving an Active Plan
|
|
154
|
+
export const getActivePurchasedPlan = async (userId, connection) => {
|
|
155
|
+
try {
|
|
156
|
+
const purchasedPlans = await getPurchasedPlans(userId, connection);
|
|
157
|
+
const currentDate = new Date();
|
|
158
|
+
const activePlan = purchasedPlans.find((plan) => {
|
|
159
|
+
if (plan.status !== 'paid')
|
|
160
|
+
return false;
|
|
161
|
+
return plan.startAt <= currentDate && plan.endAt >= currentDate;
|
|
162
|
+
});
|
|
163
|
+
return activePlan || freePurchasedPlan;
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
logger.error('Error in getActivePurchasedPlan function', error);
|
|
167
|
+
throw getErrorResponseObj({
|
|
168
|
+
errorMsg: 'An error occurred while retrieving the active purchased plan.',
|
|
169
|
+
solution: 'Please try again later or contact support if the issue persists.',
|
|
170
|
+
}, error);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
purchasedPlansRouter.get('/', async (request, response) => {
|
|
174
|
+
await initializeConnection(async (connection) => {
|
|
175
|
+
try {
|
|
176
|
+
const userId = request.user.id;
|
|
177
|
+
const purchasedPlans = await getPurchasedPlans(userId, connection);
|
|
178
|
+
const activePlan = await getActivePurchasedPlan(userId, connection);
|
|
179
|
+
sendSuccessResponse(response, getResponseObj({ purchasedPlans, activePlan }));
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
logger.error('Error in purchased-plans command', error);
|
|
183
|
+
throwErrorInResponseIfErrorIsNotCustom(response, error, {
|
|
184
|
+
errorMsg: 'An error occurred while retrieving purchased plans.',
|
|
185
|
+
solution: 'Please try again later or contact support if the issue persists.',
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
export default purchasedPlansRouter;
|
|
191
|
+
//# sourceMappingURL=purchased-plans.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"purchased-plans.js","sourceRoot":"","sources":["../../../src/routes/paid-plans/purchased-plans.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { FAQItem, purchasedPlansInf } from '../../types.js';
|
|
2
|
+
import { Plan } from './billingsdk-config.js';
|
|
3
|
+
export declare const getCurrencySymbol: (currency: string) => "₹" | "$" | "€" | "£" | "₣" | "¥" | "kr" | "R" | "";
|
|
4
|
+
export declare const getDisplayPaymentMethod: (paymentMethod: string) => string;
|
|
5
|
+
export declare const isFreePlan: (plan: purchasedPlansInf | undefined) => boolean;
|
|
6
|
+
export declare let CURRENCY: string;
|
|
7
|
+
export declare let CURRENCY_SYMBOL: string;
|
|
8
|
+
export declare const freePurchasedPlan: {
|
|
9
|
+
plan_id: string;
|
|
10
|
+
purchased_at: string;
|
|
11
|
+
status: string;
|
|
12
|
+
amount: string;
|
|
13
|
+
z_order_id: string;
|
|
14
|
+
};
|
|
15
|
+
export declare const plans: Plan[];
|
|
16
|
+
export declare let faqs: {
|
|
17
|
+
question: string;
|
|
18
|
+
answer: string;
|
|
19
|
+
}[];
|
|
20
|
+
declare const setCurrency: (currency: any, currencySymbol: string) => void;
|
|
21
|
+
declare const setFreePlan: (freePlan: typeof freePurchasedPlan) => void;
|
|
22
|
+
declare const setPremiumPlans: (premiumPlans: Plan[]) => void;
|
|
23
|
+
declare const setFaqs: (faqItems: FAQItem[]) => void;
|
|
24
|
+
export { setCurrency, setFreePlan, setPremiumPlans, setFaqs };
|
|
25
|
+
//# sourceMappingURL=subscription-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscription-utils.d.ts","sourceRoot":"","sources":["../../../src/routes/paid-plans/subscription-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAE9C,eAAO,MAAM,iBAAiB,GAAI,UAAU,MAAM,wDAgBjD,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,eAAe,MAAM,WAM5D,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,MAAM,iBAAiB,GAAG,SAAS,YAAwC,CAAC;AAGvG,eAAO,IAAI,QAAQ,QAAQ,CAAC;AAC5B,eAAO,IAAI,eAAe,QAA8B,CAAC;AAEzD,eAAO,MAAM,iBAAiB;;;;;;CAM7B,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,IAAI,EAiFvB,CAAC;AAEF,eAAO,IAAI,IAAI;;;GAKd,CAAC;AAEF,QAAA,MAAM,WAAW,GAAI,UAAU,GAAG,EAAE,gBAAgB,MAAM,SAGzD,CAAC;AAEF,QAAA,MAAM,WAAW,GAAI,UAAU,OAAO,iBAAiB,SAEtD,CAAC;AAEF,QAAA,MAAM,eAAe,GAAI,cAAc,IAAI,EAAE,SAE5C,CAAC;AAEF,QAAA,MAAM,OAAO,GAAI,UAAU,OAAO,EAAE,SAEnC,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC"}
|