Merge branch 'dev' into staging
This commit is contained in:
commit
3f0f20c5ea
@ -1,7 +1,7 @@
|
|||||||
import authHandler from "@App/middlewares/AuthHandler";
|
import authHandler from "@App/middlewares/AuthHandler";
|
||||||
// import roleHandler from "@App/middlewares/RolesHandler";
|
// import roleHandler from "@App/middlewares/RolesHandler";
|
||||||
import ApiController from "@Common/system/controller-pattern/ApiController";
|
import ApiController from "@Common/system/controller-pattern/ApiController";
|
||||||
import { Controller, Get, Post } from "@ControllerPattern/index";
|
import { Controller, Get, Post, Put } from "@ControllerPattern/index";
|
||||||
import StripeService from "@Services/common/StripeService/StripeService";
|
import StripeService from "@Services/common/StripeService/StripeService";
|
||||||
import { validateOrReject } from "class-validator";
|
import { validateOrReject } from "class-validator";
|
||||||
import { Request, Response } from "express";
|
import { Request, Response } from "express";
|
||||||
@ -40,6 +40,33 @@ 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 };
|
||||||
|
|
||||||
|
//init Subscription resource with request body values
|
||||||
|
const subscriptionEntity = Subscription.hydrate<Subscription>(req.body, { strategy: "excludeAll" });
|
||||||
|
|
||||||
|
await validateOrReject(subscriptionEntity, { groups: ["updateSubscription"], forbidUnknownValues: false });
|
||||||
|
|
||||||
|
const stripeSession = await this.stripeService.createCheckoutSessionUpdate(uid, subscriptionEntity);
|
||||||
|
|
||||||
|
this.httpCreated(response, stripeSession);
|
||||||
|
} catch (error) {
|
||||||
|
this.httpInternalError(response, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Get("/api/v1/admin/stripe/:uid", [authHandler])
|
@Get("/api/v1/admin/stripe/:uid", [authHandler])
|
||||||
protected async getClientPortalSession(req: Request, response: Response) {
|
protected async getClientPortalSession(req: Request, response: Response) {
|
||||||
try {
|
try {
|
||||||
|
@ -41,7 +41,7 @@ export default class SubscriptionsController extends ApiController {
|
|||||||
const subscriptionsEntities = await this.subscriptionsService.get(query);
|
const subscriptionsEntities = await this.subscriptionsService.get(query);
|
||||||
|
|
||||||
//Hydrate ressource with prisma entity
|
//Hydrate ressource with prisma entity
|
||||||
const subscriptions = Subscription.hydrateArray<Subscription>(subscriptionsEntities, { strategy: "excludeAll" });
|
const subscriptions = Subscription.hydrateArray<Subscription>(subscriptionsEntities, { strategy: "excludeAll" });
|
||||||
|
|
||||||
//success
|
//success
|
||||||
this.httpSuccess(response, subscriptions);
|
this.httpSuccess(response, subscriptions);
|
||||||
@ -169,4 +169,43 @@ export default class SubscriptionsController extends ApiController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @description Update a subscription seats
|
||||||
|
// */
|
||||||
|
// @Put("/api/v1/admin/subscriptions/:uid/seats", [authHandler, roleHandler])
|
||||||
|
// protected async updateSubscriptionSeats(req: Request, response: Response) {
|
||||||
|
// try {
|
||||||
|
// const uid = req.params["uid"];
|
||||||
|
// if (!uid) {
|
||||||
|
// this.httpBadRequest(response, "No uid provided");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const subscriptionFound = await this.subscriptionsService.getByUid(uid);
|
||||||
|
|
||||||
|
// if (!subscriptionFound) {
|
||||||
|
// this.httpNotFoundRequest(response, "subscription not found");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //init Subscription resource with request body values
|
||||||
|
// const seatEntities = Seat.hydrateArray<Seat>(req.body);
|
||||||
|
|
||||||
|
// //call service to get prisma entity
|
||||||
|
// const subscriptionEntityUpdated = await this.subscriptionsService.update(uid, subscriptionEntity);
|
||||||
|
|
||||||
|
// //Hydrate ressource with prisma entity
|
||||||
|
// const subscription = Subscription.hydrate<Subscription>(subscriptionEntityUpdated, {
|
||||||
|
// strategy: "excludeAll",
|
||||||
|
// });
|
||||||
|
|
||||||
|
// //success
|
||||||
|
// this.httpSuccess(response, subscription);
|
||||||
|
|
||||||
|
// } catch (error) {
|
||||||
|
// this.httpInternalError(response, error);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
@ -69,43 +69,44 @@ export default class UserController extends ApiController {
|
|||||||
this.httpUnauthorized(response, "Email not found");
|
this.httpUnauthorized(response, "Email not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let isSubscribed = false;
|
let isSubscribed = false;
|
||||||
if (userHydrated.role?.name === "admin") {
|
|
||||||
|
const subscriptions = await this.subscriptionsService.get({ where: { office_uid: userHydrated.office_membership?.uid } });
|
||||||
|
|
||||||
|
if (!subscriptions || subscriptions.length === 0 || subscriptions[0]?.status === ESubscriptionStatus.INACTIVE) {
|
||||||
|
this.httpUnauthorized(response, "User not subscribed");
|
||||||
|
isSubscribed = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subscriptions[0]?.type === EType.Unlimited) {
|
||||||
isSubscribed = true;
|
isSubscribed = true;
|
||||||
} else {
|
} else {
|
||||||
const subscriptions = await this.subscriptionsService.get({ where: { office_uid: userHydrated.office_membership?.uid } });
|
const hasSeat = await this.subscriptionsService.get({
|
||||||
|
where: { status: ESubscriptionStatus.ACTIVE, seats: { some: { user_uid: userHydrated.uid } } },
|
||||||
|
});
|
||||||
|
|
||||||
if (!subscriptions || subscriptions.length === 0 || subscriptions[0]?.status === ESubscriptionStatus.INACTIVE) {
|
if (hasSeat && hasSeat.length > 0) {
|
||||||
this.httpUnauthorized(response, "User not subscribed");
|
|
||||||
isSubscribed = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subscriptions[0]?.type === EType.Unlimited) {
|
|
||||||
isSubscribed = true;
|
isSubscribed = true;
|
||||||
} else {
|
} else {
|
||||||
const hasSeat = await this.subscriptionsService.get({
|
const nbMaxSeats = subscriptions[0]!.nb_seats;
|
||||||
where: { status: ESubscriptionStatus.ACTIVE, seats: { some: { user_uid: userHydrated.uid } } },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (hasSeat && hasSeat.length > 0) {
|
const nbCurrentSeats = await this.seatsService.get({ where: { subscription_uid: subscriptions[0]!.uid } });
|
||||||
isSubscribed = true;
|
|
||||||
} else {
|
|
||||||
const nbMaxSeats = subscriptions[0]!.nb_seats;
|
|
||||||
|
|
||||||
const nbCurrentSeats = await this.seatsService.get({ where: { subscription_uid: subscriptions[0]!.uid } });
|
//if nbMaxSeats < nbCurrentSeats, create a new seat for the user
|
||||||
|
if (nbMaxSeats > nbCurrentSeats.length) {
|
||||||
//if nbMaxSeats < nbCurrentSeats, create a new seat for the user
|
const seatAdded = await this.seatsService.create(user.uid, subscriptions[0]!.uid);
|
||||||
if (nbMaxSeats > nbCurrentSeats.length) {
|
if (seatAdded) {
|
||||||
const seatAdded = await this.seatsService.create(user.uid, subscriptions[0]!.uid);
|
isSubscribed = true;
|
||||||
if (seatAdded) {
|
|
||||||
isSubscribed = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (userHydrated.role?.name === "admin") {
|
||||||
|
isSubscribed = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!isSubscribed) {
|
if (!isSubscribed) {
|
||||||
this.httpUnauthorized(response, "User not subscribed");
|
this.httpUnauthorized(response, "User not subscribed");
|
||||||
return;
|
return;
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "seats" ADD COLUMN "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
ADD COLUMN "updated_at" TIMESTAMP(3);
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "subscriptions" ADD COLUMN "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
ADD COLUMN "updated_at" TIMESTAMP(3);
|
@ -388,6 +388,8 @@ model Subscriptions {
|
|||||||
office Offices @relation(fields: [office_uid], references: [uid], onDelete: Cascade)
|
office Offices @relation(fields: [office_uid], references: [uid], onDelete: Cascade)
|
||||||
office_uid String @db.VarChar(255)
|
office_uid String @db.VarChar(255)
|
||||||
seats Seats[]
|
seats Seats[]
|
||||||
|
created_at DateTime? @default(now())
|
||||||
|
updated_at DateTime? @updatedAt
|
||||||
@@map("subscriptions")
|
@@map("subscriptions")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,6 +399,8 @@ model Seats {
|
|||||||
subscription_uid String @db.VarChar(255)
|
subscription_uid String @db.VarChar(255)
|
||||||
user Users @relation(fields: [user_uid], references: [uid], onDelete: Cascade)
|
user Users @relation(fields: [user_uid], references: [uid], onDelete: Cascade)
|
||||||
user_uid String @db.VarChar(255)
|
user_uid String @db.VarChar(255)
|
||||||
|
created_at DateTime? @default(now())
|
||||||
|
updated_at DateTime? @updatedAt
|
||||||
@@map("seats")
|
@@map("seats")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ export default class SeatsRepository extends BaseRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description : Find many subscriptions
|
* @description : Find many seats
|
||||||
*/
|
*/
|
||||||
public async findMany(query: Prisma.SeatsFindManyArgs) {
|
public async findMany(query: Prisma.SeatsFindManyArgs) {
|
||||||
query.take = Math.min(query.take || this.defaultFetchRows, this.maxFetchRows);
|
query.take = Math.min(query.take || this.defaultFetchRows, this.maxFetchRows);
|
||||||
@ -25,7 +25,7 @@ export default class SeatsRepository extends BaseRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description : find unique subscription
|
* @description : find unique seat
|
||||||
*/
|
*/
|
||||||
public async findOneByUid(uid: string, query?: Prisma.SeatsInclude): Promise<Seats | null> {
|
public async findOneByUid(uid: string, query?: Prisma.SeatsInclude): Promise<Seats | null> {
|
||||||
return this.model.findUnique({
|
return this.model.findUnique({
|
||||||
@ -37,7 +37,7 @@ export default class SeatsRepository extends BaseRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description : Create a subscription
|
* @description : Create a seat
|
||||||
*/
|
*/
|
||||||
public async create(userUid: string, subscriptionUid: string): Promise<Seats> {
|
public async create(userUid: string, subscriptionUid: string): Promise<Seats> {
|
||||||
|
|
||||||
@ -63,5 +63,16 @@ export default class SeatsRepository extends BaseRepository {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : Delete a seat
|
||||||
|
*/
|
||||||
|
public async delete(uid: string) {
|
||||||
|
return this.model.delete({
|
||||||
|
where: {
|
||||||
|
uid: uid,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -85,8 +85,25 @@ export default class SubscriptionsRepository extends BaseRepository {
|
|||||||
/**
|
/**
|
||||||
* @description : update given subscription
|
* @description : update given subscription
|
||||||
*/
|
*/
|
||||||
public async update(uid: string, subscription: Subscription): Promise<Subscriptions> {
|
public async update(uid: string, subscription: Subscription): Promise<Subscriptions> {
|
||||||
|
if(!subscription.type || subscription.type === ""){
|
||||||
|
const updateArgs: Prisma.SubscriptionsUpdateArgs = {
|
||||||
|
where: {
|
||||||
|
uid: uid,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
seats:{
|
||||||
|
deleteMany: {},
|
||||||
|
createMany: {
|
||||||
|
data: subscription.seats?.map((seat) => ({
|
||||||
|
user_uid: seat.user.uid || "",
|
||||||
|
})) ?? [],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return this.model.update(updateArgs);
|
||||||
|
}
|
||||||
if(subscription.type === "STANDARD")
|
if(subscription.type === "STANDARD")
|
||||||
{
|
{
|
||||||
const updateArgs: Prisma.SubscriptionsUpdateArgs = {
|
const updateArgs: Prisma.SubscriptionsUpdateArgs = {
|
||||||
@ -98,16 +115,6 @@ export default class SubscriptionsRepository extends BaseRepository {
|
|||||||
type: ESubscriptionType.STANDARD,
|
type: ESubscriptionType.STANDARD,
|
||||||
status: subscription.status as ESubscriptionStatus,
|
status: subscription.status as ESubscriptionStatus,
|
||||||
nb_seats: subscription.nb_seats!,
|
nb_seats: subscription.nb_seats!,
|
||||||
seats: {
|
|
||||||
deleteMany: {},
|
|
||||||
create: subscription.seats!.map(seat => ({
|
|
||||||
user: {
|
|
||||||
connect: {
|
|
||||||
uid: seat.user!.uid,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})),
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
return this.model.update(updateArgs);
|
return this.model.update(updateArgs);
|
||||||
@ -132,5 +139,16 @@ export default class SubscriptionsRepository extends BaseRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : Delete a subscription
|
||||||
|
*/
|
||||||
|
public async delete(uid: string) {
|
||||||
|
return this.model.delete({
|
||||||
|
where: {
|
||||||
|
uid: uid,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { BackendVariables } from "@Common/config/variables/Variables";
|
||||||
import ApiController from "@Common/system/controller-pattern/ApiController";
|
import ApiController from "@Common/system/controller-pattern/ApiController";
|
||||||
import { Controller, Post } from "@ControllerPattern/index";
|
import { Controller, Post } from "@ControllerPattern/index";
|
||||||
import SubscriptionsService from "@Services/admin/SubscriptionsService/SubscriptionsService.ts";
|
import SubscriptionsService from "@Services/admin/SubscriptionsService/SubscriptionsService.ts";
|
||||||
@ -10,7 +11,7 @@ import { Service } from "typedi";
|
|||||||
@Controller()
|
@Controller()
|
||||||
@Service()
|
@Service()
|
||||||
export default class StripeWebhooks extends ApiController {
|
export default class StripeWebhooks extends ApiController {
|
||||||
constructor(private stripeService: StripeService, private subscriptionsService: SubscriptionsService) {
|
constructor(private stripeService: StripeService, private subscriptionsService: SubscriptionsService, private backendVariables: BackendVariables) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,22 +21,32 @@ export default class StripeWebhooks extends ApiController {
|
|||||||
@Post("/api/v1/webhooks/stripe")
|
@Post("/api/v1/webhooks/stripe")
|
||||||
protected async post(req: Request, response: Response) {
|
protected async post(req: Request, response: Response) {
|
||||||
try {
|
try {
|
||||||
// const sig = req.headers["stripe-signature"];
|
|
||||||
// const endpointSecret = "whsec_c4088876914bc166ff5c39253207f84900820b67f7bba3b2669c0ff392cbc838";
|
|
||||||
// const stripe = this.stripeService.getClient();
|
|
||||||
// let event: Stripe.Event;
|
|
||||||
|
|
||||||
// if (!sig || !endpointSecret) {
|
|
||||||
// throw new Error("Signature verification failed");
|
|
||||||
// }
|
|
||||||
// event = stripe.webhooks.constructEvent(req.body, sig, endpointSecret);
|
|
||||||
const event = req.body;
|
const event = req.body;
|
||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
|
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}});
|
||||||
|
if(!existingSubscription[0]) break;
|
||||||
|
|
||||||
|
const subscriptionUpdate: any = {};
|
||||||
|
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<Subscription>(subscriptionUpdate);
|
||||||
|
|
||||||
|
await validateOrReject(subscriptionEntityUpdate, { groups: ["updateSubscription"], forbidUnknownValues: false });
|
||||||
|
|
||||||
|
await this.subscriptionsService.update(existingSubscription[0].uid ,subscriptionEntityUpdate);
|
||||||
|
|
||||||
case "checkout.session.completed":
|
case "checkout.session.completed":
|
||||||
if (event.data.object.status !== "complete") break;
|
if (event.data.object.status !== "complete") break;
|
||||||
|
|
||||||
const subscription = JSON.parse(event.data.object.metadata.subscription);
|
const subscription = JSON.parse(event.data.object.metadata.subscription);
|
||||||
|
|
||||||
subscription.stripe_subscription_id = event.data.object.subscription;
|
subscription.stripe_subscription_id = event.data.object.subscription;
|
||||||
|
|
||||||
const subscriptionInfo = await this.stripeService
|
const subscriptionInfo = await this.stripeService
|
||||||
@ -48,9 +59,13 @@ export default class StripeWebhooks extends ApiController {
|
|||||||
const subscriptionEntity = Subscription.hydrate<Subscription>(subscription);
|
const subscriptionEntity = Subscription.hydrate<Subscription>(subscription);
|
||||||
|
|
||||||
await validateOrReject(subscriptionEntity, { groups: ["createSubscription"], forbidUnknownValues: false });
|
await validateOrReject(subscriptionEntity, { groups: ["createSubscription"], forbidUnknownValues: false });
|
||||||
|
|
||||||
await this.subscriptionsService.create(subscriptionEntity);
|
await this.subscriptionsService.create(subscriptionEntity);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "customer.subscription.deleted":
|
||||||
|
const subscriptionToDelete = await this.subscriptionsService.get({where : {stripe_subscription_id : event.data.object.id}});
|
||||||
|
if(!subscriptionToDelete[0]) break;
|
||||||
|
await this.subscriptionsService.delete(subscriptionToDelete[0].uid);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -34,4 +34,12 @@ export default class SeatsService extends BaseService {
|
|||||||
return this.seatsRepository.create(subscriptionUid, userUid);
|
return this.seatsRepository.create(subscriptionUid, userUid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : Delete a seat
|
||||||
|
* @throws {Error} If seat cannot be deleted
|
||||||
|
*/
|
||||||
|
public async delete(uid: string) {
|
||||||
|
return this.seatsRepository.delete(uid);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,11 @@ import { Service } from "typedi";
|
|||||||
import { Prisma, Subscriptions } from "@prisma/client";
|
import { Prisma, Subscriptions } from "@prisma/client";
|
||||||
import SubscriptionsRepository from "@Repositories/SubscriptionsRepository";
|
import SubscriptionsRepository from "@Repositories/SubscriptionsRepository";
|
||||||
import { Subscription } from "le-coffre-resources/dist/Admin";
|
import { Subscription } from "le-coffre-resources/dist/Admin";
|
||||||
|
import SeatsService from "../SeatsService/SeatsService";
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class SubscriptionsService extends BaseService {
|
export default class SubscriptionsService extends BaseService {
|
||||||
constructor(private subscriptionsRepository: SubscriptionsRepository) {
|
constructor(private subscriptionsRepository: SubscriptionsRepository, private seatsService: SeatsService) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +40,24 @@ export default class SubscriptionsService extends BaseService {
|
|||||||
* @description : Modify a subscription
|
* @description : Modify a subscription
|
||||||
* @throws {Error} If subscription cannot be modified
|
* @throws {Error} If subscription cannot be modified
|
||||||
*/
|
*/
|
||||||
public async update(uid: string, subscriptionEntity: Subscription): Promise<Subscriptions> {
|
public async update(uid: string, subscriptionEntity: Subscription): Promise<Subscriptions> {
|
||||||
|
if(subscriptionEntity.type === "STANDARD"){
|
||||||
|
const seats = await this.seatsService.get({ where: { subscription: { uid: uid } }, orderBy: {created_at: 'asc'} });
|
||||||
|
const seatsToKeep = subscriptionEntity.nb_seats;
|
||||||
|
const seatsToDelete = seats.slice(seatsToKeep);
|
||||||
|
|
||||||
|
for (const seat of seatsToDelete) {
|
||||||
|
await this.seatsService.delete(seat.uid);
|
||||||
|
}
|
||||||
|
}
|
||||||
return this.subscriptionsRepository.update(uid, subscriptionEntity);
|
return this.subscriptionsRepository.update(uid, subscriptionEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : Delete a subscription
|
||||||
|
* @throws {Error} If subscription cannot be deleted
|
||||||
|
*/
|
||||||
|
public async delete(uid: string) {
|
||||||
|
return this.subscriptionsRepository.delete(uid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,26 +15,76 @@ export default class StripeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async createCheckoutSession(subscription: Subscription) {
|
public async createCheckoutSession(subscription: Subscription) {
|
||||||
const priceId =
|
const priceId = subscription.type === "STANDARD" ? this.variables.STRIPE_STANDARD_SUBSCRIPTION_PRICE_ID : this.variables.STRIPE_UNLIMITED_SUBSCRIPTION_PRICE_ID;
|
||||||
subscription.type === "STANDARD"
|
return this.client.checkout.sessions.create({
|
||||||
? this.variables.STRIPE_STANDARD_SUBSCRIPTION_PRICE_ID
|
mode: "subscription",
|
||||||
: this.variables.STRIPE_UNLIMITED_SUBSCRIPTION_PRICE_ID;
|
payment_method_types: ["card", "paypal"],
|
||||||
return this.client.checkout.sessions.create({
|
billing_address_collection: "auto",
|
||||||
mode: "subscription",
|
line_items: [
|
||||||
payment_method_types: ["card", "paypal"],
|
{
|
||||||
billing_address_collection: "auto",
|
price: priceId,
|
||||||
line_items: [
|
quantity: subscription.type === "STANDARD" ? subscription.nb_seats : 1,
|
||||||
{
|
},
|
||||||
price: priceId,
|
],
|
||||||
quantity: subscription.type === "STANDARD" ? subscription.nb_seats : 1,
|
success_url: this.variables.APP_HOST + "/subscription/success",
|
||||||
|
cancel_url: this.variables.APP_HOST + "/subscription/error",
|
||||||
|
metadata: {
|
||||||
|
subscription: JSON.stringify(subscription),
|
||||||
},
|
},
|
||||||
],
|
});
|
||||||
success_url: this.variables.APP_HOST + "/subscription/success",
|
|
||||||
cancel_url: this.variables.APP_HOST + "/subscription/error",
|
|
||||||
metadata: {
|
|
||||||
subscription: JSON.stringify(subscription),
|
}
|
||||||
},
|
|
||||||
});
|
public async createCheckoutSessionUpdate(uid: string, subscription: Subscription) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return this.client.checkout.sessions.create({
|
||||||
|
// mode: "payment",
|
||||||
|
// payment_method_types: ["card", "paypal"],
|
||||||
|
// billing_address_collection: "auto",
|
||||||
|
// success_url: this.variables.APP_HOST + "/subscription/success",
|
||||||
|
// cancel_url: this.variables.APP_HOST + "/subscription/error",
|
||||||
|
// metadata: {
|
||||||
|
// subscription: JSON.stringify(subscription),
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
|
||||||
|
// const priceId =
|
||||||
|
// subscription.type === "STANDARD"
|
||||||
|
// ? this.variables.STRIPE_STANDARD_SUBSCRIPTION_PRICE_ID
|
||||||
|
// : this.variables.STRIPE_UNLIMITED_SUBSCRIPTION_PRICE_ID;
|
||||||
|
|
||||||
|
// return this.client.checkout.sessions.create({
|
||||||
|
// mode: "subscription",
|
||||||
|
// payment_method_types: ["card", "paypal"],
|
||||||
|
// billing_address_collection: "auto",
|
||||||
|
// line_items: [
|
||||||
|
// {
|
||||||
|
// price: priceId,
|
||||||
|
// quantity: subscription.type === "STANDARD" ? subscription.nb_seats : 1,
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// success_url: this.variables.APP_HOST + "/subscription/success",
|
||||||
|
// cancel_url: this.variables.APP_HOST + "/subscription/error",
|
||||||
|
// metadata: {
|
||||||
|
// subscription: JSON.stringify(subscription),
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// const subscriptions = await this.client.subscriptions.retrieve(uid);
|
||||||
|
// const itemId = subscriptions.items.data[0]?.id;
|
||||||
|
|
||||||
|
// return await this.client.subscriptions.update(uid, {
|
||||||
|
// items: [
|
||||||
|
// {
|
||||||
|
// id: itemId,
|
||||||
|
// price: priceId,
|
||||||
|
// quantity: subscription.nb_seats,
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
public async createClientPortalSession(subscriptionId: string) {
|
public async createClientPortalSession(subscriptionId: string) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user