6 - September - 2025
- βοΈ Tech Stack: Next.js 14, TypeScript, Prisma, MongoDB, Stripe
- π User Authentication with Kinde Auth
- πΈ Monthly & Annually Subscriptions with Stripe
- π΅ Building a Stripe Billing Portal
- πͺ Subscriptions Webhooks
- π Stripe Event Types
- π Light/Dark Mode
- π Deployment
DATABASE_URL= get_your_mongo_db_url
KINDE_CLIENT_SECRET =
KINDE_CLIENT_ID =
KINDE_ISSUER_URL =
KINDE_SITE_URL =
KINDE_POST_LOGOUT_REDIRECT_URL =
KINDE_POST_LOGIN_REDIRECT_URL =
STRIPE_MONTHLY_PLAN_LINK = get_from_stripe
STRIPE_YEARLY_PLAN_LINK = get_from_stripe
STRIPE_MONTHLY_PRICE_ID = get_from_stripe
STRIPE_YEARLY_PRICE_ID = get_from_stripe
STRIPE_SECRET_KEY = get_from_stripe
STRIPE_WEBHOOK_SECRET = get_from_stripe
NEXT_PUBLIC_STRIPE_CUSTOMER_PORTAL_URL = get_from_stripe
npm install
npm run dev
- File & Folder Structure
- Stripe product setup
- create product link + id
- same product 2 version for monthly & yearly
- webhook -
local running
for testing- yarn add stripe
- download & install
stripe cli
& PATH configure - stripe login
- stripe listen --forward-to localhost:3000/api/webhooks/stripe
- create product link + id
- System Design
- API Integration
- State Management
- Integration Engineering
- Practical Software Engineering
- npx shadcn@latest add dropdown-menu
- npx shadcn@latest add navigation-menu
- npx shadcn@latest add badge
- npx shadcn@latest add card
- prisma + mongodb
- npx prisma init
- npx prisma db push
- ποΈ Architecture with π§ clarity
π 1. ENTRY POINT β POST /api/webhooks
π 2. VERIFY SIGNATURE β verify_Stripe_Webhook_Signature(...)
π§ 3. ROUTE EVENT β handle_Webhook_Event_Route(...)
π 4. HANDLE CHECKOUT COMPLETED β handle_Checkout_Session_Completed(...)
π€ 5. SYNC USER β sync_User_With_Stripe_Customer_Id(...)
π
6. UPDATE SUBSCRIPTION β update_Subscription_Info_For_User(...)
Verify β Route β Sync β Update β Plan
[Stripe POST]
β
[Verify Signature] β Trust β
β
[Route by Event Type] β checkout.session.completed
β
[Retrieve Session + Line Items]
β
[Find User by Email] β Sync/Link customerId
β
[For Each Item] β Is Subscription?
β [Yes] β Update Subscription + Upgrade User Plan
β [No] β Skip (One-time)
β
[Return 200] β Done β
πͺ Layer 1: Entry & Verification
route.ts
βββ verifyStripeWebhookSignature
π§ Layer 2: Routing & Event Handling
handleStripeWebhookEventRoute
βββ handleCheckoutSessionCompleted
π§ Layer 3: User Sync
handleCheckoutSessionCompleted
βββ syncUserWithStripeCustomerId
βββ Prisma (find + update)
π¦ Layer 4: Subscription & Plan Activation
handleCheckoutSessionCompleted
βββ updateSubscriptionInfoForUser
βββ getPlanDetails
βββ Prisma (upsert subscription + update user plan)
POST /api/webhooks (route.ts)
β
βΌ
verifyStripeWebhookSignature(payload, signature, secret) β returns Stripe.Event
β
βΌ
handleStripeWebhookEventRoute(event) β routes by event.type
β
βΌ
handleCheckoutSessionCompleted(session) β main logic for payment success
β
βββββββββββββββββΊ syncUserWithStripeCustomerId(email, customerId) β returns User
β β
β βΌ
β prisma.user.findUnique + .update
β
βΌ
FOR EACH line_item β if subscription β updateSubscriptionInfoForUser(userId, priceId)
β
βΌ
getPlanDetails(priceId) β returns { period, endDate }
β
βΌ
prisma.subscription.upsert
β
βΌ
prisma.user.update β set plan = "premium"
- β° All events happened within ~15 seconds β typical for a successful subscription checkout.
- Stripe sends 20+ events for one checkout β we only need 1β2 to start.
- Stripe sends one webhook event per system action &
- a subscription checkout triggers many actions - almost 7+
- WEBHOOK - ENDPOINT
2025-09-20 20:21:00 --> charge.succeeded [evt_3SuX] β π° Money captured!
2025-09-20 20:21:00 --> payment_method.attached [evt_1Sgb]
2025-09-20 20:21:00 --> customer.created [evt_1SX3]
2025-09-20 20:21:00 --> customer.updated [evt_1Shv]
2025-09-20 20:21:00 --> checkout.session.completed [evt_1SiA] β π― THIS IS OUR WORKING EVENT AREA
2025-09-20 20:21:00 --> customer.subscription.created [evt_1S8k]
2025-09-20 20:21:00 <-- [200] POST [WEBHOOK - ENDPOINT] [evt_1Sgb]
2025-09-20 20:21:00 <-- [200] POST [WEBHOOK - ENDPOINT] [evt_3SuX]
2025-09-20 20:21:00 <-- [200] POST [WEBHOOK - ENDPOINT] [evt_1SX3]
2025-09-20 20:21:00 <-- [200] POST [WEBHOOK - ENDPOINT] [evt_1S8k]
2025-09-20 20:21:00 <-- [200] POST [WEBHOOK - ENDPOINT] [evt_1Shv]
2025-09-20 20:21:01 --> payment_intent.created [evt_3S9o]
2025-09-20 20:21:01 --> payment_intent.succeeded [evt_3SIm] β β
Payment authorized & succeeded
2025-09-20 20:21:01 <-- [200] POST [WEBHOOK - ENDPOINT] [evt_3S9o]
2025-09-20 20:21:01 <-- [200] POST [WEBHOOK - ENDPOINT] [evt_3SIm]
2025-09-20 20:21:01 --> invoice.created [evt_1Sm8]
2025-09-20 20:21:01 --> invoice.finalized [evt_1SOF]
2025-09-20 20:21:01 <-- [200] POST [WEBHOOK - ENDPOINT] [evt_1Sm8]
2025-09-20 20:21:01 <-- [200] POST [WEBHOOK - ENDPOINT] [evt_1SOF]
2025-09-20 20:21:01 --> invoice.paid [evt_1SQa]
2025-09-20 20:21:01 --> invoice.payment_succeeded [evt_1Swm]
2025-09-20 20:21:01 <-- [200] POST [WEBHOOK - ENDPOINT] [evt_1SQa]
2025-09-20 20:21:01 <-- [200] POST [WEBHOOK - ENDPOINT] [evt_1Swm]
2025-09-20 20:21:08 <-- [200] POST [WEBHOOK - ENDPOINT] [evt_1SiA]
2025-09-20 20:21:15 --> invoice_payment.paid [evt_1SEa]
2025-09-20 20:21:15 <-- [200] POST [WEBHOOK - ENDPOINT] [evt_1SEa]
2025-09-21 03:56:05 --> billing_portal.configuration.created [evt_1SJL]
2025-09-21 03:56:05 --> billing_portal.configuration.updated [evt_1SwW]
2025-09-21 03:56:08 <-- [200] POST [WEBHOOK - ENDPOINT] [evt_1SwW]
2025-09-21 03:56:08 <-- [200] POST [WEBHOOK - ENDPOINT] [evt_1SJL]
2025-09-21 03:58:43 --> billing_portal.configuration.updated [evt_1SQW]
2025-09-21 03:58:44 <-- [200] POST [WEBHOOK - ENDPOINT] [evt_1SQW]
2025-09-21 04:03:22 --> billing_portal.session.created [evt_1SSt]
2025-09-21 04:03:24 <-- [200] POST [WEBHOOK - ENDPOINT] [evt_1SSt]
2025-09-21 04:08:46 --> setup_intent.created [evt_1SIf]
2025-09-21 04:08:46 <-- [200] POST [WEBHOOK - ENDPOINT] [evt_1SIf]
2025-09-21 04:15:17 --> customer.subscription.updated [evt_1SeJ]
2025-09-21 04:15:17 <-- [200] POST [WEBHOOK - ENDPOINT] [evt_1SeJ]
2025-09-21 04:18:12 --> customer.subscription.deleted [evt_1SoF] β π― THIS IS OUR WORKING EVENT AREA
2025-09-21 04:18:17 <-- [200] POST [WEBHOOK - ENDPOINT] [evt_1SoF]