| import Stripe from 'stripe'; |
| import { Request, Response } from 'express'; |
| import { ENV } from '../_core/env'; |
|
|
| const stripe = new Stripe(ENV.stripeSecretKey); |
|
|
| |
| |
| |
| |
| export async function handleStripeWebhook(req: Request, res: Response) { |
| const sig = req.headers['stripe-signature'] as string; |
|
|
| let event: Stripe.Event; |
|
|
| try { |
| event = stripe.webhooks.constructEvent( |
| req.body, |
| sig, |
| ENV.stripeWebhookSecret |
| ); |
| } catch (err) { |
| console.error('[Stripe Webhook] Signature verification failed:', err); |
| return res.status(400).send(`Webhook Error: ${err}`); |
| } |
|
|
| |
| if (event.id.startsWith('evt_test_')) { |
| console.log('[Stripe Webhook] Test event detected, returning verification response'); |
| return res.json({ |
| verified: true, |
| }); |
| } |
|
|
| try { |
| switch (event.type) { |
| case 'checkout.session.completed': { |
| const session = event.data.object as Stripe.Checkout.Session; |
| console.log('[Stripe Webhook] Checkout session completed:', session.id); |
| |
| |
| const userId = session.metadata?.user_id; |
| const productId = session.metadata?.product_id; |
| const customerEmail = session.customer_email; |
|
|
| console.log('[Stripe Webhook] Order details:', { |
| sessionId: session.id, |
| userId, |
| productId, |
| customerEmail, |
| amount: session.amount_total, |
| currency: session.currency, |
| }); |
|
|
| |
| |
| |
| |
| |
|
|
| break; |
| } |
|
|
| case 'payment_intent.succeeded': { |
| const paymentIntent = event.data.object as Stripe.PaymentIntent; |
| console.log('[Stripe Webhook] Payment intent succeeded:', paymentIntent.id); |
| |
| |
| |
| |
| |
|
|
| break; |
| } |
|
|
| case 'payment_intent.payment_failed': { |
| const paymentIntent = event.data.object as Stripe.PaymentIntent; |
| console.log('[Stripe Webhook] Payment intent failed:', paymentIntent.id); |
| |
| |
| |
| |
| |
|
|
| break; |
| } |
|
|
| case 'customer.subscription.created': { |
| const subscription = event.data.object as Stripe.Subscription; |
| console.log('[Stripe Webhook] Subscription created:', subscription.id); |
| |
| |
| |
| |
| |
|
|
| break; |
| } |
|
|
| case 'customer.subscription.updated': { |
| const subscription = event.data.object as Stripe.Subscription; |
| console.log('[Stripe Webhook] Subscription updated:', subscription.id); |
| |
| |
| |
| |
|
|
| break; |
| } |
|
|
| case 'customer.subscription.deleted': { |
| const subscription = event.data.object as Stripe.Subscription; |
| console.log('[Stripe Webhook] Subscription deleted:', subscription.id); |
| |
| |
| |
| |
| |
|
|
| break; |
| } |
|
|
| case 'invoice.paid': { |
| const invoice = event.data.object as Stripe.Invoice; |
| console.log('[Stripe Webhook] Invoice paid:', invoice.id); |
| |
| |
| |
| |
| |
|
|
| break; |
| } |
|
|
| case 'invoice.payment_failed': { |
| const invoice = event.data.object as Stripe.Invoice; |
| console.log('[Stripe Webhook] Invoice payment failed:', invoice.id); |
| |
| |
| |
| |
| |
|
|
| break; |
| } |
|
|
| default: |
| console.log('[Stripe Webhook] Unhandled event type:', event.type); |
| } |
|
|
| |
| res.json({ received: true }); |
| } catch (error) { |
| console.error('[Stripe Webhook] Error processing event:', error); |
| res.status(500).json({ error: 'Webhook processing failed' }); |
| } |
| } |
|
|