Skip to content

Commit

Permalink
Remove duplicate stripe initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
DaevMithran committed Sep 5, 2024
1 parent fe23194 commit 377aae6
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 64 deletions.
93 changes: 40 additions & 53 deletions src/controllers/admin/webhook.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Stripe from 'stripe';
import type Stripe from 'stripe';
import type { Request, Response } from 'express';
import * as dotenv from 'dotenv';
import { StatusCodes } from 'http-status-codes';
Expand All @@ -15,21 +15,14 @@ import { buildSubscriptionData } from '../../services/track/helpers.js';

dotenv.config();
export class WebhookController {
private readonly stripe: Stripe;

constructor() {
this.stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
}

public static instance = new WebhookController();

public async handleWebhook(request: Request, response: Response) {
// Signature verification and webhook handling is placed in the same method
// cause stripe uses the mthod which validate the signature and provides the event.
let event = request.body;
let subscription;
let status;
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
const stripe = response.locals.stripe as Stripe;

if (!process.env.STRIPE_WEBHOOK_SECRET) {
await eventTracker.notify({
Expand Down Expand Up @@ -61,52 +54,17 @@ export class WebhookController {
try {
// Handle the event
switch (event.type) {
case 'customer.subscription.trial_will_end':
subscription = event.data.object;
status = subscription.status;
await eventTracker.notify({
message: EventTracker.compileBasicNotification(
`Subscription status is ${status} for subscription with id: ${subscription.id}`,
'Stripe Webhook: customer.subscription.trial_will_end'
),
severity: 'info',
} satisfies INotifyMessage);
break;
case 'customer.subscription.deleted':
subscription = event.data.object;
status = subscription.status;
await eventTracker.notify({
message: EventTracker.compileBasicNotification(
`Subscription status is ${status} for subscription with id: ${subscription.id}`,
'Stripe Webhook: customer.subscription.deleted'
),
severity: 'info',
} satisfies INotifyMessage);
await this.handleSubscriptionCancel(subscription);
await this.handleSubscriptionCancel(stripe, subscription);
break;
case 'customer.subscription.created':
subscription = event.data.object;
status = subscription.status;
await eventTracker.notify({
message: EventTracker.compileBasicNotification(
`Subscription status is ${status} for subscription with id: ${subscription.id}`,
'Stripe Webhook: customer.subscription.created'
),
severity: 'info',
} satisfies INotifyMessage);
await this.handleSubscriptionCreate(subscription);
await this.handleSubscriptionCreate(stripe, subscription);
break;
case 'customer.subscription.updated':
subscription = event.data.object;
status = subscription.status;
await eventTracker.notify({
message: EventTracker.compileBasicNotification(
`Subscription status is ${status} for subscription with id: ${subscription.id}`,
'Stripe Webhook: customer.subscription.updated'
),
severity: 'info',
} satisfies INotifyMessage);
await this.handleSubscriptionUpdate(subscription);
await this.handleSubscriptionUpdate(stripe, subscription);
break;
default:
// Unexpected event type
Expand Down Expand Up @@ -136,12 +94,25 @@ export class WebhookController {
}
}

async handleSubscriptionCreate(stripeSubscription: Stripe.Subscription, customer?: CustomerEntity): Promise<void> {
async handleSubscriptionCreate(
stripe: Stripe,
stripeSubscription: Stripe.Subscription,
customer?: CustomerEntity
): Promise<void> {
const data = buildSubscriptionData(stripeSubscription);
const operation = OperationNameEnum.SUBSCRIPTION_CREATE;

await eventTracker.notify({
message: EventTracker.compileBasicNotification(
`Subscription status is ${stripeSubscription.status} for subscription with id: ${stripeSubscription.id}`,
'Stripe Webhook: customer.subscription.created'
),
severity: 'info',
} satisfies INotifyMessage);

const [product, stripeCustomer] = await Promise.all([
this.stripe.products.retrieve(data.productId),
this.stripe.customers.retrieve(data.paymentProviderId),
stripe.products.retrieve(data.productId),
stripe.customers.retrieve(data.paymentProviderId),
]);
if (!customer) {
const customers = await CustomerService.instance.customerRepository.find({
Expand Down Expand Up @@ -233,10 +204,18 @@ export class WebhookController {
});
}

async handleSubscriptionUpdate(stripeSubscription: Stripe.Subscription): Promise<void> {
async handleSubscriptionUpdate(stripe: Stripe, stripeSubscription: Stripe.Subscription): Promise<void> {
const data = buildSubscriptionData(stripeSubscription);
const operation = OperationNameEnum.SUBSCRIPTION_UPDATE;

await eventTracker.notify({
message: EventTracker.compileBasicNotification(
`Subscription status is ${stripeSubscription.status} for subscription with id: ${stripeSubscription.id}`,
'Stripe Webhook: customer.subscription.updated'
),
severity: 'info',
} satisfies INotifyMessage);

const subscription = await SubscriptionService.instance.update(
data.subscriptionId,
data.status,
Expand All @@ -260,7 +239,7 @@ export class WebhookController {

const [customer, product] = await Promise.all([
CustomerService.instance.findbyPaymentProviderId(data.paymentProviderId),
this.stripe.products.retrieve(data.productId),
stripe.products.retrieve(data.productId),
]);

if (customer) {
Expand All @@ -276,10 +255,18 @@ export class WebhookController {
});
}

async handleSubscriptionCancel(stripeSubscription: Stripe.Subscription): Promise<void> {
async handleSubscriptionCancel(stripe: Stripe, stripeSubscription: Stripe.Subscription): Promise<void> {
const data = buildSubscriptionData(stripeSubscription);
const operation = OperationNameEnum.SUBSCRIPTION_CANCEL;

await eventTracker.notify({
message: EventTracker.compileBasicNotification(
`Subscription status is ${stripeSubscription.status} for subscription with id: ${stripeSubscription.id}`,
'Stripe Webhook: customer.subscription.deleted'
),
severity: 'info',
} satisfies INotifyMessage);

const subscription = await SubscriptionService.instance.update(data.subscriptionId, data.status);
if (!subscription) {
const message = EventTracker.compileBasicNotification(
Expand Down
23 changes: 12 additions & 11 deletions src/services/admin/stripe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ dotenv.config();

export class StripeService {
private isFullySynced = false;
private stripe: Stripe;

constructor() {
this.stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
}

async syncAll(next: NextFunction): Promise<void> {
if (!this.isFullySynced) {
Expand All @@ -21,9 +26,8 @@ export class StripeService {
}

async syncFull(): Promise<void> {
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
// Sync all subscriptions
for await (const subscription of stripe.subscriptions.list({
for await (const subscription of this.stripe.subscriptions.list({
status: 'all',
})) {
const current = await SubscriptionService.instance.subscriptionRepository.findOne({
Expand All @@ -46,8 +50,7 @@ export class StripeService {

// Sync all the subscriptions for current customer
async syncCustomer(customer: CustomerEntity): Promise<void> {
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
for await (const subscription of stripe.subscriptions.list({
for await (const subscription of this.stripe.subscriptions.list({
customer: customer.paymentProviderId,
status: 'all',
})) {
Expand All @@ -63,8 +66,6 @@ export class StripeService {
}

async syncOne(customer: CustomerEntity): Promise<void> {
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);

const local = await SubscriptionService.instance.findCurrent(customer);
if (!local) {
await eventTracker.notify({
Expand All @@ -74,11 +75,11 @@ export class StripeService {
),
severity: 'debug',
});
const activeSubs = await stripe.subscriptions.list({
const activeSubs = await this.stripe.subscriptions.list({
customer: customer.paymentProviderId,
status: 'active',
});
const trialSubs = await stripe.subscriptions.list({
const trialSubs = await this.stripe.subscriptions.list({
customer: customer.paymentProviderId,
status: 'trialing',
});
Expand All @@ -99,7 +100,7 @@ export class StripeService {
return;
}
const subscriptionId = local.subscriptionId;
const remote = await stripe.subscriptions.retrieve(subscriptionId);
const remote = await this.stripe.subscriptions.retrieve(subscriptionId);
if (!remote) {
await eventTracker.notify({
message: EventTracker.compileBasicNotification(
Expand All @@ -121,7 +122,7 @@ export class StripeService {
}

async createSubscription(subscription: Stripe.Subscription, customer?: CustomerEntity): Promise<void> {
await WebhookController.instance.handleSubscriptionCreate(subscription, customer);
await WebhookController.instance.handleSubscriptionCreate(this.stripe, subscription, customer);
}

async updateSubscription(subscription: Stripe.Subscription, current: SubscriptionEntity): Promise<void> {
Expand All @@ -136,7 +137,7 @@ export class StripeService {
});
return;
}
await WebhookController.instance.handleSubscriptionUpdate(subscription);
await WebhookController.instance.handleSubscriptionUpdate(this.stripe, subscription);
}
}

Expand Down

0 comments on commit 377aae6

Please sign in to comment.