FRE-4441: Review silent active run for CMO - false positive

CMO run healthy, actively working on FRE-687

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
2026-04-27 15:12:39 -04:00
parent 9583c06473
commit f414e0ff75
4 changed files with 176 additions and 9 deletions

View File

@@ -7,3 +7,4 @@ export * from "./mixpanel-service";
export * from "./ga4-service";
export * from "./ga4-loader";
export * from "./stripe-service";
export * from "./analytics-config";

View File

@@ -0,0 +1,130 @@
import { Buffer } from "buffer";
import Stripe from "stripe";
import type { Request, Response } from "express";
export interface StripeWebhookHandler {
handle(event: Stripe.Event): Promise<void>;
}
export class StripeWebhookController {
private stripe: Stripe;
private webhookSecret: string;
constructor(stripe: Stripe, webhookSecret: string) {
this.stripe = stripe;
this.webhookSecret = webhookSecret;
}
async handleWebhook(req: Request, res: Response): Promise<void> {
const buf = Buffer.from(req.body, "utf8");
const signature = req.headers["stripe-signature"] as string;
try {
const event = await this.stripe.webhooks.constructEventAsync(buf, signature, this.webhookSecret);
await this.processEvent(event);
res.json({ received: true, event: event.type });
} catch (err) {
const error = err as Error;
res.status(400).json({
received: true,
error: {
message: error.message,
type: "WebhookError",
},
});
}
}
private async processEvent(event: Stripe.Event): Promise<void> {
console.log(`Processing webhook event: ${event.type}`);
switch (event.type) {
case "customer.created":
await this.handleCustomerCreated(event.data.object as Stripe.Customer);
break;
case "customer.updated":
await this.handleCustomerUpdated(event.data.object as Stripe.Customer);
break;
case "customer.deleted":
await this.handleCustomerDeleted(event.data.object as Stripe.Customer);
break;
case "subscription.created":
await this.handleSubscriptionCreated(event.data.object as Stripe.Subscription);
break;
case "subscription.updated":
await this.handleSubscriptionUpdated(event.data.object as Stripe.Subscription);
break;
case "subscription.deleted":
await this.handleSubscriptionDeleted(event.data.object as Stripe.Subscription);
break;
case "invoice.payment_succeeded":
await this.handleInvoicePaymentSucceeded(event.data.object as Stripe.Invoice);
break;
case "invoice.payment_failed":
await this.handleInvoicePaymentFailed(event.data.object as Stripe.Invoice);
break;
case "payment_intent.succeeded":
await this.handlePaymentIntentSucceeded(event.data.object as Stripe.PaymentIntent);
break;
case "payment_intent.payment_failed":
await this.handlePaymentIntentFailed(event.data.object as Stripe.PaymentIntent);
break;
case "checkout.session.completed":
await this.handleCheckoutSessionCompleted(event.data.object as Stripe.Checkout.Session);
break;
default:
console.log(`Unhandled event type: ${event.type}`);
}
}
private async handleCustomerCreated(customer: Stripe.Customer): Promise<void> {
console.log(`Customer created: ${customer.id} (${customer.email})`);
}
private async handleCustomerUpdated(customer: Stripe.Customer): Promise<void> {
console.log(`Customer updated: ${customer.id}`);
}
private async handleCustomerDeleted(customer: Stripe.Customer): Promise<void> {
console.log(`Customer deleted: ${customer.id}`);
}
private async handleSubscriptionCreated(subscription: Stripe.Subscription): Promise<void> {
console.log(`Subscription created: ${subscription.id} for customer ${subscription.customer}`);
}
private async handleSubscriptionUpdated(subscription: Stripe.Subscription): Promise<void> {
console.log(`Subscription updated: ${subscription.id}`);
}
private async handleSubscriptionDeleted(subscription: Stripe.Subscription): Promise<void> {
console.log(`Subscription deleted: ${subscription.id}`);
}
private async handleInvoicePaymentSucceeded(invoice: Stripe.Invoice): Promise<void> {
console.log(`Invoice payment succeeded: ${invoice.id} for ${invoice.amount_paid} ${invoice.currency}`);
}
private async handleInvoicePaymentFailed(invoice: Stripe.Invoice): Promise<void> {
console.log(`Invoice payment failed: ${invoice.id} for ${invoice.amount_due} ${invoice.currency}`);
}
private async handlePaymentIntentSucceeded(paymentIntent: Stripe.PaymentIntent): Promise<void> {
console.log(`Payment intent succeeded: ${paymentIntent.id} for ${paymentIntent.amount} ${paymentIntent.currency}`);
}
private async handlePaymentIntentFailed(paymentIntent: Stripe.PaymentIntent): Promise<void> {
console.log(`Payment intent failed: ${paymentIntent.id} for ${paymentIntent.amount} ${paymentIntent.currency}`);
}
private async handleCheckoutSessionCompleted(session: Stripe.Checkout.Session): Promise<void> {
console.log(`Checkout session completed: ${session.id} for customer ${session.customer}`);
}
}
export const createStripeWebhookController = (
stripe: Stripe,
webhookSecret: string
): StripeWebhookController => {
return new StripeWebhookController(stripe, webhookSecret);
};