Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PB-1435]: feat/update users tier on subscription change. #52

Merged
merged 6 commits into from
Apr 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export const FREE_PLAN_BYTES_SPACE = 2 * 1024 * 1024 * 1024;
export const FREE_INDIVIDUAL_TIER = 'free_individual_tier';
13 changes: 13 additions & 0 deletions src/services/StorageService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,16 @@ export async function createOrUpdateUser(maxSpaceBytes: string, email: string, c
},
);
}

export async function updateUserTier(uuid: string, planId: string, config: AppConfig) {
return axios.put(
`${config.DRIVE_GATEWAY_URL}/api/gateway/user/update/tier`,
{ planId, uuid },
{
headers: {
'Content-Type': 'application/json',
},
auth: { username: config.DRIVE_GATEWAY_USER, password: config.DRIVE_GATEWAY_PASSWORD },
},
);
}
13 changes: 12 additions & 1 deletion src/webhooks/handleCheckoutSessionCompleted.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Stripe from 'stripe';
import { type AppConfig } from '../config';
import CacheService from '../services/CacheService';
import { PaymentService, PriceMetadata } from '../services/PaymentService';
import { createOrUpdateUser } from '../services/StorageService';
import { createOrUpdateUser, updateUserTier } from '../services/StorageService';
import { UsersService } from '../services/UsersService';

export default async function handleCheckoutSessionCompleted(
Expand Down Expand Up @@ -59,6 +59,17 @@ export default async function handleCheckoutSessionCompleted(
throw err;
}

try {
await updateUserTier(user.uuid, price.product as string, config);
} catch (err) {
log.error(
`Error while updating user tier: email: ${session.customer_email}, planId: ${price.product} `,
);
log.error(err);
apsantiso marked this conversation as resolved.
Show resolved Hide resolved

throw err;
}

try {
const { customerId } = await usersService.findUserByUuid(user.uuid);
if ((price.metadata as PriceMetadata).planType === 'one_time') {
Expand Down
16 changes: 14 additions & 2 deletions src/webhooks/handleLifetimeRefunded.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { FastifyLoggerInstance } from 'fastify';
import { FREE_PLAN_BYTES_SPACE } from '../constants';
import { FREE_INDIVIDUAL_TIER, FREE_PLAN_BYTES_SPACE } from '../constants';
import CacheService from '../services/CacheService';
import { StorageService } from '../services/StorageService';
import { StorageService, updateUserTier } from '../services/StorageService';
import { UsersService } from '../services/UsersService';
import { AppConfig } from '../config';

export default async function handleLifetimeRefunded(
storageService: StorageService,
usersService: UsersService,
customerId: string,
cacheService: CacheService,
log: FastifyLoggerInstance,
config: AppConfig,
): Promise<void> {
const { uuid } = await usersService.findUserByCustomerID(customerId);

Expand All @@ -20,5 +22,15 @@ export default async function handleLifetimeRefunded(
} catch (err) {
log.error(`Error in handleLifetimeRefunded after trying to clear ${customerId} subscription`);
}
try {
await updateUserTier(uuid, FREE_INDIVIDUAL_TIER, config);
} catch (err) {
log.error(
`Error while updating user tier: uuid: ${uuid} `,
);
log.error(err);
throw err;
}

return storageService.changeStorage(uuid, FREE_PLAN_BYTES_SPACE);
}
16 changes: 14 additions & 2 deletions src/webhooks/handleSubscriptionCanceled.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
import { FastifyLoggerInstance } from 'fastify';
import { FREE_PLAN_BYTES_SPACE } from '../constants';
import { FREE_INDIVIDUAL_TIER, FREE_PLAN_BYTES_SPACE } from '../constants';
import CacheService from '../services/CacheService';
import { StorageService } from '../services/StorageService';
import { StorageService, updateUserTier } from '../services/StorageService';
import { UsersService } from '../services/UsersService';
import { AppConfig } from '../config';

export default async function handleSubscriptionCanceled(
storageService: StorageService,
usersService: UsersService,
customerId: string,
cacheService: CacheService,
log: FastifyLoggerInstance,
config: AppConfig,
): Promise<void> {
const { uuid } = await usersService.findUserByCustomerID(customerId);
try {
await cacheService.clearSubscription(customerId);
} catch (err) {
log.error(`Error in handleSubscriptionCanceled after trying to clear ${customerId} subscription`);
}

try {
await updateUserTier(uuid, FREE_INDIVIDUAL_TIER, config);
} catch (err) {
log.error(
`[TIER/SUB_CANCELED] Error while updating user tier: uuid: ${uuid} `,
);
log.error(err);
}

return storageService.changeStorage(uuid, FREE_PLAN_BYTES_SPACE);
}
22 changes: 19 additions & 3 deletions src/webhooks/handleSubscriptionUpdated.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,50 @@
import { FastifyLoggerInstance } from 'fastify';
import Stripe from 'stripe';
import { FREE_PLAN_BYTES_SPACE } from '../constants';
import { FREE_INDIVIDUAL_TIER, FREE_PLAN_BYTES_SPACE } from '../constants';
import CacheService from '../services/CacheService';
import { PriceMetadata } from '../services/PaymentService';
import { StorageService } from '../services/StorageService';
import { StorageService, updateUserTier } from '../services/StorageService';
import { UsersService } from '../services/UsersService';
import { AppConfig } from '../config';

export default async function handleSubscriptionUpdated(
storageService: StorageService,
usersService: UsersService,
subscription: Stripe.Subscription,
cacheService: CacheService,
log: FastifyLoggerInstance,
config: AppConfig,
): Promise<void> {
const customerId = subscription.customer as string;
const { uuid, lifetime } = await usersService.findUserByCustomerID(customerId);
if (lifetime) {
return;
}
const isSubscriptionCanceled = subscription.status === 'canceled';

const bytesSpace =
subscription.status === 'canceled'
isSubscriptionCanceled
? FREE_PLAN_BYTES_SPACE
: parseInt((subscription.items.data[0].price.metadata as unknown as PriceMetadata).maxSpaceBytes);

const planId = isSubscriptionCanceled
? FREE_INDIVIDUAL_TIER : subscription.items.data[0].price.product as string;

try {
await cacheService.clearSubscription(customerId);
} catch (err) {
log.error(`Error in handleSubscriptionUpdated after trying to clear ${customerId} subscription`);
}

try {
await updateUserTier(uuid, planId, config);
} catch (err) {
log.error(
`Error while updating user tier: uuid: ${uuid} `,
);
log.error(err);
throw err;
}

return storageService.changeStorage(uuid, bytesSpace);
}
3 changes: 3 additions & 0 deletions src/webhooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export default function (
(event.data.object as Stripe.Subscription).customer as string,
cacheService,
fastify.log,
config,
);
break;
case 'customer.subscription.updated':
Expand All @@ -57,6 +58,7 @@ export default function (
event.data.object as Stripe.Subscription,
cacheService,
fastify.log,
config,
);
break;
case 'payment_method.attached':
Expand Down Expand Up @@ -94,6 +96,7 @@ export default function (
(event.data.object as Stripe.Charge).customer as string,
cacheService,
fastify.log,
config,
);
break;
default:
Expand Down
Loading