From 70815657e861f5db620d1b7e87321ae31bdd0327 Mon Sep 17 00:00:00 2001 From: Vins Date: Tue, 16 Apr 2024 10:57:36 +0200 Subject: [PATCH 1/2] Updated seeder with subscriptions rules --- src/app/api/admin/StripeController.ts | 44 +++++++++--------- src/app/api/admin/SubscriptionsController.ts | 47 ++++++++++---------- src/common/databases/seeders/seeder.ts | 35 +++++++++++++++ 3 files changed, 80 insertions(+), 46 deletions(-) diff --git a/src/app/api/admin/StripeController.ts b/src/app/api/admin/StripeController.ts index 1d58253b..5dd28d3a 100644 --- a/src/app/api/admin/StripeController.ts +++ b/src/app/api/admin/StripeController.ts @@ -1,7 +1,7 @@ import authHandler from "@App/middlewares/AuthHandler"; // import roleHandler from "@App/middlewares/RolesHandler"; import ApiController from "@Common/system/controller-pattern/ApiController"; -import { Controller, Get, Post, Put } from "@ControllerPattern/index"; +import { Controller, Get, Post} from "@ControllerPattern/index"; import StripeService from "@Services/common/StripeService/StripeService"; import { validateOrReject } from "class-validator"; import { Request, Response } from "express"; @@ -41,31 +41,31 @@ export default class StripeController extends ApiController { } } - @Put("/api/v1/admin/stripe/:uid") - protected async createStripeSubscriptionUpdateCheckout(req: Request, response: Response) { - try { - const uid = req.params["uid"]; - if (!uid) { - this.httpBadRequest(response, "No uid provided"); - return; - } - const officeId: string = req.body.user.office_Id; - //add office id to request body - req.body.office = { uid: officeId }; + // @Put("/api/v1/admin/stripe/:uid") + // protected async createStripeSubscriptionUpdateCheckout(req: Request, response: Response) { + // try { + // const uid = req.params["uid"]; + // if (!uid) { + // this.httpBadRequest(response, "No uid provided"); + // return; + // } + // const officeId: string = req.body.user.office_Id; + // //add office id to request body + // req.body.office = { uid: officeId }; - //init Subscription resource with request body values - const subscriptionEntity = Subscription.hydrate(req.body, { strategy: "excludeAll" }); + // //init Subscription resource with request body values + // const subscriptionEntity = Subscription.hydrate(req.body, { strategy: "excludeAll" }); - await validateOrReject(subscriptionEntity, { groups: ["updateSubscription"], forbidUnknownValues: false }); + // await validateOrReject(subscriptionEntity, { groups: ["updateSubscription"], forbidUnknownValues: false }); - const stripeSession = await this.stripeService.createCheckoutSessionUpdate(uid, subscriptionEntity); + // const stripeSession = await this.stripeService.createCheckoutSessionUpdate(uid, subscriptionEntity); - this.httpCreated(response, stripeSession); - } catch (error) { - this.httpInternalError(response, error); - return; - } - } + // this.httpCreated(response, stripeSession); + // } catch (error) { + // this.httpInternalError(response, error); + // return; + // } + // } @Get("/api/v1/admin/stripe/:uid", [authHandler]) protected async getClientPortalSession(req: Request, response: Response) { diff --git a/src/app/api/admin/SubscriptionsController.ts b/src/app/api/admin/SubscriptionsController.ts index c8f4d455..3de788b2 100644 --- a/src/app/api/admin/SubscriptionsController.ts +++ b/src/app/api/admin/SubscriptionsController.ts @@ -8,7 +8,6 @@ import { Service } from "typedi"; import { Prisma } from "@prisma/client"; import SubscriptionsService from "@Services/admin/SubscriptionsService/SubscriptionsService.ts"; import { Subscription } from "le-coffre-resources/dist/Admin"; -import { validateOrReject } from "class-validator"; import ObjectHydrate from "@Common/helpers/ObjectHydrate"; import roleHandler from "@App/middlewares/RolesHandler"; import authHandler from "@App/middlewares/AuthHandler"; @@ -81,29 +80,29 @@ export default class SubscriptionsController extends ApiController { } } - /** - * @description Create a new documentType - */ - @Post("/api/v1/admin/subscriptions", [authHandler, roleHandler]) - protected async post(req: Request, response: Response) { - try { - //init Subscription resource with request body values - const subscriptionEntity = Subscription.hydrate(req.body); - //validate subscription - await validateOrReject(subscriptionEntity, { groups: ["createSubscription"], forbidUnknownValues: false }); - //call service to get prisma entity - const subscriptionEntityCreated = await this.subscriptionsService.create(subscriptionEntity); - //Hydrate ressource with prisma entity - const subscription = Subscription.hydrate(subscriptionEntityCreated, { - strategy: "excludeAll", - }); - //success - this.httpCreated(response, subscription); - } catch (error) { - this.httpInternalError(response, error); - return; - } - } + // /** + // * @description Create a new documentType + // */ + // @Post("/api/v1/admin/subscriptions", [authHandler, roleHandler]) + // protected async post(req: Request, response: Response) { + // try { + // //init Subscription resource with request body values + // const subscriptionEntity = Subscription.hydrate(req.body); + // //validate subscription + // await validateOrReject(subscriptionEntity, { groups: ["createSubscription"], forbidUnknownValues: false }); + // //call service to get prisma entity + // const subscriptionEntityCreated = await this.subscriptionsService.create(subscriptionEntity); + // //Hydrate ressource with prisma entity + // const subscription = Subscription.hydrate(subscriptionEntityCreated, { + // strategy: "excludeAll", + // }); + // //success + // this.httpCreated(response, subscription); + // } catch (error) { + // this.httpInternalError(response, error); + // return; + // } + // } /** * @description Update a subscription diff --git a/src/common/databases/seeders/seeder.ts b/src/common/databases/seeders/seeder.ts index d8f1339c..24c2997b 100644 --- a/src/common/databases/seeders/seeder.ts +++ b/src/common/databases/seeders/seeder.ts @@ -795,6 +795,41 @@ export default async function main() { updated_at: new Date(), namespace: "notary", }, + { + name: "GET subscriptions", + label: "Récupérer les abonnements", + created_at: new Date(), + updated_at: new Date(), + namespace: "notary", + }, + { + name: "POST subscriptions", + label: "Inviter un collaborateur à l'abonnement", + created_at: new Date(), + updated_at: new Date(), + namespace: "notary", + }, + { + name: "PUT subscriptions", + label: "Modifier l'abonnement", + created_at: new Date(), + updated_at: new Date(), + namespace: "notary", + }, + { + name: "GET stripe", + label: "Gérer l'abonnement de l'office", + created_at: new Date(), + updated_at: new Date(), + namespace: "notary", + }, + { + name: "POST stripe", + label: "Payer un abonnement", + created_at: new Date(), + updated_at: new Date(), + namespace: "notary", + }, ]; const collaboratorRules = rules.filter((rule) => rule.namespace === "collaborator"); From 58665e1356adae1b223e21322d0c6bbd62d0a618 Mon Sep 17 00:00:00 2001 From: Vins Date: Tue, 16 Apr 2024 16:34:17 +0200 Subject: [PATCH 2/2] New annual prices + fix switch subscription --- src/common/config/variables/Variables.ts | 8 ++++++++ src/common/webhooks/stripeWebhooks.ts | 14 ++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/common/config/variables/Variables.ts b/src/common/config/variables/Variables.ts index a65bd265..4ff86cab 100644 --- a/src/common/config/variables/Variables.ts +++ b/src/common/config/variables/Variables.ts @@ -148,9 +148,15 @@ export class BackendVariables { @IsNotEmpty() public readonly STRIPE_STANDARD_SUBSCRIPTION_PRICE_ID!: string; + @IsNotEmpty() + public readonly STRIPE_STANDARD_ANNUAL_SUBSCRIPTION_PRICE_ID!: string; + @IsNotEmpty() public readonly STRIPE_UNLIMITED_SUBSCRIPTION_PRICE_ID!: string; + @IsNotEmpty() + public readonly STRIPE_UNLIMITED_ANNUAL_SUBSCRIPTION_PRICE_ID!: string; + @IsNotEmpty() public readonly STRIPE_PAYMENT_SUCCESS_URL!: string; @@ -210,7 +216,9 @@ export class BackendVariables { this.SCW_BUCKET_NAME = process.env["BUCKET_NAME"]!; this.STRIPE_SECRET_KEY = process.env["STRIPE_SECRET_KEY"]!; this.STRIPE_STANDARD_SUBSCRIPTION_PRICE_ID = process.env["STRIPE_STANDARD_SUBSCRIPTION_PRICE_ID"]!; + this.STRIPE_STANDARD_ANNUAL_SUBSCRIPTION_PRICE_ID = process.env["STRIPE_STANDARD_ANNUAL_SUBSCRIPTION_PRICE_ID"]!; this.STRIPE_UNLIMITED_SUBSCRIPTION_PRICE_ID = process.env["STRIPE_UNLIMITED_SUBSCRIPTION_PRICE_ID"]!; + this.STRIPE_UNLIMITED_ANNUAL_SUBSCRIPTION_PRICE_ID = process.env["STRIPE_UNLIMITED_ANNUAL_SUBSCRIPTION_PRICE_ID"]!; this.STRIPE_PAYMENT_SUCCESS_URL = process.env["STRIPE_PAYMENT_SUCCESS_URL"]!; this.STRIPE_PAYMENT_CANCEL_URL = process.env["STRIPE_PAYMENT_CANCEL_URL"]!; this.IDNOT_PROD_BASE_URL = process.env["IDNOT_PROD_BASE_URL"]!; diff --git a/src/common/webhooks/stripeWebhooks.ts b/src/common/webhooks/stripeWebhooks.ts index b0832ece..85fc45f7 100644 --- a/src/common/webhooks/stripeWebhooks.ts +++ b/src/common/webhooks/stripeWebhooks.ts @@ -24,7 +24,7 @@ export default class StripeWebhooks extends ApiController { const event = req.body; switch (event.type) { - case "invoice.payment_succeeded": + case "invoice.payment_succeeded": if (event.data.object.billing_reason !== "subscription_update") break; const stripeSubscription = await this.stripeService.getClient().subscriptions.retrieve(event.data.object.subscription); const existingSubscription = await this.subscriptionsService.get({where : {stripe_subscription_id : stripeSubscription.id}}); @@ -34,11 +34,17 @@ export default class StripeWebhooks extends ApiController { subscriptionUpdate.start_date = new Date(stripeSubscription.current_period_start * 1000); subscriptionUpdate.end_date = new Date(stripeSubscription.current_period_end * 1000); subscriptionUpdate.nb_seats = stripeSubscription.items.data[0]?.quantity; - subscriptionUpdate.type = stripeSubscription.items.data[0]?.price?.id === this.backendVariables.STRIPE_STANDARD_SUBSCRIPTION_PRICE_ID ? "STANDARD" : "UNLIMITED"; - const subscriptionEntityUpdate = Subscription.hydrate(subscriptionUpdate); + if(stripeSubscription.items.data[0]?.price?.id === this.backendVariables.STRIPE_STANDARD_SUBSCRIPTION_PRICE_ID || stripeSubscription.items.data[0]?.price?.id === this.backendVariables.STRIPE_STANDARD_ANNUAL_SUBSCRIPTION_PRICE_ID){ + subscriptionUpdate.type = "STANDARD"; + } + else{ + subscriptionUpdate.type = "UNLIMITED"; + } - await validateOrReject(subscriptionEntityUpdate, { groups: ["updateSubscription"], forbidUnknownValues: false }); + const subscriptionEntityUpdate = Subscription.hydrate(subscriptionUpdate); + + await validateOrReject(subscriptionEntityUpdate, { groups: ["updateSubscription"], forbidUnknownValues: false }); await this.subscriptionsService.update(existingSubscription[0].uid ,subscriptionEntityUpdate);