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:
@@ -7,3 +7,4 @@ export * from "./mixpanel-service";
|
||||
export * from "./ga4-service";
|
||||
export * from "./ga4-loader";
|
||||
export * from "./stripe-service";
|
||||
export * from "./analytics-config";
|
||||
|
||||
130
src/lib/analytics/stripe-webhook.ts
Normal file
130
src/lib/analytics/stripe-webhook.ts
Normal 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);
|
||||
};
|
||||
Reference in New Issue
Block a user