diff --git a/dashboard/components/banner/Offer.vue b/dashboard/components/banner/Offer.vue index 49a8680..e2ba0a7 100644 --- a/dashboard/components/banner/Offer.vue +++ b/dashboard/components/banner/Offer.vue @@ -7,11 +7,7 @@ function goToUpgrade() { showDrawer('PRICING'); } -const { project } = useProject() - -const isPremium = computed(() => { - return project.value?.premium ?? false; -}); +const { isPremium } = useLoggedUser() diff --git a/dashboard/components/settings/billing.vue b/dashboard/components/settings/billing.vue index e05eb38..d148f2b 100644 --- a/dashboard/components/settings/billing.vue +++ b/dashboard/components/settings/billing.vue @@ -222,7 +222,7 @@ const { showDrawer } = useDrawer();
Usage:
- +
{{ percent }}
diff --git a/dashboard/composables/useLoggedUser.ts b/dashboard/composables/useLoggedUser.ts index 790b4ce..53efebc 100644 --- a/dashboard/composables/useLoggedUser.ts +++ b/dashboard/composables/useLoggedUser.ts @@ -11,17 +11,18 @@ const isLogged = computed(() => { return loggedUser.value?.logged; }) -function getUserRoles() { - const isPremium = computed(() => { - if (!loggedUser.value?.logged) return false; - return loggedUser.value.user.roles.includes('PREMIUM'); - }); - const isAdmin = computed(() => { - if (!loggedUser.value?.logged) return false; - return loggedUser.value.user.roles.includes('ADMIN'); - }); +const isAdmin = computed(() => { + if (!loggedUser.value?.logged) return false; + return loggedUser.value.user.roles.includes('ADMIN'); +}); - return { isPremium, isAdmin } +const isPremium = computed(() => { + if (!loggedUser.value?.logged) return false; + return loggedUser.value.user.roles.includes('PREMIUM'); +}); + +function getUserRoles() { + return { isAdmin, isPremium } } export const isAdminHidden = ref(false); @@ -29,6 +30,8 @@ export const isAdminHidden = ref(false); export function useLoggedUser() { return { isLogged, + isPremium, + isAdmin, user: loggedUser, userRoles: getUserRoles(), setLoggedUser diff --git a/dashboard/pages/dashboard/events.vue b/dashboard/pages/dashboard/events.vue index 5777ad2..589c73e 100644 --- a/dashboard/pages/dashboard/events.vue +++ b/dashboard/pages/dashboard/events.vue @@ -6,7 +6,8 @@ definePageMeta({ layout: 'dashboard' }); const { project } = useProject(); -const isPremium = computed(() => (project.value?.premium_type || 0) > 0); +const { isPremium } = useLoggedUser(); + const selfhosted = useSelfhosted(); const canDownload = computed(() => { if (selfhosted) return true; diff --git a/dashboard/pages/dashboard/visits.vue b/dashboard/pages/dashboard/visits.vue index 3b1a0c0..4f10277 100644 --- a/dashboard/pages/dashboard/visits.vue +++ b/dashboard/pages/dashboard/visits.vue @@ -6,7 +6,8 @@ definePageMeta({ layout: 'dashboard' }); const { project } = useProject(); -const isPremium = computed(() => (project.value?.premium_type || 0) > 0); +const { isPremium } = useLoggedUser(); + const selfhosted = useSelfhosted(); const canDownload = computed(() => { if (selfhosted) return true; diff --git a/dashboard/server/ai/functions/AI_Billing.ts b/dashboard/server/ai/functions/AI_Billing.ts index f276156..0372350 100644 --- a/dashboard/server/ai/functions/AI_Billing.ts +++ b/dashboard/server/ai/functions/AI_Billing.ts @@ -1,5 +1,5 @@ -import { ProjectLimitModel } from "@schema/project/ProjectsLimits"; +import { UserLimitModel } from "@schema/UserLimitSchema"; import { AIPlugin } from "../Plugin"; import { MAX_LOG_LIMIT_PERCENT } from "@data/broker/Limits"; import { ProjectModel } from "@schema/project/ProjectSchema"; @@ -16,11 +16,11 @@ export class AiBilling extends AIPlugin<[ super({ 'getInvoices': { - handler: async (data: { project_id: string }) => { + handler: async (data: { user_id: string }) => { - const project = await ProjectModel.findOne({ _id: data.project_id }); + const project = await ProjectModel.findOne({ user_id: data.user_id }); if (!project) return { error: 'Project not found' }; - const invoices = await StripeService.getInvoices(project.customer_id); + const invoices = await StripeService.getInvoices(data.user_id); if (!invoices) return []; return invoices?.data.map(e => { @@ -45,46 +45,44 @@ export class AiBilling extends AIPlugin<[ }, 'getBillingInfo': { - handler: async (data: { project_id: string }) => { + handler: async (data: { user_id: string }) => { - const project = await ProjectModel.findOne({ _id: data.project_id }); - if (!project) return { error: 'Project not found' }; + return { error: 'NOT IMPLEMENTED YET' } + // if (project.subscription_id === 'onetime') { - if (project.subscription_id === 'onetime') { + // const projectLimits = await ProjectLimitModel.findOne({ project_id: data.project_id }); + // if (!projectLimits) return { error: 'Limits not found' } - const projectLimits = await ProjectLimitModel.findOne({ project_id: data.project_id }); - if (!projectLimits) return { error: 'Limits not found' } + // const result = { + // premium: project.premium, + // premium_type: project.premium_type, + // billing_start_at: projectLimits.billing_start_at, + // billing_expire_at: projectLimits.billing_expire_at, + // limit: projectLimits.limit, + // count: projectLimits.events + projectLimits.visits, + // subscription_status: StripeService.isDisabled() ? 'Disabled mode' : ('One time payment') + // } - const result = { - premium: project.premium, - premium_type: project.premium_type, - billing_start_at: projectLimits.billing_start_at, - billing_expire_at: projectLimits.billing_expire_at, - limit: projectLimits.limit, - count: projectLimits.events + projectLimits.visits, - subscription_status: StripeService.isDisabled() ? 'Disabled mode' : ('One time payment') - } + // return result; + // } - return result; - } + // const subscription = await StripeService.getSubscription(project.subscription_id); - const subscription = await StripeService.getSubscription(project.subscription_id); - - const projectLimits = await ProjectLimitModel.findOne({ project_id: data.project_id }); - if (!projectLimits) return { error: 'Limits not found' } + // const projectLimits = await ProjectLimitModel.findOne({ project_id: data.project_id }); + // if (!projectLimits) return { error: 'Limits not found' } - const result = { - premium: project.premium, - premium_type: project.premium_type, - billing_start_at: projectLimits.billing_start_at, - billing_expire_at: projectLimits.billing_expire_at, - limit: projectLimits.limit, - count: projectLimits.events + projectLimits.visits, - subscription_status: StripeService.isDisabled() ? 'Disabled mode' : (subscription?.status ?? '?') - } + // const result = { + // premium: project.premium, + // premium_type: project.premium_type, + // billing_start_at: projectLimits.billing_start_at, + // billing_expire_at: projectLimits.billing_expire_at, + // limit: projectLimits.limit, + // count: projectLimits.events + projectLimits.visits, + // subscription_status: StripeService.isDisabled() ? 'Disabled mode' : (subscription?.status ?? '?') + // } - return result; + // return result; }, tool: { type: 'function', @@ -98,16 +96,17 @@ export class AiBilling extends AIPlugin<[ 'getLimits': { handler: async (data: { project_id: string }) => { - const projectLimits = await ProjectLimitModel.findOne({ project_id: data.project_id }); - if (!projectLimits) return { error: 'Project limits not found' }; - const TOTAL_COUNT = projectLimits.events + projectLimits.visits; - const COUNT_LIMIT = projectLimits.limit; - return { - total: TOTAL_COUNT, - limit: COUNT_LIMIT, - limited: TOTAL_COUNT > COUNT_LIMIT * MAX_LOG_LIMIT_PERCENT, - percent: Math.round(100 / COUNT_LIMIT * TOTAL_COUNT) - } + return { error: 'NOT IMPLEMENTED YET' } + // const projectLimits = await ProjectLimitModel.findOne({ project_id: data.project_id }); + // if (!projectLimits) return { error: 'Project limits not found' }; + // const TOTAL_COUNT = projectLimits.events + projectLimits.visits; + // const COUNT_LIMIT = projectLimits.limit; + // return { + // total: TOTAL_COUNT, + // limit: COUNT_LIMIT, + // limited: TOTAL_COUNT > COUNT_LIMIT * MAX_LOG_LIMIT_PERCENT, + // percent: Math.round(100 / COUNT_LIMIT * TOTAL_COUNT) + // } }, tool: { type: 'function', diff --git a/dashboard/server/api/admin/details.ts b/dashboard/server/api/admin/details.ts index b42e8d2..e01f4ab 100644 --- a/dashboard/server/api/admin/details.ts +++ b/dashboard/server/api/admin/details.ts @@ -1,8 +1,9 @@ import { ProjectModel } from "@schema/project/ProjectSchema"; import { ProjectCountModel } from "@schema/project/ProjectsCounts"; -import { ProjectLimitModel } from "@schema/project/ProjectsLimits"; +import { UserLimitModel } from "@schema/UserLimitSchema"; import { UserModel } from "@schema/UserSchema"; import StripeService from '~/server/services/StripeService'; +import { PremiumModel } from "~/shared/schema/PremiumSchema"; export default defineEventHandler(async event => { const userData = getRequestUser(event); @@ -13,18 +14,20 @@ export default defineEventHandler(async event => { if (!project_id) return setResponseStatus(event, 400, 'ProjectId is required'); const project = await ProjectModel.findById(project_id); - const limits = await ProjectLimitModel.findOne({ project_id }); + const limits = await UserLimitModel.findOne({ user_id: userData.id }); const counts = await ProjectCountModel.findOne({ project_id }); const user = await UserModel.findOne({ project_id }); + const premium = await PremiumModel.findOne({ user_id: userData.id }); + const subscription = - project?.subscription_id ? - await StripeService.getSubscription(project.subscription_id) : 'NONE'; + premium?.subscription_id ? + await StripeService.getSubscription(premium.subscription_id) : 'NONE'; const customer = - project?.customer_id ? - await StripeService.getCustomer(project.customer_id) : 'NONE'; + premium?.customer_id ? + await StripeService.getCustomer(premium.customer_id) : 'NONE'; return { project, limits, counts, user, subscription, customer } - + }); \ No newline at end of file diff --git a/dashboard/server/api/ai/chats_list.ts b/dashboard/server/api/ai/chats_list.ts index 3878f2a..53036ea 100644 --- a/dashboard/server/api/ai/chats_list.ts +++ b/dashboard/server/api/ai/chats_list.ts @@ -4,7 +4,7 @@ import { AiChatModel } from "@schema/ai/AiChatSchema"; export default defineEventHandler(async event => { - const data = await getRequestDataOld(event); + const data = await getRequestData(event, [], ['AI']); if (!data) return; const { project_id } = data; diff --git a/dashboard/server/api/ai/chats_remaining.ts b/dashboard/server/api/ai/chats_remaining.ts index 1ec3bed..5b4e828 100644 --- a/dashboard/server/api/ai/chats_remaining.ts +++ b/dashboard/server/api/ai/chats_remaining.ts @@ -1,10 +1,10 @@ -import { ProjectLimitModel } from "@schema/project/ProjectsLimits"; -export async function getAiChatRemainings(project_id: string) { - const limits = await ProjectLimitModel.findOne({ project_id }) +import { UserLimitModel } from "@schema/UserLimitSchema"; + +export async function getAiChatRemainings(user_id: string) { + const limits = await UserLimitModel.findOne({ user_id }) if (!limits) return 0; const chatsRemaining = limits.ai_limit - limits.ai_messages; - if (isNaN(chatsRemaining)) return 0; return chatsRemaining; } @@ -13,8 +13,8 @@ export default defineEventHandler(async event => { const data = await getRequestData(event, [], ['AI']); if (!data) return; - const { pid } = data; + const { pid, user } = data; - const chatsRemaining = await getAiChatRemainings(pid); + const chatsRemaining = await getAiChatRemainings(user.id); return chatsRemaining; }); \ No newline at end of file diff --git a/dashboard/server/api/ai/send_message.post.ts b/dashboard/server/api/ai/send_message.post.ts index 665721e..c676d65 100644 --- a/dashboard/server/api/ai/send_message.post.ts +++ b/dashboard/server/api/ai/send_message.post.ts @@ -1,6 +1,6 @@ import { sendMessageOnChat, updateChatStatus } from "~/server/services/AiService"; import { getAiChatRemainings } from "./chats_remaining"; -import { ProjectLimitModel } from "@schema/project/ProjectsLimits"; +import { UserLimitModel } from "@schema/UserLimitSchema"; @@ -8,16 +8,15 @@ export default defineEventHandler(async event => { const data = await getRequestData(event, [], ['AI']); if (!data) return; - const { pid } = data; + const { pid, user } = data; const { text, chat_id, timeOffset } = await readBody(event); if (!text) return setResponseStatus(event, 400, 'text parameter missing'); - const chatsRemaining = await getAiChatRemainings(pid); + const chatsRemaining = await getAiChatRemainings(user.id); if (chatsRemaining <= 0) return setResponseStatus(event, 400, 'CHAT_LIMIT_REACHED'); - - await ProjectLimitModel.updateOne({ project_id: pid }, { $inc: { ai_messages: 1 } }); + await UserLimitModel.updateOne({ user_id: user.id }, { $inc: { ai_messages: 1 } }); const currentStatus: string[] = []; diff --git a/dashboard/server/api/pay/customer_info.ts b/dashboard/server/api/pay/customer_info.ts index 790df04..634d852 100644 --- a/dashboard/server/api/pay/customer_info.ts +++ b/dashboard/server/api/pay/customer_info.ts @@ -1,16 +1,18 @@ import StripeService from '~/server/services/StripeService'; +import { PremiumModel } from '~/shared/schema/PremiumSchema'; export default defineEventHandler(async event => { const data = await getRequestData(event, []); if (!data) return; - const { project } = data; + const premium = await PremiumModel.findOne({ user_id: data.user.id }) + if (!premium) return; - const customer = await StripeService.getCustomer(project.customer_id); + const customer = await StripeService.getCustomer(premium.customer_id); if (customer?.deleted) return; - + return customer?.address; }); \ No newline at end of file diff --git a/dashboard/server/api/pay/invoices.ts b/dashboard/server/api/pay/invoices.ts index e8cc59c..8d2a79e 100644 --- a/dashboard/server/api/pay/invoices.ts +++ b/dashboard/server/api/pay/invoices.ts @@ -1,6 +1,7 @@ import { getUserProjectFromId } from "~/server/LIVE_DEMO_DATA"; import { Redis } from "~/server/services/CacheService"; import StripeService from '~/server/services/StripeService'; +import { PremiumModel } from "~/shared/schema/PremiumSchema"; export type InvoiceData = { @@ -15,13 +16,13 @@ export default defineEventHandler(async event => { const data = await getRequestData(event, []); if (!data) return; - const { project, pid } = data; - if (!project.customer_id) return []; + return await Redis.useCache({ key: `invoices:${data.user.id}`, exp: 10 }, async () => { - return await Redis.useCache({ key: `invoices:${pid}`, exp: 10 }, async () => { - - const invoices = await StripeService.getInvoices(project.customer_id); + const premium = await PremiumModel.findOne({ user_id: data.user.id }); + if (!premium) return []; + + const invoices = await StripeService.getInvoices(premium.customer_id); if (!invoices) return []; return invoices?.data.map(e => { diff --git a/dashboard/server/api/pay/webhook.post.ts b/dashboard/server/api/pay/webhook.post.ts index 7a75e0b..fdeb88d 100644 --- a/dashboard/server/api/pay/webhook.post.ts +++ b/dashboard/server/api/pay/webhook.post.ts @@ -1,268 +1,270 @@ -import StripeService from '~/server/services/StripeService'; -import type Event from 'stripe'; -import { ProjectModel } from '@schema/project/ProjectSchema'; -import { PREMIUM_DATA, PREMIUM_PLAN, getPlanFromId, getPlanFromPrice, getPlanFromTag } from '@data/PREMIUM'; -import { ProjectLimitModel } from '@schema/project/ProjectsLimits'; -import { EmailService } from '@services/EmailService' -import { UserModel } from '@schema/UserSchema'; -import { EmailServiceHelper } from '~/server/services/EmailServiceHelper'; +// import StripeService from '~/server/services/StripeService'; +// import type Event from 'stripe'; +// import { ProjectModel } from '@schema/project/ProjectSchema'; +// import { PREMIUM_DATA, PREMIUM_PLAN, getPlanFromId, getPlanFromPrice, getPlanFromTag } from '@data/PREMIUM'; +// import { ProjectLimitModel } from '@schema/project/ProjectsLimits'; +// import { EmailService } from '@services/EmailService' +// import { UserModel } from '@schema/UserSchema'; +// import { EmailServiceHelper } from '~/server/services/EmailServiceHelper'; -async function addSubscriptionToProject(project_id: string, plan: PREMIUM_DATA, subscription_id: string, current_period_start: number, current_period_end: number) { +// async function addSubscriptionToProject(project_id: string, plan: PREMIUM_DATA, subscription_id: string, current_period_start: number, current_period_end: number) { - await ProjectModel.updateOne({ _id: project_id }, { - premium: plan.ID != 0, - premium_type: plan.ID, - subscription_id, - premium_expire_at: current_period_end * 1000 - }); +// await ProjectModel.updateOne({ _id: project_id }, { +// premium: plan.ID != 0, +// premium_type: plan.ID, +// subscription_id, +// premium_expire_at: current_period_end * 1000 +// }); - await ProjectLimitModel.updateOne({ project_id }, { - events: 0, - visits: 0, - ai_messages: 0, - limit: plan.COUNT_LIMIT, - ai_limit: plan.AI_MESSAGE_LIMIT, - billing_start_at: current_period_start * 1000, - billing_expire_at: current_period_end * 1000, - }, { upsert: true }) +// await ProjectLimitModel.updateOne({ project_id }, { +// events: 0, +// visits: 0, +// ai_messages: 0, +// limit: plan.COUNT_LIMIT, +// ai_limit: plan.AI_MESSAGE_LIMIT, +// billing_start_at: current_period_start * 1000, +// billing_expire_at: current_period_end * 1000, +// }, { upsert: true }) -} +// } -async function onPaymentFailed(event: Event.InvoicePaymentFailedEvent) { +// async function onPaymentFailed(event: Event.InvoicePaymentFailedEvent) { - //TODO: Send emails +// //TODO: Send emails - if (event.data.object.attempt_count > 1) { - const customer_id = event.data.object.customer as string; - const project = await ProjectModel.findOne({ customer_id }); - if (!project) return { error: 'CUSTOMER NOT EXIST' } +// if (event.data.object.attempt_count > 1) { +// const customer_id = event.data.object.customer as string; +// const project = await ProjectModel.findOne({ customer_id }); +// if (!project) return { error: 'CUSTOMER NOT EXIST' } - const allSubscriptions = await StripeService.getAllSubscriptions(customer_id); - if (!allSubscriptions) return; +// const allSubscriptions = await StripeService.getAllSubscriptions(customer_id); +// if (!allSubscriptions) return; - for (const subscription of allSubscriptions.data) { - await StripeService.deleteSubscription(subscription.id); - } +// for (const subscription of allSubscriptions.data) { +// await StripeService.deleteSubscription(subscription.id); +// } - const freeSub = await StripeService.createFreeSubscription(customer_id); - if (!freeSub) return; +// const freeSub = await StripeService.createFreeSubscription(customer_id); +// if (!freeSub) return; - await addSubscriptionToProject( - project._id.toString(), - getPlanFromTag('FREE'), - freeSub.id, - freeSub.current_period_start, - freeSub.current_period_end - ) +// await addSubscriptionToProject( +// project._id.toString(), +// getPlanFromTag('FREE'), +// freeSub.id, +// freeSub.current_period_start, +// freeSub.current_period_end +// ) - return { ok: true }; - } +// return { ok: true }; +// } -} +// } -async function onPaymentOnetimeSuccess(event: Event.PaymentIntentSucceededEvent) { - const customer_id = event.data.object.customer as string; - const project = await ProjectModel.findOne({ customer_id }); - if (!project) return { error: 'CUSTOMER NOT EXIST' } +// async function onPaymentOnetimeSuccess(event: Event.PaymentIntentSucceededEvent) { +// const customer_id = event.data.object.customer as string; +// const project = await ProjectModel.findOne({ customer_id }); +// if (!project) return { error: 'CUSTOMER NOT EXIST' } - if (event.data.object.status === 'succeeded') { +// if (event.data.object.status === 'succeeded') { - const PLAN = getPlanFromPrice(event.data.object.metadata.price, StripeService.testMode || false); - if (!PLAN) return { error: 'Plan not found' } - const dummyPlan = PLAN.ID + 3000; +// const PLAN = getPlanFromPrice(event.data.object.metadata.price, StripeService.testMode || false); +// if (!PLAN) return { error: 'Plan not found' } +// const dummyPlan = PLAN.ID + 3000; - const subscription = await StripeService.createOneTimeSubscriptionDummy(customer_id, dummyPlan); - if (!subscription) return { error: 'Error creating subscription' } +// const subscription = await StripeService.createOneTimeSubscriptionDummy(customer_id, dummyPlan); +// if (!subscription) return { error: 'Error creating subscription' } - const allSubscriptions = await StripeService.getAllSubscriptions(customer_id); - if (!allSubscriptions) return; - for (const subscription of allSubscriptions.data) { - if (subscription.id === subscription.id) continue; - await StripeService.deleteSubscription(subscription.id); - } +// const allSubscriptions = await StripeService.getAllSubscriptions(customer_id); +// if (!allSubscriptions) return; +// for (const subscription of allSubscriptions.data) { +// if (subscription.id === subscription.id) continue; +// await StripeService.deleteSubscription(subscription.id); +// } - await addSubscriptionToProject(project._id.toString(), PLAN, subscription.id, subscription.current_period_start, subscription.current_period_end) +// await addSubscriptionToProject(project._id.toString(), PLAN, subscription.id, subscription.current_period_start, subscription.current_period_end) - const user = await UserModel.findOne({ _id: project.owner }); - if (!user) return { ok: false, error: 'USER NOT EXIST FOR PROJECT' + project.id } +// const user = await UserModel.findOne({ _id: project.owner }); +// if (!user) return { ok: false, error: 'USER NOT EXIST FOR PROJECT' + project.id } - setTimeout(() => { - const emailData = EmailService.getEmailServerInfo('purchase', { target: user.email, projectName: project.name }); - EmailServiceHelper.sendEmail(emailData); - }, 1); +// setTimeout(() => { +// const emailData = EmailService.getEmailServerInfo('purchase', { target: user.email, projectName: project.name }); +// EmailServiceHelper.sendEmail(emailData); +// }, 1); - return { ok: true }; - } +// return { ok: true }; +// } - return { received: true, warn: 'object status not succeeded' } -} +// return { received: true, warn: 'object status not succeeded' } +// } -async function onPaymentSuccess(event: Event.InvoicePaidEvent) { +// async function onPaymentSuccess(event: Event.InvoicePaidEvent) { - const customer_id = event.data.object.customer as string; - const project = await ProjectModel.findOne({ customer_id }); - if (!project) return { error: 'CUSTOMER NOT EXIST' } +// const customer_id = event.data.object.customer as string; +// const project = await ProjectModel.findOne({ customer_id }); +// if (!project) return { error: 'CUSTOMER NOT EXIST' } - if (event.data.object.status === 'paid') { +// if (event.data.object.status === 'paid') { - const subscription_id = event.data.object.subscription as string; +// const subscription_id = event.data.object.subscription as string; - const isNewSubscription = project.subscription_id != subscription_id; +// const isNewSubscription = project.subscription_id != subscription_id; - const allSubscriptions = await StripeService.getAllSubscriptions(customer_id); - if (!allSubscriptions) return; +// const allSubscriptions = await StripeService.getAllSubscriptions(customer_id); +// if (!allSubscriptions) return; - const currentSubscription = allSubscriptions.data.find(e => e.id === subscription_id); - if (!currentSubscription) return { error: 'SUBSCRIPTION NOT EXIST' } +// const currentSubscription = allSubscriptions.data.find(e => e.id === subscription_id); +// if (!currentSubscription) return { error: 'SUBSCRIPTION NOT EXIST' } - if (currentSubscription.status !== 'active') return { error: 'SUBSCRIPTION NOT ACTIVE' } +// if (currentSubscription.status !== 'active') return { error: 'SUBSCRIPTION NOT ACTIVE' } - for (const subscription of allSubscriptions.data) { - if (subscription.id === subscription_id) continue; - await StripeService.deleteSubscription(subscription.id); - } +// for (const subscription of allSubscriptions.data) { +// if (subscription.id === subscription_id) continue; +// await StripeService.deleteSubscription(subscription.id); +// } - const price = currentSubscription.items.data[0].price.id; - if (!price) return { error: 'Price not found' } +// const price = currentSubscription.items.data[0].price.id; +// if (!price) return { error: 'Price not found' } - const PLAN = getPlanFromPrice(price, StripeService.testMode || false); - if (!PLAN) return { error: `Plan not found. Price: ${price}. TestMode: ${StripeService.testMode}` } +// const PLAN = getPlanFromPrice(price, StripeService.testMode || false); +// if (!PLAN) return { error: `Plan not found. Price: ${price}. TestMode: ${StripeService.testMode}` } - await addSubscriptionToProject(project._id.toString(), PLAN, subscription_id, currentSubscription.current_period_start, currentSubscription.current_period_end) +// await addSubscriptionToProject(project._id.toString(), PLAN, subscription_id, currentSubscription.current_period_start, currentSubscription.current_period_end) - const user = await UserModel.findOne({ _id: project.owner }); - if (!user) return { ok: false, error: 'USER NOT EXIST FOR PROJECT' + project.id } +// const user = await UserModel.findOne({ _id: project.owner }); +// if (!user) return { ok: false, error: 'USER NOT EXIST FOR PROJECT' + project.id } - setTimeout(() => { - if (PLAN.ID == 0) return; - const emailData = EmailService.getEmailServerInfo('purchase', { target: user.email, projectName: project.name }); - EmailServiceHelper.sendEmail(emailData); - }, 1); +// setTimeout(() => { +// if (PLAN.ID == 0) return; +// const emailData = EmailService.getEmailServerInfo('purchase', { target: user.email, projectName: project.name }); +// EmailServiceHelper.sendEmail(emailData); +// }, 1); - return { ok: true }; +// return { ok: true }; - } - return { received: true, warn: 'payment status not paid' } -} +// } +// return { received: true, warn: 'payment status not paid' } +// } -async function onSubscriptionCreated(event: Event.CustomerSubscriptionCreatedEvent) { +// async function onSubscriptionCreated(event: Event.CustomerSubscriptionCreatedEvent) { - // const project = await ProjectModel.findOne({ customer_id: event.data.object.customer }); - // if (!project) return { error: 'CUSTOMER NOT EXIST' } +// // const project = await ProjectModel.findOne({ customer_id: event.data.object.customer }); +// // if (!project) return { error: 'CUSTOMER NOT EXIST' } - // const price = event.data.object.items.data[0].price.id; - // if (!price) return { error: 'Price not found' } +// // const price = event.data.object.items.data[0].price.id; +// // if (!price) return { error: 'Price not found' } - // const PLAN = getPlanFromPrice(price, StripeService.testMode || false); - // if (!PLAN) return { error: 'Plan not found' } +// // const PLAN = getPlanFromPrice(price, StripeService.testMode || false); +// // if (!PLAN) return { error: 'Plan not found' } - // if (project.subscription_id != event.data.object.id) { - // try { - // await StripeService.deleteSubscription(project.subscription_id); - // } catch (ex) { } - // } +// // if (project.subscription_id != event.data.object.id) { +// // try { +// // await StripeService.deleteSubscription(project.subscription_id); +// // } catch (ex) { } +// // } - // if (event.data.object.status === 'active') { - // await addSubscriptionToProject( - // project._id.toString(), - // PLAN, - // event.data.object.id, - // event.data.object.current_period_start, - // event.data.object.current_period_end - // ); - // } +// // if (event.data.object.status === 'active') { +// // await addSubscriptionToProject( +// // project._id.toString(), +// // PLAN, +// // event.data.object.id, +// // event.data.object.current_period_start, +// // event.data.object.current_period_end +// // ); +// // } - return { ok: true } -} +// return { ok: true } +// } -async function onSubscriptionDeleted(event: Event.CustomerSubscriptionDeletedEvent) { +// async function onSubscriptionDeleted(event: Event.CustomerSubscriptionDeletedEvent) { - // const project = await ProjectModel.findOne({ - // customer_id: event.data.object.customer, - // subscription_id: event.data.object.id - // }); +// // const project = await ProjectModel.findOne({ +// // customer_id: event.data.object.customer, +// // subscription_id: event.data.object.id +// // }); - // if (!project) return { error: 'PROJECT WITH SUBSCRIPTION NOT FOUND' } +// // if (!project) return { error: 'PROJECT WITH SUBSCRIPTION NOT FOUND' } - // const targetCustomer = await StripeService.getCustomer(project.customer_id); +// // const targetCustomer = await StripeService.getCustomer(project.customer_id); - // let customer: Event.Customer; +// // let customer: Event.Customer; - // if (!targetCustomer.deleted) { - // customer = targetCustomer; - // } else { - // const user = await UserModel.findById(project._id, { email: 1 }); - // if (!user) return { error: 'User not found' } - // const newCustomer = await StripeService.createCustomer(user.email); - // customer = newCustomer; - // } +// // if (!targetCustomer.deleted) { +// // customer = targetCustomer; +// // } else { +// // const user = await UserModel.findById(project._id, { email: 1 }); +// // if (!user) return { error: 'User not found' } +// // const newCustomer = await StripeService.createCustomer(user.email); +// // customer = newCustomer; +// // } - // await StripeService.createFreeSubscription(customer.id); +// // await StripeService.createFreeSubscription(customer.id); - return { received: true } -} +// return { received: true } +// } -async function onSubscriptionUpdated(event: Event.CustomerSubscriptionUpdatedEvent) { +// async function onSubscriptionUpdated(event: Event.CustomerSubscriptionUpdatedEvent) { - // const project = await ProjectModel.findOne({ - // customer_id: event.data.object.customer, - // }); +// // const project = await ProjectModel.findOne({ +// // customer_id: event.data.object.customer, +// // }); - // if (!project) return { error: 'Project not found' } +// // if (!project) return { error: 'Project not found' } - // const price = event.data.object.items.data[0].price.id; - // if (!price) return { error: 'Price not found' } +// // const price = event.data.object.items.data[0].price.id; +// // if (!price) return { error: 'Price not found' } - // const PLAN = getPlanFromPrice(price, StripeService.testMode || false); - // if (!PLAN) return { error: 'Plan not found' } +// // const PLAN = getPlanFromPrice(price, StripeService.testMode || false); +// // if (!PLAN) return { error: 'Plan not found' } - // if (event.data.object.status === 'active') { - // await addSubscriptionToProject( - // project._id.toString(), - // PLAN, - // event.data.object.id, - // event.data.object.current_period_start, - // event.data.object.current_period_end - // ); - // } +// // if (event.data.object.status === 'active') { +// // await addSubscriptionToProject( +// // project._id.toString(), +// // PLAN, +// // event.data.object.id, +// // event.data.object.current_period_start, +// // event.data.object.current_period_end +// // ); +// // } - return { ok: true } -} +// return { ok: true } +// } export default defineEventHandler(async event => { - const body = await readRawBody(event); - const signature = getHeader(event, 'stripe-signature') || ''; - const eventData = StripeService.parseWebhook(body, signature); - if (!eventData) return; + return { error: 'NOT IMPLEMENTED ANYMORE' } + // const body = await readRawBody(event); + // const signature = getHeader(event, 'stripe-signature') || ''; - // console.log('WEBHOOK FIRED', eventData.type); + // const eventData = StripeService.parseWebhook(body, signature); + // if (!eventData) return; - if (eventData.type === 'invoice.paid') return await onPaymentSuccess(eventData); - if (eventData.type === 'payment_intent.succeeded') return await onPaymentOnetimeSuccess(eventData); - if (eventData.type === 'invoice.payment_failed') return await onPaymentFailed(eventData); - if (eventData.type === 'customer.subscription.deleted') return await onSubscriptionDeleted(eventData); - if (eventData.type === 'customer.subscription.created') return await onSubscriptionCreated(eventData); - if (eventData.type === 'customer.subscription.updated') return await onSubscriptionUpdated(eventData); + // // console.log('WEBHOOK FIRED', eventData.type); - return { received: true } + // if (eventData.type === 'invoice.paid') return await onPaymentSuccess(eventData); + // if (eventData.type === 'payment_intent.succeeded') return await onPaymentOnetimeSuccess(eventData); + // if (eventData.type === 'invoice.payment_failed') return await onPaymentFailed(eventData); + // if (eventData.type === 'customer.subscription.deleted') return await onSubscriptionDeleted(eventData); + // if (eventData.type === 'customer.subscription.created') return await onSubscriptionCreated(eventData); + // if (eventData.type === 'customer.subscription.updated') return await onSubscriptionUpdated(eventData); + + // return { received: true } }); \ No newline at end of file diff --git a/dashboard/server/api/project/create.post.ts b/dashboard/server/api/project/create.post.ts index 552db8a..d1a1751 100644 --- a/dashboard/server/api/project/create.post.ts +++ b/dashboard/server/api/project/create.post.ts @@ -1,7 +1,5 @@ import { ProjectModel, TProject } from "@schema/project/ProjectSchema"; import { ProjectCountModel } from "@schema/project/ProjectsCounts"; -import { ProjectLimitModel } from "@schema/project/ProjectsLimits"; -import { UserSettingsModel } from "@schema/UserSettings"; import StripeService from '~/server/services/StripeService'; export default defineEventHandler(async event => { @@ -41,16 +39,6 @@ export default defineEventHandler(async event => { sessions: 0 }); - await ProjectLimitModel.updateOne({ project_id: project._id }, { - events: 0, - visits: 0, - ai_messages: 0, - limit: 10_000_000, - ai_limit: 1_000_000, - billing_start_at: Date.now(), - billing_expire_at: new Date(3000, 1, 1) - }, { upsert: true }) - return project.toJSON() as TProject; } else { diff --git a/dashboard/server/api/project/delete.delete.ts b/dashboard/server/api/project/delete.delete.ts index 7272858..5ee8bf5 100644 --- a/dashboard/server/api/project/delete.delete.ts +++ b/dashboard/server/api/project/delete.delete.ts @@ -1,14 +1,12 @@ import { ProjectModel } from "@schema/project/ProjectSchema"; import { ProjectCountModel } from "@schema/project/ProjectsCounts"; -import { ProjectLimitModel } from "@schema/project/ProjectsLimits"; import { SessionModel } from "@schema/metrics/SessionSchema"; import { LimitNotifyModel } from "@schema/broker/LimitNotifySchema"; -import StripeService from '~/server/services/StripeService'; import { AiChatModel } from "@schema/ai/AiChatSchema"; export default defineEventHandler(async event => { - const data = await getRequestDataOld(event, { requireSchema: false, allowGuests: false, allowLitlyx: false }); + const data = await getRequestData(event, [], []); if (!data) return; const { project, user, project_id } = data; @@ -16,15 +14,9 @@ export default defineEventHandler(async event => { const projects = await ProjectModel.countDocuments({ owner: user.id }); if (projects == 1) return setResponseStatus(event, 400, 'Cannot delete last project'); - if (project.premium === true) return setResponseStatus(event, 400, 'Cannot delete premium project'); - - if (project.customer_id) { - await StripeService.deleteCustomer(project.customer_id); - } const projectDeletation = ProjectModel.deleteOne({ _id: project_id }); const countDeletation = ProjectCountModel.deleteMany({ project_id }); - const limitdeletation = ProjectLimitModel.deleteMany({ project_id }); const sessionsDeletation = SessionModel.deleteMany({ project_id }); const notifiesDeletation = LimitNotifyModel.deleteMany({ project_id }); const aiChatsDeletation = AiChatModel.deleteMany({ project_id }); @@ -32,7 +24,6 @@ export default defineEventHandler(async event => { const results = await Promise.all([ projectDeletation, countDeletation, - limitdeletation, sessionsDeletation, notifiesDeletation, aiChatsDeletation diff --git a/dashboard/server/api/project/limits_info.ts b/dashboard/server/api/project/limits_info.ts index 62c7218..194e19f 100644 --- a/dashboard/server/api/project/limits_info.ts +++ b/dashboard/server/api/project/limits_info.ts @@ -1,17 +1,15 @@ -import { ProjectLimitModel } from "@schema/project/ProjectsLimits"; +import { UserLimitModel } from "@schema/UserLimitSchema"; import { MAX_LOG_LIMIT_PERCENT } from '@data/broker/Limits'; export default defineEventHandler(async event => { - - - const data = await getRequestDataOld(event); + const data = await getRequestData(event, [], []); if (!data) return; - const { project_id } = data; + const { user } = data; - const projectLimits = await ProjectLimitModel.findOne({ project_id }); + const projectLimits = await UserLimitModel.findOne({ user_id: user.id }); if (!projectLimits) return; const TOTAL_COUNT = projectLimits.events + projectLimits.visits; diff --git a/dashboard/server/api/project/plan.ts b/dashboard/server/api/project/plan.ts index aa5b2ab..239fbb5 100644 --- a/dashboard/server/api/project/plan.ts +++ b/dashboard/server/api/project/plan.ts @@ -1,44 +1,46 @@ -import { ProjectLimitModel } from "@schema/project/ProjectsLimits"; +import { UserLimitModel } from "@schema/UserLimitSchema"; import StripeService from '~/server/services/StripeService'; +import { PremiumModel } from "~/shared/schema/PremiumSchema"; export default defineEventHandler(async event => { - const data = await getRequestData(event, []); + const data = await getRequestData(event, [], ['OWNER']); if (!data) return; - const { project, project_id } = data; + const premium = await PremiumModel.findOne({ user_id: data.user.id }); + if (!premium) return; - if (project.subscription_id === 'onetime') { + if (premium.subscription_id === 'onetime') { - const projectLimits = await ProjectLimitModel.findOne({ project_id }); - if (!projectLimits) return setResponseStatus(event, 400, 'Project limits not found'); + const userLimits = await UserLimitModel.findOne({ user_id: data.user.id }); + if (!userLimits) return setResponseStatus(event, 400, 'User limits not found'); const result = { - premium: project.premium, - premium_type: project.premium_type, - billing_start_at: projectLimits.billing_start_at, - billing_expire_at: projectLimits.billing_expire_at, - limit: projectLimits.limit, - count: projectLimits.events + projectLimits.visits, + premium: premium.premium_type > 0, + premium_type: premium.premium_type, + billing_start_at: userLimits.billing_start_at, + billing_expire_at: userLimits.billing_expire_at, + limit: userLimits.limit, + count: userLimits.events + userLimits.visits, subscription_status: StripeService.isDisabled() ? 'Disabled mode' : ('One time payment') } return result; } - const subscription = await StripeService.getSubscription(project.subscription_id); + const subscription = await StripeService.getSubscription(premium.subscription_id); - const projectLimits = await ProjectLimitModel.findOne({ project_id }); - if (!projectLimits) return setResponseStatus(event, 400, 'Project limits not found'); + const userLimits = await UserLimitModel.findOne({ user_id: data.user.id }); + if (!userLimits) return setResponseStatus(event, 400, 'User limits not found'); const result = { - premium: project.premium, - premium_type: project.premium_type, - billing_start_at: projectLimits.billing_start_at, - billing_expire_at: projectLimits.billing_expire_at, - limit: projectLimits.limit, - count: projectLimits.events + projectLimits.visits, + premium: premium.premium_type > 0, + premium_type: premium.premium_type, + billing_start_at: userLimits.billing_start_at, + billing_expire_at: userLimits.billing_expire_at, + limit: userLimits.limit, + count: userLimits.events + userLimits.visits, subscription_status: StripeService.isDisabled() ? 'Disabled mode' : (subscription?.status ?? '?') } diff --git a/dashboard/server/api/user/delete_account.delete.ts b/dashboard/server/api/user/delete_account.delete.ts index 9cafd5b..3d84b6c 100644 --- a/dashboard/server/api/user/delete_account.delete.ts +++ b/dashboard/server/api/user/delete_account.delete.ts @@ -1,7 +1,7 @@ import { ProjectModel } from "@schema/project/ProjectSchema"; import { ProjectCountModel } from "@schema/project/ProjectsCounts"; -import { ProjectLimitModel } from "@schema/project/ProjectsLimits"; +import { UserLimitModel } from "@schema/UserLimitSchema"; import { UserSettingsModel } from "@schema/UserSettings"; import { AiChatModel } from "@schema/ai/AiChatSchema"; import { LimitNotifyModel } from "@schema/broker/LimitNotifySchema"; @@ -14,6 +14,7 @@ import { CountryBlacklistModel } from "~/shared/schema/shields/CountryBlacklistS import { BotTrafficOptionModel } from "~/shared/schema/shields/BotTrafficOptionSchema"; import { TeamMemberModel } from "~/shared/schema/TeamMemberSchema"; import { PasswordModel } from "~/shared/schema/PasswordSchema"; +import { PremiumModel } from "~/shared/schema/PremiumSchema"; export default defineEventHandler(async event => { @@ -22,21 +23,25 @@ export default defineEventHandler(async event => { const projects = await ProjectModel.find({ owner: userData.id }); - const premiumProjects = projects.filter(e => { return e.premium && e.premium_type != 0 }).length; - if (premiumProjects > 0) return setResponseStatus(event, 400, 'Cannot delete an account with a premium project'); + const premium = await PremiumModel.findOne({ user_id: userData.id }); + if (!premium) return; + + if (premium.premium_type > 0) return setResponseStatus(event, 400, 'Cannot delete an account with a premium project'); const membersDeletation = await TeamMemberModel.deleteMany({ user_id: userData.id }); const membersEmailDeletation = await TeamMemberModel.deleteMany({ email: userData.user.email }); const passwordDeletation = await PasswordModel.deleteMany({ user_id: userData.id }); + const limitdeletation = await UserLimitModel.deleteMany({ user_id: userData.id }); + + await StripeService.deleteCustomer(premium.customer_id); + for (const project of projects) { const project_id = project._id; - await StripeService.deleteCustomer(project.customer_id); const projectDeletation = await ProjectModel.deleteOne({ _id: project_id }); const userSettingsDeletation = await UserSettingsModel.deleteOne({ project_id }); const countDeletation = await ProjectCountModel.deleteMany({ project_id }); - const limitdeletation = await ProjectLimitModel.deleteMany({ project_id }); const sessionsDeletation = await SessionModel.deleteMany({ project_id }); const notifiesDeletation = await LimitNotifyModel.deleteMany({ project_id }); const aiChatsDeletation = await AiChatModel.deleteMany({ project_id }); diff --git a/dashboard/server/api/user/max_projects.ts b/dashboard/server/api/user/max_projects.ts index 7065757..4c6e165 100644 --- a/dashboard/server/api/user/max_projects.ts +++ b/dashboard/server/api/user/max_projects.ts @@ -4,7 +4,5 @@ import { AuthContext } from "~/server/middleware/01-authorization"; export default defineEventHandler(async event => { const userData: AuthContext = getRequestUser(event) as any; if (!userData.logged) return; - // const userSettings = await UserSettingsModel.findOne({ user_id: userData.id }, { max_projects: 1 }); - // return userSettings?.max_projects || 3; return 20; }); \ No newline at end of file diff --git a/dashboard/server/middleware/01-authorization.ts b/dashboard/server/middleware/01-authorization.ts index 472145d..b4120d2 100644 --- a/dashboard/server/middleware/01-authorization.ts +++ b/dashboard/server/middleware/01-authorization.ts @@ -4,6 +4,7 @@ import { UserModel } from "@schema/UserSchema"; import { ADMIN_EMAILS } from '@data/ADMINS'; import type { H3Event, EventHandlerRequest } from 'h3'; +import { PremiumModel } from "~/shared/schema/PremiumSchema"; export type AuthContextLogged = { id: string, @@ -30,7 +31,7 @@ async function authorizationMiddleware(event: H3Event) { } else { const [type, token] = authorization.split(' '); - + const valid = readUserJwt(token); if (!valid) return event.context.auth = { logged: false } @@ -38,22 +39,28 @@ async function authorizationMiddleware(event: H3Event) { if (!user) return event.context.auth = { logged: false }; const roles: string[] = []; - + if (ADMIN_EMAILS.includes(user.email)) { roles.push('ADMIN'); } + const premium = await PremiumModel.findOne({ user_id: user.id }); + + if ((premium?.premium_type || 0) > 0) { + roles.push('PREMIUM'); + } + const authContext: AuthContext = { logged: true, user: { email: user.email, name: user.name, picture: user.picture || `https://robohash.org/${user.email}?set=set4`, - roles + roles, }, id: user._id.toString() } - + event.context.auth = authContext; } diff --git a/dashboard/server/services/AiService.ts b/dashboard/server/services/AiService.ts index 8a93ca3..7a87710 100644 --- a/dashboard/server/services/AiService.ts +++ b/dashboard/server/services/AiService.ts @@ -2,7 +2,6 @@ import OpenAI from "openai"; import { AiChatModel } from '@schema/ai/AiChatSchema'; -import { ProjectLimitModel } from '@schema/project/ProjectsLimits'; import { AiEventsInstance } from '../ai/functions/AI_Events'; import { AiVisitsInstance } from '../ai/functions/AI_Visits'; @@ -218,34 +217,5 @@ export async function sendMessageOnChat(text: string, pid: string, time_offset: return { content: ex.message, charts: [] }; } - // let response = await openai.chat.completions.create({ model: OPENAI_MODEL, messages, n: 1, tools }); - - // const chartsData: string[][] = []; - - // while ((response.choices[0].message.tool_calls?.length || 0) > 0) { - // await addMessageToChat(response.choices[0].message, chat_id); - // messages.push(response.choices[0].message); - // if (response.choices[0].message.tool_calls) { - - // console.log('Tools to call', response.choices[0].message.tool_calls.length); - // chartsData.push(getChartsInMessage(response.choices[0].message)); - - // for (const toolCall of response.choices[0].message.tool_calls) { - // const functionName = toolCall.function.name; - // console.log('Calling tool function', functionName); - // const functionToCall = functions[functionName]; - // const functionArgs = JSON.parse(toolCall.function.arguments); - // const functionResponse = await functionToCall({ project_id: pid, ...functionArgs }); - // messages.push({ tool_call_id: toolCall.id, role: "tool", content: JSON.stringify(functionResponse) }); - // await addMessageToChat({ tool_call_id: toolCall.id, role: "tool", content: JSON.stringify(functionResponse) }, chat_id); - // } - // } - // response = await openai.chat.completions.create({ model: OPENAI_MODEL, messages, n: 1, tools }); - // } - // await addMessageToChat(response.choices[0].message, chat_id); - // await ProjectLimitModel.updateOne({ project_id: pid }, { $inc: { ai_messages: 1 } }) - // return { content: response.choices[0].message.content, charts: chartsData.filter(e => e.length > 0).flat() }; - - } diff --git a/payments/src/controllers/WebhookController.ts b/payments/src/controllers/WebhookController.ts index 58d7a20..f4776be 100644 --- a/payments/src/controllers/WebhookController.ts +++ b/payments/src/controllers/WebhookController.ts @@ -11,13 +11,13 @@ import { EmailService } from '../shared/services/EmailService'; async function addSubscriptionToUser(user_id: string, plan: PLAN_DATA, subscription_id: string, current_period_start: number, current_period_end: number) { - await PremiumModel.updateOne({ _id: user_id }, { + await PremiumModel.updateOne({ user_id }, { premium_type: plan.ID, subscription_id, expire_at: current_period_end * 1000 }, { upsert: true }); - await UserLimitModel.updateOne({ _id: user_id }, { + await UserLimitModel.updateOne({ user_id }, { events: 0, visits: 0, ai_messages: 0, @@ -31,9 +31,9 @@ async function addSubscriptionToUser(user_id: string, plan: PLAN_DATA, subscript export async function onPaymentFailed(event: Event.InvoicePaymentFailedEvent) { - + if (event.data.object.attempt_count == 0) return { received: true, warn: 'attempt_count = 0' } - + //TODO: Send emails const customer_id = event.data.object.customer as string; @@ -70,7 +70,11 @@ export async function onPaymentSuccess(event: Event.InvoicePaidEvent) { const databaseSubscription = premiumData.subscription_id; if (databaseSubscription != subscription_id) { - await StripeService.deleteSubscription(subscription_id); + try { + await StripeService.deleteSubscription(databaseSubscription); + } catch (ex) { + console.error(ex); + } } await addSubscriptionToUser(premiumData.user_id.toString(), plan, subscription_id, event.data.object.period_start, event.data.object.period_end); diff --git a/payments/src/routers/PaymentRouter.ts b/payments/src/routers/PaymentRouter.ts index 5ab74fd..27076b6 100644 --- a/payments/src/routers/PaymentRouter.ts +++ b/payments/src/routers/PaymentRouter.ts @@ -4,6 +4,7 @@ import { getPlanFromId } from '../shared/data/PLANS'; import StripeService from '../services/StripeService'; import { sendJson } from '../Utils'; import { PremiumModel } from '../shared/schema/PremiumSchema'; +import { Types } from 'mongoose'; export const paymentRouter = Router(); @@ -20,7 +21,7 @@ paymentRouter.post('/create', json(), async (req, res) => { const plan = getPlanFromId(createPaymentData.plan_id); if (!plan) return sendJson(res, 400, { error: 'plan not found' }); - const premiumData = await PremiumModel.findById(createPaymentData.user_id); + const premiumData = await PremiumModel.findOne({ user_id: createPaymentData.user_id }); if (!premiumData) return sendJson(res, 400, { error: 'user not found' }); if (!premiumData.customer_id) return sendJson(res, 400, { error: 'user have no customer_id' }); diff --git a/payments/src/routers/WebhookRouter.ts b/payments/src/routers/WebhookRouter.ts index 0454864..d1f91ee 100644 --- a/payments/src/routers/WebhookRouter.ts +++ b/payments/src/routers/WebhookRouter.ts @@ -1,5 +1,5 @@ -import { json, Router } from 'express'; +import { raw, Router } from 'express'; import { sendJson } from '../Utils'; import StripeService from '../services/StripeService'; @@ -8,7 +8,7 @@ import * as WebhookController from '../controllers/WebhookController' export const webhookRouter = Router(); -webhookRouter.get('/', json(), async (req, res) => { +webhookRouter.post('/', raw({ type: 'application/json' }), async (req, res) => { try { const signature = req.header('stripe-signature'); @@ -26,7 +26,7 @@ webhookRouter.get('/', json(), async (req, res) => { const response = await WebhookController.onPaymentFailed(eventData); return sendJson(res, 200, response); } - + } catch (ex) { res.status(500).json({ error: ex.message });